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