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