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