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