cifs: add routines to build sessions and tcons on the fly
[deliverable/linux.git] / fs / cifs / connect.c
CommitLineData
1da177e4
LT
1/*
2 * fs/cifs/connect.c
3 *
d185cda7 4 * Copyright (C) International Business Machines Corp., 2002,2009
1da177e4
LT
5 * Author(s): Steve French (sfrench@us.ibm.com)
6 *
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
11 *
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
16 *
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
fb8c4b14 19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
1da177e4
LT
20 */
21#include <linux/fs.h>
22#include <linux/net.h>
23#include <linux/string.h>
24#include <linux/list.h>
25#include <linux/wait.h>
5a0e3ad6 26#include <linux/slab.h>
1da177e4
LT
27#include <linux/pagemap.h>
28#include <linux/ctype.h>
29#include <linux/utsname.h>
30#include <linux/mempool.h>
b8643e1b 31#include <linux/delay.h>
f191401f 32#include <linux/completion.h>
aaf737ad 33#include <linux/kthread.h>
0ae0efad 34#include <linux/pagevec.h>
7dfb7103 35#include <linux/freezer.h>
5c2503a8 36#include <linux/namei.h>
1da177e4
LT
37#include <asm/uaccess.h>
38#include <asm/processor.h>
50b64e3b 39#include <linux/inet.h>
0e2bedaa 40#include <net/ipv6.h>
1da177e4
LT
41#include "cifspdu.h"
42#include "cifsglob.h"
43#include "cifsproto.h"
44#include "cifs_unicode.h"
45#include "cifs_debug.h"
46#include "cifs_fs_sb.h"
47#include "ntlmssp.h"
48#include "nterr.h"
49#include "rfc1002pdu.h"
488f1d2d 50#include "fscache.h"
1da177e4
LT
51
52#define CIFS_PORT 445
53#define RFC1001_PORT 139
54
1da177e4
LT
55extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
56 unsigned char *p24);
57
58extern mempool_t *cifs_req_poolp;
59
60struct smb_vol {
61 char *username;
62 char *password;
63 char *domainname;
64 char *UNC;
65 char *UNCip;
1da177e4
LT
66 char *iocharset; /* local code page for mapping to and from Unicode */
67 char source_rfc1001_name[16]; /* netbios name of client */
a10faeb2 68 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
3e4b3e1f 69 uid_t cred_uid;
1da177e4
LT
70 uid_t linux_uid;
71 gid_t linux_gid;
72 mode_t file_mode;
73 mode_t dir_mode;
189acaae 74 unsigned secFlg;
4b18f2a9
SF
75 bool retry:1;
76 bool intr:1;
77 bool setuids:1;
78 bool override_uid:1;
79 bool override_gid:1;
d0a9c078 80 bool dynperm:1;
4b18f2a9
SF
81 bool noperm:1;
82 bool no_psx_acl:1; /* set if posix acl support should be disabled */
83 bool cifs_acl:1;
84 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
85 bool server_ino:1; /* use inode numbers from server ie UniqueId */
86 bool direct_io:1;
95b1cb90
SF
87 bool remap:1; /* set to remap seven reserved chars in filenames */
88 bool posix_paths:1; /* unset to not ask for posix pathnames. */
4b18f2a9
SF
89 bool no_linux_ext:1;
90 bool sfu_emul:1;
95b1cb90
SF
91 bool nullauth:1; /* attempt to authenticate with null user */
92 bool nocase:1; /* request case insensitive filenames */
93 bool nobrl:1; /* disable sending byte range locks to srv */
13a6e42a 94 bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
95b1cb90 95 bool seal:1; /* request transport encryption on share */
84210e91
SF
96 bool nodfs:1; /* Do not request DFS, even if available */
97 bool local_lease:1; /* check leases only on local system, not remote */
edf1ae40
SF
98 bool noblocksnd:1;
99 bool noautotune:1;
be652445 100 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
fa1df75d 101 bool fsc:1; /* enable fscache */
736a3320 102 bool mfsymlinks:1; /* use Minshall+French Symlinks */
1da177e4
LT
103 unsigned int rsize;
104 unsigned int wsize;
6a5fa236 105 bool sockopt_tcp_nodelay:1;
1da177e4 106 unsigned short int port;
fb8c4b14 107 char *prepath;
3eb9a889 108 struct sockaddr_storage srcaddr; /* allow binding to a local IP */
a5fc4ce0 109 struct nls_table *local_nls;
1da177e4
LT
110};
111
9d002df4
JL
112#define TLINK_ERROR_EXPIRE (1 * HZ)
113
114
bcf4b106 115static int ipv4_connect(struct TCP_Server_Info *server);
d5c5605c 116static int ipv6_connect(struct TCP_Server_Info *server);
1da177e4 117
d5c5605c
JL
118/*
119 * cifs tcp session reconnection
120 *
121 * mark tcp session as reconnecting so temporarily locked
122 * mark all smb sessions as reconnecting for tcp session
123 * reconnect tcp session
124 * wake up waiters on reconnection? - (not needed currently)
125 */
2cd646a2 126static int
1da177e4
LT
127cifs_reconnect(struct TCP_Server_Info *server)
128{
129 int rc = 0;
f1987b44 130 struct list_head *tmp, *tmp2;
1da177e4
LT
131 struct cifsSesInfo *ses;
132 struct cifsTconInfo *tcon;
fb8c4b14 133 struct mid_q_entry *mid_entry;
50c2f753 134
1da177e4 135 spin_lock(&GlobalMid_Lock);
469ee614 136 if (server->tcpStatus == CifsExiting) {
fb8c4b14 137 /* the demux thread will exit normally
1da177e4
LT
138 next time through the loop */
139 spin_unlock(&GlobalMid_Lock);
140 return rc;
141 } else
142 server->tcpStatus = CifsNeedReconnect;
143 spin_unlock(&GlobalMid_Lock);
144 server->maxBuf = 0;
145
b6b38f70 146 cFYI(1, "Reconnecting tcp session");
1da177e4
LT
147
148 /* before reconnecting the tcp session, mark the smb session (uid)
149 and the tid bad so they are not used until reconnected */
14fbf50d
JL
150 read_lock(&cifs_tcp_ses_lock);
151 list_for_each(tmp, &server->smb_ses_list) {
152 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
153 ses->need_reconnect = true;
154 ses->ipc_tid = 0;
f1987b44
JL
155 list_for_each(tmp2, &ses->tcon_list) {
156 tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list);
3b795210 157 tcon->need_reconnect = true;
1da177e4 158 }
1da177e4 159 }
f1987b44 160 read_unlock(&cifs_tcp_ses_lock);
1da177e4 161 /* do not want to be sending data on a socket we are freeing */
72ca545b 162 mutex_lock(&server->srv_mutex);
fb8c4b14 163 if (server->ssocket) {
b6b38f70
JP
164 cFYI(1, "State: 0x%x Flags: 0x%lx", server->ssocket->state,
165 server->ssocket->flags);
91cf45f0 166 kernel_sock_shutdown(server->ssocket, SHUT_WR);
b6b38f70 167 cFYI(1, "Post shutdown state: 0x%x Flags: 0x%lx",
467a8f8d 168 server->ssocket->state,
b6b38f70 169 server->ssocket->flags);
1da177e4
LT
170 sock_release(server->ssocket);
171 server->ssocket = NULL;
172 }
173
174 spin_lock(&GlobalMid_Lock);
175 list_for_each(tmp, &server->pending_mid_q) {
176 mid_entry = list_entry(tmp, struct
177 mid_q_entry,
178 qhead);
ad8b15f0 179 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
09d1db5c
SF
180 /* Mark other intransit requests as needing
181 retry so we do not immediately mark the
182 session bad again (ie after we reconnect
183 below) as they timeout too */
ad8b15f0 184 mid_entry->midState = MID_RETRY_NEEDED;
1da177e4
LT
185 }
186 }
187 spin_unlock(&GlobalMid_Lock);
72ca545b 188 mutex_unlock(&server->srv_mutex);
1da177e4 189
469ee614
JL
190 while ((server->tcpStatus != CifsExiting) &&
191 (server->tcpStatus != CifsGood)) {
6c3d8909 192 try_to_freeze();
bcf4b106 193 if (server->addr.sockAddr6.sin6_family == AF_INET6)
d5c5605c 194 rc = ipv6_connect(server);
bcf4b106
JL
195 else
196 rc = ipv4_connect(server);
fb8c4b14 197 if (rc) {
b6b38f70 198 cFYI(1, "reconnect error %d", rc);
0cb766ae 199 msleep(3000);
1da177e4
LT
200 } else {
201 atomic_inc(&tcpSesReconnectCount);
202 spin_lock(&GlobalMid_Lock);
469ee614 203 if (server->tcpStatus != CifsExiting)
1da177e4 204 server->tcpStatus = CifsGood;
ad009ac9 205 server->sequence_number = 0;
fb8c4b14 206 spin_unlock(&GlobalMid_Lock);
1da177e4
LT
207 /* atomic_set(&server->inFlight,0);*/
208 wake_up(&server->response_q);
209 }
210 }
211 return rc;
212}
213
fb8c4b14 214/*
e4eb295d
SF
215 return codes:
216 0 not a transact2, or all data present
217 >0 transact2 with that much data missing
218 -EINVAL = invalid transact2
219
220 */
fb8c4b14 221static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
e4eb295d 222{
fb8c4b14
SF
223 struct smb_t2_rsp *pSMBt;
224 int total_data_size;
e4eb295d
SF
225 int data_in_this_rsp;
226 int remaining;
227
fb8c4b14 228 if (pSMB->Command != SMB_COM_TRANSACTION2)
e4eb295d
SF
229 return 0;
230
fb8c4b14
SF
231 /* check for plausible wct, bcc and t2 data and parm sizes */
232 /* check for parm and data offset going beyond end of smb */
233 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
b6b38f70 234 cFYI(1, "invalid transact2 word count");
e4eb295d
SF
235 return -EINVAL;
236 }
237
238 pSMBt = (struct smb_t2_rsp *)pSMB;
239
240 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
241 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
242
243 remaining = total_data_size - data_in_this_rsp;
244
fb8c4b14 245 if (remaining == 0)
e4eb295d 246 return 0;
fb8c4b14 247 else if (remaining < 0) {
b6b38f70
JP
248 cFYI(1, "total data %d smaller than data in frame %d",
249 total_data_size, data_in_this_rsp);
e4eb295d
SF
250 return -EINVAL;
251 } else {
b6b38f70
JP
252 cFYI(1, "missing %d bytes from transact2, check next response",
253 remaining);
fb8c4b14 254 if (total_data_size > maxBufSize) {
b6b38f70
JP
255 cERROR(1, "TotalDataSize %d is over maximum buffer %d",
256 total_data_size, maxBufSize);
fb8c4b14 257 return -EINVAL;
e4eb295d
SF
258 }
259 return remaining;
260 }
261}
262
fb8c4b14 263static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
e4eb295d
SF
264{
265 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
266 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
267 int total_data_size;
268 int total_in_buf;
269 int remaining;
270 int total_in_buf2;
fb8c4b14
SF
271 char *data_area_of_target;
272 char *data_area_of_buf2;
e4eb295d
SF
273 __u16 byte_count;
274
275 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
276
fb8c4b14 277 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
b6b38f70 278 cFYI(1, "total data size of primary and secondary t2 differ");
e4eb295d
SF
279 }
280
281 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
282
283 remaining = total_data_size - total_in_buf;
50c2f753 284
fb8c4b14 285 if (remaining < 0)
e4eb295d
SF
286 return -EINVAL;
287
fb8c4b14 288 if (remaining == 0) /* nothing to do, ignore */
e4eb295d 289 return 0;
50c2f753 290
e4eb295d 291 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
fb8c4b14 292 if (remaining < total_in_buf2) {
b6b38f70 293 cFYI(1, "transact2 2nd response contains too much data");
e4eb295d
SF
294 }
295
296 /* find end of first SMB data area */
fb8c4b14 297 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
e4eb295d
SF
298 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
299 /* validate target area */
300
301 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
fb8c4b14 302 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
e4eb295d
SF
303
304 data_area_of_target += total_in_buf;
305
306 /* copy second buffer into end of first buffer */
fb8c4b14 307 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
e4eb295d
SF
308 total_in_buf += total_in_buf2;
309 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
310 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
311 byte_count += total_in_buf2;
312 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
313
70ca734a 314 byte_count = pTargetSMB->smb_buf_length;
e4eb295d
SF
315 byte_count += total_in_buf2;
316
317 /* BB also add check that we are not beyond maximum buffer size */
50c2f753 318
70ca734a 319 pTargetSMB->smb_buf_length = byte_count;
e4eb295d 320
fb8c4b14 321 if (remaining == total_in_buf2) {
b6b38f70 322 cFYI(1, "found the last secondary response");
e4eb295d
SF
323 return 0; /* we are done */
324 } else /* more responses to go */
325 return 1;
326
327}
328
1da177e4
LT
329static int
330cifs_demultiplex_thread(struct TCP_Server_Info *server)
331{
332 int length;
333 unsigned int pdu_length, total_read;
334 struct smb_hdr *smb_buffer = NULL;
b8643e1b
SF
335 struct smb_hdr *bigbuf = NULL;
336 struct smb_hdr *smallbuf = NULL;
1da177e4
LT
337 struct msghdr smb_msg;
338 struct kvec iov;
339 struct socket *csocket = server->ssocket;
340 struct list_head *tmp;
341 struct cifsSesInfo *ses;
342 struct task_struct *task_to_wake = NULL;
343 struct mid_q_entry *mid_entry;
70ca734a 344 char temp;
4b18f2a9
SF
345 bool isLargeBuf = false;
346 bool isMultiRsp;
e4eb295d 347 int reconnect;
1da177e4 348
1da177e4 349 current->flags |= PF_MEMALLOC;
b6b38f70 350 cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
93d0ec85
JL
351
352 length = atomic_inc_return(&tcpSesAllocCount);
353 if (length > 1)
26f57364
SF
354 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
355 GFP_KERNEL);
1da177e4 356
83144186 357 set_freezable();
469ee614 358 while (server->tcpStatus != CifsExiting) {
ede1327e
SF
359 if (try_to_freeze())
360 continue;
b8643e1b
SF
361 if (bigbuf == NULL) {
362 bigbuf = cifs_buf_get();
0fd1ffe0 363 if (!bigbuf) {
b6b38f70 364 cERROR(1, "No memory for large SMB response");
b8643e1b
SF
365 msleep(3000);
366 /* retry will check if exiting */
367 continue;
368 }
0fd1ffe0
PM
369 } else if (isLargeBuf) {
370 /* we are reusing a dirty large buf, clear its start */
26f57364 371 memset(bigbuf, 0, sizeof(struct smb_hdr));
1da177e4 372 }
b8643e1b
SF
373
374 if (smallbuf == NULL) {
375 smallbuf = cifs_small_buf_get();
0fd1ffe0 376 if (!smallbuf) {
b6b38f70 377 cERROR(1, "No memory for SMB response");
b8643e1b
SF
378 msleep(1000);
379 /* retry will check if exiting */
380 continue;
381 }
382 /* beginning of smb buffer is cleared in our buf_get */
383 } else /* if existing small buf clear beginning */
26f57364 384 memset(smallbuf, 0, sizeof(struct smb_hdr));
b8643e1b 385
4b18f2a9
SF
386 isLargeBuf = false;
387 isMultiRsp = false;
b8643e1b 388 smb_buffer = smallbuf;
1da177e4
LT
389 iov.iov_base = smb_buffer;
390 iov.iov_len = 4;
391 smb_msg.msg_control = NULL;
392 smb_msg.msg_controllen = 0;
f01d5e14
SF
393 pdu_length = 4; /* enough to get RFC1001 header */
394incomplete_rcv:
1da177e4
LT
395 length =
396 kernel_recvmsg(csocket, &smb_msg,
f01d5e14 397 &iov, 1, pdu_length, 0 /* BB other flags? */);
1da177e4 398
469ee614 399 if (server->tcpStatus == CifsExiting) {
1da177e4
LT
400 break;
401 } else if (server->tcpStatus == CifsNeedReconnect) {
b6b38f70 402 cFYI(1, "Reconnect after server stopped responding");
1da177e4 403 cifs_reconnect(server);
b6b38f70 404 cFYI(1, "call to reconnect done");
1da177e4
LT
405 csocket = server->ssocket;
406 continue;
522bbe65
JL
407 } else if (length == -ERESTARTSYS ||
408 length == -EAGAIN ||
409 length == -EINTR) {
b8643e1b 410 msleep(1); /* minimum sleep to prevent looping
1da177e4
LT
411 allowing socket to clear and app threads to set
412 tcpStatus CifsNeedReconnect if server hung */
c527c8a7
SF
413 if (pdu_length < 4) {
414 iov.iov_base = (4 - pdu_length) +
415 (char *)smb_buffer;
416 iov.iov_len = pdu_length;
417 smb_msg.msg_control = NULL;
418 smb_msg.msg_controllen = 0;
c18c732e 419 goto incomplete_rcv;
c527c8a7 420 } else
c18c732e 421 continue;
1da177e4 422 } else if (length <= 0) {
b6b38f70
JP
423 cFYI(1, "Reconnect after unexpected peek error %d",
424 length);
1da177e4
LT
425 cifs_reconnect(server);
426 csocket = server->ssocket;
427 wake_up(&server->response_q);
428 continue;
2a974680 429 } else if (length < pdu_length) {
b6b38f70
JP
430 cFYI(1, "requested %d bytes but only got %d bytes",
431 pdu_length, length);
f01d5e14 432 pdu_length -= length;
f01d5e14
SF
433 msleep(1);
434 goto incomplete_rcv;
46810cbf 435 }
1da177e4 436
70ca734a
SF
437 /* The right amount was read from socket - 4 bytes */
438 /* so we can now interpret the length field */
46810cbf 439
70ca734a
SF
440 /* the first byte big endian of the length field,
441 is actually not part of the length but the type
442 with the most common, zero, as regular data */
443 temp = *((char *) smb_buffer);
46810cbf 444
fb8c4b14 445 /* Note that FC 1001 length is big endian on the wire,
70ca734a
SF
446 but we convert it here so it is always manipulated
447 as host byte order */
5ca33c6a 448 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
70ca734a
SF
449 smb_buffer->smb_buf_length = pdu_length;
450
b6b38f70 451 cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
46810cbf 452
70ca734a 453 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
fb8c4b14 454 continue;
70ca734a 455 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
b6b38f70 456 cFYI(1, "Good RFC 1002 session rsp");
e4eb295d 457 continue;
70ca734a 458 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
fb8c4b14 459 /* we get this from Windows 98 instead of
46810cbf 460 an error on SMB negprot response */
b6b38f70
JP
461 cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
462 pdu_length);
7332f2a6
JL
463 /* give server a second to clean up */
464 msleep(1000);
465 /* always try 445 first on reconnect since we get NACK
466 * on some if we ever connected to port 139 (the NACK
467 * is since we do not begin with RFC1001 session
468 * initialize frame)
469 */
32670396
JL
470 cifs_set_port((struct sockaddr *)
471 &server->addr.sockAddr, CIFS_PORT);
7332f2a6
JL
472 cifs_reconnect(server);
473 csocket = server->ssocket;
474 wake_up(&server->response_q);
475 continue;
70ca734a 476 } else if (temp != (char) 0) {
b6b38f70 477 cERROR(1, "Unknown RFC 1002 frame");
70ca734a
SF
478 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
479 length);
46810cbf
SF
480 cifs_reconnect(server);
481 csocket = server->ssocket;
482 continue;
e4eb295d
SF
483 }
484
485 /* else we have an SMB response */
fb8c4b14 486 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
26f57364 487 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
b6b38f70
JP
488 cERROR(1, "Invalid size SMB length %d pdu_length %d",
489 length, pdu_length+4);
e4eb295d
SF
490 cifs_reconnect(server);
491 csocket = server->ssocket;
492 wake_up(&server->response_q);
493 continue;
fb8c4b14 494 }
e4eb295d
SF
495
496 /* else length ok */
497 reconnect = 0;
498
fb8c4b14 499 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
4b18f2a9 500 isLargeBuf = true;
e4eb295d
SF
501 memcpy(bigbuf, smallbuf, 4);
502 smb_buffer = bigbuf;
503 }
504 length = 0;
505 iov.iov_base = 4 + (char *)smb_buffer;
506 iov.iov_len = pdu_length;
fb8c4b14 507 for (total_read = 0; total_read < pdu_length;
e4eb295d
SF
508 total_read += length) {
509 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
510 pdu_length - total_read, 0);
522bbe65 511 if (server->tcpStatus == CifsExiting) {
e4eb295d
SF
512 /* then will exit */
513 reconnect = 2;
514 break;
515 } else if (server->tcpStatus == CifsNeedReconnect) {
46810cbf
SF
516 cifs_reconnect(server);
517 csocket = server->ssocket;
fb8c4b14 518 /* Reconnect wakes up rspns q */
e4eb295d
SF
519 /* Now we will reread sock */
520 reconnect = 1;
521 break;
522bbe65
JL
522 } else if (length == -ERESTARTSYS ||
523 length == -EAGAIN ||
524 length == -EINTR) {
e4eb295d 525 msleep(1); /* minimum sleep to prevent looping,
fb8c4b14 526 allowing socket to clear and app
e4eb295d
SF
527 threads to set tcpStatus
528 CifsNeedReconnect if server hung*/
c18c732e 529 length = 0;
46810cbf 530 continue;
e4eb295d 531 } else if (length <= 0) {
b6b38f70
JP
532 cERROR(1, "Received no data, expecting %d",
533 pdu_length - total_read);
e4eb295d
SF
534 cifs_reconnect(server);
535 csocket = server->ssocket;
536 reconnect = 1;
537 break;
46810cbf 538 }
e4eb295d 539 }
fb8c4b14 540 if (reconnect == 2)
e4eb295d 541 break;
fb8c4b14 542 else if (reconnect == 1)
e4eb295d 543 continue;
1da177e4 544
e4eb295d 545 length += 4; /* account for rfc1002 hdr */
50c2f753 546
09d1db5c 547
e4eb295d 548 dump_smb(smb_buffer, length);
184ed211 549 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
b387eaeb 550 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
e4eb295d
SF
551 continue;
552 }
1da177e4 553
e4eb295d
SF
554
555 task_to_wake = NULL;
556 spin_lock(&GlobalMid_Lock);
557 list_for_each(tmp, &server->pending_mid_q) {
558 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
559
50c2f753 560 if ((mid_entry->mid == smb_buffer->Mid) &&
e4eb295d
SF
561 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
562 (mid_entry->command == smb_buffer->Command)) {
fb8c4b14 563 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
e4eb295d 564 /* We have a multipart transact2 resp */
4b18f2a9 565 isMultiRsp = true;
fb8c4b14 566 if (mid_entry->resp_buf) {
e4eb295d 567 /* merge response - fix up 1st*/
50c2f753 568 if (coalesce_t2(smb_buffer,
e4eb295d 569 mid_entry->resp_buf)) {
4b18f2a9
SF
570 mid_entry->multiRsp =
571 true;
e4eb295d
SF
572 break;
573 } else {
574 /* all parts received */
4b18f2a9
SF
575 mid_entry->multiEnd =
576 true;
50c2f753 577 goto multi_t2_fnd;
e4eb295d
SF
578 }
579 } else {
fb8c4b14 580 if (!isLargeBuf) {
b6b38f70 581 cERROR(1, "1st trans2 resp needs bigbuf");
e4eb295d 582 /* BB maybe we can fix this up, switch
50c2f753 583 to already allocated large buffer? */
e4eb295d 584 } else {
cd63499c 585 /* Have first buffer */
e4eb295d
SF
586 mid_entry->resp_buf =
587 smb_buffer;
4b18f2a9
SF
588 mid_entry->largeBuf =
589 true;
e4eb295d
SF
590 bigbuf = NULL;
591 }
592 }
593 break;
50c2f753 594 }
e4eb295d 595 mid_entry->resp_buf = smb_buffer;
4b18f2a9 596 mid_entry->largeBuf = isLargeBuf;
e4eb295d
SF
597multi_t2_fnd:
598 task_to_wake = mid_entry->tsk;
599 mid_entry->midState = MID_RESPONSE_RECEIVED;
1047abc1
SF
600#ifdef CONFIG_CIFS_STATS2
601 mid_entry->when_received = jiffies;
602#endif
3a5ff61c
SF
603 /* so we do not time out requests to server
604 which is still responding (since server could
605 be busy but not dead) */
606 server->lstrp = jiffies;
e4eb295d 607 break;
46810cbf 608 }
1da177e4 609 }
e4eb295d
SF
610 spin_unlock(&GlobalMid_Lock);
611 if (task_to_wake) {
cd63499c 612 /* Was previous buf put in mpx struct for multi-rsp? */
fb8c4b14 613 if (!isMultiRsp) {
cd63499c 614 /* smb buffer will be freed by user thread */
26f57364 615 if (isLargeBuf)
cd63499c 616 bigbuf = NULL;
26f57364 617 else
cd63499c
SF
618 smallbuf = NULL;
619 }
e4eb295d 620 wake_up_process(task_to_wake);
4b18f2a9
SF
621 } else if (!is_valid_oplock_break(smb_buffer, server) &&
622 !isMultiRsp) {
b6b38f70
JP
623 cERROR(1, "No task to wake, unknown frame received! "
624 "NumMids %d", midCount.counter);
50c2f753 625 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
70ca734a 626 sizeof(struct smb_hdr));
3979877e
SF
627#ifdef CONFIG_CIFS_DEBUG2
628 cifs_dump_detail(smb_buffer);
629 cifs_dump_mids(server);
630#endif /* CIFS_DEBUG2 */
50c2f753 631
e4eb295d
SF
632 }
633 } /* end while !EXITING */
634
e7ddee90
JL
635 /* take it off the list, if it's not already */
636 write_lock(&cifs_tcp_ses_lock);
637 list_del_init(&server->tcp_ses_list);
638 write_unlock(&cifs_tcp_ses_lock);
639
1da177e4
LT
640 spin_lock(&GlobalMid_Lock);
641 server->tcpStatus = CifsExiting;
e691b9d1 642 spin_unlock(&GlobalMid_Lock);
dbdbb876 643 wake_up_all(&server->response_q);
e691b9d1 644
31ca3bc3
SF
645 /* check if we have blocked requests that need to free */
646 /* Note that cifs_max_pending is normally 50, but
647 can be set at module install time to as little as two */
e691b9d1 648 spin_lock(&GlobalMid_Lock);
fb8c4b14 649 if (atomic_read(&server->inFlight) >= cifs_max_pending)
31ca3bc3
SF
650 atomic_set(&server->inFlight, cifs_max_pending - 1);
651 /* We do not want to set the max_pending too low or we
652 could end up with the counter going negative */
1da177e4 653 spin_unlock(&GlobalMid_Lock);
50c2f753 654 /* Although there should not be any requests blocked on
1da177e4 655 this queue it can not hurt to be paranoid and try to wake up requests
09d1db5c 656 that may haven been blocked when more than 50 at time were on the wire
1da177e4
LT
657 to the same server - they now will see the session is in exit state
658 and get out of SendReceive. */
659 wake_up_all(&server->request_q);
660 /* give those requests time to exit */
b8643e1b 661 msleep(125);
50c2f753 662
fb8c4b14 663 if (server->ssocket) {
1da177e4
LT
664 sock_release(csocket);
665 server->ssocket = NULL;
666 }
b8643e1b 667 /* buffer usuallly freed in free_mid - need to free it here on exit */
a8a11d39
MK
668 cifs_buf_release(bigbuf);
669 if (smallbuf) /* no sense logging a debug message if NULL */
b8643e1b 670 cifs_small_buf_release(smallbuf);
1da177e4 671
14fbf50d
JL
672 /*
673 * BB: we shouldn't have to do any of this. It shouldn't be
674 * possible to exit from the thread with active SMB sessions
675 */
676 read_lock(&cifs_tcp_ses_lock);
1da177e4 677 if (list_empty(&server->pending_mid_q)) {
09d1db5c
SF
678 /* loop through server session structures attached to this and
679 mark them dead */
14fbf50d
JL
680 list_for_each(tmp, &server->smb_ses_list) {
681 ses = list_entry(tmp, struct cifsSesInfo,
682 smb_ses_list);
683 ses->status = CifsExiting;
684 ses->server = NULL;
1da177e4 685 }
14fbf50d 686 read_unlock(&cifs_tcp_ses_lock);
1da177e4 687 } else {
31ca3bc3
SF
688 /* although we can not zero the server struct pointer yet,
689 since there are active requests which may depnd on them,
690 mark the corresponding SMB sessions as exiting too */
14fbf50d 691 list_for_each(tmp, &server->smb_ses_list) {
31ca3bc3 692 ses = list_entry(tmp, struct cifsSesInfo,
14fbf50d
JL
693 smb_ses_list);
694 ses->status = CifsExiting;
31ca3bc3
SF
695 }
696
1da177e4
LT
697 spin_lock(&GlobalMid_Lock);
698 list_for_each(tmp, &server->pending_mid_q) {
699 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
700 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
b6b38f70
JP
701 cFYI(1, "Clearing Mid 0x%x - waking up ",
702 mid_entry->mid);
1da177e4 703 task_to_wake = mid_entry->tsk;
26f57364 704 if (task_to_wake)
1da177e4 705 wake_up_process(task_to_wake);
1da177e4
LT
706 }
707 }
708 spin_unlock(&GlobalMid_Lock);
14fbf50d 709 read_unlock(&cifs_tcp_ses_lock);
1da177e4 710 /* 1/8th of sec is more than enough time for them to exit */
b8643e1b 711 msleep(125);
1da177e4
LT
712 }
713
f191401f 714 if (!list_empty(&server->pending_mid_q)) {
50c2f753 715 /* mpx threads have not exited yet give them
1da177e4 716 at least the smb send timeout time for long ops */
31ca3bc3
SF
717 /* due to delays on oplock break requests, we need
718 to wait at least 45 seconds before giving up
719 on a request getting a response and going ahead
720 and killing cifsd */
b6b38f70 721 cFYI(1, "Wait for exit from demultiplex thread");
31ca3bc3 722 msleep(46000);
1da177e4
LT
723 /* if threads still have not exited they are probably never
724 coming home not much else we can do but free the memory */
725 }
1da177e4 726
31ca3bc3
SF
727 /* last chance to mark ses pointers invalid
728 if there are any pointing to this (e.g
50c2f753 729 if a crazy root user tried to kill cifsd
31ca3bc3 730 kernel thread explicitly this might happen) */
14fbf50d
JL
731 /* BB: This shouldn't be necessary, see above */
732 read_lock(&cifs_tcp_ses_lock);
733 list_for_each(tmp, &server->smb_ses_list) {
734 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
735 ses->server = NULL;
31ca3bc3 736 }
14fbf50d 737 read_unlock(&cifs_tcp_ses_lock);
31ca3bc3 738
c359cf3c 739 kfree(server->hostname);
b1c8d2b4 740 task_to_wake = xchg(&server->tsk, NULL);
31ca3bc3 741 kfree(server);
93d0ec85
JL
742
743 length = atomic_dec_return(&tcpSesAllocCount);
26f57364
SF
744 if (length > 0)
745 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
746 GFP_KERNEL);
50c2f753 747
b1c8d2b4
JL
748 /* if server->tsk was NULL then wait for a signal before exiting */
749 if (!task_to_wake) {
750 set_current_state(TASK_INTERRUPTIBLE);
751 while (!signal_pending(current)) {
752 schedule();
753 set_current_state(TASK_INTERRUPTIBLE);
754 }
755 set_current_state(TASK_RUNNING);
756 }
757
0468a2cf 758 module_put_and_exit(0);
1da177e4
LT
759}
760
c359cf3c
JL
761/* extract the host portion of the UNC string */
762static char *
763extract_hostname(const char *unc)
764{
765 const char *src;
766 char *dst, *delim;
767 unsigned int len;
768
769 /* skip double chars at beginning of string */
770 /* BB: check validity of these bytes? */
771 src = unc + 2;
772
773 /* delimiter between hostname and sharename is always '\\' now */
774 delim = strchr(src, '\\');
775 if (!delim)
776 return ERR_PTR(-EINVAL);
777
778 len = delim - src;
779 dst = kmalloc((len + 1), GFP_KERNEL);
780 if (dst == NULL)
781 return ERR_PTR(-ENOMEM);
782
783 memcpy(dst, src, len);
784 dst[len] = '\0';
785
786 return dst;
787}
788
1da177e4 789static int
50c2f753
SF
790cifs_parse_mount_options(char *options, const char *devname,
791 struct smb_vol *vol)
1da177e4
LT
792{
793 char *value;
794 char *data;
795 unsigned int temp_len, i, j;
796 char separator[2];
9b9d6b24
JL
797 short int override_uid = -1;
798 short int override_gid = -1;
799 bool uid_specified = false;
800 bool gid_specified = false;
1da177e4
LT
801
802 separator[0] = ',';
50c2f753 803 separator[1] = 0;
1da177e4 804
12e36b2f 805 if (Local_System_Name[0] != 0)
50c2f753 806 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
2cd646a2 807 else {
12e36b2f 808 char *nodename = utsname()->nodename;
50c2f753
SF
809 int n = strnlen(nodename, 15);
810 memset(vol->source_rfc1001_name, 0x20, 15);
811 for (i = 0; i < n; i++) {
2cd646a2
SF
812 /* does not have to be perfect mapping since field is
813 informational, only used for servers that do not support
814 port 445 and it can be overridden at mount time */
12e36b2f 815 vol->source_rfc1001_name[i] = toupper(nodename[i]);
2cd646a2 816 }
1da177e4
LT
817 }
818 vol->source_rfc1001_name[15] = 0;
a10faeb2
SF
819 /* null target name indicates to use *SMBSERVR default called name
820 if we end up sending RFC1001 session initialize */
821 vol->target_rfc1001_name[0] = 0;
3e4b3e1f
JL
822 vol->cred_uid = current_uid();
823 vol->linux_uid = current_uid();
a001e5b5 824 vol->linux_gid = current_gid();
f55ed1a8
JL
825
826 /* default to only allowing write access to owner of the mount */
827 vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
1da177e4
LT
828
829 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
ac67055e
JA
830 /* default is always to request posix paths. */
831 vol->posix_paths = 1;
a0c9217f
JL
832 /* default to using server inode numbers where available */
833 vol->server_ino = 1;
ac67055e 834
1da177e4
LT
835 if (!options)
836 return 1;
837
50c2f753 838 if (strncmp(options, "sep=", 4) == 0) {
fb8c4b14 839 if (options[4] != 0) {
1da177e4
LT
840 separator[0] = options[4];
841 options += 5;
842 } else {
b6b38f70 843 cFYI(1, "Null separator not allowed");
1da177e4
LT
844 }
845 }
50c2f753 846
1da177e4
LT
847 while ((data = strsep(&options, separator)) != NULL) {
848 if (!*data)
849 continue;
850 if ((value = strchr(data, '=')) != NULL)
851 *value++ = '\0';
852
50c2f753
SF
853 /* Have to parse this before we parse for "user" */
854 if (strnicmp(data, "user_xattr", 10) == 0) {
1da177e4 855 vol->no_xattr = 0;
50c2f753 856 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
1da177e4
LT
857 vol->no_xattr = 1;
858 } else if (strnicmp(data, "user", 4) == 0) {
4b952a9b 859 if (!value) {
1da177e4
LT
860 printk(KERN_WARNING
861 "CIFS: invalid or missing username\n");
862 return 1; /* needs_arg; */
fb8c4b14 863 } else if (!*value) {
4b952a9b
SF
864 /* null user, ie anonymous, authentication */
865 vol->nullauth = 1;
1da177e4
LT
866 }
867 if (strnlen(value, 200) < 200) {
868 vol->username = value;
869 } else {
870 printk(KERN_WARNING "CIFS: username too long\n");
871 return 1;
872 }
873 } else if (strnicmp(data, "pass", 4) == 0) {
874 if (!value) {
875 vol->password = NULL;
876 continue;
fb8c4b14 877 } else if (value[0] == 0) {
1da177e4
LT
878 /* check if string begins with double comma
879 since that would mean the password really
880 does start with a comma, and would not
881 indicate an empty string */
fb8c4b14 882 if (value[1] != separator[0]) {
1da177e4
LT
883 vol->password = NULL;
884 continue;
885 }
886 }
887 temp_len = strlen(value);
888 /* removed password length check, NTLM passwords
889 can be arbitrarily long */
890
50c2f753 891 /* if comma in password, the string will be
1da177e4
LT
892 prematurely null terminated. Commas in password are
893 specified across the cifs mount interface by a double
894 comma ie ,, and a comma used as in other cases ie ','
895 as a parameter delimiter/separator is single and due
896 to the strsep above is temporarily zeroed. */
897
898 /* NB: password legally can have multiple commas and
899 the only illegal character in a password is null */
900
50c2f753 901 if ((value[temp_len] == 0) &&
09d1db5c 902 (value[temp_len+1] == separator[0])) {
1da177e4
LT
903 /* reinsert comma */
904 value[temp_len] = separator[0];
50c2f753
SF
905 temp_len += 2; /* move after second comma */
906 while (value[temp_len] != 0) {
1da177e4 907 if (value[temp_len] == separator[0]) {
50c2f753 908 if (value[temp_len+1] ==
09d1db5c
SF
909 separator[0]) {
910 /* skip second comma */
911 temp_len++;
50c2f753 912 } else {
1da177e4
LT
913 /* single comma indicating start
914 of next parm */
915 break;
916 }
917 }
918 temp_len++;
919 }
fb8c4b14 920 if (value[temp_len] == 0) {
1da177e4
LT
921 options = NULL;
922 } else {
923 value[temp_len] = 0;
924 /* point option to start of next parm */
925 options = value + temp_len + 1;
926 }
50c2f753 927 /* go from value to value + temp_len condensing
1da177e4
LT
928 double commas to singles. Note that this ends up
929 allocating a few bytes too many, which is ok */
e915fc49 930 vol->password = kzalloc(temp_len, GFP_KERNEL);
fb8c4b14 931 if (vol->password == NULL) {
50c2f753
SF
932 printk(KERN_WARNING "CIFS: no memory "
933 "for password\n");
433dc24f
SF
934 return 1;
935 }
50c2f753 936 for (i = 0, j = 0; i < temp_len; i++, j++) {
1da177e4 937 vol->password[j] = value[i];
fb8c4b14 938 if (value[i] == separator[0]
09d1db5c 939 && value[i+1] == separator[0]) {
1da177e4
LT
940 /* skip second comma */
941 i++;
942 }
943 }
944 vol->password[j] = 0;
945 } else {
e915fc49 946 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
fb8c4b14 947 if (vol->password == NULL) {
50c2f753
SF
948 printk(KERN_WARNING "CIFS: no memory "
949 "for password\n");
433dc24f
SF
950 return 1;
951 }
1da177e4
LT
952 strcpy(vol->password, value);
953 }
58f7f68f
JL
954 } else if (!strnicmp(data, "ip", 2) ||
955 !strnicmp(data, "addr", 4)) {
1da177e4
LT
956 if (!value || !*value) {
957 vol->UNCip = NULL;
50b64e3b
JL
958 } else if (strnlen(value, INET6_ADDRSTRLEN) <
959 INET6_ADDRSTRLEN) {
1da177e4
LT
960 vol->UNCip = value;
961 } else {
50c2f753
SF
962 printk(KERN_WARNING "CIFS: ip address "
963 "too long\n");
1da177e4
LT
964 return 1;
965 }
50c2f753
SF
966 } else if (strnicmp(data, "sec", 3) == 0) {
967 if (!value || !*value) {
b6b38f70 968 cERROR(1, "no security value specified");
50c2f753
SF
969 continue;
970 } else if (strnicmp(value, "krb5i", 5) == 0) {
971 vol->secFlg |= CIFSSEC_MAY_KRB5 |
189acaae 972 CIFSSEC_MUST_SIGN;
bf820679 973 } else if (strnicmp(value, "krb5p", 5) == 0) {
50c2f753
SF
974 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
975 CIFSSEC_MAY_KRB5; */
b6b38f70 976 cERROR(1, "Krb5 cifs privacy not supported");
bf820679
SF
977 return 1;
978 } else if (strnicmp(value, "krb5", 4) == 0) {
750d1151 979 vol->secFlg |= CIFSSEC_MAY_KRB5;
ac683924
SF
980#ifdef CONFIG_CIFS_EXPERIMENTAL
981 } else if (strnicmp(value, "ntlmsspi", 8) == 0) {
982 vol->secFlg |= CIFSSEC_MAY_NTLMSSP |
983 CIFSSEC_MUST_SIGN;
984 } else if (strnicmp(value, "ntlmssp", 7) == 0) {
985 vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
986#endif
bf820679 987 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
750d1151 988 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
189acaae 989 CIFSSEC_MUST_SIGN;
bf820679 990 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
750d1151 991 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
bf820679 992 } else if (strnicmp(value, "ntlmi", 5) == 0) {
750d1151 993 vol->secFlg |= CIFSSEC_MAY_NTLM |
189acaae 994 CIFSSEC_MUST_SIGN;
bf820679
SF
995 } else if (strnicmp(value, "ntlm", 4) == 0) {
996 /* ntlm is default so can be turned off too */
750d1151 997 vol->secFlg |= CIFSSEC_MAY_NTLM;
bf820679 998 } else if (strnicmp(value, "nontlm", 6) == 0) {
189acaae 999 /* BB is there a better way to do this? */
750d1151 1000 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
189acaae
SF
1001#ifdef CONFIG_CIFS_WEAK_PW_HASH
1002 } else if (strnicmp(value, "lanman", 6) == 0) {
50c2f753 1003 vol->secFlg |= CIFSSEC_MAY_LANMAN;
189acaae 1004#endif
bf820679 1005 } else if (strnicmp(value, "none", 4) == 0) {
189acaae 1006 vol->nullauth = 1;
50c2f753 1007 } else {
b6b38f70 1008 cERROR(1, "bad security option: %s", value);
50c2f753
SF
1009 return 1;
1010 }
1da177e4
LT
1011 } else if ((strnicmp(data, "unc", 3) == 0)
1012 || (strnicmp(data, "target", 6) == 0)
1013 || (strnicmp(data, "path", 4) == 0)) {
1014 if (!value || !*value) {
50c2f753
SF
1015 printk(KERN_WARNING "CIFS: invalid path to "
1016 "network resource\n");
1da177e4
LT
1017 return 1; /* needs_arg; */
1018 }
1019 if ((temp_len = strnlen(value, 300)) < 300) {
50c2f753 1020 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
4523cc30 1021 if (vol->UNC == NULL)
1da177e4 1022 return 1;
50c2f753 1023 strcpy(vol->UNC, value);
1da177e4
LT
1024 if (strncmp(vol->UNC, "//", 2) == 0) {
1025 vol->UNC[0] = '\\';
1026 vol->UNC[1] = '\\';
50c2f753 1027 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1da177e4 1028 printk(KERN_WARNING
50c2f753
SF
1029 "CIFS: UNC Path does not begin "
1030 "with // or \\\\ \n");
1da177e4
LT
1031 return 1;
1032 }
1033 } else {
1034 printk(KERN_WARNING "CIFS: UNC name too long\n");
1035 return 1;
1036 }
1037 } else if ((strnicmp(data, "domain", 3) == 0)
1038 || (strnicmp(data, "workgroup", 5) == 0)) {
1039 if (!value || !*value) {
1040 printk(KERN_WARNING "CIFS: invalid domain name\n");
1041 return 1; /* needs_arg; */
1042 }
1043 /* BB are there cases in which a comma can be valid in
1044 a domain name and need special handling? */
3979877e 1045 if (strnlen(value, 256) < 256) {
1da177e4 1046 vol->domainname = value;
b6b38f70 1047 cFYI(1, "Domain name set");
1da177e4 1048 } else {
50c2f753
SF
1049 printk(KERN_WARNING "CIFS: domain name too "
1050 "long\n");
1da177e4
LT
1051 return 1;
1052 }
3eb9a889
BG
1053 } else if (strnicmp(data, "srcaddr", 7) == 0) {
1054 vol->srcaddr.ss_family = AF_UNSPEC;
1055
1056 if (!value || !*value) {
1057 printk(KERN_WARNING "CIFS: srcaddr value"
1058 " not specified.\n");
1059 return 1; /* needs_arg; */
1060 }
1061 i = cifs_convert_address((struct sockaddr *)&vol->srcaddr,
1062 value, strlen(value));
1063 if (i < 0) {
1064 printk(KERN_WARNING "CIFS: Could not parse"
1065 " srcaddr: %s\n",
1066 value);
1067 return 1;
1068 }
50c2f753
SF
1069 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1070 if (!value || !*value) {
1071 printk(KERN_WARNING
1072 "CIFS: invalid path prefix\n");
1073 return 1; /* needs_argument */
1074 }
1075 if ((temp_len = strnlen(value, 1024)) < 1024) {
4523cc30 1076 if (value[0] != '/')
2fe87f02 1077 temp_len++; /* missing leading slash */
50c2f753
SF
1078 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1079 if (vol->prepath == NULL)
1080 return 1;
4523cc30 1081 if (value[0] != '/') {
2fe87f02 1082 vol->prepath[0] = '/';
50c2f753 1083 strcpy(vol->prepath+1, value);
2fe87f02 1084 } else
50c2f753 1085 strcpy(vol->prepath, value);
b6b38f70 1086 cFYI(1, "prefix path %s", vol->prepath);
50c2f753
SF
1087 } else {
1088 printk(KERN_WARNING "CIFS: prefix too long\n");
1089 return 1;
1090 }
1da177e4
LT
1091 } else if (strnicmp(data, "iocharset", 9) == 0) {
1092 if (!value || !*value) {
63135e08
SF
1093 printk(KERN_WARNING "CIFS: invalid iocharset "
1094 "specified\n");
1da177e4
LT
1095 return 1; /* needs_arg; */
1096 }
1097 if (strnlen(value, 65) < 65) {
50c2f753 1098 if (strnicmp(value, "default", 7))
1da177e4 1099 vol->iocharset = value;
50c2f753
SF
1100 /* if iocharset not set then load_nls_default
1101 is used by caller */
b6b38f70 1102 cFYI(1, "iocharset set to %s", value);
1da177e4 1103 } else {
63135e08
SF
1104 printk(KERN_WARNING "CIFS: iocharset name "
1105 "too long.\n");
1da177e4
LT
1106 return 1;
1107 }
9b9d6b24
JL
1108 } else if (!strnicmp(data, "uid", 3) && value && *value) {
1109 vol->linux_uid = simple_strtoul(value, &value, 0);
1110 uid_specified = true;
1111 } else if (!strnicmp(data, "forceuid", 8)) {
1112 override_uid = 1;
1113 } else if (!strnicmp(data, "noforceuid", 10)) {
1114 override_uid = 0;
1115 } else if (!strnicmp(data, "gid", 3) && value && *value) {
1116 vol->linux_gid = simple_strtoul(value, &value, 0);
1117 gid_specified = true;
1118 } else if (!strnicmp(data, "forcegid", 8)) {
1119 override_gid = 1;
1120 } else if (!strnicmp(data, "noforcegid", 10)) {
1121 override_gid = 0;
1da177e4
LT
1122 } else if (strnicmp(data, "file_mode", 4) == 0) {
1123 if (value && *value) {
1124 vol->file_mode =
1125 simple_strtoul(value, &value, 0);
1126 }
1127 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1128 if (value && *value) {
1129 vol->dir_mode =
1130 simple_strtoul(value, &value, 0);
1131 }
1132 } else if (strnicmp(data, "dirmode", 4) == 0) {
1133 if (value && *value) {
1134 vol->dir_mode =
1135 simple_strtoul(value, &value, 0);
1136 }
1137 } else if (strnicmp(data, "port", 4) == 0) {
1138 if (value && *value) {
1139 vol->port =
1140 simple_strtoul(value, &value, 0);
1141 }
1142 } else if (strnicmp(data, "rsize", 5) == 0) {
1143 if (value && *value) {
1144 vol->rsize =
1145 simple_strtoul(value, &value, 0);
1146 }
1147 } else if (strnicmp(data, "wsize", 5) == 0) {
1148 if (value && *value) {
1149 vol->wsize =
1150 simple_strtoul(value, &value, 0);
1151 }
1152 } else if (strnicmp(data, "sockopt", 5) == 0) {
6a5fa236 1153 if (!value || !*value) {
b6b38f70 1154 cERROR(1, "no socket option specified");
6a5fa236
SF
1155 continue;
1156 } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
1157 vol->sockopt_tcp_nodelay = 1;
1da177e4
LT
1158 }
1159 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1160 if (!value || !*value || (*value == ' ')) {
b6b38f70 1161 cFYI(1, "invalid (empty) netbiosname");
1da177e4 1162 } else {
50c2f753
SF
1163 memset(vol->source_rfc1001_name, 0x20, 15);
1164 for (i = 0; i < 15; i++) {
1165 /* BB are there cases in which a comma can be
1da177e4
LT
1166 valid in this workstation netbios name (and need
1167 special handling)? */
1168
1169 /* We do not uppercase netbiosname for user */
50c2f753 1170 if (value[i] == 0)
1da177e4 1171 break;
50c2f753
SF
1172 else
1173 vol->source_rfc1001_name[i] =
1174 value[i];
1da177e4
LT
1175 }
1176 /* The string has 16th byte zero still from
1177 set at top of the function */
50c2f753
SF
1178 if ((i == 15) && (value[i] != 0))
1179 printk(KERN_WARNING "CIFS: netbiosname"
1180 " longer than 15 truncated.\n");
a10faeb2
SF
1181 }
1182 } else if (strnicmp(data, "servern", 7) == 0) {
1183 /* servernetbiosname specified override *SMBSERVER */
1184 if (!value || !*value || (*value == ' ')) {
b6b38f70 1185 cFYI(1, "empty server netbiosname specified");
a10faeb2
SF
1186 } else {
1187 /* last byte, type, is 0x20 for servr type */
50c2f753 1188 memset(vol->target_rfc1001_name, 0x20, 16);
a10faeb2 1189
50c2f753 1190 for (i = 0; i < 15; i++) {
a10faeb2 1191 /* BB are there cases in which a comma can be
50c2f753
SF
1192 valid in this workstation netbios name
1193 (and need special handling)? */
a10faeb2 1194
50c2f753
SF
1195 /* user or mount helper must uppercase
1196 the netbiosname */
1197 if (value[i] == 0)
a10faeb2
SF
1198 break;
1199 else
50c2f753
SF
1200 vol->target_rfc1001_name[i] =
1201 value[i];
a10faeb2
SF
1202 }
1203 /* The string has 16th byte zero still from
1204 set at top of the function */
50c2f753
SF
1205 if ((i == 15) && (value[i] != 0))
1206 printk(KERN_WARNING "CIFS: server net"
1207 "biosname longer than 15 truncated.\n");
1da177e4
LT
1208 }
1209 } else if (strnicmp(data, "credentials", 4) == 0) {
1210 /* ignore */
1211 } else if (strnicmp(data, "version", 3) == 0) {
1212 /* ignore */
50c2f753 1213 } else if (strnicmp(data, "guest", 5) == 0) {
1da177e4 1214 /* ignore */
71a394fa
SF
1215 } else if (strnicmp(data, "rw", 2) == 0) {
1216 /* ignore */
1217 } else if (strnicmp(data, "ro", 2) == 0) {
1218 /* ignore */
edf1ae40
SF
1219 } else if (strnicmp(data, "noblocksend", 11) == 0) {
1220 vol->noblocksnd = 1;
1221 } else if (strnicmp(data, "noautotune", 10) == 0) {
1222 vol->noautotune = 1;
1da177e4
LT
1223 } else if ((strnicmp(data, "suid", 4) == 0) ||
1224 (strnicmp(data, "nosuid", 6) == 0) ||
1225 (strnicmp(data, "exec", 4) == 0) ||
1226 (strnicmp(data, "noexec", 6) == 0) ||
1227 (strnicmp(data, "nodev", 5) == 0) ||
1228 (strnicmp(data, "noauto", 6) == 0) ||
1229 (strnicmp(data, "dev", 3) == 0)) {
1230 /* The mount tool or mount.cifs helper (if present)
50c2f753
SF
1231 uses these opts to set flags, and the flags are read
1232 by the kernel vfs layer before we get here (ie
1233 before read super) so there is no point trying to
1234 parse these options again and set anything and it
1235 is ok to just ignore them */
1da177e4 1236 continue;
1da177e4
LT
1237 } else if (strnicmp(data, "hard", 4) == 0) {
1238 vol->retry = 1;
1239 } else if (strnicmp(data, "soft", 4) == 0) {
1240 vol->retry = 0;
1241 } else if (strnicmp(data, "perm", 4) == 0) {
1242 vol->noperm = 0;
1243 } else if (strnicmp(data, "noperm", 6) == 0) {
1244 vol->noperm = 1;
6a0b4824
SF
1245 } else if (strnicmp(data, "mapchars", 8) == 0) {
1246 vol->remap = 1;
1247 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1248 vol->remap = 0;
50c2f753
SF
1249 } else if (strnicmp(data, "sfu", 3) == 0) {
1250 vol->sfu_emul = 1;
1251 } else if (strnicmp(data, "nosfu", 5) == 0) {
1252 vol->sfu_emul = 0;
2c1b8615
SF
1253 } else if (strnicmp(data, "nodfs", 5) == 0) {
1254 vol->nodfs = 1;
ac67055e
JA
1255 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1256 vol->posix_paths = 1;
1257 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1258 vol->posix_paths = 0;
c18c842b
SF
1259 } else if (strnicmp(data, "nounix", 6) == 0) {
1260 vol->no_linux_ext = 1;
1261 } else if (strnicmp(data, "nolinux", 7) == 0) {
1262 vol->no_linux_ext = 1;
50c2f753 1263 } else if ((strnicmp(data, "nocase", 6) == 0) ||
a10faeb2 1264 (strnicmp(data, "ignorecase", 10) == 0)) {
50c2f753 1265 vol->nocase = 1;
f636a348
JL
1266 } else if (strnicmp(data, "mand", 4) == 0) {
1267 /* ignore */
1268 } else if (strnicmp(data, "nomand", 6) == 0) {
1269 /* ignore */
1270 } else if (strnicmp(data, "_netdev", 7) == 0) {
1271 /* ignore */
c46fa8ac
SF
1272 } else if (strnicmp(data, "brl", 3) == 0) {
1273 vol->nobrl = 0;
50c2f753 1274 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1c955187 1275 (strnicmp(data, "nolock", 6) == 0)) {
c46fa8ac 1276 vol->nobrl = 1;
d3485d37
SF
1277 /* turn off mandatory locking in mode
1278 if remote locking is turned off since the
1279 local vfs will do advisory */
50c2f753
SF
1280 if (vol->file_mode ==
1281 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
d3485d37 1282 vol->file_mode = S_IALLUGO;
13a6e42a
SF
1283 } else if (strnicmp(data, "forcemandatorylock", 9) == 0) {
1284 /* will take the shorter form "forcemand" as well */
1285 /* This mount option will force use of mandatory
1286 (DOS/Windows style) byte range locks, instead of
1287 using posix advisory byte range locks, even if the
1288 Unix extensions are available and posix locks would
1289 be supported otherwise. If Unix extensions are not
1290 negotiated this has no effect since mandatory locks
1291 would be used (mandatory locks is all that those
1292 those servers support) */
1293 vol->mand_lock = 1;
1da177e4
LT
1294 } else if (strnicmp(data, "setuids", 7) == 0) {
1295 vol->setuids = 1;
1296 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1297 vol->setuids = 0;
d0a9c078
JL
1298 } else if (strnicmp(data, "dynperm", 7) == 0) {
1299 vol->dynperm = true;
1300 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1301 vol->dynperm = false;
1da177e4
LT
1302 } else if (strnicmp(data, "nohard", 6) == 0) {
1303 vol->retry = 0;
1304 } else if (strnicmp(data, "nosoft", 6) == 0) {
1305 vol->retry = 1;
1306 } else if (strnicmp(data, "nointr", 6) == 0) {
1307 vol->intr = 0;
1308 } else if (strnicmp(data, "intr", 4) == 0) {
1309 vol->intr = 1;
be652445
SF
1310 } else if (strnicmp(data, "nostrictsync", 12) == 0) {
1311 vol->nostrictsync = 1;
1312 } else if (strnicmp(data, "strictsync", 10) == 0) {
1313 vol->nostrictsync = 0;
50c2f753 1314 } else if (strnicmp(data, "serverino", 7) == 0) {
1da177e4 1315 vol->server_ino = 1;
50c2f753 1316 } else if (strnicmp(data, "noserverino", 9) == 0) {
1da177e4 1317 vol->server_ino = 0;
50c2f753 1318 } else if (strnicmp(data, "cifsacl", 7) == 0) {
0a4b92c0
SF
1319 vol->cifs_acl = 1;
1320 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1321 vol->cifs_acl = 0;
50c2f753 1322 } else if (strnicmp(data, "acl", 3) == 0) {
1da177e4 1323 vol->no_psx_acl = 0;
50c2f753 1324 } else if (strnicmp(data, "noacl", 5) == 0) {
1da177e4 1325 vol->no_psx_acl = 1;
84210e91
SF
1326#ifdef CONFIG_CIFS_EXPERIMENTAL
1327 } else if (strnicmp(data, "locallease", 6) == 0) {
1328 vol->local_lease = 1;
1329#endif
50c2f753 1330 } else if (strnicmp(data, "sign", 4) == 0) {
750d1151 1331 vol->secFlg |= CIFSSEC_MUST_SIGN;
95b1cb90
SF
1332 } else if (strnicmp(data, "seal", 4) == 0) {
1333 /* we do not do the following in secFlags because seal
1334 is a per tree connection (mount) not a per socket
1335 or per-smb connection option in the protocol */
1336 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1337 vol->seal = 1;
50c2f753 1338 } else if (strnicmp(data, "direct", 6) == 0) {
1da177e4 1339 vol->direct_io = 1;
50c2f753 1340 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1da177e4 1341 vol->direct_io = 1;
1da177e4 1342 } else if (strnicmp(data, "noac", 4) == 0) {
50c2f753
SF
1343 printk(KERN_WARNING "CIFS: Mount option noac not "
1344 "supported. Instead set "
1345 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
fa1df75d
SJ
1346 } else if (strnicmp(data, "fsc", 3) == 0) {
1347 vol->fsc = true;
736a3320
SM
1348 } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
1349 vol->mfsymlinks = true;
1da177e4 1350 } else
50c2f753
SF
1351 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1352 data);
1da177e4
LT
1353 }
1354 if (vol->UNC == NULL) {
4523cc30 1355 if (devname == NULL) {
50c2f753
SF
1356 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1357 "target\n");
1da177e4
LT
1358 return 1;
1359 }
1360 if ((temp_len = strnlen(devname, 300)) < 300) {
50c2f753 1361 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
4523cc30 1362 if (vol->UNC == NULL)
1da177e4 1363 return 1;
50c2f753 1364 strcpy(vol->UNC, devname);
1da177e4
LT
1365 if (strncmp(vol->UNC, "//", 2) == 0) {
1366 vol->UNC[0] = '\\';
1367 vol->UNC[1] = '\\';
1368 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
50c2f753
SF
1369 printk(KERN_WARNING "CIFS: UNC Path does not "
1370 "begin with // or \\\\ \n");
1da177e4
LT
1371 return 1;
1372 }
7c5e628f
IM
1373 value = strpbrk(vol->UNC+2, "/\\");
1374 if (value)
1375 *value = '\\';
1da177e4
LT
1376 } else {
1377 printk(KERN_WARNING "CIFS: UNC name too long\n");
1378 return 1;
1379 }
1380 }
fb8c4b14 1381 if (vol->UNCip == NULL)
1da177e4
LT
1382 vol->UNCip = &vol->UNC[2];
1383
9b9d6b24
JL
1384 if (uid_specified)
1385 vol->override_uid = override_uid;
1386 else if (override_uid == 1)
1387 printk(KERN_NOTICE "CIFS: ignoring forceuid mount option "
1388 "specified with no uid= option.\n");
1389
1390 if (gid_specified)
1391 vol->override_gid = override_gid;
1392 else if (override_gid == 1)
1393 printk(KERN_NOTICE "CIFS: ignoring forcegid mount option "
1394 "specified with no gid= option.\n");
1395
1da177e4
LT
1396 return 0;
1397}
1398
3eb9a889
BG
1399/** Returns true if srcaddr isn't specified and rhs isn't
1400 * specified, or if srcaddr is specified and
1401 * matches the IP address of the rhs argument.
1402 */
1403static bool
1404srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1405{
1406 switch (srcaddr->sa_family) {
1407 case AF_UNSPEC:
1408 return (rhs->sa_family == AF_UNSPEC);
1409 case AF_INET: {
1410 struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
1411 struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
1412 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
1413 }
1414 case AF_INET6: {
1415 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
1416 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs;
1417 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
1418 }
1419 default:
1420 WARN_ON(1);
1421 return false; /* don't expect to be here */
1422 }
1423}
1424
1425
4515148e 1426static bool
3eb9a889
BG
1427match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1428 struct sockaddr *srcaddr)
4515148e
JL
1429{
1430 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1431 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1432
1433 switch (addr->sa_family) {
1434 case AF_INET:
1435 if (addr4->sin_addr.s_addr !=
1436 server->addr.sockAddr.sin_addr.s_addr)
1437 return false;
1438 if (addr4->sin_port &&
1439 addr4->sin_port != server->addr.sockAddr.sin_port)
1440 return false;
1441 break;
1442 case AF_INET6:
1443 if (!ipv6_addr_equal(&addr6->sin6_addr,
1444 &server->addr.sockAddr6.sin6_addr))
1445 return false;
1446 if (addr6->sin6_scope_id !=
1447 server->addr.sockAddr6.sin6_scope_id)
1448 return false;
1449 if (addr6->sin6_port &&
1450 addr6->sin6_port != server->addr.sockAddr6.sin6_port)
1451 return false;
1452 break;
1453 }
1454
3eb9a889
BG
1455 if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
1456 return false;
1457
4515148e
JL
1458 return true;
1459}
1460
daf5b0b6
JL
1461static bool
1462match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
1463{
1464 unsigned int secFlags;
1465
1466 if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
1467 secFlags = vol->secFlg;
1468 else
1469 secFlags = global_secflags | vol->secFlg;
1470
1471 switch (server->secType) {
1472 case LANMAN:
1473 if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
1474 return false;
1475 break;
1476 case NTLMv2:
1477 if (!(secFlags & CIFSSEC_MAY_NTLMV2))
1478 return false;
1479 break;
1480 case NTLM:
1481 if (!(secFlags & CIFSSEC_MAY_NTLM))
1482 return false;
1483 break;
1484 case Kerberos:
1485 if (!(secFlags & CIFSSEC_MAY_KRB5))
1486 return false;
1487 break;
1488 case RawNTLMSSP:
1489 if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
1490 return false;
1491 break;
1492 default:
1493 /* shouldn't happen */
1494 return false;
1495 }
1496
1497 /* now check if signing mode is acceptible */
1498 if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
1499 (server->secMode & SECMODE_SIGN_REQUIRED))
1500 return false;
1501 else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
1502 (server->secMode &
1503 (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
1504 return false;
1505
1506 return true;
1507}
1508
e7ddee90 1509static struct TCP_Server_Info *
daf5b0b6 1510cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1da177e4 1511{
e7ddee90 1512 struct TCP_Server_Info *server;
e7ddee90
JL
1513
1514 write_lock(&cifs_tcp_ses_lock);
4515148e 1515 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
3eb9a889
BG
1516 if (!match_address(server, addr,
1517 (struct sockaddr *)&vol->srcaddr))
4515148e 1518 continue;
1b20d672 1519
daf5b0b6
JL
1520 if (!match_security(server, vol))
1521 continue;
1522
e7ddee90
JL
1523 ++server->srv_count;
1524 write_unlock(&cifs_tcp_ses_lock);
b6b38f70 1525 cFYI(1, "Existing tcp session with server found");
e7ddee90 1526 return server;
1da177e4 1527 }
e7ddee90 1528 write_unlock(&cifs_tcp_ses_lock);
1da177e4
LT
1529 return NULL;
1530}
1b20d672 1531
14fbf50d 1532static void
e7ddee90 1533cifs_put_tcp_session(struct TCP_Server_Info *server)
1da177e4 1534{
e7ddee90 1535 struct task_struct *task;
1b20d672 1536
e7ddee90
JL
1537 write_lock(&cifs_tcp_ses_lock);
1538 if (--server->srv_count > 0) {
1539 write_unlock(&cifs_tcp_ses_lock);
1540 return;
1da177e4 1541 }
1b20d672 1542
e7ddee90
JL
1543 list_del_init(&server->tcp_ses_list);
1544 write_unlock(&cifs_tcp_ses_lock);
dea570e0 1545
e7ddee90
JL
1546 spin_lock(&GlobalMid_Lock);
1547 server->tcpStatus = CifsExiting;
1548 spin_unlock(&GlobalMid_Lock);
dea570e0 1549
488f1d2d
SJ
1550 cifs_fscache_release_client_cookie(server);
1551
e7ddee90
JL
1552 task = xchg(&server->tsk, NULL);
1553 if (task)
1554 force_sig(SIGKILL, task);
1da177e4
LT
1555}
1556
63c038c2
JL
1557static struct TCP_Server_Info *
1558cifs_get_tcp_session(struct smb_vol *volume_info)
1559{
1560 struct TCP_Server_Info *tcp_ses = NULL;
a9ac49d3 1561 struct sockaddr_storage addr;
63c038c2
JL
1562 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
1563 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
1564 int rc;
1565
a9ac49d3 1566 memset(&addr, 0, sizeof(struct sockaddr_storage));
63c038c2 1567
b6b38f70 1568 cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
63c038c2 1569
1e68b2b2 1570 if (volume_info->UNCip && volume_info->UNC) {
50d97160
JL
1571 rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
1572 volume_info->UNCip,
67b7626a 1573 strlen(volume_info->UNCip),
50d97160 1574 volume_info->port);
1e68b2b2 1575 if (!rc) {
63c038c2
JL
1576 /* we failed translating address */
1577 rc = -EINVAL;
1578 goto out_err;
1579 }
63c038c2
JL
1580 } else if (volume_info->UNCip) {
1581 /* BB using ip addr as tcp_ses name to connect to the
1582 DFS root below */
b6b38f70 1583 cERROR(1, "Connecting to DFS root not implemented yet");
63c038c2
JL
1584 rc = -EINVAL;
1585 goto out_err;
1586 } else /* which tcp_sess DFS root would we conect to */ {
b6b38f70
JP
1587 cERROR(1, "CIFS mount error: No UNC path (e.g. -o "
1588 "unc=//192.168.1.100/public) specified");
63c038c2
JL
1589 rc = -EINVAL;
1590 goto out_err;
1591 }
1592
1593 /* see if we already have a matching tcp_ses */
daf5b0b6 1594 tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info);
63c038c2
JL
1595 if (tcp_ses)
1596 return tcp_ses;
1597
1598 tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1599 if (!tcp_ses) {
1600 rc = -ENOMEM;
1601 goto out_err;
1602 }
1603
1604 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1605 if (IS_ERR(tcp_ses->hostname)) {
1606 rc = PTR_ERR(tcp_ses->hostname);
1607 goto out_err;
1608 }
1609
1610 tcp_ses->noblocksnd = volume_info->noblocksnd;
1611 tcp_ses->noautotune = volume_info->noautotune;
6a5fa236 1612 tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
63c038c2
JL
1613 atomic_set(&tcp_ses->inFlight, 0);
1614 init_waitqueue_head(&tcp_ses->response_q);
1615 init_waitqueue_head(&tcp_ses->request_q);
1616 INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
1617 mutex_init(&tcp_ses->srv_mutex);
1618 memcpy(tcp_ses->workstation_RFC1001_name,
1619 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1620 memcpy(tcp_ses->server_RFC1001_name,
1621 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1622 tcp_ses->sequence_number = 0;
1623 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1624 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1625
1626 /*
1627 * at this point we are the only ones with the pointer
1628 * to the struct since the kernel thread not created yet
1629 * no need to spinlock this init of tcpStatus or srv_count
1630 */
1631 tcp_ses->tcpStatus = CifsNew;
3eb9a889
BG
1632 memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
1633 sizeof(tcp_ses->srcaddr));
63c038c2
JL
1634 ++tcp_ses->srv_count;
1635
a9ac49d3 1636 if (addr.ss_family == AF_INET6) {
b6b38f70 1637 cFYI(1, "attempting ipv6 connect");
63c038c2
JL
1638 /* BB should we allow ipv6 on port 139? */
1639 /* other OS never observed in Wild doing 139 with v6 */
1640 memcpy(&tcp_ses->addr.sockAddr6, sin_server6,
1641 sizeof(struct sockaddr_in6));
d5c5605c 1642 rc = ipv6_connect(tcp_ses);
63c038c2
JL
1643 } else {
1644 memcpy(&tcp_ses->addr.sockAddr, sin_server,
1645 sizeof(struct sockaddr_in));
bcf4b106 1646 rc = ipv4_connect(tcp_ses);
63c038c2
JL
1647 }
1648 if (rc < 0) {
b6b38f70 1649 cERROR(1, "Error connecting to socket. Aborting operation");
63c038c2
JL
1650 goto out_err;
1651 }
1652
1653 /*
1654 * since we're in a cifs function already, we know that
1655 * this will succeed. No need for try_module_get().
1656 */
1657 __module_get(THIS_MODULE);
1658 tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread,
1659 tcp_ses, "cifsd");
1660 if (IS_ERR(tcp_ses->tsk)) {
1661 rc = PTR_ERR(tcp_ses->tsk);
b6b38f70 1662 cERROR(1, "error %d create cifsd thread", rc);
63c038c2
JL
1663 module_put(THIS_MODULE);
1664 goto out_err;
1665 }
1666
1667 /* thread spawned, put it on the list */
1668 write_lock(&cifs_tcp_ses_lock);
1669 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1670 write_unlock(&cifs_tcp_ses_lock);
1671
488f1d2d
SJ
1672 cifs_fscache_get_client_cookie(tcp_ses);
1673
63c038c2
JL
1674 return tcp_ses;
1675
1676out_err:
1677 if (tcp_ses) {
8347a5cd
SF
1678 if (!IS_ERR(tcp_ses->hostname))
1679 kfree(tcp_ses->hostname);
63c038c2
JL
1680 if (tcp_ses->ssocket)
1681 sock_release(tcp_ses->ssocket);
1682 kfree(tcp_ses);
1683 }
1684 return ERR_PTR(rc);
1685}
1686
14fbf50d 1687static struct cifsSesInfo *
4ff67b72 1688cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1da177e4 1689{
14fbf50d 1690 struct cifsSesInfo *ses;
dea570e0 1691
14fbf50d 1692 write_lock(&cifs_tcp_ses_lock);
4ff67b72
JL
1693 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1694 switch (server->secType) {
1695 case Kerberos:
3e4b3e1f 1696 if (vol->cred_uid != ses->cred_uid)
4ff67b72
JL
1697 continue;
1698 break;
1699 default:
1700 /* anything else takes username/password */
1701 if (strncmp(ses->userName, vol->username,
1702 MAX_USERNAME_SIZE))
1703 continue;
1704 if (strlen(vol->username) != 0 &&
24e6cf92 1705 ses->password != NULL &&
fc87a406
JL
1706 strncmp(ses->password,
1707 vol->password ? vol->password : "",
4ff67b72
JL
1708 MAX_PASSWORD_SIZE))
1709 continue;
1710 }
14fbf50d
JL
1711 ++ses->ses_count;
1712 write_unlock(&cifs_tcp_ses_lock);
1713 return ses;
1714 }
1715 write_unlock(&cifs_tcp_ses_lock);
1716 return NULL;
1717}
dea570e0 1718
14fbf50d
JL
1719static void
1720cifs_put_smb_ses(struct cifsSesInfo *ses)
1721{
1722 int xid;
1723 struct TCP_Server_Info *server = ses->server;
dea570e0 1724
36988c76 1725 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
14fbf50d
JL
1726 write_lock(&cifs_tcp_ses_lock);
1727 if (--ses->ses_count > 0) {
1728 write_unlock(&cifs_tcp_ses_lock);
1729 return;
1730 }
dea570e0 1731
14fbf50d
JL
1732 list_del_init(&ses->smb_ses_list);
1733 write_unlock(&cifs_tcp_ses_lock);
dea570e0 1734
14fbf50d
JL
1735 if (ses->status == CifsGood) {
1736 xid = GetXid();
1737 CIFSSMBLogoff(xid, ses);
1738 _FreeXid(xid);
1739 }
1740 sesInfoFree(ses);
1741 cifs_put_tcp_session(server);
1742}
dea570e0 1743
36988c76
JL
1744static struct cifsSesInfo *
1745cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1746{
1747 int rc = -ENOMEM, xid;
1748 struct cifsSesInfo *ses;
1749
1750 xid = GetXid();
1751
4ff67b72 1752 ses = cifs_find_smb_ses(server, volume_info);
36988c76
JL
1753 if (ses) {
1754 cFYI(1, "Existing smb sess found (status=%d)", ses->status);
1755
36988c76 1756 mutex_lock(&ses->session_mutex);
198b5682
JL
1757 rc = cifs_negotiate_protocol(xid, ses);
1758 if (rc) {
1759 mutex_unlock(&ses->session_mutex);
1760 /* problem -- put our ses reference */
1761 cifs_put_smb_ses(ses);
1762 FreeXid(xid);
1763 return ERR_PTR(rc);
1764 }
36988c76
JL
1765 if (ses->need_reconnect) {
1766 cFYI(1, "Session needs reconnect");
1767 rc = cifs_setup_session(xid, ses,
1768 volume_info->local_nls);
1769 if (rc) {
1770 mutex_unlock(&ses->session_mutex);
1771 /* problem -- put our reference */
1772 cifs_put_smb_ses(ses);
1773 FreeXid(xid);
1774 return ERR_PTR(rc);
1775 }
1776 }
1777 mutex_unlock(&ses->session_mutex);
460cf341
JL
1778
1779 /* existing SMB ses has a server reference already */
1780 cifs_put_tcp_session(server);
36988c76
JL
1781 FreeXid(xid);
1782 return ses;
1783 }
1784
1785 cFYI(1, "Existing smb sess not found");
1786 ses = sesInfoAlloc();
1787 if (ses == NULL)
1788 goto get_ses_fail;
1789
2b149f11
SP
1790 ses->tilen = 0;
1791 ses->tiblob = NULL;
36988c76
JL
1792 /* new SMB session uses our server ref */
1793 ses->server = server;
1794 if (server->addr.sockAddr6.sin6_family == AF_INET6)
1795 sprintf(ses->serverName, "%pI6",
1796 &server->addr.sockAddr6.sin6_addr);
1797 else
1798 sprintf(ses->serverName, "%pI4",
1799 &server->addr.sockAddr.sin_addr.s_addr);
1800
1801 if (volume_info->username)
1802 strncpy(ses->userName, volume_info->username,
1803 MAX_USERNAME_SIZE);
1804
1805 /* volume_info->password freed at unmount */
1806 if (volume_info->password) {
1807 ses->password = kstrdup(volume_info->password, GFP_KERNEL);
1808 if (!ses->password)
1809 goto get_ses_fail;
1810 }
1811 if (volume_info->domainname) {
1812 int len = strlen(volume_info->domainname);
1813 ses->domainName = kmalloc(len + 1, GFP_KERNEL);
1814 if (ses->domainName)
1815 strcpy(ses->domainName, volume_info->domainname);
1816 }
3e4b3e1f 1817 ses->cred_uid = volume_info->cred_uid;
36988c76
JL
1818 ses->linux_uid = volume_info->linux_uid;
1819 ses->overrideSecFlg = volume_info->secFlg;
1820
1821 mutex_lock(&ses->session_mutex);
198b5682
JL
1822 rc = cifs_negotiate_protocol(xid, ses);
1823 if (!rc)
1824 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
36988c76 1825 mutex_unlock(&ses->session_mutex);
c8e56f1f 1826 if (rc)
36988c76
JL
1827 goto get_ses_fail;
1828
1829 /* success, put it on the list */
1830 write_lock(&cifs_tcp_ses_lock);
1831 list_add(&ses->smb_ses_list, &server->smb_ses_list);
1832 write_unlock(&cifs_tcp_ses_lock);
1833
1834 FreeXid(xid);
1835 return ses;
1836
1837get_ses_fail:
1838 sesInfoFree(ses);
1839 FreeXid(xid);
1840 return ERR_PTR(rc);
1841}
1842
f1987b44
JL
1843static struct cifsTconInfo *
1844cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1845{
1846 struct list_head *tmp;
1847 struct cifsTconInfo *tcon;
1848
1849 write_lock(&cifs_tcp_ses_lock);
1850 list_for_each(tmp, &ses->tcon_list) {
1851 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1852 if (tcon->tidStatus == CifsExiting)
1853 continue;
1854 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
dea570e0
SF
1855 continue;
1856
f1987b44
JL
1857 ++tcon->tc_count;
1858 write_unlock(&cifs_tcp_ses_lock);
dea570e0 1859 return tcon;
1da177e4 1860 }
f1987b44 1861 write_unlock(&cifs_tcp_ses_lock);
1da177e4
LT
1862 return NULL;
1863}
1864
f1987b44
JL
1865static void
1866cifs_put_tcon(struct cifsTconInfo *tcon)
1867{
1868 int xid;
1869 struct cifsSesInfo *ses = tcon->ses;
1870
d00c28de 1871 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
f1987b44
JL
1872 write_lock(&cifs_tcp_ses_lock);
1873 if (--tcon->tc_count > 0) {
1874 write_unlock(&cifs_tcp_ses_lock);
1875 return;
1876 }
1877
1878 list_del_init(&tcon->tcon_list);
1879 write_unlock(&cifs_tcp_ses_lock);
1880
1881 xid = GetXid();
1882 CIFSSMBTDis(xid, tcon);
1883 _FreeXid(xid);
1884
d03382ce 1885 cifs_fscache_release_super_cookie(tcon);
9f841593 1886 tconInfoFree(tcon);
f1987b44
JL
1887 cifs_put_smb_ses(ses);
1888}
1889
d00c28de
JL
1890static struct cifsTconInfo *
1891cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
1892{
1893 int rc, xid;
1894 struct cifsTconInfo *tcon;
1895
1896 tcon = cifs_find_tcon(ses, volume_info->UNC);
1897 if (tcon) {
1898 cFYI(1, "Found match on UNC path");
1899 /* existing tcon already has a reference */
1900 cifs_put_smb_ses(ses);
1901 if (tcon->seal != volume_info->seal)
1902 cERROR(1, "transport encryption setting "
1903 "conflicts with existing tid");
1904 return tcon;
1905 }
1906
1907 tcon = tconInfoAlloc();
1908 if (tcon == NULL) {
1909 rc = -ENOMEM;
1910 goto out_fail;
1911 }
1912
1913 tcon->ses = ses;
1914 if (volume_info->password) {
1915 tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
1916 if (!tcon->password) {
1917 rc = -ENOMEM;
1918 goto out_fail;
1919 }
1920 }
1921
1922 if (strchr(volume_info->UNC + 3, '\\') == NULL
1923 && strchr(volume_info->UNC + 3, '/') == NULL) {
1924 cERROR(1, "Missing share name");
1925 rc = -ENODEV;
1926 goto out_fail;
1927 }
1928
1929 /* BB Do we need to wrap session_mutex around
1930 * this TCon call and Unix SetFS as
1931 * we do on SessSetup and reconnect? */
1932 xid = GetXid();
1933 rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls);
1934 FreeXid(xid);
1935 cFYI(1, "CIFS Tcon rc = %d", rc);
1936 if (rc)
1937 goto out_fail;
1938
1939 if (volume_info->nodfs) {
1940 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
1941 cFYI(1, "DFS disabled (%d)", tcon->Flags);
1942 }
1943 tcon->seal = volume_info->seal;
1944 /* we can have only one retry value for a connection
1945 to a share so for resources mounted more than once
1946 to the same server share the last value passed in
1947 for the retry flag is used */
1948 tcon->retry = volume_info->retry;
1949 tcon->nocase = volume_info->nocase;
1950 tcon->local_lease = volume_info->local_lease;
1951
1952 write_lock(&cifs_tcp_ses_lock);
1953 list_add(&tcon->tcon_list, &ses->tcon_list);
1954 write_unlock(&cifs_tcp_ses_lock);
1955
d03382ce
SJ
1956 cifs_fscache_get_super_cookie(tcon);
1957
d00c28de
JL
1958 return tcon;
1959
1960out_fail:
1961 tconInfoFree(tcon);
1962 return ERR_PTR(rc);
1963}
1964
9d002df4
JL
1965void
1966cifs_put_tlink(struct tcon_link *tlink)
1967{
1968 if (!tlink || IS_ERR(tlink))
1969 return;
1970
1971 if (!atomic_dec_and_test(&tlink->tl_count) ||
1972 test_bit(TCON_LINK_IN_TREE, &tlink->tl_flags)) {
1973 tlink->tl_time = jiffies;
1974 return;
1975 }
1976
1977 if (!IS_ERR(tlink_tcon(tlink)))
1978 cifs_put_tcon(tlink_tcon(tlink));
1979 kfree(tlink);
1980 return;
1981}
d00c28de 1982
1da177e4 1983int
50c2f753
SF
1984get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1985 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
366781c1 1986 struct dfs_info3_param **preferrals, int remap)
1da177e4
LT
1987{
1988 char *temp_unc;
1989 int rc = 0;
1990
1991 *pnum_referrals = 0;
366781c1 1992 *preferrals = NULL;
1da177e4
LT
1993
1994 if (pSesInfo->ipc_tid == 0) {
1995 temp_unc = kmalloc(2 /* for slashes */ +
50c2f753
SF
1996 strnlen(pSesInfo->serverName,
1997 SERVER_NAME_LEN_WITH_NULL * 2)
1da177e4
LT
1998 + 1 + 4 /* slash IPC$ */ + 2,
1999 GFP_KERNEL);
2000 if (temp_unc == NULL)
2001 return -ENOMEM;
2002 temp_unc[0] = '\\';
2003 temp_unc[1] = '\\';
2004 strcpy(temp_unc + 2, pSesInfo->serverName);
2005 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
2006 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
b6b38f70 2007 cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid);
1da177e4
LT
2008 kfree(temp_unc);
2009 }
2010 if (rc == 0)
c2cf07d5 2011 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
737b758c 2012 pnum_referrals, nls_codepage, remap);
366781c1
SF
2013 /* BB map targetUNCs to dfs_info3 structures, here or
2014 in CIFSGetDFSRefer BB */
1da177e4
LT
2015
2016 return rc;
2017}
2018
09e50d55
JL
2019#ifdef CONFIG_DEBUG_LOCK_ALLOC
2020static struct lock_class_key cifs_key[2];
2021static struct lock_class_key cifs_slock_key[2];
2022
2023static inline void
2024cifs_reclassify_socket4(struct socket *sock)
2025{
2026 struct sock *sk = sock->sk;
2027 BUG_ON(sock_owned_by_user(sk));
2028 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
2029 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
2030}
2031
2032static inline void
2033cifs_reclassify_socket6(struct socket *sock)
2034{
2035 struct sock *sk = sock->sk;
2036 BUG_ON(sock_owned_by_user(sk));
2037 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
2038 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
2039}
2040#else
2041static inline void
2042cifs_reclassify_socket4(struct socket *sock)
2043{
2044}
2045
2046static inline void
2047cifs_reclassify_socket6(struct socket *sock)
2048{
2049}
2050#endif
2051
1da177e4 2052/* See RFC1001 section 14 on representation of Netbios names */
50c2f753 2053static void rfc1002mangle(char *target, char *source, unsigned int length)
1da177e4 2054{
50c2f753 2055 unsigned int i, j;
1da177e4 2056
50c2f753 2057 for (i = 0, j = 0; i < (length); i++) {
1da177e4
LT
2058 /* mask a nibble at a time and encode */
2059 target[j] = 'A' + (0x0F & (source[i] >> 4));
2060 target[j+1] = 'A' + (0x0F & source[i]);
50c2f753 2061 j += 2;
1da177e4
LT
2062 }
2063
2064}
2065
3eb9a889
BG
2066static int
2067bind_socket(struct TCP_Server_Info *server)
2068{
2069 int rc = 0;
2070 if (server->srcaddr.ss_family != AF_UNSPEC) {
2071 /* Bind to the specified local IP address */
2072 struct socket *socket = server->ssocket;
2073 rc = socket->ops->bind(socket,
2074 (struct sockaddr *) &server->srcaddr,
2075 sizeof(server->srcaddr));
2076 if (rc < 0) {
2077 struct sockaddr_in *saddr4;
2078 struct sockaddr_in6 *saddr6;
2079 saddr4 = (struct sockaddr_in *)&server->srcaddr;
2080 saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
2081 if (saddr6->sin6_family == AF_INET6)
2082 cERROR(1, "cifs: "
2083 "Failed to bind to: %pI6c, error: %d\n",
2084 &saddr6->sin6_addr, rc);
2085 else
2086 cERROR(1, "cifs: "
2087 "Failed to bind to: %pI4, error: %d\n",
2088 &saddr4->sin_addr.s_addr, rc);
2089 }
2090 }
2091 return rc;
2092}
1da177e4
LT
2093
2094static int
bcf4b106 2095ipv4_connect(struct TCP_Server_Info *server)
1da177e4
LT
2096{
2097 int rc = 0;
6a5fa236 2098 int val;
bcf4b106 2099 bool connected = false;
1da177e4 2100 __be16 orig_port = 0;
bcf4b106 2101 struct socket *socket = server->ssocket;
1da177e4 2102
bcf4b106 2103 if (socket == NULL) {
50c2f753 2104 rc = sock_create_kern(PF_INET, SOCK_STREAM,
bcf4b106 2105 IPPROTO_TCP, &socket);
1da177e4 2106 if (rc < 0) {
b6b38f70 2107 cERROR(1, "Error %d creating socket", rc);
1da177e4 2108 return rc;
1da177e4 2109 }
bcf4b106
JL
2110
2111 /* BB other socket options to set KEEPALIVE, NODELAY? */
b6b38f70 2112 cFYI(1, "Socket created");
bcf4b106
JL
2113 server->ssocket = socket;
2114 socket->sk->sk_allocation = GFP_NOFS;
2115 cifs_reclassify_socket4(socket);
1da177e4
LT
2116 }
2117
3eb9a889
BG
2118 rc = bind_socket(server);
2119 if (rc < 0)
2120 return rc;
2121
bcf4b106
JL
2122 /* user overrode default port */
2123 if (server->addr.sockAddr.sin_port) {
2124 rc = socket->ops->connect(socket, (struct sockaddr *)
2125 &server->addr.sockAddr,
2126 sizeof(struct sockaddr_in), 0);
1da177e4 2127 if (rc >= 0)
bcf4b106 2128 connected = true;
50c2f753 2129 }
1da177e4 2130
fb8c4b14 2131 if (!connected) {
50c2f753 2132 /* save original port so we can retry user specified port
1da177e4 2133 later if fall back ports fail this time */
bcf4b106 2134 orig_port = server->addr.sockAddr.sin_port;
1da177e4
LT
2135
2136 /* do not retry on the same port we just failed on */
bcf4b106
JL
2137 if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
2138 server->addr.sockAddr.sin_port = htons(CIFS_PORT);
2139 rc = socket->ops->connect(socket,
2140 (struct sockaddr *)
2141 &server->addr.sockAddr,
2142 sizeof(struct sockaddr_in), 0);
1da177e4 2143 if (rc >= 0)
bcf4b106 2144 connected = true;
1da177e4
LT
2145 }
2146 }
2147 if (!connected) {
bcf4b106
JL
2148 server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
2149 rc = socket->ops->connect(socket, (struct sockaddr *)
2150 &server->addr.sockAddr,
6345a3a8 2151 sizeof(struct sockaddr_in), 0);
50c2f753 2152 if (rc >= 0)
bcf4b106 2153 connected = true;
1da177e4
LT
2154 }
2155
2156 /* give up here - unless we want to retry on different
2157 protocol families some day */
2158 if (!connected) {
fb8c4b14 2159 if (orig_port)
bcf4b106 2160 server->addr.sockAddr.sin_port = orig_port;
b6b38f70 2161 cFYI(1, "Error %d connecting to server via ipv4", rc);
bcf4b106
JL
2162 sock_release(socket);
2163 server->ssocket = NULL;
1da177e4
LT
2164 return rc;
2165 }
bcf4b106
JL
2166
2167
2168 /*
2169 * Eventually check for other socket options to change from
2170 * the default. sock_setsockopt not used because it expects
2171 * user space buffer
2172 */
2173 socket->sk->sk_rcvtimeo = 7 * HZ;
da505c38 2174 socket->sk->sk_sndtimeo = 5 * HZ;
edf1ae40 2175
b387eaeb 2176 /* make the bufsizes depend on wsize/rsize and max requests */
bcf4b106
JL
2177 if (server->noautotune) {
2178 if (socket->sk->sk_sndbuf < (200 * 1024))
2179 socket->sk->sk_sndbuf = 200 * 1024;
2180 if (socket->sk->sk_rcvbuf < (140 * 1024))
2181 socket->sk->sk_rcvbuf = 140 * 1024;
edf1ae40 2182 }
1da177e4 2183
6a5fa236
SF
2184 if (server->tcp_nodelay) {
2185 val = 1;
2186 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2187 (char *)&val, sizeof(val));
2188 if (rc)
b6b38f70 2189 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
6a5fa236
SF
2190 }
2191
b6b38f70 2192 cFYI(1, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
bcf4b106 2193 socket->sk->sk_sndbuf,
b6b38f70 2194 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
bcf4b106 2195
1da177e4 2196 /* send RFC1001 sessinit */
bcf4b106 2197 if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) {
1da177e4 2198 /* some servers require RFC1001 sessinit before sending
50c2f753 2199 negprot - BB check reconnection in case where second
1da177e4 2200 sessinit is sent but no second negprot */
50c2f753
SF
2201 struct rfc1002_session_packet *ses_init_buf;
2202 struct smb_hdr *smb_buf;
2203 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2204 GFP_KERNEL);
fb8c4b14 2205 if (ses_init_buf) {
1da177e4 2206 ses_init_buf->trailer.session_req.called_len = 32;
bcf4b106
JL
2207 if (server->server_RFC1001_name &&
2208 server->server_RFC1001_name[0] != 0)
8ecaf67a
JL
2209 rfc1002mangle(ses_init_buf->trailer.
2210 session_req.called_name,
bcf4b106 2211 server->server_RFC1001_name,
8ecaf67a 2212 RFC1001_NAME_LEN_WITH_NULL);
bcf4b106 2213 else
8ecaf67a
JL
2214 rfc1002mangle(ses_init_buf->trailer.
2215 session_req.called_name,
2216 DEFAULT_CIFS_CALLED_NAME,
2217 RFC1001_NAME_LEN_WITH_NULL);
a10faeb2 2218
1da177e4 2219 ses_init_buf->trailer.session_req.calling_len = 32;
bcf4b106 2220
1da177e4
LT
2221 /* calling name ends in null (byte 16) from old smb
2222 convention. */
bcf4b106
JL
2223 if (server->workstation_RFC1001_name &&
2224 server->workstation_RFC1001_name[0] != 0)
8ecaf67a
JL
2225 rfc1002mangle(ses_init_buf->trailer.
2226 session_req.calling_name,
bcf4b106 2227 server->workstation_RFC1001_name,
8ecaf67a 2228 RFC1001_NAME_LEN_WITH_NULL);
bcf4b106 2229 else
8ecaf67a
JL
2230 rfc1002mangle(ses_init_buf->trailer.
2231 session_req.calling_name,
2232 "LINUX_CIFS_CLNT",
2233 RFC1001_NAME_LEN_WITH_NULL);
bcf4b106 2234
1da177e4
LT
2235 ses_init_buf->trailer.session_req.scope1 = 0;
2236 ses_init_buf->trailer.session_req.scope2 = 0;
2237 smb_buf = (struct smb_hdr *)ses_init_buf;
2238 /* sizeof RFC1002_SESSION_REQUEST with no scope */
2239 smb_buf->smb_buf_length = 0x81000044;
0496e02d 2240 rc = smb_send(server, smb_buf, 0x44);
1da177e4 2241 kfree(ses_init_buf);
50c2f753 2242 msleep(1); /* RFC1001 layer in at least one server
083d3a2c
SF
2243 requires very short break before negprot
2244 presumably because not expecting negprot
2245 to follow so fast. This is a simple
50c2f753 2246 solution that works without
083d3a2c
SF
2247 complicating the code and causes no
2248 significant slowing down on mount
2249 for everyone else */
1da177e4 2250 }
50c2f753 2251 /* else the negprot may still work without this
1da177e4 2252 even though malloc failed */
50c2f753 2253
1da177e4 2254 }
50c2f753 2255
1da177e4
LT
2256 return rc;
2257}
2258
2259static int
d5c5605c 2260ipv6_connect(struct TCP_Server_Info *server)
1da177e4
LT
2261{
2262 int rc = 0;
6a5fa236 2263 int val;
d5c5605c 2264 bool connected = false;
1da177e4 2265 __be16 orig_port = 0;
d5c5605c 2266 struct socket *socket = server->ssocket;
1da177e4 2267
d5c5605c 2268 if (socket == NULL) {
50c2f753 2269 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
d5c5605c 2270 IPPROTO_TCP, &socket);
1da177e4 2271 if (rc < 0) {
b6b38f70 2272 cERROR(1, "Error %d creating ipv6 socket", rc);
d5c5605c 2273 socket = NULL;
1da177e4 2274 return rc;
1da177e4 2275 }
1da177e4 2276
d5c5605c 2277 /* BB other socket options to set KEEPALIVE, NODELAY? */
b6b38f70 2278 cFYI(1, "ipv6 Socket created");
d5c5605c
JL
2279 server->ssocket = socket;
2280 socket->sk->sk_allocation = GFP_NOFS;
2281 cifs_reclassify_socket6(socket);
2282 }
1da177e4 2283
3eb9a889
BG
2284 rc = bind_socket(server);
2285 if (rc < 0)
2286 return rc;
2287
d5c5605c
JL
2288 /* user overrode default port */
2289 if (server->addr.sockAddr6.sin6_port) {
2290 rc = socket->ops->connect(socket,
2291 (struct sockaddr *) &server->addr.sockAddr6,
6345a3a8 2292 sizeof(struct sockaddr_in6), 0);
1da177e4 2293 if (rc >= 0)
d5c5605c 2294 connected = true;
50c2f753 2295 }
1da177e4 2296
fb8c4b14 2297 if (!connected) {
50c2f753 2298 /* save original port so we can retry user specified port
1da177e4
LT
2299 later if fall back ports fail this time */
2300
d5c5605c 2301 orig_port = server->addr.sockAddr6.sin6_port;
1da177e4 2302 /* do not retry on the same port we just failed on */
d5c5605c
JL
2303 if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) {
2304 server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
2305 rc = socket->ops->connect(socket, (struct sockaddr *)
2306 &server->addr.sockAddr6,
6345a3a8 2307 sizeof(struct sockaddr_in6), 0);
1da177e4 2308 if (rc >= 0)
d5c5605c 2309 connected = true;
1da177e4
LT
2310 }
2311 }
2312 if (!connected) {
d5c5605c
JL
2313 server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT);
2314 rc = socket->ops->connect(socket, (struct sockaddr *)
2315 &server->addr.sockAddr6,
2316 sizeof(struct sockaddr_in6), 0);
50c2f753 2317 if (rc >= 0)
d5c5605c 2318 connected = true;
1da177e4
LT
2319 }
2320
2321 /* give up here - unless we want to retry on different
2322 protocol families some day */
2323 if (!connected) {
fb8c4b14 2324 if (orig_port)
d5c5605c 2325 server->addr.sockAddr6.sin6_port = orig_port;
b6b38f70 2326 cFYI(1, "Error %d connecting to server via ipv6", rc);
d5c5605c
JL
2327 sock_release(socket);
2328 server->ssocket = NULL;
1da177e4
LT
2329 return rc;
2330 }
edf1ae40 2331
d5c5605c
JL
2332 /*
2333 * Eventually check for other socket options to change from
2334 * the default. sock_setsockopt not used because it expects
2335 * user space buffer
2336 */
2337 socket->sk->sk_rcvtimeo = 7 * HZ;
da505c38 2338 socket->sk->sk_sndtimeo = 5 * HZ;
6a5fa236
SF
2339
2340 if (server->tcp_nodelay) {
2341 val = 1;
2342 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2343 (char *)&val, sizeof(val));
2344 if (rc)
b6b38f70 2345 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
6a5fa236
SF
2346 }
2347
d5c5605c 2348 server->ssocket = socket;
50c2f753 2349
1da177e4
LT
2350 return rc;
2351}
2352
50c2f753
SF
2353void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2354 struct super_block *sb, struct smb_vol *vol_info)
8af18971
SF
2355{
2356 /* if we are reconnecting then should we check to see if
2357 * any requested capabilities changed locally e.g. via
2358 * remount but we can not do much about it here
2359 * if they have (even if we could detect it by the following)
2360 * Perhaps we could add a backpointer to array of sb from tcon
2361 * or if we change to make all sb to same share the same
2362 * sb as NFS - then we only have one backpointer to sb.
2363 * What if we wanted to mount the server share twice once with
2364 * and once without posixacls or posix paths? */
2365 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
50c2f753 2366
c18c842b
SF
2367 if (vol_info && vol_info->no_linux_ext) {
2368 tcon->fsUnixInfo.Capability = 0;
2369 tcon->unix_ext = 0; /* Unix Extensions disabled */
b6b38f70 2370 cFYI(1, "Linux protocol extensions disabled");
c18c842b
SF
2371 return;
2372 } else if (vol_info)
2373 tcon->unix_ext = 1; /* Unix Extensions supported */
2374
2375 if (tcon->unix_ext == 0) {
b6b38f70 2376 cFYI(1, "Unix extensions disabled so not set on reconnect");
c18c842b
SF
2377 return;
2378 }
50c2f753 2379
fb8c4b14 2380 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
8af18971 2381 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
50c2f753 2382
8af18971
SF
2383 /* check for reconnect case in which we do not
2384 want to change the mount behavior if we can avoid it */
fb8c4b14 2385 if (vol_info == NULL) {
50c2f753 2386 /* turn off POSIX ACL and PATHNAMES if not set
8af18971
SF
2387 originally at mount time */
2388 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
2389 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
11b6d645
IM
2390 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2391 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
b6b38f70 2392 cERROR(1, "POSIXPATH support change");
8af18971 2393 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
11b6d645 2394 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
b6b38f70
JP
2395 cERROR(1, "possible reconnect error");
2396 cERROR(1, "server disabled POSIX path support");
11b6d645 2397 }
8af18971 2398 }
50c2f753 2399
8af18971 2400 cap &= CIFS_UNIX_CAP_MASK;
75865f8c 2401 if (vol_info && vol_info->no_psx_acl)
8af18971 2402 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
75865f8c 2403 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
b6b38f70 2404 cFYI(1, "negotiated posix acl support");
fb8c4b14 2405 if (sb)
8af18971
SF
2406 sb->s_flags |= MS_POSIXACL;
2407 }
2408
75865f8c 2409 if (vol_info && vol_info->posix_paths == 0)
8af18971 2410 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
75865f8c 2411 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
b6b38f70 2412 cFYI(1, "negotiate posix pathnames");
75865f8c 2413 if (sb)
50c2f753 2414 CIFS_SB(sb)->mnt_cifs_flags |=
8af18971
SF
2415 CIFS_MOUNT_POSIX_PATHS;
2416 }
50c2f753 2417
984acfe1
SF
2418 /* We might be setting the path sep back to a different
2419 form if we are reconnecting and the server switched its
50c2f753 2420 posix path capability for this share */
75865f8c 2421 if (sb && (CIFS_SB(sb)->prepathlen > 0))
984acfe1 2422 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
75865f8c
SF
2423
2424 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2425 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2426 CIFS_SB(sb)->rsize = 127 * 1024;
b6b38f70 2427 cFYI(DBG2, "larger reads not supported by srv");
75865f8c
SF
2428 }
2429 }
50c2f753
SF
2430
2431
b6b38f70 2432 cFYI(1, "Negotiate caps 0x%x", (int)cap);
8af18971 2433#ifdef CONFIG_CIFS_DEBUG2
75865f8c 2434 if (cap & CIFS_UNIX_FCNTL_CAP)
b6b38f70 2435 cFYI(1, "FCNTL cap");
75865f8c 2436 if (cap & CIFS_UNIX_EXTATTR_CAP)
b6b38f70 2437 cFYI(1, "EXTATTR cap");
75865f8c 2438 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
b6b38f70 2439 cFYI(1, "POSIX path cap");
75865f8c 2440 if (cap & CIFS_UNIX_XATTR_CAP)
b6b38f70 2441 cFYI(1, "XATTR cap");
75865f8c 2442 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
b6b38f70 2443 cFYI(1, "POSIX ACL cap");
75865f8c 2444 if (cap & CIFS_UNIX_LARGE_READ_CAP)
b6b38f70 2445 cFYI(1, "very large read cap");
75865f8c 2446 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
b6b38f70 2447 cFYI(1, "very large write cap");
8af18971
SF
2448#endif /* CIFS_DEBUG2 */
2449 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
442aa310 2450 if (vol_info == NULL) {
b6b38f70 2451 cFYI(1, "resetting capabilities failed");
442aa310 2452 } else
b6b38f70 2453 cERROR(1, "Negotiating Unix capabilities "
5a44b319
SF
2454 "with the server failed. Consider "
2455 "mounting with the Unix Extensions\n"
2456 "disabled, if problems are found, "
2457 "by specifying the nounix mount "
b6b38f70 2458 "option.");
5a44b319 2459
8af18971
SF
2460 }
2461 }
2462}
2463
03a143c9
SF
2464static void
2465convert_delimiter(char *path, char delim)
2466{
2467 int i;
c2d68ea6 2468 char old_delim;
03a143c9
SF
2469
2470 if (path == NULL)
2471 return;
2472
582d21e5 2473 if (delim == '/')
c2d68ea6
SF
2474 old_delim = '\\';
2475 else
2476 old_delim = '/';
2477
03a143c9 2478 for (i = 0; path[i] != '\0'; i++) {
c2d68ea6 2479 if (path[i] == old_delim)
03a143c9
SF
2480 path[i] = delim;
2481 }
2482}
2483
3b795210
SF
2484static void setup_cifs_sb(struct smb_vol *pvolume_info,
2485 struct cifs_sb_info *cifs_sb)
b1c8d2b4 2486{
3b795210 2487 if (pvolume_info->rsize > CIFSMaxBufSize) {
b6b38f70
JP
2488 cERROR(1, "rsize %d too large, using MaxBufSize",
2489 pvolume_info->rsize);
3b795210
SF
2490 cifs_sb->rsize = CIFSMaxBufSize;
2491 } else if ((pvolume_info->rsize) &&
2492 (pvolume_info->rsize <= CIFSMaxBufSize))
2493 cifs_sb->rsize = pvolume_info->rsize;
2494 else /* default */
2495 cifs_sb->rsize = CIFSMaxBufSize;
2496
2497 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
b6b38f70
JP
2498 cERROR(1, "wsize %d too large, using 4096 instead",
2499 pvolume_info->wsize);
3b795210
SF
2500 cifs_sb->wsize = 4096;
2501 } else if (pvolume_info->wsize)
2502 cifs_sb->wsize = pvolume_info->wsize;
2503 else
2504 cifs_sb->wsize = min_t(const int,
2505 PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2506 127*1024);
2507 /* old default of CIFSMaxBufSize was too small now
2508 that SMB Write2 can send multiple pages in kvec.
2509 RFC1001 does not describe what happens when frame
2510 bigger than 128K is sent so use that as max in
2511 conjunction with 52K kvec constraint on arch with 4K
2512 page size */
2513
2514 if (cifs_sb->rsize < 2048) {
2515 cifs_sb->rsize = 2048;
2516 /* Windows ME may prefer this */
b6b38f70 2517 cFYI(1, "readsize set to minimum: 2048");
3b795210
SF
2518 }
2519 /* calculate prepath */
2520 cifs_sb->prepath = pvolume_info->prepath;
2521 if (cifs_sb->prepath) {
2522 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2523 /* we can not convert the / to \ in the path
2524 separators in the prefixpath yet because we do not
2525 know (until reset_cifs_unix_caps is called later)
2526 whether POSIX PATH CAP is available. We normalize
2527 the / to \ after reset_cifs_unix_caps is called */
2528 pvolume_info->prepath = NULL;
2529 } else
2530 cifs_sb->prepathlen = 0;
2531 cifs_sb->mnt_uid = pvolume_info->linux_uid;
2532 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2533 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
2534 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
b6b38f70
JP
2535 cFYI(1, "file mode: 0x%x dir mode: 0x%x",
2536 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
3b795210
SF
2537
2538 if (pvolume_info->noperm)
2539 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2540 if (pvolume_info->setuids)
2541 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2542 if (pvolume_info->server_ino)
2543 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2544 if (pvolume_info->remap)
2545 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2546 if (pvolume_info->no_xattr)
2547 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2548 if (pvolume_info->sfu_emul)
2549 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2550 if (pvolume_info->nobrl)
2551 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
be652445 2552 if (pvolume_info->nostrictsync)
4717bed6 2553 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
13a6e42a
SF
2554 if (pvolume_info->mand_lock)
2555 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
3b795210
SF
2556 if (pvolume_info->cifs_acl)
2557 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2558 if (pvolume_info->override_uid)
2559 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2560 if (pvolume_info->override_gid)
2561 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2562 if (pvolume_info->dynperm)
2563 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
fa1df75d
SJ
2564 if (pvolume_info->fsc)
2565 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
3b795210 2566 if (pvolume_info->direct_io) {
b6b38f70 2567 cFYI(1, "mounting share using direct i/o");
3b795210
SF
2568 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2569 }
736a3320
SM
2570 if (pvolume_info->mfsymlinks) {
2571 if (pvolume_info->sfu_emul) {
2572 cERROR(1, "mount option mfsymlinks ignored if sfu "
2573 "mount option is used");
2574 } else {
2575 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
2576 }
2577 }
3b795210
SF
2578
2579 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
b6b38f70
JP
2580 cERROR(1, "mount option dynperm ignored if cifsacl "
2581 "mount option supported");
b1c8d2b4
JL
2582}
2583
e4cce94c
IM
2584static int
2585is_path_accessible(int xid, struct cifsTconInfo *tcon,
2586 struct cifs_sb_info *cifs_sb, const char *full_path)
2587{
2588 int rc;
e4cce94c
IM
2589 FILE_ALL_INFO *pfile_info;
2590
e4cce94c
IM
2591 pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
2592 if (pfile_info == NULL)
2593 return -ENOMEM;
2594
2595 rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info,
2596 0 /* not legacy */, cifs_sb->local_nls,
2597 cifs_sb->mnt_cifs_flags &
2598 CIFS_MOUNT_MAP_SPECIAL_CHR);
2599 kfree(pfile_info);
2600 return rc;
2601}
2602
1bfe73c2
IM
2603static void
2604cleanup_volume_info(struct smb_vol **pvolume_info)
2605{
2606 struct smb_vol *volume_info;
2607
ad6cca6d 2608 if (!pvolume_info || !*pvolume_info)
1bfe73c2
IM
2609 return;
2610
2611 volume_info = *pvolume_info;
2612 kzfree(volume_info->password);
2613 kfree(volume_info->UNC);
2614 kfree(volume_info->prepath);
2615 kfree(volume_info);
2616 *pvolume_info = NULL;
2617 return;
2618}
2619
2d6d589d 2620#ifdef CONFIG_CIFS_DFS_UPCALL
1bfe73c2
IM
2621/* build_path_to_root returns full path to root when
2622 * we do not have an exiting connection (tcon) */
2623static char *
2624build_unc_path_to_root(const struct smb_vol *volume_info,
2625 const struct cifs_sb_info *cifs_sb)
2626{
2627 char *full_path;
2628
2629 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
2630 full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL);
2631 if (full_path == NULL)
2632 return ERR_PTR(-ENOMEM);
2633
2634 strncpy(full_path, volume_info->UNC, unc_len);
2635 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
2636 int i;
2637 for (i = 0; i < unc_len; i++) {
2638 if (full_path[i] == '\\')
2639 full_path[i] = '/';
2640 }
2641 }
2642
2643 if (cifs_sb->prepathlen)
2644 strncpy(full_path + unc_len, cifs_sb->prepath,
2645 cifs_sb->prepathlen);
2646
2647 full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
2648 return full_path;
2649}
2d6d589d 2650#endif
1bfe73c2 2651
1da177e4
LT
2652int
2653cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1bfe73c2 2654 char *mount_data_global, const char *devname)
1da177e4 2655{
a2934c7b 2656 int rc;
1da177e4 2657 int xid;
7586b765 2658 struct smb_vol *volume_info;
a2934c7b
JL
2659 struct cifsSesInfo *pSesInfo;
2660 struct cifsTconInfo *tcon;
2661 struct TCP_Server_Info *srvTcp;
e4cce94c 2662 char *full_path;
2d6d589d 2663 char *mount_data = mount_data_global;
9d002df4 2664 struct tcon_link *tlink;
2d6d589d 2665#ifdef CONFIG_CIFS_DFS_UPCALL
1bfe73c2
IM
2666 struct dfs_info3_param *referrals = NULL;
2667 unsigned int num_referrals = 0;
5c2503a8 2668 int referral_walks_count = 0;
1bfe73c2 2669try_mount_again:
2d6d589d 2670#endif
a2934c7b
JL
2671 rc = 0;
2672 tcon = NULL;
2673 pSesInfo = NULL;
2674 srvTcp = NULL;
1bfe73c2 2675 full_path = NULL;
9d002df4 2676 tlink = NULL;
1da177e4
LT
2677
2678 xid = GetXid();
2679
7586b765
JL
2680 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2681 if (!volume_info) {
2682 rc = -ENOMEM;
2683 goto out;
2684 }
50c2f753 2685
7586b765 2686 if (cifs_parse_mount_options(mount_data, devname, volume_info)) {
70fe7dc0
JL
2687 rc = -EINVAL;
2688 goto out;
1da177e4
LT
2689 }
2690
7586b765 2691 if (volume_info->nullauth) {
b6b38f70 2692 cFYI(1, "null user");
7586b765
JL
2693 volume_info->username = "";
2694 } else if (volume_info->username) {
1da177e4 2695 /* BB fixme parse for domain name here */
b6b38f70 2696 cFYI(1, "Username: %s", volume_info->username);
1da177e4 2697 } else {
bf820679 2698 cifserror("No username specified");
50c2f753
SF
2699 /* In userspace mount helper we can get user name from alternate
2700 locations such as env variables and files on disk */
70fe7dc0
JL
2701 rc = -EINVAL;
2702 goto out;
1da177e4
LT
2703 }
2704
1da177e4 2705 /* this is needed for ASCII cp to Unicode converts */
7586b765 2706 if (volume_info->iocharset == NULL) {
a5fc4ce0
JL
2707 /* load_nls_default cannot return null */
2708 volume_info->local_nls = load_nls_default();
1da177e4 2709 } else {
a5fc4ce0
JL
2710 volume_info->local_nls = load_nls(volume_info->iocharset);
2711 if (volume_info->local_nls == NULL) {
b6b38f70
JP
2712 cERROR(1, "CIFS mount error: iocharset %s not found",
2713 volume_info->iocharset);
70fe7dc0
JL
2714 rc = -ELIBACC;
2715 goto out;
1da177e4
LT
2716 }
2717 }
a5fc4ce0 2718 cifs_sb->local_nls = volume_info->local_nls;
1da177e4 2719
63c038c2 2720 /* get a reference to a tcp session */
7586b765 2721 srvTcp = cifs_get_tcp_session(volume_info);
63c038c2
JL
2722 if (IS_ERR(srvTcp)) {
2723 rc = PTR_ERR(srvTcp);
2724 goto out;
1da177e4
LT
2725 }
2726
36988c76
JL
2727 /* get a reference to a SMB session */
2728 pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
2729 if (IS_ERR(pSesInfo)) {
2730 rc = PTR_ERR(pSesInfo);
2731 pSesInfo = NULL;
2732 goto mount_fail_check;
1da177e4 2733 }
50c2f753 2734
d00c28de
JL
2735 setup_cifs_sb(volume_info, cifs_sb);
2736 if (pSesInfo->capabilities & CAP_LARGE_FILES)
2737 sb->s_maxbytes = MAX_LFS_FILESIZE;
2738 else
2739 sb->s_maxbytes = MAX_NON_LFS;
1da177e4 2740
8af18971 2741 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
1da177e4
LT
2742 sb->s_time_gran = 100;
2743
d00c28de
JL
2744 /* search for existing tcon to this server share */
2745 tcon = cifs_get_tcon(pSesInfo, volume_info);
2746 if (IS_ERR(tcon)) {
2747 rc = PTR_ERR(tcon);
2748 tcon = NULL;
1bfe73c2 2749 goto remote_path_check;
d00c28de 2750 }
1bfe73c2 2751
d82c2df5
SF
2752 /* do not care if following two calls succeed - informational */
2753 if (!tcon->ipc) {
2754 CIFSSMBQFSDeviceInfo(xid, tcon);
2755 CIFSSMBQFSAttributeInfo(xid, tcon);
2756 }
03a143c9 2757
d82c2df5
SF
2758 /* tell server which Unix caps we support */
2759 if (tcon->ses->capabilities & CAP_UNIX)
2760 /* reset of caps checks mount to see if unix extensions
2761 disabled for just this mount */
7586b765 2762 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
d82c2df5
SF
2763 else
2764 tcon->unix_ext = 0; /* server does not support them */
c18c842b 2765
d82c2df5
SF
2766 /* convert forward to back slashes in prepath here if needed */
2767 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2768 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
03a143c9 2769
d82c2df5
SF
2770 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2771 cifs_sb->rsize = 1024 * 127;
b6b38f70 2772 cFYI(DBG2, "no very large read support, rsize now 127K");
1da177e4 2773 }
d82c2df5
SF
2774 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2775 cifs_sb->wsize = min(cifs_sb->wsize,
2776 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2777 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2778 cifs_sb->rsize = min(cifs_sb->rsize,
2779 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
1da177e4 2780
1bfe73c2
IM
2781remote_path_check:
2782 /* check if a whole path (including prepath) is not remote */
2783 if (!rc && cifs_sb->prepathlen && tcon) {
e4cce94c
IM
2784 /* build_path_to_root works only when we have a valid tcon */
2785 full_path = cifs_build_path_to_root(cifs_sb);
2786 if (full_path == NULL) {
2787 rc = -ENOMEM;
2788 goto mount_fail_check;
2789 }
2790 rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
1bfe73c2 2791 if (rc != -EREMOTE) {
e4cce94c
IM
2792 kfree(full_path);
2793 goto mount_fail_check;
2794 }
2795 kfree(full_path);
2796 }
2797
1bfe73c2
IM
2798 /* get referral if needed */
2799 if (rc == -EREMOTE) {
d036f50f 2800#ifdef CONFIG_CIFS_DFS_UPCALL
5c2503a8
IM
2801 if (referral_walks_count > MAX_NESTED_LINKS) {
2802 /*
2803 * BB: when we implement proper loop detection,
2804 * we will remove this check. But now we need it
2805 * to prevent an indefinite loop if 'DFS tree' is
2806 * misconfigured (i.e. has loops).
2807 */
2808 rc = -ELOOP;
2809 goto mount_fail_check;
2810 }
1bfe73c2
IM
2811 /* convert forward to back slashes in prepath here if needed */
2812 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2813 convert_delimiter(cifs_sb->prepath,
2814 CIFS_DIR_SEP(cifs_sb));
2815 full_path = build_unc_path_to_root(volume_info, cifs_sb);
2816 if (IS_ERR(full_path)) {
2817 rc = PTR_ERR(full_path);
2818 goto mount_fail_check;
2819 }
2820
b6b38f70 2821 cFYI(1, "Getting referral for: %s", full_path);
1bfe73c2
IM
2822 rc = get_dfs_path(xid, pSesInfo , full_path + 1,
2823 cifs_sb->local_nls, &num_referrals, &referrals,
2824 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
2825 if (!rc && num_referrals > 0) {
2826 char *fake_devname = NULL;
2827
2828 if (mount_data != mount_data_global)
2829 kfree(mount_data);
7b91e266 2830
1bfe73c2
IM
2831 mount_data = cifs_compose_mount_options(
2832 cifs_sb->mountdata, full_path + 1,
2833 referrals, &fake_devname);
7b91e266 2834
1bfe73c2 2835 free_dfs_info_array(referrals, num_referrals);
7b91e266
JL
2836 kfree(fake_devname);
2837 kfree(full_path);
2838
2839 if (IS_ERR(mount_data)) {
2840 rc = PTR_ERR(mount_data);
2841 mount_data = NULL;
2842 goto mount_fail_check;
2843 }
1bfe73c2
IM
2844
2845 if (tcon)
2846 cifs_put_tcon(tcon);
2847 else if (pSesInfo)
2848 cifs_put_smb_ses(pSesInfo);
2849
2850 cleanup_volume_info(&volume_info);
5c2503a8 2851 referral_walks_count++;
a2934c7b 2852 FreeXid(xid);
1bfe73c2
IM
2853 goto try_mount_again;
2854 }
d036f50f
SF
2855#else /* No DFS support, return error on mount */
2856 rc = -EOPNOTSUPP;
2857#endif
1bfe73c2
IM
2858 }
2859
9d002df4
JL
2860 if (rc)
2861 goto mount_fail_check;
2862
2863 /* now, hang the tcon off of the superblock */
2864 tlink = kzalloc(sizeof *tlink, GFP_KERNEL);
2865 if (tlink == NULL) {
2866 rc = -ENOMEM;
2867 goto mount_fail_check;
2868 }
2869
2870 tlink->tl_index = pSesInfo->linux_uid;
2871 tlink->tl_tcon = tcon;
2872 tlink->tl_time = jiffies;
2873 set_bit(TCON_LINK_MASTER, &tlink->tl_flags);
2874 set_bit(TCON_LINK_IN_TREE, &tlink->tl_flags);
2875
2876 rc = radix_tree_preload(GFP_KERNEL);
2877 if (rc == -ENOMEM) {
2878 kfree(tlink);
2879 goto mount_fail_check;
2880 }
2881
2882 spin_lock(&cifs_sb->tlink_tree_lock);
2883 radix_tree_insert(&cifs_sb->tlink_tree, pSesInfo->linux_uid, tlink);
2884 radix_tree_tag_set(&cifs_sb->tlink_tree, pSesInfo->linux_uid,
2885 CIFS_TLINK_MASTER_TAG);
2886 spin_unlock(&cifs_sb->tlink_tree_lock);
2887 radix_tree_preload_end();
2888
1bfe73c2
IM
2889mount_fail_check:
2890 /* on error free sesinfo and tcon struct if needed */
2891 if (rc) {
2892 if (mount_data != mount_data_global)
2893 kfree(mount_data);
2894 /* If find_unc succeeded then rc == 0 so we can not end */
2895 /* up accidently freeing someone elses tcon struct */
2896 if (tcon)
2897 cifs_put_tcon(tcon);
2898 else if (pSesInfo)
2899 cifs_put_smb_ses(pSesInfo);
2900 else
2901 cifs_put_tcp_session(srvTcp);
2902 goto out;
2903 }
2904
7586b765 2905 /* volume_info->password is freed above when existing session found
1da177e4
LT
2906 (in which case it is not needed anymore) but when new sesion is created
2907 the password ptr is put in the new session structure (in which case the
2908 password will be freed at unmount time) */
70fe7dc0
JL
2909out:
2910 /* zero out password before freeing */
1bfe73c2 2911 cleanup_volume_info(&volume_info);
1da177e4
LT
2912 FreeXid(xid);
2913 return rc;
2914}
2915
1da177e4
LT
2916int
2917CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2918 const char *tree, struct cifsTconInfo *tcon,
2919 const struct nls_table *nls_codepage)
2920{
2921 struct smb_hdr *smb_buffer;
2922 struct smb_hdr *smb_buffer_response;
2923 TCONX_REQ *pSMB;
2924 TCONX_RSP *pSMBr;
2925 unsigned char *bcc_ptr;
2926 int rc = 0;
cc20c031 2927 int length, bytes_left;
1da177e4
LT
2928 __u16 count;
2929
2930 if (ses == NULL)
2931 return -EIO;
2932
2933 smb_buffer = cifs_buf_get();
ca43e3be 2934 if (smb_buffer == NULL)
1da177e4 2935 return -ENOMEM;
ca43e3be 2936
1da177e4
LT
2937 smb_buffer_response = smb_buffer;
2938
2939 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
2940 NULL /*no tid */ , 4 /*wct */ );
1982c344
SF
2941
2942 smb_buffer->Mid = GetNextMid(ses->server);
1da177e4
LT
2943 smb_buffer->Uid = ses->Suid;
2944 pSMB = (TCONX_REQ *) smb_buffer;
2945 pSMBr = (TCONX_RSP *) smb_buffer_response;
2946
2947 pSMB->AndXCommand = 0xFF;
2948 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
1da177e4 2949 bcc_ptr = &pSMB->Password[0];
fb8c4b14 2950 if ((ses->server->secMode) & SECMODE_USER) {
eeac8047 2951 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
7c7b25bc 2952 *bcc_ptr = 0; /* password is null byte */
eeac8047 2953 bcc_ptr++; /* skip password */
7c7b25bc 2954 /* already aligned so no need to do it below */
eeac8047 2955 } else {
7c7b25bc 2956 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
eeac8047
SF
2957 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
2958 specified as required (when that support is added to
2959 the vfs in the future) as only NTLM or the much
7c7b25bc 2960 weaker LANMAN (which we do not send by default) is accepted
eeac8047
SF
2961 by Samba (not sure whether other servers allow
2962 NTLMv2 password here) */
7c7b25bc 2963#ifdef CONFIG_CIFS_WEAK_PW_HASH
04912d6a 2964 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
00e485b0
JL
2965 (ses->server->secType == LANMAN))
2966 calc_lanman_hash(tcon->password, ses->server->cryptKey,
4e53a3fb
JL
2967 ses->server->secMode &
2968 SECMODE_PW_ENCRYPT ? true : false,
2969 bcc_ptr);
7c7b25bc
SF
2970 else
2971#endif /* CIFS_WEAK_PW_HASH */
00e485b0 2972 SMBNTencrypt(tcon->password, ses->server->cryptKey,
eeac8047
SF
2973 bcc_ptr);
2974
7c7b25bc 2975 bcc_ptr += CIFS_SESS_KEY_SIZE;
fb8c4b14 2976 if (ses->capabilities & CAP_UNICODE) {
7c7b25bc
SF
2977 /* must align unicode strings */
2978 *bcc_ptr = 0; /* null byte password */
2979 bcc_ptr++;
2980 }
eeac8047 2981 }
1da177e4 2982
50c2f753 2983 if (ses->server->secMode &
a878fb22 2984 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1da177e4
LT
2985 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2986
2987 if (ses->capabilities & CAP_STATUS32) {
2988 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2989 }
2990 if (ses->capabilities & CAP_DFS) {
2991 smb_buffer->Flags2 |= SMBFLG2_DFS;
2992 }
2993 if (ses->capabilities & CAP_UNICODE) {
2994 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2995 length =
50c2f753
SF
2996 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
2997 6 /* max utf8 char length in bytes */ *
a878fb22
SF
2998 (/* server len*/ + 256 /* share len */), nls_codepage);
2999 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
1da177e4
LT
3000 bcc_ptr += 2; /* skip trailing null */
3001 } else { /* ASCII */
1da177e4
LT
3002 strcpy(bcc_ptr, tree);
3003 bcc_ptr += strlen(tree) + 1;
3004 }
3005 strcpy(bcc_ptr, "?????");
3006 bcc_ptr += strlen("?????");
3007 bcc_ptr += 1;
3008 count = bcc_ptr - &pSMB->Password[0];
3009 pSMB->hdr.smb_buf_length += count;
3010 pSMB->ByteCount = cpu_to_le16(count);
3011
133672ef
SF
3012 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3013 CIFS_STD_OP);
1da177e4 3014
1da177e4
LT
3015 /* above now done in SendReceive */
3016 if ((rc == 0) && (tcon != NULL)) {
0e0d2cf3
SF
3017 bool is_unicode;
3018
1da177e4 3019 tcon->tidStatus = CifsGood;
3b795210 3020 tcon->need_reconnect = false;
1da177e4
LT
3021 tcon->tid = smb_buffer_response->Tid;
3022 bcc_ptr = pByteArea(smb_buffer_response);
cc20c031
JL
3023 bytes_left = BCC(smb_buffer_response);
3024 length = strnlen(bcc_ptr, bytes_left - 2);
0e0d2cf3
SF
3025 if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
3026 is_unicode = true;
3027 else
3028 is_unicode = false;
3029
cc20c031 3030
50c2f753 3031 /* skip service field (NB: this field is always ASCII) */
7f8ed420
SF
3032 if (length == 3) {
3033 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3034 (bcc_ptr[2] == 'C')) {
b6b38f70 3035 cFYI(1, "IPC connection");
7f8ed420
SF
3036 tcon->ipc = 1;
3037 }
3038 } else if (length == 2) {
3039 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3040 /* the most common case */
b6b38f70 3041 cFYI(1, "disk share connection");
7f8ed420
SF
3042 }
3043 }
50c2f753 3044 bcc_ptr += length + 1;
cc20c031 3045 bytes_left -= (length + 1);
1da177e4 3046 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
cc20c031
JL
3047
3048 /* mostly informational -- no need to fail on error here */
90a98b2f 3049 kfree(tcon->nativeFileSystem);
d185cda7 3050 tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr,
0e0d2cf3 3051 bytes_left, is_unicode,
cc20c031
JL
3052 nls_codepage);
3053
b6b38f70 3054 cFYI(1, "nativeFileSystem=%s", tcon->nativeFileSystem);
cc20c031 3055
fb8c4b14 3056 if ((smb_buffer_response->WordCount == 3) ||
1a4e15a0
SF
3057 (smb_buffer_response->WordCount == 7))
3058 /* field is in same location */
3979877e
SF
3059 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3060 else
3061 tcon->Flags = 0;
b6b38f70 3062 cFYI(1, "Tcon flags: 0x%x ", tcon->Flags);
1da177e4 3063 } else if ((rc == 0) && tcon == NULL) {
50c2f753 3064 /* all we need to save for IPC$ connection */
1da177e4
LT
3065 ses->ipc_tid = smb_buffer_response->Tid;
3066 }
3067
a8a11d39 3068 cifs_buf_release(smb_buffer);
1da177e4
LT
3069 return rc;
3070}
3071
3072int
3073cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3074{
9d002df4 3075 int i, ret;
50c2f753 3076 char *tmp;
9d002df4
JL
3077 struct tcon_link *tlink[8];
3078 unsigned long index = 0;
3079
3080 do {
3081 spin_lock(&cifs_sb->tlink_tree_lock);
3082 ret = radix_tree_gang_lookup(&cifs_sb->tlink_tree,
3083 (void **)tlink, index,
3084 ARRAY_SIZE(tlink));
3085 /* increment index for next pass */
3086 if (ret > 0)
3087 index = tlink[ret - 1]->tl_index + 1;
3088 for (i = 0; i < ret; i++) {
3089 cifs_get_tlink(tlink[i]);
3090 clear_bit(TCON_LINK_IN_TREE, &tlink[i]->tl_flags);
3091 radix_tree_delete(&cifs_sb->tlink_tree,
3092 tlink[i]->tl_index);
3093 }
3094 spin_unlock(&cifs_sb->tlink_tree_lock);
1da177e4 3095
9d002df4
JL
3096 for (i = 0; i < ret; i++)
3097 cifs_put_tlink(tlink[i]);
3098 } while (ret != 0);
50c2f753 3099
2fe87f02
SF
3100 tmp = cifs_sb->prepath;
3101 cifs_sb->prepathlen = 0;
3102 cifs_sb->prepath = NULL;
3103 kfree(tmp);
1da177e4 3104
9d002df4 3105 return 0;
50c2f753 3106}
1da177e4 3107
198b5682 3108int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
1da177e4
LT
3109{
3110 int rc = 0;
198b5682 3111 struct TCP_Server_Info *server = ses->server;
1da177e4 3112
198b5682
JL
3113 /* only send once per connect */
3114 if (server->maxBuf != 0)
3115 return 0;
3116
3117 rc = CIFSSMBNegotiate(xid, ses);
3118 if (rc == -EAGAIN) {
3119 /* retry only once on 1st time connection */
3120 rc = CIFSSMBNegotiate(xid, ses);
3121 if (rc == -EAGAIN)
3122 rc = -EHOSTDOWN;
1da177e4 3123 }
198b5682
JL
3124 if (rc == 0) {
3125 spin_lock(&GlobalMid_Lock);
3126 if (server->tcpStatus != CifsExiting)
3127 server->tcpStatus = CifsGood;
3128 else
3129 rc = -EHOSTDOWN;
3130 spin_unlock(&GlobalMid_Lock);
26b994fa 3131
198b5682
JL
3132 }
3133
3134 return rc;
3135}
3136
3137
3138int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3139 struct nls_table *nls_info)
3140{
3141 int rc = 0;
3142 struct TCP_Server_Info *server = ses->server;
26b994fa 3143
198b5682
JL
3144 ses->flags = 0;
3145 ses->capabilities = server->capabilities;
26b994fa 3146 if (linuxExtEnabled == 0)
198b5682 3147 ses->capabilities &= (~CAP_UNIX);
20418acd 3148
b6b38f70
JP
3149 cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3150 server->secMode, server->capabilities, server->timeAdj);
cb7691b6 3151
198b5682 3152 rc = CIFS_SessSetup(xid, ses, nls_info);
26b994fa 3153 if (rc) {
b6b38f70 3154 cERROR(1, "Send error in SessSetup = %d", rc);
26b994fa 3155 } else {
b6b38f70 3156 cFYI(1, "CIFS Session Established successfully");
20418acd 3157 spin_lock(&GlobalMid_Lock);
198b5682
JL
3158 ses->status = CifsGood;
3159 ses->need_reconnect = false;
20418acd 3160 spin_unlock(&GlobalMid_Lock);
1da177e4 3161 }
26b994fa 3162
1da177e4
LT
3163 return rc;
3164}
3165
9d002df4
JL
3166struct cifsTconInfo *
3167cifs_construct_tcon(struct cifs_sb_info *cifs_sb, uid_t fsuid)
3168{
3169 struct cifsTconInfo *master_tcon = cifs_sb_master_tcon(cifs_sb);
3170 struct cifsSesInfo *ses;
3171 struct cifsTconInfo *tcon = NULL;
3172 struct smb_vol *vol_info;
3173 char username[MAX_USERNAME_SIZE + 1];
3174
3175 vol_info = kzalloc(sizeof(*vol_info), GFP_KERNEL);
3176 if (vol_info == NULL) {
3177 tcon = ERR_PTR(-ENOMEM);
3178 goto out;
3179 }
3180
3181 snprintf(username, MAX_USERNAME_SIZE, "krb50x%x", fsuid);
3182 vol_info->username = username;
3183 vol_info->local_nls = cifs_sb->local_nls;
3184 vol_info->linux_uid = fsuid;
3185 vol_info->cred_uid = fsuid;
3186 vol_info->UNC = master_tcon->treeName;
3187 vol_info->retry = master_tcon->retry;
3188 vol_info->nocase = master_tcon->nocase;
3189 vol_info->local_lease = master_tcon->local_lease;
3190 vol_info->no_linux_ext = !master_tcon->unix_ext;
3191
3192 /* FIXME: allow for other secFlg settings */
3193 vol_info->secFlg = CIFSSEC_MUST_KRB5;
3194
3195 /* get a reference for the same TCP session */
3196 write_lock(&cifs_tcp_ses_lock);
3197 ++master_tcon->ses->server->srv_count;
3198 write_unlock(&cifs_tcp_ses_lock);
3199
3200 ses = cifs_get_smb_ses(master_tcon->ses->server, vol_info);
3201 if (IS_ERR(ses)) {
3202 tcon = (struct cifsTconInfo *)ses;
3203 cifs_put_tcp_session(master_tcon->ses->server);
3204 goto out;
3205 }
3206
3207 tcon = cifs_get_tcon(ses, vol_info);
3208 if (IS_ERR(tcon)) {
3209 cifs_put_smb_ses(ses);
3210 goto out;
3211 }
3212
3213 if (ses->capabilities & CAP_UNIX)
3214 reset_cifs_unix_caps(0, tcon, NULL, vol_info);
3215out:
3216 kfree(vol_info);
3217
3218 return tcon;
3219}
3220
3221static struct tcon_link *
3222cifs_sb_master_tlink(struct cifs_sb_info *cifs_sb)
3223{
3224 struct tcon_link *tlink;
3225 unsigned int ret;
3226
3227 spin_lock(&cifs_sb->tlink_tree_lock);
3228 ret = radix_tree_gang_lookup_tag(&cifs_sb->tlink_tree, (void **)&tlink,
3229 0, 1, CIFS_TLINK_MASTER_TAG);
3230 spin_unlock(&cifs_sb->tlink_tree_lock);
3231
3232 /* the master tcon should always be present */
3233 if (ret == 0)
3234 BUG();
3235
3236 return tlink;
3237}
3238
3239struct cifsTconInfo *
3240cifs_sb_master_tcon(struct cifs_sb_info *cifs_sb)
3241{
3242 return tlink_tcon(cifs_sb_master_tlink(cifs_sb));
3243}
3244
3245static int
3246cifs_sb_tcon_pending_wait(void *unused)
3247{
3248 schedule();
3249 return signal_pending(current) ? -ERESTARTSYS : 0;
3250}
3251
3252/*
3253 * Find or construct an appropriate tcon given a cifs_sb and the fsuid of the
3254 * current task.
3255 *
3256 * If the superblock doesn't refer to a multiuser mount, then just return
3257 * the master tcon for the mount.
3258 *
3259 * First, search the radix tree for an existing tcon for this fsuid. If one
3260 * exists, then check to see if it's pending construction. If it is then wait
3261 * for construction to complete. Once it's no longer pending, check to see if
3262 * it failed and either return an error or retry construction, depending on
3263 * the timeout.
3264 *
3265 * If one doesn't exist then insert a new tcon_link struct into the tree and
3266 * try to construct a new one.
3267 */
3268struct tcon_link *
3269cifs_sb_tlink(struct cifs_sb_info *cifs_sb)
3270{
3271 int ret;
3272 unsigned long fsuid = (unsigned long) current_fsuid();
3273 struct tcon_link *tlink, *newtlink;
3274
3275 if (!(cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MULTIUSER))
3276 return cifs_get_tlink(cifs_sb_master_tlink(cifs_sb));
3277
3278 spin_lock(&cifs_sb->tlink_tree_lock);
3279 tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid);
3280 if (tlink)
3281 cifs_get_tlink(tlink);
3282 spin_unlock(&cifs_sb->tlink_tree_lock);
3283
3284 if (tlink == NULL) {
3285 newtlink = kzalloc(sizeof(*tlink), GFP_KERNEL);
3286 if (newtlink == NULL)
3287 return ERR_PTR(-ENOMEM);
3288 newtlink->tl_index = fsuid;
3289 newtlink->tl_tcon = ERR_PTR(-EACCES);
3290 set_bit(TCON_LINK_PENDING, &newtlink->tl_flags);
3291 set_bit(TCON_LINK_IN_TREE, &newtlink->tl_flags);
3292 cifs_get_tlink(newtlink);
3293
3294 ret = radix_tree_preload(GFP_KERNEL);
3295 if (ret != 0) {
3296 kfree(newtlink);
3297 return ERR_PTR(ret);
3298 }
3299
3300 spin_lock(&cifs_sb->tlink_tree_lock);
3301 /* was one inserted after previous search? */
3302 tlink = radix_tree_lookup(&cifs_sb->tlink_tree, fsuid);
3303 if (tlink) {
3304 cifs_get_tlink(tlink);
3305 spin_unlock(&cifs_sb->tlink_tree_lock);
3306 radix_tree_preload_end();
3307 kfree(newtlink);
3308 goto wait_for_construction;
3309 }
3310 ret = radix_tree_insert(&cifs_sb->tlink_tree, fsuid, newtlink);
3311 spin_unlock(&cifs_sb->tlink_tree_lock);
3312 radix_tree_preload_end();
3313 if (ret) {
3314 kfree(newtlink);
3315 return ERR_PTR(ret);
3316 }
3317 tlink = newtlink;
3318 } else {
3319wait_for_construction:
3320 ret = wait_on_bit(&tlink->tl_flags, TCON_LINK_PENDING,
3321 cifs_sb_tcon_pending_wait,
3322 TASK_INTERRUPTIBLE);
3323 if (ret) {
3324 cifs_put_tlink(tlink);
3325 return ERR_PTR(ret);
3326 }
3327
3328 /* if it's good, return it */
3329 if (!IS_ERR(tlink->tl_tcon))
3330 return tlink;
3331
3332 /* return error if we tried this already recently */
3333 if (time_before(jiffies, tlink->tl_time + TLINK_ERROR_EXPIRE)) {
3334 cifs_put_tlink(tlink);
3335 return ERR_PTR(-EACCES);
3336 }
3337
3338 if (test_and_set_bit(TCON_LINK_PENDING, &tlink->tl_flags))
3339 goto wait_for_construction;
3340 }
3341
3342 tlink->tl_tcon = cifs_construct_tcon(cifs_sb, fsuid);
3343 clear_bit(TCON_LINK_PENDING, &tlink->tl_flags);
3344 wake_up_bit(&tlink->tl_flags, TCON_LINK_PENDING);
3345
3346 if (IS_ERR(tlink->tl_tcon)) {
3347 cifs_put_tlink(tlink);
3348 return ERR_PTR(-EACCES);
3349 }
3350
3351 return tlink;
3352}
This page took 0.607174 seconds and 5 git commands to generate.