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