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