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