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