Enable dfs submounts to handle remote referrals.
[linux-2.6-block.git] / fs / cifs / connect.c
CommitLineData
1da177e4
LT
1/*
2 * fs/cifs/connect.c
3 *
366781c1 4 * Copyright (C) International Business Machines Corp., 2002,2008
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>
1da177e4
LT
35#include <asm/uaccess.h>
36#include <asm/processor.h>
0e2bedaa 37#include <net/ipv6.h>
1da177e4
LT
38#include "cifspdu.h"
39#include "cifsglob.h"
40#include "cifsproto.h"
41#include "cifs_unicode.h"
42#include "cifs_debug.h"
43#include "cifs_fs_sb.h"
44#include "ntlmssp.h"
45#include "nterr.h"
46#include "rfc1002pdu.h"
a2653eba 47#include "cn_cifs.h"
1da177e4
LT
48
49#define CIFS_PORT 445
50#define RFC1001_PORT 139
51
1da177e4
LT
52extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
53 unsigned char *p24);
54
55extern mempool_t *cifs_req_poolp;
56
57struct smb_vol {
58 char *username;
59 char *password;
60 char *domainname;
61 char *UNC;
62 char *UNCip;
95b1cb90 63 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
1da177e4
LT
64 char *iocharset; /* local code page for mapping to and from Unicode */
65 char source_rfc1001_name[16]; /* netbios name of client */
a10faeb2 66 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
1da177e4
LT
67 uid_t linux_uid;
68 gid_t linux_gid;
69 mode_t file_mode;
70 mode_t dir_mode;
189acaae 71 unsigned secFlg;
4b18f2a9
SF
72 bool rw:1;
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();
1da177e4
LT
829 vol->dir_mode = S_IRWXUGO;
830 /* 2767 perms indicate mandatory locking support */
7505e052 831 vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
1da177e4
LT
832
833 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
4b18f2a9 834 vol->rw = true;
ac67055e
JA
835 /* default is always to request posix paths. */
836 vol->posix_paths = 1;
837
1da177e4
LT
838 if (!options)
839 return 1;
840
50c2f753 841 if (strncmp(options, "sep=", 4) == 0) {
fb8c4b14 842 if (options[4] != 0) {
1da177e4
LT
843 separator[0] = options[4];
844 options += 5;
845 } else {
467a8f8d 846 cFYI(1, ("Null separator not allowed"));
1da177e4
LT
847 }
848 }
50c2f753 849
1da177e4
LT
850 while ((data = strsep(&options, separator)) != NULL) {
851 if (!*data)
852 continue;
853 if ((value = strchr(data, '=')) != NULL)
854 *value++ = '\0';
855
50c2f753
SF
856 /* Have to parse this before we parse for "user" */
857 if (strnicmp(data, "user_xattr", 10) == 0) {
1da177e4 858 vol->no_xattr = 0;
50c2f753 859 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
1da177e4
LT
860 vol->no_xattr = 1;
861 } else if (strnicmp(data, "user", 4) == 0) {
4b952a9b 862 if (!value) {
1da177e4
LT
863 printk(KERN_WARNING
864 "CIFS: invalid or missing username\n");
865 return 1; /* needs_arg; */
fb8c4b14 866 } else if (!*value) {
4b952a9b
SF
867 /* null user, ie anonymous, authentication */
868 vol->nullauth = 1;
1da177e4
LT
869 }
870 if (strnlen(value, 200) < 200) {
871 vol->username = value;
872 } else {
873 printk(KERN_WARNING "CIFS: username too long\n");
874 return 1;
875 }
876 } else if (strnicmp(data, "pass", 4) == 0) {
877 if (!value) {
878 vol->password = NULL;
879 continue;
fb8c4b14 880 } else if (value[0] == 0) {
1da177e4
LT
881 /* check if string begins with double comma
882 since that would mean the password really
883 does start with a comma, and would not
884 indicate an empty string */
fb8c4b14 885 if (value[1] != separator[0]) {
1da177e4
LT
886 vol->password = NULL;
887 continue;
888 }
889 }
890 temp_len = strlen(value);
891 /* removed password length check, NTLM passwords
892 can be arbitrarily long */
893
50c2f753 894 /* if comma in password, the string will be
1da177e4
LT
895 prematurely null terminated. Commas in password are
896 specified across the cifs mount interface by a double
897 comma ie ,, and a comma used as in other cases ie ','
898 as a parameter delimiter/separator is single and due
899 to the strsep above is temporarily zeroed. */
900
901 /* NB: password legally can have multiple commas and
902 the only illegal character in a password is null */
903
50c2f753 904 if ((value[temp_len] == 0) &&
09d1db5c 905 (value[temp_len+1] == separator[0])) {
1da177e4
LT
906 /* reinsert comma */
907 value[temp_len] = separator[0];
50c2f753
SF
908 temp_len += 2; /* move after second comma */
909 while (value[temp_len] != 0) {
1da177e4 910 if (value[temp_len] == separator[0]) {
50c2f753 911 if (value[temp_len+1] ==
09d1db5c
SF
912 separator[0]) {
913 /* skip second comma */
914 temp_len++;
50c2f753 915 } else {
1da177e4
LT
916 /* single comma indicating start
917 of next parm */
918 break;
919 }
920 }
921 temp_len++;
922 }
fb8c4b14 923 if (value[temp_len] == 0) {
1da177e4
LT
924 options = NULL;
925 } else {
926 value[temp_len] = 0;
927 /* point option to start of next parm */
928 options = value + temp_len + 1;
929 }
50c2f753 930 /* go from value to value + temp_len condensing
1da177e4
LT
931 double commas to singles. Note that this ends up
932 allocating a few bytes too many, which is ok */
e915fc49 933 vol->password = kzalloc(temp_len, GFP_KERNEL);
fb8c4b14 934 if (vol->password == NULL) {
50c2f753
SF
935 printk(KERN_WARNING "CIFS: no memory "
936 "for password\n");
433dc24f
SF
937 return 1;
938 }
50c2f753 939 for (i = 0, j = 0; i < temp_len; i++, j++) {
1da177e4 940 vol->password[j] = value[i];
fb8c4b14 941 if (value[i] == separator[0]
09d1db5c 942 && value[i+1] == separator[0]) {
1da177e4
LT
943 /* skip second comma */
944 i++;
945 }
946 }
947 vol->password[j] = 0;
948 } else {
e915fc49 949 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
fb8c4b14 950 if (vol->password == NULL) {
50c2f753
SF
951 printk(KERN_WARNING "CIFS: no memory "
952 "for password\n");
433dc24f
SF
953 return 1;
954 }
1da177e4
LT
955 strcpy(vol->password, value);
956 }
957 } else if (strnicmp(data, "ip", 2) == 0) {
958 if (!value || !*value) {
959 vol->UNCip = NULL;
960 } else if (strnlen(value, 35) < 35) {
961 vol->UNCip = value;
962 } else {
50c2f753
SF
963 printk(KERN_WARNING "CIFS: ip address "
964 "too long\n");
1da177e4
LT
965 return 1;
966 }
50c2f753
SF
967 } else if (strnicmp(data, "sec", 3) == 0) {
968 if (!value || !*value) {
969 cERROR(1, ("no security value specified"));
970 continue;
971 } else if (strnicmp(value, "krb5i", 5) == 0) {
972 vol->secFlg |= CIFSSEC_MAY_KRB5 |
189acaae 973 CIFSSEC_MUST_SIGN;
bf820679 974 } else if (strnicmp(value, "krb5p", 5) == 0) {
50c2f753
SF
975 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
976 CIFSSEC_MAY_KRB5; */
977 cERROR(1, ("Krb5 cifs privacy not supported"));
bf820679
SF
978 return 1;
979 } else if (strnicmp(value, "krb5", 4) == 0) {
750d1151 980 vol->secFlg |= CIFSSEC_MAY_KRB5;
bf820679 981 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
750d1151 982 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
189acaae 983 CIFSSEC_MUST_SIGN;
bf820679 984 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
750d1151 985 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
bf820679 986 } else if (strnicmp(value, "ntlmi", 5) == 0) {
750d1151 987 vol->secFlg |= CIFSSEC_MAY_NTLM |
189acaae 988 CIFSSEC_MUST_SIGN;
bf820679
SF
989 } else if (strnicmp(value, "ntlm", 4) == 0) {
990 /* ntlm is default so can be turned off too */
750d1151 991 vol->secFlg |= CIFSSEC_MAY_NTLM;
bf820679 992 } else if (strnicmp(value, "nontlm", 6) == 0) {
189acaae 993 /* BB is there a better way to do this? */
750d1151 994 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
189acaae
SF
995#ifdef CONFIG_CIFS_WEAK_PW_HASH
996 } else if (strnicmp(value, "lanman", 6) == 0) {
50c2f753 997 vol->secFlg |= CIFSSEC_MAY_LANMAN;
189acaae 998#endif
bf820679 999 } else if (strnicmp(value, "none", 4) == 0) {
189acaae 1000 vol->nullauth = 1;
50c2f753
SF
1001 } else {
1002 cERROR(1, ("bad security option: %s", value));
1003 return 1;
1004 }
1da177e4
LT
1005 } else if ((strnicmp(data, "unc", 3) == 0)
1006 || (strnicmp(data, "target", 6) == 0)
1007 || (strnicmp(data, "path", 4) == 0)) {
1008 if (!value || !*value) {
50c2f753
SF
1009 printk(KERN_WARNING "CIFS: invalid path to "
1010 "network resource\n");
1da177e4
LT
1011 return 1; /* needs_arg; */
1012 }
1013 if ((temp_len = strnlen(value, 300)) < 300) {
50c2f753 1014 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
4523cc30 1015 if (vol->UNC == NULL)
1da177e4 1016 return 1;
50c2f753 1017 strcpy(vol->UNC, value);
1da177e4
LT
1018 if (strncmp(vol->UNC, "//", 2) == 0) {
1019 vol->UNC[0] = '\\';
1020 vol->UNC[1] = '\\';
50c2f753 1021 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1da177e4 1022 printk(KERN_WARNING
50c2f753
SF
1023 "CIFS: UNC Path does not begin "
1024 "with // or \\\\ \n");
1da177e4
LT
1025 return 1;
1026 }
1027 } else {
1028 printk(KERN_WARNING "CIFS: UNC name too long\n");
1029 return 1;
1030 }
1031 } else if ((strnicmp(data, "domain", 3) == 0)
1032 || (strnicmp(data, "workgroup", 5) == 0)) {
1033 if (!value || !*value) {
1034 printk(KERN_WARNING "CIFS: invalid domain name\n");
1035 return 1; /* needs_arg; */
1036 }
1037 /* BB are there cases in which a comma can be valid in
1038 a domain name and need special handling? */
3979877e 1039 if (strnlen(value, 256) < 256) {
1da177e4
LT
1040 vol->domainname = value;
1041 cFYI(1, ("Domain name set"));
1042 } else {
50c2f753
SF
1043 printk(KERN_WARNING "CIFS: domain name too "
1044 "long\n");
1da177e4
LT
1045 return 1;
1046 }
50c2f753
SF
1047 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1048 if (!value || !*value) {
1049 printk(KERN_WARNING
1050 "CIFS: invalid path prefix\n");
1051 return 1; /* needs_argument */
1052 }
1053 if ((temp_len = strnlen(value, 1024)) < 1024) {
4523cc30 1054 if (value[0] != '/')
2fe87f02 1055 temp_len++; /* missing leading slash */
50c2f753
SF
1056 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1057 if (vol->prepath == NULL)
1058 return 1;
4523cc30 1059 if (value[0] != '/') {
2fe87f02 1060 vol->prepath[0] = '/';
50c2f753 1061 strcpy(vol->prepath+1, value);
2fe87f02 1062 } else
50c2f753
SF
1063 strcpy(vol->prepath, value);
1064 cFYI(1, ("prefix path %s", vol->prepath));
1065 } else {
1066 printk(KERN_WARNING "CIFS: prefix too long\n");
1067 return 1;
1068 }
1da177e4
LT
1069 } else if (strnicmp(data, "iocharset", 9) == 0) {
1070 if (!value || !*value) {
63135e08
SF
1071 printk(KERN_WARNING "CIFS: invalid iocharset "
1072 "specified\n");
1da177e4
LT
1073 return 1; /* needs_arg; */
1074 }
1075 if (strnlen(value, 65) < 65) {
50c2f753 1076 if (strnicmp(value, "default", 7))
1da177e4 1077 vol->iocharset = value;
50c2f753
SF
1078 /* if iocharset not set then load_nls_default
1079 is used by caller */
1080 cFYI(1, ("iocharset set to %s", value));
1da177e4 1081 } else {
63135e08
SF
1082 printk(KERN_WARNING "CIFS: iocharset name "
1083 "too long.\n");
1da177e4
LT
1084 return 1;
1085 }
1086 } else if (strnicmp(data, "uid", 3) == 0) {
1087 if (value && *value) {
1088 vol->linux_uid =
1089 simple_strtoul(value, &value, 0);
4523cc30 1090 vol->override_uid = 1;
1da177e4
LT
1091 }
1092 } else if (strnicmp(data, "gid", 3) == 0) {
1093 if (value && *value) {
1094 vol->linux_gid =
1095 simple_strtoul(value, &value, 0);
4523cc30 1096 vol->override_gid = 1;
1da177e4
LT
1097 }
1098 } else if (strnicmp(data, "file_mode", 4) == 0) {
1099 if (value && *value) {
1100 vol->file_mode =
1101 simple_strtoul(value, &value, 0);
1102 }
1103 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1104 if (value && *value) {
1105 vol->dir_mode =
1106 simple_strtoul(value, &value, 0);
1107 }
1108 } else if (strnicmp(data, "dirmode", 4) == 0) {
1109 if (value && *value) {
1110 vol->dir_mode =
1111 simple_strtoul(value, &value, 0);
1112 }
1113 } else if (strnicmp(data, "port", 4) == 0) {
1114 if (value && *value) {
1115 vol->port =
1116 simple_strtoul(value, &value, 0);
1117 }
1118 } else if (strnicmp(data, "rsize", 5) == 0) {
1119 if (value && *value) {
1120 vol->rsize =
1121 simple_strtoul(value, &value, 0);
1122 }
1123 } else if (strnicmp(data, "wsize", 5) == 0) {
1124 if (value && *value) {
1125 vol->wsize =
1126 simple_strtoul(value, &value, 0);
1127 }
1128 } else if (strnicmp(data, "sockopt", 5) == 0) {
1129 if (value && *value) {
1130 vol->sockopt =
1131 simple_strtoul(value, &value, 0);
1132 }
1133 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1134 if (!value || !*value || (*value == ' ')) {
63135e08 1135 cFYI(1, ("invalid (empty) netbiosname"));
1da177e4 1136 } else {
50c2f753
SF
1137 memset(vol->source_rfc1001_name, 0x20, 15);
1138 for (i = 0; i < 15; i++) {
1139 /* BB are there cases in which a comma can be
1da177e4
LT
1140 valid in this workstation netbios name (and need
1141 special handling)? */
1142
1143 /* We do not uppercase netbiosname for user */
50c2f753 1144 if (value[i] == 0)
1da177e4 1145 break;
50c2f753
SF
1146 else
1147 vol->source_rfc1001_name[i] =
1148 value[i];
1da177e4
LT
1149 }
1150 /* The string has 16th byte zero still from
1151 set at top of the function */
50c2f753
SF
1152 if ((i == 15) && (value[i] != 0))
1153 printk(KERN_WARNING "CIFS: netbiosname"
1154 " longer than 15 truncated.\n");
a10faeb2
SF
1155 }
1156 } else if (strnicmp(data, "servern", 7) == 0) {
1157 /* servernetbiosname specified override *SMBSERVER */
1158 if (!value || !*value || (*value == ' ')) {
467a8f8d 1159 cFYI(1, ("empty server netbiosname specified"));
a10faeb2
SF
1160 } else {
1161 /* last byte, type, is 0x20 for servr type */
50c2f753 1162 memset(vol->target_rfc1001_name, 0x20, 16);
a10faeb2 1163
50c2f753 1164 for (i = 0; i < 15; i++) {
a10faeb2 1165 /* BB are there cases in which a comma can be
50c2f753
SF
1166 valid in this workstation netbios name
1167 (and need special handling)? */
a10faeb2 1168
50c2f753
SF
1169 /* user or mount helper must uppercase
1170 the netbiosname */
1171 if (value[i] == 0)
a10faeb2
SF
1172 break;
1173 else
50c2f753
SF
1174 vol->target_rfc1001_name[i] =
1175 value[i];
a10faeb2
SF
1176 }
1177 /* The string has 16th byte zero still from
1178 set at top of the function */
50c2f753
SF
1179 if ((i == 15) && (value[i] != 0))
1180 printk(KERN_WARNING "CIFS: server net"
1181 "biosname longer than 15 truncated.\n");
1da177e4
LT
1182 }
1183 } else if (strnicmp(data, "credentials", 4) == 0) {
1184 /* ignore */
1185 } else if (strnicmp(data, "version", 3) == 0) {
1186 /* ignore */
50c2f753 1187 } else if (strnicmp(data, "guest", 5) == 0) {
1da177e4
LT
1188 /* ignore */
1189 } else if (strnicmp(data, "rw", 2) == 0) {
4b18f2a9 1190 vol->rw = true;
edf1ae40
SF
1191 } else if (strnicmp(data, "noblocksend", 11) == 0) {
1192 vol->noblocksnd = 1;
1193 } else if (strnicmp(data, "noautotune", 10) == 0) {
1194 vol->noautotune = 1;
1da177e4
LT
1195 } else if ((strnicmp(data, "suid", 4) == 0) ||
1196 (strnicmp(data, "nosuid", 6) == 0) ||
1197 (strnicmp(data, "exec", 4) == 0) ||
1198 (strnicmp(data, "noexec", 6) == 0) ||
1199 (strnicmp(data, "nodev", 5) == 0) ||
1200 (strnicmp(data, "noauto", 6) == 0) ||
1201 (strnicmp(data, "dev", 3) == 0)) {
1202 /* The mount tool or mount.cifs helper (if present)
50c2f753
SF
1203 uses these opts to set flags, and the flags are read
1204 by the kernel vfs layer before we get here (ie
1205 before read super) so there is no point trying to
1206 parse these options again and set anything and it
1207 is ok to just ignore them */
1da177e4
LT
1208 continue;
1209 } else if (strnicmp(data, "ro", 2) == 0) {
4b18f2a9 1210 vol->rw = false;
1da177e4
LT
1211 } else if (strnicmp(data, "hard", 4) == 0) {
1212 vol->retry = 1;
1213 } else if (strnicmp(data, "soft", 4) == 0) {
1214 vol->retry = 0;
1215 } else if (strnicmp(data, "perm", 4) == 0) {
1216 vol->noperm = 0;
1217 } else if (strnicmp(data, "noperm", 6) == 0) {
1218 vol->noperm = 1;
6a0b4824
SF
1219 } else if (strnicmp(data, "mapchars", 8) == 0) {
1220 vol->remap = 1;
1221 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1222 vol->remap = 0;
50c2f753
SF
1223 } else if (strnicmp(data, "sfu", 3) == 0) {
1224 vol->sfu_emul = 1;
1225 } else if (strnicmp(data, "nosfu", 5) == 0) {
1226 vol->sfu_emul = 0;
2c1b8615
SF
1227 } else if (strnicmp(data, "nodfs", 5) == 0) {
1228 vol->nodfs = 1;
ac67055e
JA
1229 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1230 vol->posix_paths = 1;
1231 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1232 vol->posix_paths = 0;
c18c842b
SF
1233 } else if (strnicmp(data, "nounix", 6) == 0) {
1234 vol->no_linux_ext = 1;
1235 } else if (strnicmp(data, "nolinux", 7) == 0) {
1236 vol->no_linux_ext = 1;
50c2f753 1237 } else if ((strnicmp(data, "nocase", 6) == 0) ||
a10faeb2 1238 (strnicmp(data, "ignorecase", 10) == 0)) {
50c2f753 1239 vol->nocase = 1;
c46fa8ac
SF
1240 } else if (strnicmp(data, "brl", 3) == 0) {
1241 vol->nobrl = 0;
50c2f753 1242 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1c955187 1243 (strnicmp(data, "nolock", 6) == 0)) {
c46fa8ac 1244 vol->nobrl = 1;
d3485d37
SF
1245 /* turn off mandatory locking in mode
1246 if remote locking is turned off since the
1247 local vfs will do advisory */
50c2f753
SF
1248 if (vol->file_mode ==
1249 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
d3485d37 1250 vol->file_mode = S_IALLUGO;
13a6e42a
SF
1251 } else if (strnicmp(data, "forcemandatorylock", 9) == 0) {
1252 /* will take the shorter form "forcemand" as well */
1253 /* This mount option will force use of mandatory
1254 (DOS/Windows style) byte range locks, instead of
1255 using posix advisory byte range locks, even if the
1256 Unix extensions are available and posix locks would
1257 be supported otherwise. If Unix extensions are not
1258 negotiated this has no effect since mandatory locks
1259 would be used (mandatory locks is all that those
1260 those servers support) */
1261 vol->mand_lock = 1;
1da177e4
LT
1262 } else if (strnicmp(data, "setuids", 7) == 0) {
1263 vol->setuids = 1;
1264 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1265 vol->setuids = 0;
d0a9c078
JL
1266 } else if (strnicmp(data, "dynperm", 7) == 0) {
1267 vol->dynperm = true;
1268 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1269 vol->dynperm = false;
1da177e4
LT
1270 } else if (strnicmp(data, "nohard", 6) == 0) {
1271 vol->retry = 0;
1272 } else if (strnicmp(data, "nosoft", 6) == 0) {
1273 vol->retry = 1;
1274 } else if (strnicmp(data, "nointr", 6) == 0) {
1275 vol->intr = 0;
1276 } else if (strnicmp(data, "intr", 4) == 0) {
1277 vol->intr = 1;
be652445
SF
1278 } else if (strnicmp(data, "nostrictsync", 12) == 0) {
1279 vol->nostrictsync = 1;
1280 } else if (strnicmp(data, "strictsync", 10) == 0) {
1281 vol->nostrictsync = 0;
50c2f753 1282 } else if (strnicmp(data, "serverino", 7) == 0) {
1da177e4 1283 vol->server_ino = 1;
50c2f753 1284 } else if (strnicmp(data, "noserverino", 9) == 0) {
1da177e4 1285 vol->server_ino = 0;
50c2f753 1286 } else if (strnicmp(data, "cifsacl", 7) == 0) {
0a4b92c0
SF
1287 vol->cifs_acl = 1;
1288 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1289 vol->cifs_acl = 0;
50c2f753 1290 } else if (strnicmp(data, "acl", 3) == 0) {
1da177e4 1291 vol->no_psx_acl = 0;
50c2f753 1292 } else if (strnicmp(data, "noacl", 5) == 0) {
1da177e4 1293 vol->no_psx_acl = 1;
84210e91
SF
1294#ifdef CONFIG_CIFS_EXPERIMENTAL
1295 } else if (strnicmp(data, "locallease", 6) == 0) {
1296 vol->local_lease = 1;
1297#endif
50c2f753 1298 } else if (strnicmp(data, "sign", 4) == 0) {
750d1151 1299 vol->secFlg |= CIFSSEC_MUST_SIGN;
95b1cb90
SF
1300 } else if (strnicmp(data, "seal", 4) == 0) {
1301 /* we do not do the following in secFlags because seal
1302 is a per tree connection (mount) not a per socket
1303 or per-smb connection option in the protocol */
1304 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1305 vol->seal = 1;
50c2f753 1306 } else if (strnicmp(data, "direct", 6) == 0) {
1da177e4 1307 vol->direct_io = 1;
50c2f753 1308 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1da177e4 1309 vol->direct_io = 1;
50c2f753 1310 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1da177e4
LT
1311 if (!value || !*value) {
1312 vol->in6_addr = NULL;
1313 } else if (strnlen(value, 49) == 48) {
1314 vol->in6_addr = value;
1315 } else {
50c2f753
SF
1316 printk(KERN_WARNING "CIFS: ip v6 address not "
1317 "48 characters long\n");
1da177e4
LT
1318 return 1;
1319 }
1320 } else if (strnicmp(data, "noac", 4) == 0) {
50c2f753
SF
1321 printk(KERN_WARNING "CIFS: Mount option noac not "
1322 "supported. Instead set "
1323 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1da177e4 1324 } else
50c2f753
SF
1325 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1326 data);
1da177e4
LT
1327 }
1328 if (vol->UNC == NULL) {
4523cc30 1329 if (devname == NULL) {
50c2f753
SF
1330 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1331 "target\n");
1da177e4
LT
1332 return 1;
1333 }
1334 if ((temp_len = strnlen(devname, 300)) < 300) {
50c2f753 1335 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
4523cc30 1336 if (vol->UNC == NULL)
1da177e4 1337 return 1;
50c2f753 1338 strcpy(vol->UNC, devname);
1da177e4
LT
1339 if (strncmp(vol->UNC, "//", 2) == 0) {
1340 vol->UNC[0] = '\\';
1341 vol->UNC[1] = '\\';
1342 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
50c2f753
SF
1343 printk(KERN_WARNING "CIFS: UNC Path does not "
1344 "begin with // or \\\\ \n");
1da177e4
LT
1345 return 1;
1346 }
7c5e628f
IM
1347 value = strpbrk(vol->UNC+2, "/\\");
1348 if (value)
1349 *value = '\\';
1da177e4
LT
1350 } else {
1351 printk(KERN_WARNING "CIFS: UNC name too long\n");
1352 return 1;
1353 }
1354 }
fb8c4b14 1355 if (vol->UNCip == NULL)
1da177e4
LT
1356 vol->UNCip = &vol->UNC[2];
1357
1358 return 0;
1359}
1360
e7ddee90 1361static struct TCP_Server_Info *
a9ac49d3 1362cifs_find_tcp_session(struct sockaddr_storage *addr)
1da177e4
LT
1363{
1364 struct list_head *tmp;
e7ddee90
JL
1365 struct TCP_Server_Info *server;
1366 struct sockaddr_in *addr4 = (struct sockaddr_in *) addr;
1367 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr;
1368
1369 write_lock(&cifs_tcp_ses_lock);
1370 list_for_each(tmp, &cifs_tcp_ses_list) {
1371 server = list_entry(tmp, struct TCP_Server_Info,
1372 tcp_ses_list);
e7ddee90
JL
1373 /*
1374 * the demux thread can exit on its own while still in CifsNew
1375 * so don't accept any sockets in that state. Since the
1376 * tcpStatus never changes back to CifsNew it's safe to check
1377 * for this without a lock.
1378 */
1379 if (server->tcpStatus == CifsNew)
1b20d672 1380 continue;
1da177e4 1381
a9ac49d3 1382 if (addr->ss_family == AF_INET &&
e7ddee90
JL
1383 (addr4->sin_addr.s_addr !=
1384 server->addr.sockAddr.sin_addr.s_addr))
1385 continue;
a9ac49d3 1386 else if (addr->ss_family == AF_INET6 &&
0e2bedaa
SF
1387 !ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr,
1388 &addr6->sin6_addr))
1b20d672
CG
1389 continue;
1390
e7ddee90
JL
1391 ++server->srv_count;
1392 write_unlock(&cifs_tcp_ses_lock);
d82c2df5 1393 cFYI(1, ("Existing tcp session with server found"));
e7ddee90 1394 return server;
1da177e4 1395 }
e7ddee90 1396 write_unlock(&cifs_tcp_ses_lock);
1da177e4
LT
1397 return NULL;
1398}
1b20d672 1399
14fbf50d 1400static void
e7ddee90 1401cifs_put_tcp_session(struct TCP_Server_Info *server)
1da177e4 1402{
e7ddee90 1403 struct task_struct *task;
1b20d672 1404
e7ddee90
JL
1405 write_lock(&cifs_tcp_ses_lock);
1406 if (--server->srv_count > 0) {
1407 write_unlock(&cifs_tcp_ses_lock);
1408 return;
1da177e4 1409 }
1b20d672 1410
e7ddee90
JL
1411 list_del_init(&server->tcp_ses_list);
1412 write_unlock(&cifs_tcp_ses_lock);
dea570e0 1413
e7ddee90
JL
1414 spin_lock(&GlobalMid_Lock);
1415 server->tcpStatus = CifsExiting;
1416 spin_unlock(&GlobalMid_Lock);
dea570e0 1417
e7ddee90
JL
1418 task = xchg(&server->tsk, NULL);
1419 if (task)
1420 force_sig(SIGKILL, task);
1da177e4
LT
1421}
1422
63c038c2
JL
1423static struct TCP_Server_Info *
1424cifs_get_tcp_session(struct smb_vol *volume_info)
1425{
1426 struct TCP_Server_Info *tcp_ses = NULL;
a9ac49d3 1427 struct sockaddr_storage addr;
63c038c2
JL
1428 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
1429 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
1430 int rc;
1431
a9ac49d3 1432 memset(&addr, 0, sizeof(struct sockaddr_storage));
63c038c2
JL
1433
1434 if (volume_info->UNCip && volume_info->UNC) {
1435 rc = cifs_inet_pton(AF_INET, volume_info->UNCip,
1436 &sin_server->sin_addr.s_addr);
1437
1438 if (rc <= 0) {
1439 /* not ipv4 address, try ipv6 */
1440 rc = cifs_inet_pton(AF_INET6, volume_info->UNCip,
1441 &sin_server6->sin6_addr.in6_u);
1442 if (rc > 0)
a9ac49d3 1443 addr.ss_family = AF_INET6;
63c038c2 1444 } else {
a9ac49d3 1445 addr.ss_family = AF_INET;
63c038c2
JL
1446 }
1447
1448 if (rc <= 0) {
1449 /* we failed translating address */
1450 rc = -EINVAL;
1451 goto out_err;
1452 }
1453
1454 cFYI(1, ("UNC: %s ip: %s", volume_info->UNC,
1455 volume_info->UNCip));
1456 } else if (volume_info->UNCip) {
1457 /* BB using ip addr as tcp_ses name to connect to the
1458 DFS root below */
1459 cERROR(1, ("Connecting to DFS root not implemented yet"));
1460 rc = -EINVAL;
1461 goto out_err;
1462 } else /* which tcp_sess DFS root would we conect to */ {
1463 cERROR(1,
1464 ("CIFS mount error: No UNC path (e.g. -o "
1465 "unc=//192.168.1.100/public) specified"));
1466 rc = -EINVAL;
1467 goto out_err;
1468 }
1469
1470 /* see if we already have a matching tcp_ses */
1471 tcp_ses = cifs_find_tcp_session(&addr);
1472 if (tcp_ses)
1473 return tcp_ses;
1474
1475 tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1476 if (!tcp_ses) {
1477 rc = -ENOMEM;
1478 goto out_err;
1479 }
1480
1481 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1482 if (IS_ERR(tcp_ses->hostname)) {
1483 rc = PTR_ERR(tcp_ses->hostname);
1484 goto out_err;
1485 }
1486
1487 tcp_ses->noblocksnd = volume_info->noblocksnd;
1488 tcp_ses->noautotune = volume_info->noautotune;
1489 atomic_set(&tcp_ses->inFlight, 0);
1490 init_waitqueue_head(&tcp_ses->response_q);
1491 init_waitqueue_head(&tcp_ses->request_q);
1492 INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
1493 mutex_init(&tcp_ses->srv_mutex);
1494 memcpy(tcp_ses->workstation_RFC1001_name,
1495 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1496 memcpy(tcp_ses->server_RFC1001_name,
1497 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1498 tcp_ses->sequence_number = 0;
1499 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1500 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1501
1502 /*
1503 * at this point we are the only ones with the pointer
1504 * to the struct since the kernel thread not created yet
1505 * no need to spinlock this init of tcpStatus or srv_count
1506 */
1507 tcp_ses->tcpStatus = CifsNew;
1508 ++tcp_ses->srv_count;
1509
a9ac49d3 1510 if (addr.ss_family == AF_INET6) {
63c038c2
JL
1511 cFYI(1, ("attempting ipv6 connect"));
1512 /* BB should we allow ipv6 on port 139? */
1513 /* other OS never observed in Wild doing 139 with v6 */
1514 memcpy(&tcp_ses->addr.sockAddr6, sin_server6,
1515 sizeof(struct sockaddr_in6));
1516 sin_server6->sin6_port = htons(volume_info->port);
d5c5605c 1517 rc = ipv6_connect(tcp_ses);
63c038c2
JL
1518 } else {
1519 memcpy(&tcp_ses->addr.sockAddr, sin_server,
1520 sizeof(struct sockaddr_in));
1521 sin_server->sin_port = htons(volume_info->port);
bcf4b106 1522 rc = ipv4_connect(tcp_ses);
63c038c2
JL
1523 }
1524 if (rc < 0) {
1525 cERROR(1, ("Error connecting to socket. Aborting operation"));
1526 goto out_err;
1527 }
1528
1529 /*
1530 * since we're in a cifs function already, we know that
1531 * this will succeed. No need for try_module_get().
1532 */
1533 __module_get(THIS_MODULE);
1534 tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread,
1535 tcp_ses, "cifsd");
1536 if (IS_ERR(tcp_ses->tsk)) {
1537 rc = PTR_ERR(tcp_ses->tsk);
1538 cERROR(1, ("error %d create cifsd thread", rc));
1539 module_put(THIS_MODULE);
1540 goto out_err;
1541 }
1542
1543 /* thread spawned, put it on the list */
1544 write_lock(&cifs_tcp_ses_lock);
1545 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1546 write_unlock(&cifs_tcp_ses_lock);
1547
1548 return tcp_ses;
1549
1550out_err:
1551 if (tcp_ses) {
1552 kfree(tcp_ses->hostname);
1553 if (tcp_ses->ssocket)
1554 sock_release(tcp_ses->ssocket);
1555 kfree(tcp_ses);
1556 }
1557 return ERR_PTR(rc);
1558}
1559
14fbf50d
JL
1560static struct cifsSesInfo *
1561cifs_find_smb_ses(struct TCP_Server_Info *server, char *username)
1da177e4
LT
1562{
1563 struct list_head *tmp;
14fbf50d 1564 struct cifsSesInfo *ses;
dea570e0 1565
14fbf50d
JL
1566 write_lock(&cifs_tcp_ses_lock);
1567 list_for_each(tmp, &server->smb_ses_list) {
1568 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
1569 if (strncmp(ses->userName, username, MAX_USERNAME_SIZE))
dea570e0
SF
1570 continue;
1571
14fbf50d
JL
1572 ++ses->ses_count;
1573 write_unlock(&cifs_tcp_ses_lock);
1574 return ses;
1575 }
1576 write_unlock(&cifs_tcp_ses_lock);
1577 return NULL;
1578}
dea570e0 1579
14fbf50d
JL
1580static void
1581cifs_put_smb_ses(struct cifsSesInfo *ses)
1582{
1583 int xid;
1584 struct TCP_Server_Info *server = ses->server;
dea570e0 1585
14fbf50d
JL
1586 write_lock(&cifs_tcp_ses_lock);
1587 if (--ses->ses_count > 0) {
1588 write_unlock(&cifs_tcp_ses_lock);
1589 return;
1590 }
dea570e0 1591
14fbf50d
JL
1592 list_del_init(&ses->smb_ses_list);
1593 write_unlock(&cifs_tcp_ses_lock);
dea570e0 1594
14fbf50d
JL
1595 if (ses->status == CifsGood) {
1596 xid = GetXid();
1597 CIFSSMBLogoff(xid, ses);
1598 _FreeXid(xid);
1599 }
1600 sesInfoFree(ses);
1601 cifs_put_tcp_session(server);
1602}
dea570e0 1603
f1987b44
JL
1604static struct cifsTconInfo *
1605cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1606{
1607 struct list_head *tmp;
1608 struct cifsTconInfo *tcon;
1609
1610 write_lock(&cifs_tcp_ses_lock);
1611 list_for_each(tmp, &ses->tcon_list) {
1612 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1613 if (tcon->tidStatus == CifsExiting)
1614 continue;
1615 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
dea570e0
SF
1616 continue;
1617
f1987b44
JL
1618 ++tcon->tc_count;
1619 write_unlock(&cifs_tcp_ses_lock);
dea570e0 1620 return tcon;
1da177e4 1621 }
f1987b44 1622 write_unlock(&cifs_tcp_ses_lock);
1da177e4
LT
1623 return NULL;
1624}
1625
f1987b44
JL
1626static void
1627cifs_put_tcon(struct cifsTconInfo *tcon)
1628{
1629 int xid;
1630 struct cifsSesInfo *ses = tcon->ses;
1631
1632 write_lock(&cifs_tcp_ses_lock);
1633 if (--tcon->tc_count > 0) {
1634 write_unlock(&cifs_tcp_ses_lock);
1635 return;
1636 }
1637
1638 list_del_init(&tcon->tcon_list);
1639 write_unlock(&cifs_tcp_ses_lock);
1640
1641 xid = GetXid();
1642 CIFSSMBTDis(xid, tcon);
1643 _FreeXid(xid);
1644
1645 DeleteTconOplockQEntries(tcon);
1646 tconInfoFree(tcon);
1647 cifs_put_smb_ses(ses);
1648}
1649
1da177e4 1650int
50c2f753
SF
1651get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1652 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
366781c1 1653 struct dfs_info3_param **preferrals, int remap)
1da177e4
LT
1654{
1655 char *temp_unc;
1656 int rc = 0;
1657
1658 *pnum_referrals = 0;
366781c1 1659 *preferrals = NULL;
1da177e4
LT
1660
1661 if (pSesInfo->ipc_tid == 0) {
1662 temp_unc = kmalloc(2 /* for slashes */ +
50c2f753
SF
1663 strnlen(pSesInfo->serverName,
1664 SERVER_NAME_LEN_WITH_NULL * 2)
1da177e4
LT
1665 + 1 + 4 /* slash IPC$ */ + 2,
1666 GFP_KERNEL);
1667 if (temp_unc == NULL)
1668 return -ENOMEM;
1669 temp_unc[0] = '\\';
1670 temp_unc[1] = '\\';
1671 strcpy(temp_unc + 2, pSesInfo->serverName);
1672 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1673 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1674 cFYI(1,
50c2f753 1675 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1da177e4
LT
1676 kfree(temp_unc);
1677 }
1678 if (rc == 0)
c2cf07d5 1679 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
737b758c 1680 pnum_referrals, nls_codepage, remap);
366781c1
SF
1681 /* BB map targetUNCs to dfs_info3 structures, here or
1682 in CIFSGetDFSRefer BB */
1da177e4
LT
1683
1684 return rc;
1685}
1686
09e50d55
JL
1687#ifdef CONFIG_DEBUG_LOCK_ALLOC
1688static struct lock_class_key cifs_key[2];
1689static struct lock_class_key cifs_slock_key[2];
1690
1691static inline void
1692cifs_reclassify_socket4(struct socket *sock)
1693{
1694 struct sock *sk = sock->sk;
1695 BUG_ON(sock_owned_by_user(sk));
1696 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
1697 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
1698}
1699
1700static inline void
1701cifs_reclassify_socket6(struct socket *sock)
1702{
1703 struct sock *sk = sock->sk;
1704 BUG_ON(sock_owned_by_user(sk));
1705 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
1706 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
1707}
1708#else
1709static inline void
1710cifs_reclassify_socket4(struct socket *sock)
1711{
1712}
1713
1714static inline void
1715cifs_reclassify_socket6(struct socket *sock)
1716{
1717}
1718#endif
1719
1da177e4 1720/* See RFC1001 section 14 on representation of Netbios names */
50c2f753 1721static void rfc1002mangle(char *target, char *source, unsigned int length)
1da177e4 1722{
50c2f753 1723 unsigned int i, j;
1da177e4 1724
50c2f753 1725 for (i = 0, j = 0; i < (length); i++) {
1da177e4
LT
1726 /* mask a nibble at a time and encode */
1727 target[j] = 'A' + (0x0F & (source[i] >> 4));
1728 target[j+1] = 'A' + (0x0F & source[i]);
50c2f753 1729 j += 2;
1da177e4
LT
1730 }
1731
1732}
1733
1734
1735static int
bcf4b106 1736ipv4_connect(struct TCP_Server_Info *server)
1da177e4
LT
1737{
1738 int rc = 0;
bcf4b106 1739 bool connected = false;
1da177e4 1740 __be16 orig_port = 0;
bcf4b106 1741 struct socket *socket = server->ssocket;
1da177e4 1742
bcf4b106 1743 if (socket == NULL) {
50c2f753 1744 rc = sock_create_kern(PF_INET, SOCK_STREAM,
bcf4b106 1745 IPPROTO_TCP, &socket);
1da177e4 1746 if (rc < 0) {
50c2f753 1747 cERROR(1, ("Error %d creating socket", rc));
1da177e4 1748 return rc;
1da177e4 1749 }
bcf4b106
JL
1750
1751 /* BB other socket options to set KEEPALIVE, NODELAY? */
1752 cFYI(1, ("Socket created"));
1753 server->ssocket = socket;
1754 socket->sk->sk_allocation = GFP_NOFS;
1755 cifs_reclassify_socket4(socket);
1da177e4
LT
1756 }
1757
bcf4b106
JL
1758 /* user overrode default port */
1759 if (server->addr.sockAddr.sin_port) {
1760 rc = socket->ops->connect(socket, (struct sockaddr *)
1761 &server->addr.sockAddr,
1762 sizeof(struct sockaddr_in), 0);
1da177e4 1763 if (rc >= 0)
bcf4b106 1764 connected = true;
50c2f753 1765 }
1da177e4 1766
fb8c4b14 1767 if (!connected) {
50c2f753 1768 /* save original port so we can retry user specified port
1da177e4 1769 later if fall back ports fail this time */
bcf4b106 1770 orig_port = server->addr.sockAddr.sin_port;
1da177e4
LT
1771
1772 /* do not retry on the same port we just failed on */
bcf4b106
JL
1773 if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
1774 server->addr.sockAddr.sin_port = htons(CIFS_PORT);
1775 rc = socket->ops->connect(socket,
1776 (struct sockaddr *)
1777 &server->addr.sockAddr,
1778 sizeof(struct sockaddr_in), 0);
1da177e4 1779 if (rc >= 0)
bcf4b106 1780 connected = true;
1da177e4
LT
1781 }
1782 }
1783 if (!connected) {
bcf4b106
JL
1784 server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
1785 rc = socket->ops->connect(socket, (struct sockaddr *)
1786 &server->addr.sockAddr,
6345a3a8 1787 sizeof(struct sockaddr_in), 0);
50c2f753 1788 if (rc >= 0)
bcf4b106 1789 connected = true;
1da177e4
LT
1790 }
1791
1792 /* give up here - unless we want to retry on different
1793 protocol families some day */
1794 if (!connected) {
fb8c4b14 1795 if (orig_port)
bcf4b106 1796 server->addr.sockAddr.sin_port = orig_port;
50c2f753 1797 cFYI(1, ("Error %d connecting to server via ipv4", rc));
bcf4b106
JL
1798 sock_release(socket);
1799 server->ssocket = NULL;
1da177e4
LT
1800 return rc;
1801 }
bcf4b106
JL
1802
1803
1804 /*
1805 * Eventually check for other socket options to change from
1806 * the default. sock_setsockopt not used because it expects
1807 * user space buffer
1808 */
1809 socket->sk->sk_rcvtimeo = 7 * HZ;
da505c38 1810 socket->sk->sk_sndtimeo = 5 * HZ;
edf1ae40 1811
b387eaeb 1812 /* make the bufsizes depend on wsize/rsize and max requests */
bcf4b106
JL
1813 if (server->noautotune) {
1814 if (socket->sk->sk_sndbuf < (200 * 1024))
1815 socket->sk->sk_sndbuf = 200 * 1024;
1816 if (socket->sk->sk_rcvbuf < (140 * 1024))
1817 socket->sk->sk_rcvbuf = 140 * 1024;
edf1ae40 1818 }
1da177e4 1819
bcf4b106
JL
1820 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1821 socket->sk->sk_sndbuf,
1822 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo));
1823
1da177e4 1824 /* send RFC1001 sessinit */
bcf4b106 1825 if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) {
1da177e4 1826 /* some servers require RFC1001 sessinit before sending
50c2f753 1827 negprot - BB check reconnection in case where second
1da177e4 1828 sessinit is sent but no second negprot */
50c2f753
SF
1829 struct rfc1002_session_packet *ses_init_buf;
1830 struct smb_hdr *smb_buf;
1831 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1832 GFP_KERNEL);
fb8c4b14 1833 if (ses_init_buf) {
1da177e4 1834 ses_init_buf->trailer.session_req.called_len = 32;
bcf4b106
JL
1835 if (server->server_RFC1001_name &&
1836 server->server_RFC1001_name[0] != 0)
8ecaf67a
JL
1837 rfc1002mangle(ses_init_buf->trailer.
1838 session_req.called_name,
bcf4b106 1839 server->server_RFC1001_name,
8ecaf67a 1840 RFC1001_NAME_LEN_WITH_NULL);
bcf4b106 1841 else
8ecaf67a
JL
1842 rfc1002mangle(ses_init_buf->trailer.
1843 session_req.called_name,
1844 DEFAULT_CIFS_CALLED_NAME,
1845 RFC1001_NAME_LEN_WITH_NULL);
a10faeb2 1846
1da177e4 1847 ses_init_buf->trailer.session_req.calling_len = 32;
bcf4b106 1848
1da177e4
LT
1849 /* calling name ends in null (byte 16) from old smb
1850 convention. */
bcf4b106
JL
1851 if (server->workstation_RFC1001_name &&
1852 server->workstation_RFC1001_name[0] != 0)
8ecaf67a
JL
1853 rfc1002mangle(ses_init_buf->trailer.
1854 session_req.calling_name,
bcf4b106 1855 server->workstation_RFC1001_name,
8ecaf67a 1856 RFC1001_NAME_LEN_WITH_NULL);
bcf4b106 1857 else
8ecaf67a
JL
1858 rfc1002mangle(ses_init_buf->trailer.
1859 session_req.calling_name,
1860 "LINUX_CIFS_CLNT",
1861 RFC1001_NAME_LEN_WITH_NULL);
bcf4b106 1862
1da177e4
LT
1863 ses_init_buf->trailer.session_req.scope1 = 0;
1864 ses_init_buf->trailer.session_req.scope2 = 0;
1865 smb_buf = (struct smb_hdr *)ses_init_buf;
1866 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1867 smb_buf->smb_buf_length = 0x81000044;
0496e02d 1868 rc = smb_send(server, smb_buf, 0x44);
1da177e4 1869 kfree(ses_init_buf);
50c2f753 1870 msleep(1); /* RFC1001 layer in at least one server
083d3a2c
SF
1871 requires very short break before negprot
1872 presumably because not expecting negprot
1873 to follow so fast. This is a simple
50c2f753 1874 solution that works without
083d3a2c
SF
1875 complicating the code and causes no
1876 significant slowing down on mount
1877 for everyone else */
1da177e4 1878 }
50c2f753 1879 /* else the negprot may still work without this
1da177e4 1880 even though malloc failed */
50c2f753 1881
1da177e4 1882 }
50c2f753 1883
1da177e4
LT
1884 return rc;
1885}
1886
1887static int
d5c5605c 1888ipv6_connect(struct TCP_Server_Info *server)
1da177e4
LT
1889{
1890 int rc = 0;
d5c5605c 1891 bool connected = false;
1da177e4 1892 __be16 orig_port = 0;
d5c5605c 1893 struct socket *socket = server->ssocket;
1da177e4 1894
d5c5605c 1895 if (socket == NULL) {
50c2f753 1896 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
d5c5605c 1897 IPPROTO_TCP, &socket);
1da177e4 1898 if (rc < 0) {
50c2f753 1899 cERROR(1, ("Error %d creating ipv6 socket", rc));
d5c5605c 1900 socket = NULL;
1da177e4 1901 return rc;
1da177e4 1902 }
1da177e4 1903
d5c5605c
JL
1904 /* BB other socket options to set KEEPALIVE, NODELAY? */
1905 cFYI(1, ("ipv6 Socket created"));
1906 server->ssocket = socket;
1907 socket->sk->sk_allocation = GFP_NOFS;
1908 cifs_reclassify_socket6(socket);
1909 }
1da177e4 1910
d5c5605c
JL
1911 /* user overrode default port */
1912 if (server->addr.sockAddr6.sin6_port) {
1913 rc = socket->ops->connect(socket,
1914 (struct sockaddr *) &server->addr.sockAddr6,
6345a3a8 1915 sizeof(struct sockaddr_in6), 0);
1da177e4 1916 if (rc >= 0)
d5c5605c 1917 connected = true;
50c2f753 1918 }
1da177e4 1919
fb8c4b14 1920 if (!connected) {
50c2f753 1921 /* save original port so we can retry user specified port
1da177e4
LT
1922 later if fall back ports fail this time */
1923
d5c5605c 1924 orig_port = server->addr.sockAddr6.sin6_port;
1da177e4 1925 /* do not retry on the same port we just failed on */
d5c5605c
JL
1926 if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) {
1927 server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
1928 rc = socket->ops->connect(socket, (struct sockaddr *)
1929 &server->addr.sockAddr6,
6345a3a8 1930 sizeof(struct sockaddr_in6), 0);
1da177e4 1931 if (rc >= 0)
d5c5605c 1932 connected = true;
1da177e4
LT
1933 }
1934 }
1935 if (!connected) {
d5c5605c
JL
1936 server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT);
1937 rc = socket->ops->connect(socket, (struct sockaddr *)
1938 &server->addr.sockAddr6,
1939 sizeof(struct sockaddr_in6), 0);
50c2f753 1940 if (rc >= 0)
d5c5605c 1941 connected = true;
1da177e4
LT
1942 }
1943
1944 /* give up here - unless we want to retry on different
1945 protocol families some day */
1946 if (!connected) {
fb8c4b14 1947 if (orig_port)
d5c5605c 1948 server->addr.sockAddr6.sin6_port = orig_port;
50c2f753 1949 cFYI(1, ("Error %d connecting to server via ipv6", rc));
d5c5605c
JL
1950 sock_release(socket);
1951 server->ssocket = NULL;
1da177e4
LT
1952 return rc;
1953 }
edf1ae40 1954
d5c5605c
JL
1955 /*
1956 * Eventually check for other socket options to change from
1957 * the default. sock_setsockopt not used because it expects
1958 * user space buffer
1959 */
1960 socket->sk->sk_rcvtimeo = 7 * HZ;
da505c38 1961 socket->sk->sk_sndtimeo = 5 * HZ;
d5c5605c 1962 server->ssocket = socket;
50c2f753 1963
1da177e4
LT
1964 return rc;
1965}
1966
50c2f753
SF
1967void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1968 struct super_block *sb, struct smb_vol *vol_info)
8af18971
SF
1969{
1970 /* if we are reconnecting then should we check to see if
1971 * any requested capabilities changed locally e.g. via
1972 * remount but we can not do much about it here
1973 * if they have (even if we could detect it by the following)
1974 * Perhaps we could add a backpointer to array of sb from tcon
1975 * or if we change to make all sb to same share the same
1976 * sb as NFS - then we only have one backpointer to sb.
1977 * What if we wanted to mount the server share twice once with
1978 * and once without posixacls or posix paths? */
1979 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
50c2f753 1980
c18c842b
SF
1981 if (vol_info && vol_info->no_linux_ext) {
1982 tcon->fsUnixInfo.Capability = 0;
1983 tcon->unix_ext = 0; /* Unix Extensions disabled */
1984 cFYI(1, ("Linux protocol extensions disabled"));
1985 return;
1986 } else if (vol_info)
1987 tcon->unix_ext = 1; /* Unix Extensions supported */
1988
1989 if (tcon->unix_ext == 0) {
1990 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1991 return;
1992 }
50c2f753 1993
fb8c4b14 1994 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
8af18971 1995 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
50c2f753 1996
8af18971
SF
1997 /* check for reconnect case in which we do not
1998 want to change the mount behavior if we can avoid it */
fb8c4b14 1999 if (vol_info == NULL) {
50c2f753 2000 /* turn off POSIX ACL and PATHNAMES if not set
8af18971
SF
2001 originally at mount time */
2002 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
2003 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
11b6d645
IM
2004 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2005 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2006 cERROR(1, ("POSIXPATH support change"));
8af18971 2007 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
11b6d645
IM
2008 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2009 cERROR(1, ("possible reconnect error"));
2010 cERROR(1,
2011 ("server disabled POSIX path support"));
2012 }
8af18971 2013 }
50c2f753 2014
8af18971 2015 cap &= CIFS_UNIX_CAP_MASK;
75865f8c 2016 if (vol_info && vol_info->no_psx_acl)
8af18971 2017 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
75865f8c 2018 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
fb8c4b14
SF
2019 cFYI(1, ("negotiated posix acl support"));
2020 if (sb)
8af18971
SF
2021 sb->s_flags |= MS_POSIXACL;
2022 }
2023
75865f8c 2024 if (vol_info && vol_info->posix_paths == 0)
8af18971 2025 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
75865f8c 2026 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
fb8c4b14 2027 cFYI(1, ("negotiate posix pathnames"));
75865f8c 2028 if (sb)
50c2f753 2029 CIFS_SB(sb)->mnt_cifs_flags |=
8af18971
SF
2030 CIFS_MOUNT_POSIX_PATHS;
2031 }
50c2f753 2032
984acfe1
SF
2033 /* We might be setting the path sep back to a different
2034 form if we are reconnecting and the server switched its
50c2f753 2035 posix path capability for this share */
75865f8c 2036 if (sb && (CIFS_SB(sb)->prepathlen > 0))
984acfe1 2037 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
75865f8c
SF
2038
2039 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2040 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2041 CIFS_SB(sb)->rsize = 127 * 1024;
90c81e0b
SF
2042 cFYI(DBG2,
2043 ("larger reads not supported by srv"));
75865f8c
SF
2044 }
2045 }
50c2f753
SF
2046
2047
2048 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
8af18971 2049#ifdef CONFIG_CIFS_DEBUG2
75865f8c 2050 if (cap & CIFS_UNIX_FCNTL_CAP)
fb8c4b14 2051 cFYI(1, ("FCNTL cap"));
75865f8c 2052 if (cap & CIFS_UNIX_EXTATTR_CAP)
fb8c4b14 2053 cFYI(1, ("EXTATTR cap"));
75865f8c 2054 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
fb8c4b14 2055 cFYI(1, ("POSIX path cap"));
75865f8c 2056 if (cap & CIFS_UNIX_XATTR_CAP)
fb8c4b14 2057 cFYI(1, ("XATTR cap"));
75865f8c 2058 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
fb8c4b14 2059 cFYI(1, ("POSIX ACL cap"));
75865f8c 2060 if (cap & CIFS_UNIX_LARGE_READ_CAP)
fb8c4b14 2061 cFYI(1, ("very large read cap"));
75865f8c 2062 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
fb8c4b14 2063 cFYI(1, ("very large write cap"));
8af18971
SF
2064#endif /* CIFS_DEBUG2 */
2065 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
442aa310 2066 if (vol_info == NULL) {
5a44b319 2067 cFYI(1, ("resetting capabilities failed"));
442aa310 2068 } else
5a44b319
SF
2069 cERROR(1, ("Negotiating Unix capabilities "
2070 "with the server failed. Consider "
2071 "mounting with the Unix Extensions\n"
2072 "disabled, if problems are found, "
2073 "by specifying the nounix mount "
2224f4e5 2074 "option."));
5a44b319 2075
8af18971
SF
2076 }
2077 }
2078}
2079
03a143c9
SF
2080static void
2081convert_delimiter(char *path, char delim)
2082{
2083 int i;
c2d68ea6 2084 char old_delim;
03a143c9
SF
2085
2086 if (path == NULL)
2087 return;
2088
582d21e5 2089 if (delim == '/')
c2d68ea6
SF
2090 old_delim = '\\';
2091 else
2092 old_delim = '/';
2093
03a143c9 2094 for (i = 0; path[i] != '\0'; i++) {
c2d68ea6 2095 if (path[i] == old_delim)
03a143c9
SF
2096 path[i] = delim;
2097 }
2098}
2099
3b795210
SF
2100static void setup_cifs_sb(struct smb_vol *pvolume_info,
2101 struct cifs_sb_info *cifs_sb)
b1c8d2b4 2102{
3b795210
SF
2103 if (pvolume_info->rsize > CIFSMaxBufSize) {
2104 cERROR(1, ("rsize %d too large, using MaxBufSize",
2105 pvolume_info->rsize));
2106 cifs_sb->rsize = CIFSMaxBufSize;
2107 } else if ((pvolume_info->rsize) &&
2108 (pvolume_info->rsize <= CIFSMaxBufSize))
2109 cifs_sb->rsize = pvolume_info->rsize;
2110 else /* default */
2111 cifs_sb->rsize = CIFSMaxBufSize;
2112
2113 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2114 cERROR(1, ("wsize %d too large, using 4096 instead",
2115 pvolume_info->wsize));
2116 cifs_sb->wsize = 4096;
2117 } else if (pvolume_info->wsize)
2118 cifs_sb->wsize = pvolume_info->wsize;
2119 else
2120 cifs_sb->wsize = min_t(const int,
2121 PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2122 127*1024);
2123 /* old default of CIFSMaxBufSize was too small now
2124 that SMB Write2 can send multiple pages in kvec.
2125 RFC1001 does not describe what happens when frame
2126 bigger than 128K is sent so use that as max in
2127 conjunction with 52K kvec constraint on arch with 4K
2128 page size */
2129
2130 if (cifs_sb->rsize < 2048) {
2131 cifs_sb->rsize = 2048;
2132 /* Windows ME may prefer this */
2133 cFYI(1, ("readsize set to minimum: 2048"));
2134 }
2135 /* calculate prepath */
2136 cifs_sb->prepath = pvolume_info->prepath;
2137 if (cifs_sb->prepath) {
2138 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2139 /* we can not convert the / to \ in the path
2140 separators in the prefixpath yet because we do not
2141 know (until reset_cifs_unix_caps is called later)
2142 whether POSIX PATH CAP is available. We normalize
2143 the / to \ after reset_cifs_unix_caps is called */
2144 pvolume_info->prepath = NULL;
2145 } else
2146 cifs_sb->prepathlen = 0;
2147 cifs_sb->mnt_uid = pvolume_info->linux_uid;
2148 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2149 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
2150 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
2151 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2152 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2153
2154 if (pvolume_info->noperm)
2155 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2156 if (pvolume_info->setuids)
2157 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2158 if (pvolume_info->server_ino)
2159 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2160 if (pvolume_info->remap)
2161 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2162 if (pvolume_info->no_xattr)
2163 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2164 if (pvolume_info->sfu_emul)
2165 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2166 if (pvolume_info->nobrl)
2167 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
be652445 2168 if (pvolume_info->nostrictsync)
4717bed6 2169 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
13a6e42a
SF
2170 if (pvolume_info->mand_lock)
2171 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
3b795210
SF
2172 if (pvolume_info->cifs_acl)
2173 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2174 if (pvolume_info->override_uid)
2175 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2176 if (pvolume_info->override_gid)
2177 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2178 if (pvolume_info->dynperm)
2179 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2180 if (pvolume_info->direct_io) {
2181 cFYI(1, ("mounting share using direct i/o"));
2182 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2183 }
2184
2185 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2186 cERROR(1, ("mount option dynperm ignored if cifsacl "
2187 "mount option supported"));
b1c8d2b4
JL
2188}
2189
e4cce94c
IM
2190static int
2191is_path_accessible(int xid, struct cifsTconInfo *tcon,
2192 struct cifs_sb_info *cifs_sb, const char *full_path)
2193{
2194 int rc;
2195 __u64 inode_num;
2196 FILE_ALL_INFO *pfile_info;
2197
2198 rc = CIFSGetSrvInodeNumber(xid, tcon, full_path, &inode_num,
2199 cifs_sb->local_nls,
2200 cifs_sb->mnt_cifs_flags &
2201 CIFS_MOUNT_MAP_SPECIAL_CHR);
2202 if (rc != -EOPNOTSUPP)
2203 return rc;
2204
2205 pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
2206 if (pfile_info == NULL)
2207 return -ENOMEM;
2208
2209 rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info,
2210 0 /* not legacy */, cifs_sb->local_nls,
2211 cifs_sb->mnt_cifs_flags &
2212 CIFS_MOUNT_MAP_SPECIAL_CHR);
2213 kfree(pfile_info);
2214 return rc;
2215}
2216
1bfe73c2
IM
2217static void
2218cleanup_volume_info(struct smb_vol **pvolume_info)
2219{
2220 struct smb_vol *volume_info;
2221
2222 if (!pvolume_info && !*pvolume_info)
2223 return;
2224
2225 volume_info = *pvolume_info;
2226 kzfree(volume_info->password);
2227 kfree(volume_info->UNC);
2228 kfree(volume_info->prepath);
2229 kfree(volume_info);
2230 *pvolume_info = NULL;
2231 return;
2232}
2233
2d6d589d 2234#ifdef CONFIG_CIFS_DFS_UPCALL
1bfe73c2
IM
2235/* build_path_to_root returns full path to root when
2236 * we do not have an exiting connection (tcon) */
2237static char *
2238build_unc_path_to_root(const struct smb_vol *volume_info,
2239 const struct cifs_sb_info *cifs_sb)
2240{
2241 char *full_path;
2242
2243 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
2244 full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL);
2245 if (full_path == NULL)
2246 return ERR_PTR(-ENOMEM);
2247
2248 strncpy(full_path, volume_info->UNC, unc_len);
2249 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
2250 int i;
2251 for (i = 0; i < unc_len; i++) {
2252 if (full_path[i] == '\\')
2253 full_path[i] = '/';
2254 }
2255 }
2256
2257 if (cifs_sb->prepathlen)
2258 strncpy(full_path + unc_len, cifs_sb->prepath,
2259 cifs_sb->prepathlen);
2260
2261 full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
2262 return full_path;
2263}
2d6d589d 2264#endif
1bfe73c2 2265
1da177e4
LT
2266int
2267cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1bfe73c2 2268 char *mount_data_global, const char *devname)
1da177e4
LT
2269{
2270 int rc = 0;
2271 int xid;
7586b765 2272 struct smb_vol *volume_info;
1da177e4 2273 struct cifsSesInfo *pSesInfo = NULL;
1da177e4
LT
2274 struct cifsTconInfo *tcon = NULL;
2275 struct TCP_Server_Info *srvTcp = NULL;
e4cce94c 2276 char *full_path;
2d6d589d
SF
2277 char *mount_data = mount_data_global;
2278#ifdef CONFIG_CIFS_DFS_UPCALL
1bfe73c2
IM
2279 struct dfs_info3_param *referrals = NULL;
2280 unsigned int num_referrals = 0;
1bfe73c2 2281try_mount_again:
2d6d589d 2282#endif
1bfe73c2 2283 full_path = NULL;
1da177e4
LT
2284
2285 xid = GetXid();
2286
7586b765
JL
2287 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2288 if (!volume_info) {
2289 rc = -ENOMEM;
2290 goto out;
2291 }
50c2f753 2292
7586b765 2293 if (cifs_parse_mount_options(mount_data, devname, volume_info)) {
70fe7dc0
JL
2294 rc = -EINVAL;
2295 goto out;
1da177e4
LT
2296 }
2297
7586b765 2298 if (volume_info->nullauth) {
fb8c4b14 2299 cFYI(1, ("null user"));
7586b765
JL
2300 volume_info->username = "";
2301 } else if (volume_info->username) {
1da177e4 2302 /* BB fixme parse for domain name here */
7586b765 2303 cFYI(1, ("Username: %s", volume_info->username));
1da177e4 2304 } else {
bf820679 2305 cifserror("No username specified");
50c2f753
SF
2306 /* In userspace mount helper we can get user name from alternate
2307 locations such as env variables and files on disk */
70fe7dc0
JL
2308 rc = -EINVAL;
2309 goto out;
1da177e4
LT
2310 }
2311
1da177e4
LT
2312
2313 /* this is needed for ASCII cp to Unicode converts */
7586b765 2314 if (volume_info->iocharset == NULL) {
1da177e4
LT
2315 cifs_sb->local_nls = load_nls_default();
2316 /* load_nls_default can not return null */
2317 } else {
7586b765 2318 cifs_sb->local_nls = load_nls(volume_info->iocharset);
fb8c4b14 2319 if (cifs_sb->local_nls == NULL) {
50c2f753 2320 cERROR(1, ("CIFS mount error: iocharset %s not found",
7586b765 2321 volume_info->iocharset));
70fe7dc0
JL
2322 rc = -ELIBACC;
2323 goto out;
1da177e4
LT
2324 }
2325 }
2326
63c038c2 2327 /* get a reference to a tcp session */
7586b765 2328 srvTcp = cifs_get_tcp_session(volume_info);
63c038c2
JL
2329 if (IS_ERR(srvTcp)) {
2330 rc = PTR_ERR(srvTcp);
2331 goto out;
1da177e4
LT
2332 }
2333
7586b765 2334 pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username);
14fbf50d 2335 if (pSesInfo) {
1d9a8852
JL
2336 cFYI(1, ("Existing smb sess found (status=%d)",
2337 pSesInfo->status));
14fbf50d
JL
2338 /*
2339 * The existing SMB session already has a reference to srvTcp,
2340 * so we can put back the extra one we got before
2341 */
2342 cifs_put_tcp_session(srvTcp);
2343
88e7d705 2344 down(&pSesInfo->sesSem);
3b795210 2345 if (pSesInfo->need_reconnect) {
1d9a8852 2346 cFYI(1, ("Session needs reconnect"));
1d9a8852
JL
2347 rc = cifs_setup_session(xid, pSesInfo,
2348 cifs_sb->local_nls);
1d9a8852 2349 }
88e7d705 2350 up(&pSesInfo->sesSem);
1da177e4 2351 } else if (!rc) {
bf820679 2352 cFYI(1, ("Existing smb sess not found"));
1da177e4 2353 pSesInfo = sesInfoAlloc();
14fbf50d 2354 if (pSesInfo == NULL) {
1da177e4 2355 rc = -ENOMEM;
14fbf50d 2356 goto mount_fail_check;
1da177e4
LT
2357 }
2358
14fbf50d
JL
2359 /* new SMB session uses our srvTcp ref */
2360 pSesInfo->server = srvTcp;
63c038c2 2361 if (srvTcp->addr.sockAddr6.sin6_family == AF_INET6)
0191b625
LT
2362 sprintf(pSesInfo->serverName, "%pI6",
2363 &srvTcp->addr.sockAddr6.sin6_addr);
8ecaf67a 2364 else
0191b625
LT
2365 sprintf(pSesInfo->serverName, "%pI4",
2366 &srvTcp->addr.sockAddr.sin_addr.s_addr);
14fbf50d
JL
2367
2368 write_lock(&cifs_tcp_ses_lock);
2369 list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
2370 write_unlock(&cifs_tcp_ses_lock);
2371
7586b765
JL
2372 /* volume_info->password freed at unmount */
2373 if (volume_info->password) {
00e485b0
JL
2374 pSesInfo->password = kstrdup(volume_info->password,
2375 GFP_KERNEL);
2376 if (!pSesInfo->password) {
2377 rc = -ENOMEM;
2378 goto mount_fail_check;
2379 }
14fbf50d 2380 }
7586b765
JL
2381 if (volume_info->username)
2382 strncpy(pSesInfo->userName, volume_info->username,
14fbf50d 2383 MAX_USERNAME_SIZE);
7586b765
JL
2384 if (volume_info->domainname) {
2385 int len = strlen(volume_info->domainname);
14fbf50d
JL
2386 pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
2387 if (pSesInfo->domainName)
2388 strcpy(pSesInfo->domainName,
7586b765 2389 volume_info->domainname);
70fe7dc0 2390 }
7586b765
JL
2391 pSesInfo->linux_uid = volume_info->linux_uid;
2392 pSesInfo->overrideSecFlg = volume_info->secFlg;
14fbf50d 2393 down(&pSesInfo->sesSem);
1da177e4 2394
14fbf50d
JL
2395 /* BB FIXME need to pass vol->secFlgs BB */
2396 rc = cifs_setup_session(xid, pSesInfo,
2397 cifs_sb->local_nls);
2398 up(&pSesInfo->sesSem);
1da177e4 2399 }
50c2f753 2400
1da177e4
LT
2401 /* search for existing tcon to this server share */
2402 if (!rc) {
7586b765 2403 setup_cifs_sb(volume_info, cifs_sb);
1da177e4 2404
7586b765 2405 tcon = cifs_find_tcon(pSesInfo, volume_info->UNC);
1da177e4 2406 if (tcon) {
bf820679 2407 cFYI(1, ("Found match on UNC path"));
f1987b44
JL
2408 /* existing tcon already has a reference */
2409 cifs_put_smb_ses(pSesInfo);
7586b765 2410 if (tcon->seal != volume_info->seal)
95b1cb90
SF
2411 cERROR(1, ("transport encryption setting "
2412 "conflicts with existing tid"));
1da177e4
LT
2413 } else {
2414 tcon = tconInfoAlloc();
3b795210 2415 if (tcon == NULL) {
1da177e4 2416 rc = -ENOMEM;
3b795210
SF
2417 goto mount_fail_check;
2418 }
00e485b0 2419
ab3f9929 2420 tcon->ses = pSesInfo;
00e485b0
JL
2421 if (volume_info->password) {
2422 tcon->password = kstrdup(volume_info->password,
2423 GFP_KERNEL);
2424 if (!tcon->password) {
2425 rc = -ENOMEM;
2426 goto mount_fail_check;
2427 }
2428 }
3b795210 2429
7586b765
JL
2430 if ((strchr(volume_info->UNC + 3, '\\') == NULL)
2431 && (strchr(volume_info->UNC + 3, '/') == NULL)) {
1bfe73c2 2432 cERROR(1, ("Missing share name"));
3b795210
SF
2433 rc = -ENODEV;
2434 goto mount_fail_check;
2435 } else {
2436 /* BB Do we need to wrap sesSem around
2437 * this TCon call and Unix SetFS as
2438 * we do on SessSetup and reconnect? */
7586b765 2439 rc = CIFSTCon(xid, pSesInfo, volume_info->UNC,
3b795210
SF
2440 tcon, cifs_sb->local_nls);
2441 cFYI(1, ("CIFS Tcon rc = %d", rc));
7586b765 2442 if (volume_info->nodfs) {
3b795210
SF
2443 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2444 cFYI(1, ("DFS disabled (%d)",
2445 tcon->Flags));
1da177e4
LT
2446 }
2447 }
14fbf50d 2448 if (rc)
1bfe73c2 2449 goto remote_path_check;
7586b765 2450 tcon->seal = volume_info->seal;
f1987b44
JL
2451 write_lock(&cifs_tcp_ses_lock);
2452 list_add(&tcon->tcon_list, &pSesInfo->tcon_list);
2453 write_unlock(&cifs_tcp_ses_lock);
1da177e4 2454 }
3b795210
SF
2455
2456 /* we can have only one retry value for a connection
2457 to a share so for resources mounted more than once
2458 to the same server share the last value passed in
2459 for the retry flag is used */
7586b765
JL
2460 tcon->retry = volume_info->retry;
2461 tcon->nocase = volume_info->nocase;
2462 tcon->local_lease = volume_info->local_lease;
1da177e4 2463 }
4523cc30 2464 if (pSesInfo) {
1da177e4
LT
2465 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2466 sb->s_maxbytes = (u64) 1 << 63;
2467 } else
2468 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2469 }
2470
8af18971 2471 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
1da177e4
LT
2472 sb->s_time_gran = 100;
2473
1bfe73c2
IM
2474 if (rc)
2475 goto remote_path_check;
2476
d82c2df5 2477 cifs_sb->tcon = tcon;
c18c842b 2478
d82c2df5
SF
2479 /* do not care if following two calls succeed - informational */
2480 if (!tcon->ipc) {
2481 CIFSSMBQFSDeviceInfo(xid, tcon);
2482 CIFSSMBQFSAttributeInfo(xid, tcon);
2483 }
03a143c9 2484
d82c2df5
SF
2485 /* tell server which Unix caps we support */
2486 if (tcon->ses->capabilities & CAP_UNIX)
2487 /* reset of caps checks mount to see if unix extensions
2488 disabled for just this mount */
7586b765 2489 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
d82c2df5
SF
2490 else
2491 tcon->unix_ext = 0; /* server does not support them */
c18c842b 2492
d82c2df5
SF
2493 /* convert forward to back slashes in prepath here if needed */
2494 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2495 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
03a143c9 2496
d82c2df5
SF
2497 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2498 cifs_sb->rsize = 1024 * 127;
2499 cFYI(DBG2, ("no very large read support, rsize now 127K"));
1da177e4 2500 }
d82c2df5
SF
2501 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2502 cifs_sb->wsize = min(cifs_sb->wsize,
2503 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2504 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2505 cifs_sb->rsize = min(cifs_sb->rsize,
2506 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
1da177e4 2507
1bfe73c2
IM
2508remote_path_check:
2509 /* check if a whole path (including prepath) is not remote */
2510 if (!rc && cifs_sb->prepathlen && tcon) {
e4cce94c
IM
2511 /* build_path_to_root works only when we have a valid tcon */
2512 full_path = cifs_build_path_to_root(cifs_sb);
2513 if (full_path == NULL) {
2514 rc = -ENOMEM;
2515 goto mount_fail_check;
2516 }
2517 rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
1bfe73c2 2518 if (rc != -EREMOTE) {
e4cce94c
IM
2519 kfree(full_path);
2520 goto mount_fail_check;
2521 }
2522 kfree(full_path);
2523 }
2524
1bfe73c2
IM
2525 /* get referral if needed */
2526 if (rc == -EREMOTE) {
d036f50f 2527#ifdef CONFIG_CIFS_DFS_UPCALL
1bfe73c2
IM
2528 /* convert forward to back slashes in prepath here if needed */
2529 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2530 convert_delimiter(cifs_sb->prepath,
2531 CIFS_DIR_SEP(cifs_sb));
2532 full_path = build_unc_path_to_root(volume_info, cifs_sb);
2533 if (IS_ERR(full_path)) {
2534 rc = PTR_ERR(full_path);
2535 goto mount_fail_check;
2536 }
2537
2538 cFYI(1, ("Getting referral for: %s", full_path));
2539 rc = get_dfs_path(xid, pSesInfo , full_path + 1,
2540 cifs_sb->local_nls, &num_referrals, &referrals,
2541 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
2542 if (!rc && num_referrals > 0) {
2543 char *fake_devname = NULL;
2544
2545 if (mount_data != mount_data_global)
2546 kfree(mount_data);
2547 mount_data = cifs_compose_mount_options(
2548 cifs_sb->mountdata, full_path + 1,
2549 referrals, &fake_devname);
2550 kfree(fake_devname);
2551 free_dfs_info_array(referrals, num_referrals);
2552
2553 if (tcon)
2554 cifs_put_tcon(tcon);
2555 else if (pSesInfo)
2556 cifs_put_smb_ses(pSesInfo);
2557
2558 cleanup_volume_info(&volume_info);
2559 FreeXid(xid);
2560 kfree(full_path);
2561 goto try_mount_again;
2562 }
d036f50f
SF
2563#else /* No DFS support, return error on mount */
2564 rc = -EOPNOTSUPP;
2565#endif
1bfe73c2
IM
2566 }
2567
2568mount_fail_check:
2569 /* on error free sesinfo and tcon struct if needed */
2570 if (rc) {
2571 if (mount_data != mount_data_global)
2572 kfree(mount_data);
2573 /* If find_unc succeeded then rc == 0 so we can not end */
2574 /* up accidently freeing someone elses tcon struct */
2575 if (tcon)
2576 cifs_put_tcon(tcon);
2577 else if (pSesInfo)
2578 cifs_put_smb_ses(pSesInfo);
2579 else
2580 cifs_put_tcp_session(srvTcp);
2581 goto out;
2582 }
2583
7586b765 2584 /* volume_info->password is freed above when existing session found
1da177e4
LT
2585 (in which case it is not needed anymore) but when new sesion is created
2586 the password ptr is put in the new session structure (in which case the
2587 password will be freed at unmount time) */
70fe7dc0
JL
2588out:
2589 /* zero out password before freeing */
1bfe73c2 2590 cleanup_volume_info(&volume_info);
1da177e4
LT
2591 FreeXid(xid);
2592 return rc;
2593}
2594
1da177e4
LT
2595static int
2596CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
4b18f2a9 2597 struct cifsSesInfo *ses, bool *pNTLMv2_flag,
1da177e4
LT
2598 const struct nls_table *nls_codepage)
2599{
2600 struct smb_hdr *smb_buffer;
2601 struct smb_hdr *smb_buffer_response;
2602 SESSION_SETUP_ANDX *pSMB;
2603 SESSION_SETUP_ANDX *pSMBr;
2604 char *bcc_ptr;
2605 char *domain;
2606 int rc = 0;
2607 int remaining_words = 0;
2608 int bytes_returned = 0;
2609 int len;
6345a3a8 2610 int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
1da177e4
LT
2611 PNEGOTIATE_MESSAGE SecurityBlob;
2612 PCHALLENGE_MESSAGE SecurityBlob2;
2613 __u32 negotiate_flags, capabilities;
2614 __u16 count;
2615
12b3b8ff 2616 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
fb8c4b14 2617 if (ses == NULL)
1da177e4
LT
2618 return -EINVAL;
2619 domain = ses->domainName;
4b18f2a9 2620 *pNTLMv2_flag = false;
1da177e4
LT
2621 smb_buffer = cifs_buf_get();
2622 if (smb_buffer == NULL) {
2623 return -ENOMEM;
2624 }
2625 smb_buffer_response = smb_buffer;
2626 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2627 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2628
2629 /* send SMBsessionSetup here */
2630 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2631 NULL /* no tCon exists yet */ , 12 /* wct */ );
1982c344
SF
2632
2633 smb_buffer->Mid = GetNextMid(ses->server);
1da177e4
LT
2634 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2635 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2636
2637 pSMB->req.AndXCommand = 0xFF;
2638 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2639 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2640
fb8c4b14 2641 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1da177e4
LT
2642 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2643
2644 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2645 CAP_EXTENDED_SECURITY;
2646 if (ses->capabilities & CAP_UNICODE) {
2647 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2648 capabilities |= CAP_UNICODE;
2649 }
2650 if (ses->capabilities & CAP_STATUS32) {
2651 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2652 capabilities |= CAP_STATUS32;
2653 }
2654 if (ses->capabilities & CAP_DFS) {
2655 smb_buffer->Flags2 |= SMBFLG2_DFS;
2656 capabilities |= CAP_DFS;
2657 }
2658 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2659
2660 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2661 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2662 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2663 SecurityBlob->MessageType = NtLmNegotiate;
2664 negotiate_flags =
2665 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
12b3b8ff
SF
2666 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2667 NTLMSSP_NEGOTIATE_56 |
1da177e4 2668 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
fb8c4b14 2669 if (sign_CIFS_PDUs)
1da177e4 2670 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
fb8c4b14 2671/* if (ntlmv2_support)
3979877e 2672 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
1da177e4
LT
2673 /* setup pointers to domain name and workstation name */
2674 bcc_ptr += SecurityBlobLength;
2675
2676 SecurityBlob->WorkstationName.Buffer = 0;
2677 SecurityBlob->WorkstationName.Length = 0;
2678 SecurityBlob->WorkstationName.MaximumLength = 0;
2679
12b3b8ff
SF
2680 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2681 along with username on auth request (ie the response to challenge) */
2682 SecurityBlob->DomainName.Buffer = 0;
2683 SecurityBlob->DomainName.Length = 0;
2684 SecurityBlob->DomainName.MaximumLength = 0;
1da177e4
LT
2685 if (ses->capabilities & CAP_UNICODE) {
2686 if ((long) bcc_ptr % 2) {
2687 *bcc_ptr = 0;
2688 bcc_ptr++;
2689 }
2690
2691 bytes_returned =
e89dc920 2692 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
1da177e4
LT
2693 32, nls_codepage);
2694 bcc_ptr += 2 * bytes_returned;
2695 bytes_returned =
e9ff3990 2696 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
1da177e4
LT
2697 nls_codepage);
2698 bcc_ptr += 2 * bytes_returned;
2699 bcc_ptr += 2; /* null terminate Linux version */
2700 bytes_returned =
e89dc920 2701 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
1da177e4
LT
2702 64, nls_codepage);
2703 bcc_ptr += 2 * bytes_returned;
2704 *(bcc_ptr + 1) = 0;
2705 *(bcc_ptr + 2) = 0;
2706 bcc_ptr += 2; /* null terminate network opsys string */
2707 *(bcc_ptr + 1) = 0;
2708 *(bcc_ptr + 2) = 0;
2709 bcc_ptr += 2; /* null domain */
2710 } else { /* ASCII */
2711 strcpy(bcc_ptr, "Linux version ");
2712 bcc_ptr += strlen("Linux version ");
e9ff3990
SH
2713 strcpy(bcc_ptr, utsname()->release);
2714 bcc_ptr += strlen(utsname()->release) + 1;
1da177e4
LT
2715 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2716 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2717 bcc_ptr++; /* empty domain field */
2718 *bcc_ptr = 0;
2719 }
2720 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2721 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2722 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2723 smb_buffer->smb_buf_length += count;
2724 pSMB->req.ByteCount = cpu_to_le16(count);
2725
2726 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
133672ef 2727 &bytes_returned, CIFS_LONG_OP);
1da177e4
LT
2728
2729 if (smb_buffer_response->Status.CifsError ==
2730 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2731 rc = 0;
2732
2733 if (rc) {
2734/* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2735 } else if ((smb_buffer_response->WordCount == 3)
2736 || (smb_buffer_response->WordCount == 4)) {
2737 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2738 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2739
2740 if (action & GUEST_LOGIN)
61e74801 2741 cFYI(1, ("Guest login"));
50c2f753 2742 /* Do we want to set anything in SesInfo struct when guest login? */
1da177e4 2743
50c2f753
SF
2744 bcc_ptr = pByteArea(smb_buffer_response);
2745 /* response can have either 3 or 4 word count - Samba sends 3 */
1da177e4
LT
2746
2747 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2748 if (SecurityBlob2->MessageType != NtLmChallenge) {
61e74801 2749 cFYI(1, ("Unexpected NTLMSSP message type received %d",
1da177e4
LT
2750 SecurityBlob2->MessageType));
2751 } else if (ses) {
50c2f753 2752 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
12b3b8ff 2753 cFYI(1, ("UID = %d", ses->Suid));
1da177e4
LT
2754 if ((pSMBr->resp.hdr.WordCount == 3)
2755 || ((pSMBr->resp.hdr.WordCount == 4)
2756 && (blob_len <
2757 pSMBr->resp.ByteCount))) {
2758
2759 if (pSMBr->resp.hdr.WordCount == 4) {
2760 bcc_ptr += blob_len;
12b3b8ff 2761 cFYI(1, ("Security Blob Length %d",
1da177e4
LT
2762 blob_len));
2763 }
2764
12b3b8ff 2765 cFYI(1, ("NTLMSSP Challenge rcvd"));
1da177e4
LT
2766
2767 memcpy(ses->server->cryptKey,
2768 SecurityBlob2->Challenge,
2769 CIFS_CRYPTO_KEY_SIZE);
50c2f753 2770 if (SecurityBlob2->NegotiateFlags &
12b3b8ff 2771 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
4b18f2a9 2772 *pNTLMv2_flag = true;
1da177e4 2773
50c2f753
SF
2774 if ((SecurityBlob2->NegotiateFlags &
2775 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
1da177e4 2776 || (sign_CIFS_PDUs > 1))
50c2f753
SF
2777 ses->server->secMode |=
2778 SECMODE_SIGN_REQUIRED;
2779 if ((SecurityBlob2->NegotiateFlags &
1da177e4 2780 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
50c2f753 2781 ses->server->secMode |=
1da177e4
LT
2782 SECMODE_SIGN_ENABLED;
2783
2784 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2785 if ((long) (bcc_ptr) % 2) {
2786 remaining_words =
2787 (BCC(smb_buffer_response)
2788 - 1) / 2;
50c2f753
SF
2789 /* Must word align unicode strings */
2790 bcc_ptr++;
1da177e4
LT
2791 } else {
2792 remaining_words =
2793 BCC
2794 (smb_buffer_response) / 2;
2795 }
2796 len =
2797 UniStrnlen((wchar_t *) bcc_ptr,
2798 remaining_words - 1);
2799/* We look for obvious messed up bcc or strings in response so we do not go off
2800 the end since (at least) WIN2K and Windows XP have a major bug in not null
2801 terminating last Unicode string in response */
74496d36 2802 kfree(ses->serverOS);
1da177e4 2803 ses->serverOS =
e915fc49 2804 kzalloc(2 * (len + 1), GFP_KERNEL);
1da177e4 2805 cifs_strfromUCS_le(ses->serverOS,
e89dc920 2806 (__le16 *)
1da177e4
LT
2807 bcc_ptr, len,
2808 nls_codepage);
2809 bcc_ptr += 2 * (len + 1);
2810 remaining_words -= len + 1;
2811 ses->serverOS[2 * len] = 0;
2812 ses->serverOS[1 + (2 * len)] = 0;
2813 if (remaining_words > 0) {
2814 len = UniStrnlen((wchar_t *)
2815 bcc_ptr,
2816 remaining_words
2817 - 1);
cd49b492 2818 kfree(ses->serverNOS);
1da177e4 2819 ses->serverNOS =
e915fc49 2820 kzalloc(2 * (len + 1),
1da177e4
LT
2821 GFP_KERNEL);
2822 cifs_strfromUCS_le(ses->
2823 serverNOS,
e89dc920 2824 (__le16 *)
1da177e4
LT
2825 bcc_ptr,
2826 len,
2827 nls_codepage);
2828 bcc_ptr += 2 * (len + 1);
2829 ses->serverNOS[2 * len] = 0;
2830 ses->serverNOS[1 +
2831 (2 * len)] = 0;
2832 remaining_words -= len + 1;
2833 if (remaining_words > 0) {
50c2f753
SF
2834 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2835 /* last string not always null terminated
2836 (for e.g. for Windows XP & 2000) */
cd49b492 2837 kfree(ses->serverDomain);
1da177e4 2838 ses->serverDomain =
e915fc49 2839 kzalloc(2 *
1da177e4
LT
2840 (len +
2841 1),
2842 GFP_KERNEL);
2843 cifs_strfromUCS_le
e89dc920
SF
2844 (ses->serverDomain,
2845 (__le16 *)bcc_ptr,
2846 len, nls_codepage);
1da177e4
LT
2847 bcc_ptr +=
2848 2 * (len + 1);
e89dc920 2849 ses->serverDomain[2*len]
1da177e4 2850 = 0;
e89dc920
SF
2851 ses->serverDomain
2852 [1 + (2 * len)]
1da177e4
LT
2853 = 0;
2854 } /* else no more room so create dummy domain string */
a424f8bf 2855 else {
cd49b492 2856 kfree(ses->serverDomain);
1da177e4 2857 ses->serverDomain =
e915fc49 2858 kzalloc(2,
1da177e4 2859 GFP_KERNEL);
a424f8bf 2860 }
1da177e4 2861 } else { /* no room so create dummy domain and NOS string */
cd49b492 2862 kfree(ses->serverDomain);
1da177e4 2863 ses->serverDomain =
e915fc49 2864 kzalloc(2, GFP_KERNEL);
cd49b492 2865 kfree(ses->serverNOS);
1da177e4 2866 ses->serverNOS =
e915fc49 2867 kzalloc(2, GFP_KERNEL);
1da177e4
LT
2868 }
2869 } else { /* ASCII */
2870 len = strnlen(bcc_ptr, 1024);
2871 if (((long) bcc_ptr + len) - (long)
2872 pByteArea(smb_buffer_response)
2873 <= BCC(smb_buffer_response)) {
74496d36 2874 kfree(ses->serverOS);
1da177e4 2875 ses->serverOS =
e915fc49 2876 kzalloc(len + 1,
1da177e4
LT
2877 GFP_KERNEL);
2878 strncpy(ses->serverOS,
2879 bcc_ptr, len);
2880
2881 bcc_ptr += len;
2882 bcc_ptr[0] = 0; /* null terminate string */
2883 bcc_ptr++;
2884
2885 len = strnlen(bcc_ptr, 1024);
cd49b492 2886 kfree(ses->serverNOS);
1da177e4 2887 ses->serverNOS =
e915fc49 2888 kzalloc(len + 1,
1da177e4
LT
2889 GFP_KERNEL);
2890 strncpy(ses->serverNOS, bcc_ptr, len);
2891 bcc_ptr += len;
2892 bcc_ptr[0] = 0;
2893 bcc_ptr++;
2894
2895 len = strnlen(bcc_ptr, 1024);
cd49b492 2896 kfree(ses->serverDomain);
1da177e4 2897 ses->serverDomain =
e915fc49 2898 kzalloc(len + 1,
1da177e4 2899 GFP_KERNEL);
50c2f753
SF
2900 strncpy(ses->serverDomain,
2901 bcc_ptr, len);
1da177e4
LT
2902 bcc_ptr += len;
2903 bcc_ptr[0] = 0;
2904 bcc_ptr++;
2905 } else
2906 cFYI(1,
63135e08
SF
2907 ("field of length %d "
2908 "extends beyond end of smb",
1da177e4
LT
2909 len));
2910 }
2911 } else {
50c2f753
SF
2912 cERROR(1, ("Security Blob Length extends beyond"
2913 " end of SMB"));
1da177e4
LT
2914 }
2915 } else {
2916 cERROR(1, ("No session structure passed in."));
2917 }
2918 } else {
61e74801 2919 cERROR(1, ("Invalid Word count %d:",
1da177e4
LT
2920 smb_buffer_response->WordCount));
2921 rc = -EIO;
2922 }
2923
a8a11d39 2924 cifs_buf_release(smb_buffer);
1da177e4
LT
2925
2926 return rc;
2927}
20418acd 2928
1da177e4
LT
2929static int
2930CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
4b18f2a9 2931 char *ntlm_session_key, bool ntlmv2_flag,
6345a3a8 2932 const struct nls_table *nls_codepage)
1da177e4
LT
2933{
2934 struct smb_hdr *smb_buffer;
2935 struct smb_hdr *smb_buffer_response;
2936 SESSION_SETUP_ANDX *pSMB;
2937 SESSION_SETUP_ANDX *pSMBr;
2938 char *bcc_ptr;
2939 char *user;
2940 char *domain;
2941 int rc = 0;
2942 int remaining_words = 0;
2943 int bytes_returned = 0;
2944 int len;
6345a3a8 2945 int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
1da177e4
LT
2946 PAUTHENTICATE_MESSAGE SecurityBlob;
2947 __u32 negotiate_flags, capabilities;
2948 __u16 count;
2949
2950 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
fb8c4b14 2951 if (ses == NULL)
1da177e4
LT
2952 return -EINVAL;
2953 user = ses->userName;
2954 domain = ses->domainName;
2955 smb_buffer = cifs_buf_get();
2956 if (smb_buffer == NULL) {
2957 return -ENOMEM;
2958 }
2959 smb_buffer_response = smb_buffer;
6345a3a8
CG
2960 pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
2961 pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
1da177e4
LT
2962
2963 /* send SMBsessionSetup here */
2964 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2965 NULL /* no tCon exists yet */ , 12 /* wct */ );
1982c344
SF
2966
2967 smb_buffer->Mid = GetNextMid(ses->server);
1da177e4
LT
2968 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2969 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2970 pSMB->req.AndXCommand = 0xFF;
2971 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2972 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2973
2974 pSMB->req.hdr.Uid = ses->Suid;
2975
fb8c4b14 2976 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1da177e4
LT
2977 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2978
2979 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
6345a3a8 2980 CAP_EXTENDED_SECURITY;
1da177e4
LT
2981 if (ses->capabilities & CAP_UNICODE) {
2982 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2983 capabilities |= CAP_UNICODE;
2984 }
2985 if (ses->capabilities & CAP_STATUS32) {
2986 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2987 capabilities |= CAP_STATUS32;
2988 }
2989 if (ses->capabilities & CAP_DFS) {
2990 smb_buffer->Flags2 |= SMBFLG2_DFS;
2991 capabilities |= CAP_DFS;
2992 }
2993 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2994
6345a3a8
CG
2995 bcc_ptr = (char *)&pSMB->req.SecurityBlob;
2996 SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
1da177e4
LT
2997 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2998 SecurityBlob->MessageType = NtLmAuthenticate;
2999 bcc_ptr += SecurityBlobLength;
6345a3a8
CG
3000 negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
3001 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
3002 0x80000000 | NTLMSSP_NEGOTIATE_128;
fb8c4b14 3003 if (sign_CIFS_PDUs)
1da177e4 3004 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
fb8c4b14 3005 if (ntlmv2_flag)
1da177e4
LT
3006 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
3007
3008/* setup pointers to domain name and workstation name */
3009
3010 SecurityBlob->WorkstationName.Buffer = 0;
3011 SecurityBlob->WorkstationName.Length = 0;
3012 SecurityBlob->WorkstationName.MaximumLength = 0;
3013 SecurityBlob->SessionKey.Length = 0;
3014 SecurityBlob->SessionKey.MaximumLength = 0;
3015 SecurityBlob->SessionKey.Buffer = 0;
3016
3017 SecurityBlob->LmChallengeResponse.Length = 0;
3018 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
3019 SecurityBlob->LmChallengeResponse.Buffer = 0;
3020
3021 SecurityBlob->NtChallengeResponse.Length =
7c7b25bc 3022 cpu_to_le16(CIFS_SESS_KEY_SIZE);
1da177e4 3023 SecurityBlob->NtChallengeResponse.MaximumLength =
7c7b25bc
SF
3024 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3025 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
1da177e4
LT
3026 SecurityBlob->NtChallengeResponse.Buffer =
3027 cpu_to_le32(SecurityBlobLength);
7c7b25bc
SF
3028 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
3029 bcc_ptr += CIFS_SESS_KEY_SIZE;
1da177e4
LT
3030
3031 if (ses->capabilities & CAP_UNICODE) {
3032 if (domain == NULL) {
3033 SecurityBlob->DomainName.Buffer = 0;
3034 SecurityBlob->DomainName.Length = 0;
3035 SecurityBlob->DomainName.MaximumLength = 0;
3036 } else {
77159b4d 3037 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
1da177e4 3038 nls_codepage);
77159b4d 3039 ln *= 2;
1da177e4 3040 SecurityBlob->DomainName.MaximumLength =
77159b4d 3041 cpu_to_le16(ln);
1da177e4
LT
3042 SecurityBlob->DomainName.Buffer =
3043 cpu_to_le32(SecurityBlobLength);
77159b4d
SF
3044 bcc_ptr += ln;
3045 SecurityBlobLength += ln;
3046 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
1da177e4
LT
3047 }
3048 if (user == NULL) {
3049 SecurityBlob->UserName.Buffer = 0;
3050 SecurityBlob->UserName.Length = 0;
3051 SecurityBlob->UserName.MaximumLength = 0;
3052 } else {
77159b4d 3053 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
1da177e4 3054 nls_codepage);
77159b4d 3055 ln *= 2;
1da177e4 3056 SecurityBlob->UserName.MaximumLength =
77159b4d 3057 cpu_to_le16(ln);
1da177e4
LT
3058 SecurityBlob->UserName.Buffer =
3059 cpu_to_le32(SecurityBlobLength);
77159b4d
SF
3060 bcc_ptr += ln;
3061 SecurityBlobLength += ln;
3062 SecurityBlob->UserName.Length = cpu_to_le16(ln);
1da177e4
LT
3063 }
3064
63135e08
SF
3065 /* SecurityBlob->WorkstationName.Length =
3066 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
1da177e4 3067 SecurityBlob->WorkstationName.Length *= 2;
63135e08
SF
3068 SecurityBlob->WorkstationName.MaximumLength =
3069 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3070 SecurityBlob->WorkstationName.Buffer =
3071 cpu_to_le32(SecurityBlobLength);
1da177e4
LT
3072 bcc_ptr += SecurityBlob->WorkstationName.Length;
3073 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
63135e08
SF
3074 SecurityBlob->WorkstationName.Length =
3075 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
1da177e4
LT
3076
3077 if ((long) bcc_ptr % 2) {
3078 *bcc_ptr = 0;
3079 bcc_ptr++;
3080 }
3081 bytes_returned =
e89dc920 3082 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
1da177e4
LT
3083 32, nls_codepage);
3084 bcc_ptr += 2 * bytes_returned;
3085 bytes_returned =
e9ff3990 3086 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
1da177e4
LT
3087 nls_codepage);
3088 bcc_ptr += 2 * bytes_returned;
3089 bcc_ptr += 2; /* null term version string */
3090 bytes_returned =
e89dc920 3091 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
1da177e4
LT
3092 64, nls_codepage);
3093 bcc_ptr += 2 * bytes_returned;
3094 *(bcc_ptr + 1) = 0;
3095 *(bcc_ptr + 2) = 0;
3096 bcc_ptr += 2; /* null terminate network opsys string */
3097 *(bcc_ptr + 1) = 0;
3098 *(bcc_ptr + 2) = 0;
3099 bcc_ptr += 2; /* null domain */
3100 } else { /* ASCII */
3101 if (domain == NULL) {
3102 SecurityBlob->DomainName.Buffer = 0;
3103 SecurityBlob->DomainName.Length = 0;
3104 SecurityBlob->DomainName.MaximumLength = 0;
3105 } else {
77159b4d 3106 __u16 ln;
1da177e4
LT
3107 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3108 strncpy(bcc_ptr, domain, 63);
77159b4d 3109 ln = strnlen(domain, 64);
1da177e4 3110 SecurityBlob->DomainName.MaximumLength =
77159b4d 3111 cpu_to_le16(ln);
1da177e4
LT
3112 SecurityBlob->DomainName.Buffer =
3113 cpu_to_le32(SecurityBlobLength);
77159b4d
SF
3114 bcc_ptr += ln;
3115 SecurityBlobLength += ln;
3116 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
1da177e4
LT
3117 }
3118 if (user == NULL) {
3119 SecurityBlob->UserName.Buffer = 0;
3120 SecurityBlob->UserName.Length = 0;
3121 SecurityBlob->UserName.MaximumLength = 0;
3122 } else {
77159b4d 3123 __u16 ln;
1da177e4 3124 strncpy(bcc_ptr, user, 63);
77159b4d
SF
3125 ln = strnlen(user, 64);
3126 SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
1da177e4 3127 SecurityBlob->UserName.Buffer =
77159b4d
SF
3128 cpu_to_le32(SecurityBlobLength);
3129 bcc_ptr += ln;
3130 SecurityBlobLength += ln;
3131 SecurityBlob->UserName.Length = cpu_to_le16(ln);
1da177e4
LT
3132 }
3133 /* BB fill in our workstation name if known BB */
3134
3135 strcpy(bcc_ptr, "Linux version ");
3136 bcc_ptr += strlen("Linux version ");
e9ff3990
SH
3137 strcpy(bcc_ptr, utsname()->release);
3138 bcc_ptr += strlen(utsname()->release) + 1;
1da177e4
LT
3139 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3140 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3141 bcc_ptr++; /* null domain */
3142 *bcc_ptr = 0;
3143 }
3144 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3145 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3146 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3147 smb_buffer->smb_buf_length += count;
3148 pSMB->req.ByteCount = cpu_to_le16(count);
3149
3150 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
133672ef 3151 &bytes_returned, CIFS_LONG_OP);
1da177e4 3152 if (rc) {
6345a3a8
CG
3153/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3154 } else if ((smb_buffer_response->WordCount == 3) ||
3155 (smb_buffer_response->WordCount == 4)) {
1da177e4 3156 __u16 action = le16_to_cpu(pSMBr->resp.Action);
6345a3a8 3157 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
1da177e4 3158 if (action & GUEST_LOGIN)
61e74801 3159 cFYI(1, ("Guest login")); /* BB Should we set anything
50c2f753
SF
3160 in SesInfo struct ? */
3161/* if (SecurityBlob2->MessageType != NtLm??) {
3162 cFYI("Unexpected message type on auth response is %d"));
3163 } */
3164
1da177e4
LT
3165 if (ses) {
3166 cFYI(1,
50c2f753 3167 ("Check challenge UID %d vs auth response UID %d",
1da177e4 3168 ses->Suid, smb_buffer_response->Uid));
50c2f753
SF
3169 /* UID left in wire format */
3170 ses->Suid = smb_buffer_response->Uid;
3171 bcc_ptr = pByteArea(smb_buffer_response);
3172 /* response can have either 3 or 4 word count - Samba sends 3 */
1da177e4
LT
3173 if ((pSMBr->resp.hdr.WordCount == 3)
3174 || ((pSMBr->resp.hdr.WordCount == 4)
3175 && (blob_len <
3176 pSMBr->resp.ByteCount))) {
3177 if (pSMBr->resp.hdr.WordCount == 4) {
3178 bcc_ptr +=
3179 blob_len;
3180 cFYI(1,
3181 ("Security Blob Length %d ",
3182 blob_len));
3183 }
3184
3185 cFYI(1,
3186 ("NTLMSSP response to Authenticate "));
3187
3188 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3189 if ((long) (bcc_ptr) % 2) {
3190 remaining_words =
3191 (BCC(smb_buffer_response)
3192 - 1) / 2;
3193 bcc_ptr++; /* Unicode strings must be word aligned */
3194 } else {
3195 remaining_words = BCC(smb_buffer_response) / 2;
3196 }
77159b4d
SF
3197 len = UniStrnlen((wchar_t *) bcc_ptr,
3198 remaining_words - 1);
1da177e4
LT
3199/* We look for obvious messed up bcc or strings in response so we do not go off
3200 the end since (at least) WIN2K and Windows XP have a major bug in not null
3201 terminating last Unicode string in response */
74496d36 3202 kfree(ses->serverOS);
1da177e4 3203 ses->serverOS =
e915fc49 3204 kzalloc(2 * (len + 1), GFP_KERNEL);
1da177e4 3205 cifs_strfromUCS_le(ses->serverOS,
e89dc920 3206 (__le16 *)
1da177e4
LT
3207 bcc_ptr, len,
3208 nls_codepage);
3209 bcc_ptr += 2 * (len + 1);
3210 remaining_words -= len + 1;
3211 ses->serverOS[2 * len] = 0;
3212 ses->serverOS[1 + (2 * len)] = 0;
3213 if (remaining_words > 0) {
3214 len = UniStrnlen((wchar_t *)
3215 bcc_ptr,
3216 remaining_words
3217 - 1);
cd49b492 3218 kfree(ses->serverNOS);
1da177e4 3219 ses->serverNOS =
e915fc49 3220 kzalloc(2 * (len + 1),
1da177e4
LT
3221 GFP_KERNEL);
3222 cifs_strfromUCS_le(ses->
3223 serverNOS,
e89dc920 3224 (__le16 *)
1da177e4
LT
3225 bcc_ptr,
3226 len,
3227 nls_codepage);
3228 bcc_ptr += 2 * (len + 1);
3229 ses->serverNOS[2 * len] = 0;
3230 ses->serverNOS[1+(2*len)] = 0;
3231 remaining_words -= len + 1;
3232 if (remaining_words > 0) {
50c2f753 3233 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
1da177e4 3234 /* last string not always null terminated (e.g. for Windows XP & 2000) */
74496d36 3235 kfree(ses->serverDomain);
1da177e4 3236 ses->serverDomain =
e915fc49 3237 kzalloc(2 *
1da177e4
LT
3238 (len +
3239 1),
3240 GFP_KERNEL);
3241 cifs_strfromUCS_le
3242 (ses->
3243 serverDomain,
e89dc920 3244 (__le16 *)
1da177e4
LT
3245 bcc_ptr, len,
3246 nls_codepage);
3247 bcc_ptr +=
3248 2 * (len + 1);
3249 ses->
3250 serverDomain[2
3251 * len]
3252 = 0;
3253 ses->
3254 serverDomain[1
3255 +
3256 (2
3257 *
3258 len)]
3259 = 0;
3260 } /* else no more room so create dummy domain string */
a424f8bf 3261 else {
74496d36 3262 kfree(ses->serverDomain);
e915fc49 3263 ses->serverDomain = kzalloc(2,GFP_KERNEL);
a424f8bf 3264 }
1da177e4 3265 } else { /* no room so create dummy domain and NOS string */
74496d36 3266 kfree(ses->serverDomain);
e915fc49 3267 ses->serverDomain = kzalloc(2, GFP_KERNEL);
cd49b492 3268 kfree(ses->serverNOS);
e915fc49 3269 ses->serverNOS = kzalloc(2, GFP_KERNEL);
1da177e4
LT
3270 }
3271 } else { /* ASCII */
3272 len = strnlen(bcc_ptr, 1024);
50c2f753
SF
3273 if (((long) bcc_ptr + len) -
3274 (long) pByteArea(smb_buffer_response)
63135e08 3275 <= BCC(smb_buffer_response)) {
74496d36 3276 kfree(ses->serverOS);
77159b4d 3277 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
1da177e4
LT
3278 strncpy(ses->serverOS,bcc_ptr, len);
3279
3280 bcc_ptr += len;
3281 bcc_ptr[0] = 0; /* null terminate the string */
3282 bcc_ptr++;
3283
3284 len = strnlen(bcc_ptr, 1024);
cd49b492 3285 kfree(ses->serverNOS);
50c2f753
SF
3286 ses->serverNOS = kzalloc(len+1,
3287 GFP_KERNEL);
63135e08
SF
3288 strncpy(ses->serverNOS,
3289 bcc_ptr, len);
1da177e4
LT
3290 bcc_ptr += len;
3291 bcc_ptr[0] = 0;
3292 bcc_ptr++;
3293
3294 len = strnlen(bcc_ptr, 1024);
74496d36 3295 kfree(ses->serverDomain);
63135e08
SF
3296 ses->serverDomain =
3297 kzalloc(len+1,
3298 GFP_KERNEL);
3299 strncpy(ses->serverDomain,
3300 bcc_ptr, len);
1da177e4
LT
3301 bcc_ptr += len;
3302 bcc_ptr[0] = 0;
3303 bcc_ptr++;
3304 } else
6345a3a8 3305 cFYI(1, ("field of length %d "
63135e08 3306 "extends beyond end of smb ",
1da177e4
LT
3307 len));
3308 }
3309 } else {
6345a3a8 3310 cERROR(1, ("Security Blob extends beyond end "
63135e08 3311 "of SMB"));
1da177e4
LT
3312 }
3313 } else {
3314 cERROR(1, ("No session structure passed in."));
3315 }
3316 } else {
6345a3a8 3317 cERROR(1, ("Invalid Word count %d: ",
1da177e4
LT
3318 smb_buffer_response->WordCount));
3319 rc = -EIO;
3320 }
3321
a8a11d39 3322 cifs_buf_release(smb_buffer);
1da177e4
LT
3323
3324 return rc;
3325}
3326
3327int
3328CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3329 const char *tree, struct cifsTconInfo *tcon,
3330 const struct nls_table *nls_codepage)
3331{
3332 struct smb_hdr *smb_buffer;
3333 struct smb_hdr *smb_buffer_response;
3334 TCONX_REQ *pSMB;
3335 TCONX_RSP *pSMBr;
3336 unsigned char *bcc_ptr;
3337 int rc = 0;
cc20c031 3338 int length, bytes_left;
1da177e4
LT
3339 __u16 count;
3340
3341 if (ses == NULL)
3342 return -EIO;
3343
3344 smb_buffer = cifs_buf_get();
3345 if (smb_buffer == NULL) {
3346 return -ENOMEM;
3347 }
3348 smb_buffer_response = smb_buffer;
3349
3350 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3351 NULL /*no tid */ , 4 /*wct */ );
1982c344
SF
3352
3353 smb_buffer->Mid = GetNextMid(ses->server);
1da177e4
LT
3354 smb_buffer->Uid = ses->Suid;
3355 pSMB = (TCONX_REQ *) smb_buffer;
3356 pSMBr = (TCONX_RSP *) smb_buffer_response;
3357
3358 pSMB->AndXCommand = 0xFF;
3359 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
1da177e4 3360 bcc_ptr = &pSMB->Password[0];
fb8c4b14 3361 if ((ses->server->secMode) & SECMODE_USER) {
eeac8047 3362 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
7c7b25bc 3363 *bcc_ptr = 0; /* password is null byte */
eeac8047 3364 bcc_ptr++; /* skip password */
7c7b25bc 3365 /* already aligned so no need to do it below */
eeac8047 3366 } else {
7c7b25bc 3367 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
eeac8047
SF
3368 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3369 specified as required (when that support is added to
3370 the vfs in the future) as only NTLM or the much
7c7b25bc 3371 weaker LANMAN (which we do not send by default) is accepted
eeac8047
SF
3372 by Samba (not sure whether other servers allow
3373 NTLMv2 password here) */
7c7b25bc 3374#ifdef CONFIG_CIFS_WEAK_PW_HASH
50c2f753 3375 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
00e485b0
JL
3376 (ses->server->secType == LANMAN))
3377 calc_lanman_hash(tcon->password, ses->server->cryptKey,
4e53a3fb
JL
3378 ses->server->secMode &
3379 SECMODE_PW_ENCRYPT ? true : false,
3380 bcc_ptr);
7c7b25bc
SF
3381 else
3382#endif /* CIFS_WEAK_PW_HASH */
00e485b0 3383 SMBNTencrypt(tcon->password, ses->server->cryptKey,
eeac8047
SF
3384 bcc_ptr);
3385
7c7b25bc 3386 bcc_ptr += CIFS_SESS_KEY_SIZE;
fb8c4b14 3387 if (ses->capabilities & CAP_UNICODE) {
7c7b25bc
SF
3388 /* must align unicode strings */
3389 *bcc_ptr = 0; /* null byte password */
3390 bcc_ptr++;
3391 }
eeac8047 3392 }
1da177e4 3393
50c2f753 3394 if (ses->server->secMode &
a878fb22 3395 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1da177e4
LT
3396 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3397
3398 if (ses->capabilities & CAP_STATUS32) {
3399 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3400 }
3401 if (ses->capabilities & CAP_DFS) {
3402 smb_buffer->Flags2 |= SMBFLG2_DFS;
3403 }
3404 if (ses->capabilities & CAP_UNICODE) {
3405 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3406 length =
50c2f753
SF
3407 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3408 6 /* max utf8 char length in bytes */ *
a878fb22
SF
3409 (/* server len*/ + 256 /* share len */), nls_codepage);
3410 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
1da177e4
LT
3411 bcc_ptr += 2; /* skip trailing null */
3412 } else { /* ASCII */
1da177e4
LT
3413 strcpy(bcc_ptr, tree);
3414 bcc_ptr += strlen(tree) + 1;
3415 }
3416 strcpy(bcc_ptr, "?????");
3417 bcc_ptr += strlen("?????");
3418 bcc_ptr += 1;
3419 count = bcc_ptr - &pSMB->Password[0];
3420 pSMB->hdr.smb_buf_length += count;
3421 pSMB->ByteCount = cpu_to_le16(count);
3422
133672ef
SF
3423 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3424 CIFS_STD_OP);
1da177e4 3425
1da177e4
LT
3426 /* above now done in SendReceive */
3427 if ((rc == 0) && (tcon != NULL)) {
3428 tcon->tidStatus = CifsGood;
3b795210 3429 tcon->need_reconnect = false;
1da177e4
LT
3430 tcon->tid = smb_buffer_response->Tid;
3431 bcc_ptr = pByteArea(smb_buffer_response);
cc20c031
JL
3432 bytes_left = BCC(smb_buffer_response);
3433 length = strnlen(bcc_ptr, bytes_left - 2);
3434
50c2f753 3435 /* skip service field (NB: this field is always ASCII) */
7f8ed420
SF
3436 if (length == 3) {
3437 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3438 (bcc_ptr[2] == 'C')) {
3439 cFYI(1, ("IPC connection"));
3440 tcon->ipc = 1;
3441 }
3442 } else if (length == 2) {
3443 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3444 /* the most common case */
3445 cFYI(1, ("disk share connection"));
3446 }
3447 }
50c2f753 3448 bcc_ptr += length + 1;
cc20c031 3449 bytes_left -= (length + 1);
1da177e4 3450 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
cc20c031
JL
3451
3452 /* mostly informational -- no need to fail on error here */
3453 tcon->nativeFileSystem = cifs_strndup(bcc_ptr, bytes_left,
3454 smb_buffer->Flags2 &
3455 SMBFLG2_UNICODE,
3456 nls_codepage);
3457
3458 cFYI(1, ("nativeFileSystem=%s", tcon->nativeFileSystem));
3459
fb8c4b14 3460 if ((smb_buffer_response->WordCount == 3) ||
1a4e15a0
SF
3461 (smb_buffer_response->WordCount == 7))
3462 /* field is in same location */
3979877e
SF
3463 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3464 else
3465 tcon->Flags = 0;
1da177e4
LT
3466 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3467 } else if ((rc == 0) && tcon == NULL) {
50c2f753 3468 /* all we need to save for IPC$ connection */
1da177e4
LT
3469 ses->ipc_tid = smb_buffer_response->Tid;
3470 }
3471
a8a11d39 3472 cifs_buf_release(smb_buffer);
1da177e4
LT
3473 return rc;
3474}
3475
3476int
3477cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3478{
3479 int rc = 0;
50c2f753 3480 char *tmp;
1da177e4 3481
f1987b44
JL
3482 if (cifs_sb->tcon)
3483 cifs_put_tcon(cifs_sb->tcon);
50c2f753 3484
1da177e4 3485 cifs_sb->tcon = NULL;
2fe87f02
SF
3486 tmp = cifs_sb->prepath;
3487 cifs_sb->prepathlen = 0;
3488 cifs_sb->prepath = NULL;
3489 kfree(tmp);
1da177e4 3490
88e7d705 3491 return rc;
50c2f753 3492}
1da177e4
LT
3493
3494int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
50c2f753 3495 struct nls_table *nls_info)
1da177e4
LT
3496{
3497 int rc = 0;
7c7b25bc 3498 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
4b18f2a9 3499 bool ntlmv2_flag = false;
ad009ac9 3500 int first_time = 0;
cb7691b6 3501 struct TCP_Server_Info *server = pSesInfo->server;
1da177e4
LT
3502
3503 /* what if server changes its buffer size after dropping the session? */
cb7691b6 3504 if (server->maxBuf == 0) /* no need to send on reconnect */ {
1da177e4 3505 rc = CIFSSMBNegotiate(xid, pSesInfo);
cb7691b6
JL
3506 if (rc == -EAGAIN) {
3507 /* retry only once on 1st time connection */
1da177e4 3508 rc = CIFSSMBNegotiate(xid, pSesInfo);
50c2f753 3509 if (rc == -EAGAIN)
1da177e4
LT
3510 rc = -EHOSTDOWN;
3511 }
fb8c4b14 3512 if (rc == 0) {
1da177e4 3513 spin_lock(&GlobalMid_Lock);
cb7691b6
JL
3514 if (server->tcpStatus != CifsExiting)
3515 server->tcpStatus = CifsGood;
1da177e4
LT
3516 else
3517 rc = -EHOSTDOWN;
3518 spin_unlock(&GlobalMid_Lock);
3519
3520 }
ad009ac9 3521 first_time = 1;
1da177e4 3522 }
26b994fa
SF
3523
3524 if (rc)
3525 goto ss_err_exit;
3526
3527 pSesInfo->flags = 0;
cb7691b6 3528 pSesInfo->capabilities = server->capabilities;
26b994fa
SF
3529 if (linuxExtEnabled == 0)
3530 pSesInfo->capabilities &= (~CAP_UNIX);
20418acd 3531
26b994fa 3532 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
cb7691b6
JL
3533 server->secMode, server->capabilities, server->timeAdj));
3534
20418acd 3535 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
26b994fa
SF
3536 if (rc) {
3537 cERROR(1, ("Send error in SessSetup = %d", rc));
3538 } else {
3539 cFYI(1, ("CIFS Session Established successfully"));
20418acd
SF
3540 spin_lock(&GlobalMid_Lock);
3541 pSesInfo->status = CifsGood;
3542 pSesInfo->need_reconnect = false;
3543 spin_unlock(&GlobalMid_Lock);
1da177e4 3544 }
26b994fa 3545
1da177e4
LT
3546ss_err_exit:
3547 return rc;
3548}
3549