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