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