cifs: don't declare smb_vol info on the stack
[deliverable/linux.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
63c038c2
JL
1420static struct TCP_Server_Info *
1421cifs_get_tcp_session(struct smb_vol *volume_info)
1422{
1423 struct TCP_Server_Info *tcp_ses = NULL;
1424 struct sockaddr addr;
1425 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
1426 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
1427 int rc;
1428
1429 memset(&addr, 0, sizeof(struct sockaddr));
1430
1431 if (volume_info->UNCip && volume_info->UNC) {
1432 rc = cifs_inet_pton(AF_INET, volume_info->UNCip,
1433 &sin_server->sin_addr.s_addr);
1434
1435 if (rc <= 0) {
1436 /* not ipv4 address, try ipv6 */
1437 rc = cifs_inet_pton(AF_INET6, volume_info->UNCip,
1438 &sin_server6->sin6_addr.in6_u);
1439 if (rc > 0)
1440 addr.sa_family = AF_INET6;
1441 } else {
1442 addr.sa_family = AF_INET;
1443 }
1444
1445 if (rc <= 0) {
1446 /* we failed translating address */
1447 rc = -EINVAL;
1448 goto out_err;
1449 }
1450
1451 cFYI(1, ("UNC: %s ip: %s", volume_info->UNC,
1452 volume_info->UNCip));
1453 } else if (volume_info->UNCip) {
1454 /* BB using ip addr as tcp_ses name to connect to the
1455 DFS root below */
1456 cERROR(1, ("Connecting to DFS root not implemented yet"));
1457 rc = -EINVAL;
1458 goto out_err;
1459 } else /* which tcp_sess DFS root would we conect to */ {
1460 cERROR(1,
1461 ("CIFS mount error: No UNC path (e.g. -o "
1462 "unc=//192.168.1.100/public) specified"));
1463 rc = -EINVAL;
1464 goto out_err;
1465 }
1466
1467 /* see if we already have a matching tcp_ses */
1468 tcp_ses = cifs_find_tcp_session(&addr);
1469 if (tcp_ses)
1470 return tcp_ses;
1471
1472 tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1473 if (!tcp_ses) {
1474 rc = -ENOMEM;
1475 goto out_err;
1476 }
1477
1478 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1479 if (IS_ERR(tcp_ses->hostname)) {
1480 rc = PTR_ERR(tcp_ses->hostname);
1481 goto out_err;
1482 }
1483
1484 tcp_ses->noblocksnd = volume_info->noblocksnd;
1485 tcp_ses->noautotune = volume_info->noautotune;
1486 atomic_set(&tcp_ses->inFlight, 0);
1487 init_waitqueue_head(&tcp_ses->response_q);
1488 init_waitqueue_head(&tcp_ses->request_q);
1489 INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
1490 mutex_init(&tcp_ses->srv_mutex);
1491 memcpy(tcp_ses->workstation_RFC1001_name,
1492 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1493 memcpy(tcp_ses->server_RFC1001_name,
1494 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1495 tcp_ses->sequence_number = 0;
1496 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1497 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1498
1499 /*
1500 * at this point we are the only ones with the pointer
1501 * to the struct since the kernel thread not created yet
1502 * no need to spinlock this init of tcpStatus or srv_count
1503 */
1504 tcp_ses->tcpStatus = CifsNew;
1505 ++tcp_ses->srv_count;
1506
1507 if (addr.sa_family == AF_INET6) {
1508 cFYI(1, ("attempting ipv6 connect"));
1509 /* BB should we allow ipv6 on port 139? */
1510 /* other OS never observed in Wild doing 139 with v6 */
1511 memcpy(&tcp_ses->addr.sockAddr6, sin_server6,
1512 sizeof(struct sockaddr_in6));
1513 sin_server6->sin6_port = htons(volume_info->port);
1514 rc = ipv6_connect(sin_server6, &tcp_ses->ssocket,
1515 volume_info->noblocksnd);
1516 } else {
1517 memcpy(&tcp_ses->addr.sockAddr, sin_server,
1518 sizeof(struct sockaddr_in));
1519 sin_server->sin_port = htons(volume_info->port);
1520 rc = ipv4_connect(sin_server, &tcp_ses->ssocket,
1521 volume_info->source_rfc1001_name,
1522 volume_info->target_rfc1001_name,
1523 volume_info->noblocksnd,
1524 volume_info->noautotune);
1525 }
1526 if (rc < 0) {
1527 cERROR(1, ("Error connecting to socket. Aborting operation"));
1528 goto out_err;
1529 }
1530
1531 /*
1532 * since we're in a cifs function already, we know that
1533 * this will succeed. No need for try_module_get().
1534 */
1535 __module_get(THIS_MODULE);
1536 tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread,
1537 tcp_ses, "cifsd");
1538 if (IS_ERR(tcp_ses->tsk)) {
1539 rc = PTR_ERR(tcp_ses->tsk);
1540 cERROR(1, ("error %d create cifsd thread", rc));
1541 module_put(THIS_MODULE);
1542 goto out_err;
1543 }
1544
1545 /* thread spawned, put it on the list */
1546 write_lock(&cifs_tcp_ses_lock);
1547 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1548 write_unlock(&cifs_tcp_ses_lock);
1549
1550 return tcp_ses;
1551
1552out_err:
1553 if (tcp_ses) {
1554 kfree(tcp_ses->hostname);
1555 if (tcp_ses->ssocket)
1556 sock_release(tcp_ses->ssocket);
1557 kfree(tcp_ses);
1558 }
1559 return ERR_PTR(rc);
1560}
1561
14fbf50d
JL
1562static struct cifsSesInfo *
1563cifs_find_smb_ses(struct TCP_Server_Info *server, char *username)
1564{
1565 struct list_head *tmp;
1566 struct cifsSesInfo *ses;
1567
1568 write_lock(&cifs_tcp_ses_lock);
1569 list_for_each(tmp, &server->smb_ses_list) {
1570 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
1571 if (strncmp(ses->userName, username, MAX_USERNAME_SIZE))
1572 continue;
1573
1574 ++ses->ses_count;
1575 write_unlock(&cifs_tcp_ses_lock);
1576 return ses;
1577 }
1578 write_unlock(&cifs_tcp_ses_lock);
1579 return NULL;
1580}
1581
1582static void
1583cifs_put_smb_ses(struct cifsSesInfo *ses)
1584{
1585 int xid;
1586 struct TCP_Server_Info *server = ses->server;
1587
1588 write_lock(&cifs_tcp_ses_lock);
1589 if (--ses->ses_count > 0) {
1590 write_unlock(&cifs_tcp_ses_lock);
1591 return;
1592 }
1593
1594 list_del_init(&ses->smb_ses_list);
1595 write_unlock(&cifs_tcp_ses_lock);
1596
1597 if (ses->status == CifsGood) {
1598 xid = GetXid();
1599 CIFSSMBLogoff(xid, ses);
1600 _FreeXid(xid);
1601 }
1602 sesInfoFree(ses);
1603 cifs_put_tcp_session(server);
1604}
1605
f1987b44
JL
1606static struct cifsTconInfo *
1607cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1608{
1609 struct list_head *tmp;
1610 struct cifsTconInfo *tcon;
1611
1612 write_lock(&cifs_tcp_ses_lock);
1613 list_for_each(tmp, &ses->tcon_list) {
1614 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1615 if (tcon->tidStatus == CifsExiting)
1616 continue;
1617 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
1618 continue;
1619
1620 ++tcon->tc_count;
1621 write_unlock(&cifs_tcp_ses_lock);
1622 return tcon;
1623 }
1624 write_unlock(&cifs_tcp_ses_lock);
1625 return NULL;
1626}
1627
1628static void
1629cifs_put_tcon(struct cifsTconInfo *tcon)
1630{
1631 int xid;
1632 struct cifsSesInfo *ses = tcon->ses;
1633
1634 write_lock(&cifs_tcp_ses_lock);
1635 if (--tcon->tc_count > 0) {
1636 write_unlock(&cifs_tcp_ses_lock);
1637 return;
1638 }
1639
1640 list_del_init(&tcon->tcon_list);
1641 write_unlock(&cifs_tcp_ses_lock);
1642
1643 xid = GetXid();
1644 CIFSSMBTDis(xid, tcon);
1645 _FreeXid(xid);
1646
1647 DeleteTconOplockQEntries(tcon);
1648 tconInfoFree(tcon);
1649 cifs_put_smb_ses(ses);
1650}
1651
1da177e4 1652int
50c2f753
SF
1653get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1654 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
366781c1 1655 struct dfs_info3_param **preferrals, int remap)
1da177e4
LT
1656{
1657 char *temp_unc;
1658 int rc = 0;
1659
1660 *pnum_referrals = 0;
366781c1 1661 *preferrals = NULL;
1da177e4
LT
1662
1663 if (pSesInfo->ipc_tid == 0) {
1664 temp_unc = kmalloc(2 /* for slashes */ +
50c2f753
SF
1665 strnlen(pSesInfo->serverName,
1666 SERVER_NAME_LEN_WITH_NULL * 2)
1da177e4
LT
1667 + 1 + 4 /* slash IPC$ */ + 2,
1668 GFP_KERNEL);
1669 if (temp_unc == NULL)
1670 return -ENOMEM;
1671 temp_unc[0] = '\\';
1672 temp_unc[1] = '\\';
1673 strcpy(temp_unc + 2, pSesInfo->serverName);
1674 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1675 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1676 cFYI(1,
50c2f753 1677 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1da177e4
LT
1678 kfree(temp_unc);
1679 }
1680 if (rc == 0)
c2cf07d5 1681 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
737b758c 1682 pnum_referrals, nls_codepage, remap);
366781c1
SF
1683 /* BB map targetUNCs to dfs_info3 structures, here or
1684 in CIFSGetDFSRefer BB */
1da177e4
LT
1685
1686 return rc;
1687}
1688
09e50d55
JL
1689#ifdef CONFIG_DEBUG_LOCK_ALLOC
1690static struct lock_class_key cifs_key[2];
1691static struct lock_class_key cifs_slock_key[2];
1692
1693static inline void
1694cifs_reclassify_socket4(struct socket *sock)
1695{
1696 struct sock *sk = sock->sk;
1697 BUG_ON(sock_owned_by_user(sk));
1698 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
1699 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
1700}
1701
1702static inline void
1703cifs_reclassify_socket6(struct socket *sock)
1704{
1705 struct sock *sk = sock->sk;
1706 BUG_ON(sock_owned_by_user(sk));
1707 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
1708 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
1709}
1710#else
1711static inline void
1712cifs_reclassify_socket4(struct socket *sock)
1713{
1714}
1715
1716static inline void
1717cifs_reclassify_socket6(struct socket *sock)
1718{
1719}
1720#endif
1721
1da177e4 1722/* See RFC1001 section 14 on representation of Netbios names */
50c2f753 1723static void rfc1002mangle(char *target, char *source, unsigned int length)
1da177e4 1724{
50c2f753 1725 unsigned int i, j;
1da177e4 1726
50c2f753 1727 for (i = 0, j = 0; i < (length); i++) {
1da177e4
LT
1728 /* mask a nibble at a time and encode */
1729 target[j] = 'A' + (0x0F & (source[i] >> 4));
1730 target[j+1] = 'A' + (0x0F & source[i]);
50c2f753 1731 j += 2;
1da177e4
LT
1732 }
1733
1734}
1735
1736
1737static int
50c2f753 1738ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
edf1ae40
SF
1739 char *netbios_name, char *target_name,
1740 bool noblocksnd, bool noautotune)
1da177e4
LT
1741{
1742 int rc = 0;
1743 int connected = 0;
1744 __be16 orig_port = 0;
1745
fb8c4b14 1746 if (*csocket == NULL) {
50c2f753
SF
1747 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1748 IPPROTO_TCP, csocket);
1da177e4 1749 if (rc < 0) {
50c2f753 1750 cERROR(1, ("Error %d creating socket", rc));
1da177e4
LT
1751 *csocket = NULL;
1752 return rc;
1753 } else {
1754 /* BB other socket options to set KEEPALIVE, NODELAY? */
467a8f8d 1755 cFYI(1, ("Socket created"));
50c2f753 1756 (*csocket)->sk->sk_allocation = GFP_NOFS;
09e50d55 1757 cifs_reclassify_socket4(*csocket);
1da177e4
LT
1758 }
1759 }
1760
1761 psin_server->sin_family = AF_INET;
fb8c4b14 1762 if (psin_server->sin_port) { /* user overrode default port */
1da177e4
LT
1763 rc = (*csocket)->ops->connect(*csocket,
1764 (struct sockaddr *) psin_server,
6345a3a8 1765 sizeof(struct sockaddr_in), 0);
1da177e4
LT
1766 if (rc >= 0)
1767 connected = 1;
50c2f753 1768 }
1da177e4 1769
fb8c4b14 1770 if (!connected) {
50c2f753 1771 /* save original port so we can retry user specified port
1da177e4
LT
1772 later if fall back ports fail this time */
1773 orig_port = psin_server->sin_port;
1774
1775 /* do not retry on the same port we just failed on */
fb8c4b14 1776 if (psin_server->sin_port != htons(CIFS_PORT)) {
1da177e4
LT
1777 psin_server->sin_port = htons(CIFS_PORT);
1778
1779 rc = (*csocket)->ops->connect(*csocket,
1780 (struct sockaddr *) psin_server,
6345a3a8 1781 sizeof(struct sockaddr_in), 0);
1da177e4
LT
1782 if (rc >= 0)
1783 connected = 1;
1784 }
1785 }
1786 if (!connected) {
1787 psin_server->sin_port = htons(RFC1001_PORT);
1788 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
50c2f753 1789 psin_server,
6345a3a8 1790 sizeof(struct sockaddr_in), 0);
50c2f753 1791 if (rc >= 0)
1da177e4
LT
1792 connected = 1;
1793 }
1794
1795 /* give up here - unless we want to retry on different
1796 protocol families some day */
1797 if (!connected) {
fb8c4b14 1798 if (orig_port)
1da177e4 1799 psin_server->sin_port = orig_port;
50c2f753 1800 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1da177e4
LT
1801 sock_release(*csocket);
1802 *csocket = NULL;
1803 return rc;
1804 }
50c2f753
SF
1805 /* Eventually check for other socket options to change from
1806 the default. sock_setsockopt not used because it expects
1da177e4 1807 user space buffer */
50c2f753
SF
1808 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1809 (*csocket)->sk->sk_sndbuf,
b387eaeb 1810 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1da177e4 1811 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
edf1ae40
SF
1812 if (!noblocksnd)
1813 (*csocket)->sk->sk_sndtimeo = 3 * HZ;
1814
b387eaeb 1815 /* make the bufsizes depend on wsize/rsize and max requests */
edf1ae40
SF
1816 if (noautotune) {
1817 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1818 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1819 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1820 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1821 }
1da177e4
LT
1822
1823 /* send RFC1001 sessinit */
fb8c4b14 1824 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1da177e4 1825 /* some servers require RFC1001 sessinit before sending
50c2f753 1826 negprot - BB check reconnection in case where second
1da177e4 1827 sessinit is sent but no second negprot */
50c2f753
SF
1828 struct rfc1002_session_packet *ses_init_buf;
1829 struct smb_hdr *smb_buf;
1830 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1831 GFP_KERNEL);
fb8c4b14 1832 if (ses_init_buf) {
1da177e4 1833 ses_init_buf->trailer.session_req.called_len = 32;
fb8c4b14 1834 if (target_name && (target_name[0] != 0)) {
8ecaf67a
JL
1835 rfc1002mangle(ses_init_buf->trailer.
1836 session_req.called_name,
1837 target_name,
1838 RFC1001_NAME_LEN_WITH_NULL);
a10faeb2 1839 } else {
8ecaf67a
JL
1840 rfc1002mangle(ses_init_buf->trailer.
1841 session_req.called_name,
1842 DEFAULT_CIFS_CALLED_NAME,
1843 RFC1001_NAME_LEN_WITH_NULL);
a10faeb2
SF
1844 }
1845
1da177e4
LT
1846 ses_init_buf->trailer.session_req.calling_len = 32;
1847 /* calling name ends in null (byte 16) from old smb
1848 convention. */
50c2f753 1849 if (netbios_name && (netbios_name[0] != 0)) {
8ecaf67a
JL
1850 rfc1002mangle(ses_init_buf->trailer.
1851 session_req.calling_name,
1852 netbios_name,
1853 RFC1001_NAME_LEN_WITH_NULL);
1da177e4 1854 } else {
8ecaf67a
JL
1855 rfc1002mangle(ses_init_buf->trailer.
1856 session_req.calling_name,
1857 "LINUX_CIFS_CLNT",
1858 RFC1001_NAME_LEN_WITH_NULL);
1da177e4
LT
1859 }
1860 ses_init_buf->trailer.session_req.scope1 = 0;
1861 ses_init_buf->trailer.session_req.scope2 = 0;
1862 smb_buf = (struct smb_hdr *)ses_init_buf;
1863 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1864 smb_buf->smb_buf_length = 0x81000044;
1865 rc = smb_send(*csocket, smb_buf, 0x44,
edf1ae40 1866 (struct sockaddr *)psin_server, noblocksnd);
1da177e4 1867 kfree(ses_init_buf);
50c2f753 1868 msleep(1); /* RFC1001 layer in at least one server
083d3a2c
SF
1869 requires very short break before negprot
1870 presumably because not expecting negprot
1871 to follow so fast. This is a simple
50c2f753 1872 solution that works without
083d3a2c
SF
1873 complicating the code and causes no
1874 significant slowing down on mount
1875 for everyone else */
1da177e4 1876 }
50c2f753 1877 /* else the negprot may still work without this
1da177e4 1878 even though malloc failed */
50c2f753 1879
1da177e4 1880 }
50c2f753 1881
1da177e4
LT
1882 return rc;
1883}
1884
1885static int
edf1ae40
SF
1886ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket,
1887 bool noblocksnd)
1da177e4
LT
1888{
1889 int rc = 0;
1890 int connected = 0;
1891 __be16 orig_port = 0;
1892
fb8c4b14 1893 if (*csocket == NULL) {
50c2f753
SF
1894 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1895 IPPROTO_TCP, csocket);
1da177e4 1896 if (rc < 0) {
50c2f753 1897 cERROR(1, ("Error %d creating ipv6 socket", rc));
1da177e4
LT
1898 *csocket = NULL;
1899 return rc;
1900 } else {
1901 /* BB other socket options to set KEEPALIVE, NODELAY? */
fb8c4b14 1902 cFYI(1, ("ipv6 Socket created"));
1da177e4 1903 (*csocket)->sk->sk_allocation = GFP_NOFS;
09e50d55 1904 cifs_reclassify_socket6(*csocket);
1da177e4
LT
1905 }
1906 }
1907
1908 psin_server->sin6_family = AF_INET6;
1909
fb8c4b14 1910 if (psin_server->sin6_port) { /* user overrode default port */
1da177e4
LT
1911 rc = (*csocket)->ops->connect(*csocket,
1912 (struct sockaddr *) psin_server,
6345a3a8 1913 sizeof(struct sockaddr_in6), 0);
1da177e4
LT
1914 if (rc >= 0)
1915 connected = 1;
50c2f753 1916 }
1da177e4 1917
fb8c4b14 1918 if (!connected) {
50c2f753 1919 /* save original port so we can retry user specified port
1da177e4
LT
1920 later if fall back ports fail this time */
1921
1922 orig_port = psin_server->sin6_port;
1923 /* do not retry on the same port we just failed on */
fb8c4b14 1924 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1da177e4
LT
1925 psin_server->sin6_port = htons(CIFS_PORT);
1926
1927 rc = (*csocket)->ops->connect(*csocket,
1928 (struct sockaddr *) psin_server,
6345a3a8 1929 sizeof(struct sockaddr_in6), 0);
1da177e4
LT
1930 if (rc >= 0)
1931 connected = 1;
1932 }
1933 }
1934 if (!connected) {
1935 psin_server->sin6_port = htons(RFC1001_PORT);
1936 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
6345a3a8 1937 psin_server, sizeof(struct sockaddr_in6), 0);
50c2f753 1938 if (rc >= 0)
1da177e4
LT
1939 connected = 1;
1940 }
1941
1942 /* give up here - unless we want to retry on different
1943 protocol families some day */
1944 if (!connected) {
fb8c4b14 1945 if (orig_port)
1da177e4 1946 psin_server->sin6_port = orig_port;
50c2f753 1947 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1da177e4
LT
1948 sock_release(*csocket);
1949 *csocket = NULL;
1950 return rc;
1951 }
50c2f753
SF
1952 /* Eventually check for other socket options to change from
1953 the default. sock_setsockopt not used because it expects
1da177e4
LT
1954 user space buffer */
1955 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
edf1ae40
SF
1956 if (!noblocksnd)
1957 (*csocket)->sk->sk_sndtimeo = 3 * HZ;
1958
50c2f753 1959
1da177e4
LT
1960 return rc;
1961}
1962
50c2f753
SF
1963void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1964 struct super_block *sb, struct smb_vol *vol_info)
8af18971
SF
1965{
1966 /* if we are reconnecting then should we check to see if
1967 * any requested capabilities changed locally e.g. via
1968 * remount but we can not do much about it here
1969 * if they have (even if we could detect it by the following)
1970 * Perhaps we could add a backpointer to array of sb from tcon
1971 * or if we change to make all sb to same share the same
1972 * sb as NFS - then we only have one backpointer to sb.
1973 * What if we wanted to mount the server share twice once with
1974 * and once without posixacls or posix paths? */
1975 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
50c2f753 1976
c18c842b
SF
1977 if (vol_info && vol_info->no_linux_ext) {
1978 tcon->fsUnixInfo.Capability = 0;
1979 tcon->unix_ext = 0; /* Unix Extensions disabled */
1980 cFYI(1, ("Linux protocol extensions disabled"));
1981 return;
1982 } else if (vol_info)
1983 tcon->unix_ext = 1; /* Unix Extensions supported */
1984
1985 if (tcon->unix_ext == 0) {
1986 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1987 return;
1988 }
50c2f753 1989
fb8c4b14 1990 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
8af18971 1991 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
50c2f753 1992
8af18971
SF
1993 /* check for reconnect case in which we do not
1994 want to change the mount behavior if we can avoid it */
fb8c4b14 1995 if (vol_info == NULL) {
50c2f753 1996 /* turn off POSIX ACL and PATHNAMES if not set
8af18971
SF
1997 originally at mount time */
1998 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1999 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
11b6d645
IM
2000 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2001 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2002 cERROR(1, ("POSIXPATH support change"));
8af18971 2003 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
11b6d645
IM
2004 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2005 cERROR(1, ("possible reconnect error"));
2006 cERROR(1,
2007 ("server disabled POSIX path support"));
2008 }
8af18971 2009 }
50c2f753 2010
8af18971 2011 cap &= CIFS_UNIX_CAP_MASK;
75865f8c 2012 if (vol_info && vol_info->no_psx_acl)
8af18971 2013 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
75865f8c 2014 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
fb8c4b14
SF
2015 cFYI(1, ("negotiated posix acl support"));
2016 if (sb)
8af18971
SF
2017 sb->s_flags |= MS_POSIXACL;
2018 }
2019
75865f8c 2020 if (vol_info && vol_info->posix_paths == 0)
8af18971 2021 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
75865f8c 2022 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
fb8c4b14 2023 cFYI(1, ("negotiate posix pathnames"));
75865f8c 2024 if (sb)
50c2f753 2025 CIFS_SB(sb)->mnt_cifs_flags |=
8af18971
SF
2026 CIFS_MOUNT_POSIX_PATHS;
2027 }
50c2f753 2028
984acfe1
SF
2029 /* We might be setting the path sep back to a different
2030 form if we are reconnecting and the server switched its
50c2f753 2031 posix path capability for this share */
75865f8c 2032 if (sb && (CIFS_SB(sb)->prepathlen > 0))
984acfe1 2033 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
75865f8c
SF
2034
2035 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2036 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2037 CIFS_SB(sb)->rsize = 127 * 1024;
90c81e0b
SF
2038 cFYI(DBG2,
2039 ("larger reads not supported by srv"));
75865f8c
SF
2040 }
2041 }
50c2f753
SF
2042
2043
2044 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
8af18971 2045#ifdef CONFIG_CIFS_DEBUG2
75865f8c 2046 if (cap & CIFS_UNIX_FCNTL_CAP)
fb8c4b14 2047 cFYI(1, ("FCNTL cap"));
75865f8c 2048 if (cap & CIFS_UNIX_EXTATTR_CAP)
fb8c4b14 2049 cFYI(1, ("EXTATTR cap"));
75865f8c 2050 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
fb8c4b14 2051 cFYI(1, ("POSIX path cap"));
75865f8c 2052 if (cap & CIFS_UNIX_XATTR_CAP)
fb8c4b14 2053 cFYI(1, ("XATTR cap"));
75865f8c 2054 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
fb8c4b14 2055 cFYI(1, ("POSIX ACL cap"));
75865f8c 2056 if (cap & CIFS_UNIX_LARGE_READ_CAP)
fb8c4b14 2057 cFYI(1, ("very large read cap"));
75865f8c 2058 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
fb8c4b14 2059 cFYI(1, ("very large write cap"));
8af18971
SF
2060#endif /* CIFS_DEBUG2 */
2061 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
442aa310 2062 if (vol_info == NULL) {
5a44b319 2063 cFYI(1, ("resetting capabilities failed"));
442aa310 2064 } else
5a44b319
SF
2065 cERROR(1, ("Negotiating Unix capabilities "
2066 "with the server failed. Consider "
2067 "mounting with the Unix Extensions\n"
2068 "disabled, if problems are found, "
2069 "by specifying the nounix mount "
2224f4e5 2070 "option."));
5a44b319 2071
8af18971
SF
2072 }
2073 }
2074}
2075
03a143c9
SF
2076static void
2077convert_delimiter(char *path, char delim)
2078{
2079 int i;
c2d68ea6 2080 char old_delim;
03a143c9
SF
2081
2082 if (path == NULL)
2083 return;
2084
582d21e5 2085 if (delim == '/')
c2d68ea6
SF
2086 old_delim = '\\';
2087 else
2088 old_delim = '/';
2089
03a143c9 2090 for (i = 0; path[i] != '\0'; i++) {
c2d68ea6 2091 if (path[i] == old_delim)
03a143c9
SF
2092 path[i] = delim;
2093 }
2094}
2095
3b795210
SF
2096static void setup_cifs_sb(struct smb_vol *pvolume_info,
2097 struct cifs_sb_info *cifs_sb)
2098{
2099 if (pvolume_info->rsize > CIFSMaxBufSize) {
2100 cERROR(1, ("rsize %d too large, using MaxBufSize",
2101 pvolume_info->rsize));
2102 cifs_sb->rsize = CIFSMaxBufSize;
2103 } else if ((pvolume_info->rsize) &&
2104 (pvolume_info->rsize <= CIFSMaxBufSize))
2105 cifs_sb->rsize = pvolume_info->rsize;
2106 else /* default */
2107 cifs_sb->rsize = CIFSMaxBufSize;
2108
2109 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2110 cERROR(1, ("wsize %d too large, using 4096 instead",
2111 pvolume_info->wsize));
2112 cifs_sb->wsize = 4096;
2113 } else if (pvolume_info->wsize)
2114 cifs_sb->wsize = pvolume_info->wsize;
2115 else
2116 cifs_sb->wsize = min_t(const int,
2117 PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2118 127*1024);
2119 /* old default of CIFSMaxBufSize was too small now
2120 that SMB Write2 can send multiple pages in kvec.
2121 RFC1001 does not describe what happens when frame
2122 bigger than 128K is sent so use that as max in
2123 conjunction with 52K kvec constraint on arch with 4K
2124 page size */
2125
2126 if (cifs_sb->rsize < 2048) {
2127 cifs_sb->rsize = 2048;
2128 /* Windows ME may prefer this */
2129 cFYI(1, ("readsize set to minimum: 2048"));
2130 }
2131 /* calculate prepath */
2132 cifs_sb->prepath = pvolume_info->prepath;
2133 if (cifs_sb->prepath) {
2134 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2135 /* we can not convert the / to \ in the path
2136 separators in the prefixpath yet because we do not
2137 know (until reset_cifs_unix_caps is called later)
2138 whether POSIX PATH CAP is available. We normalize
2139 the / to \ after reset_cifs_unix_caps is called */
2140 pvolume_info->prepath = NULL;
2141 } else
2142 cifs_sb->prepathlen = 0;
2143 cifs_sb->mnt_uid = pvolume_info->linux_uid;
2144 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2145 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
2146 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
2147 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2148 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2149
2150 if (pvolume_info->noperm)
2151 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2152 if (pvolume_info->setuids)
2153 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2154 if (pvolume_info->server_ino)
2155 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2156 if (pvolume_info->remap)
2157 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2158 if (pvolume_info->no_xattr)
2159 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2160 if (pvolume_info->sfu_emul)
2161 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2162 if (pvolume_info->nobrl)
2163 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2164 if (pvolume_info->cifs_acl)
2165 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2166 if (pvolume_info->override_uid)
2167 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2168 if (pvolume_info->override_gid)
2169 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2170 if (pvolume_info->dynperm)
2171 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2172 if (pvolume_info->direct_io) {
2173 cFYI(1, ("mounting share using direct i/o"));
2174 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2175 }
2176
2177 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2178 cERROR(1, ("mount option dynperm ignored if cifsacl "
2179 "mount option supported"));
2180}
2181
1da177e4
LT
2182int
2183cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2184 char *mount_data, const char *devname)
2185{
2186 int rc = 0;
2187 int xid;
7586b765 2188 struct smb_vol *volume_info;
1da177e4 2189 struct cifsSesInfo *pSesInfo = NULL;
1da177e4
LT
2190 struct cifsTconInfo *tcon = NULL;
2191 struct TCP_Server_Info *srvTcp = NULL;
2192
2193 xid = GetXid();
2194
7586b765
JL
2195 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2196 if (!volume_info) {
2197 rc = -ENOMEM;
2198 goto out;
2199 }
50c2f753 2200
7586b765 2201 if (cifs_parse_mount_options(mount_data, devname, volume_info)) {
70fe7dc0
JL
2202 rc = -EINVAL;
2203 goto out;
1da177e4
LT
2204 }
2205
7586b765 2206 if (volume_info->nullauth) {
fb8c4b14 2207 cFYI(1, ("null user"));
7586b765
JL
2208 volume_info->username = "";
2209 } else if (volume_info->username) {
1da177e4 2210 /* BB fixme parse for domain name here */
7586b765 2211 cFYI(1, ("Username: %s", volume_info->username));
1da177e4 2212 } else {
bf820679 2213 cifserror("No username specified");
50c2f753
SF
2214 /* In userspace mount helper we can get user name from alternate
2215 locations such as env variables and files on disk */
70fe7dc0
JL
2216 rc = -EINVAL;
2217 goto out;
1da177e4
LT
2218 }
2219
1da177e4
LT
2220
2221 /* this is needed for ASCII cp to Unicode converts */
7586b765 2222 if (volume_info->iocharset == NULL) {
1da177e4
LT
2223 cifs_sb->local_nls = load_nls_default();
2224 /* load_nls_default can not return null */
2225 } else {
7586b765 2226 cifs_sb->local_nls = load_nls(volume_info->iocharset);
fb8c4b14 2227 if (cifs_sb->local_nls == NULL) {
50c2f753 2228 cERROR(1, ("CIFS mount error: iocharset %s not found",
7586b765 2229 volume_info->iocharset));
70fe7dc0
JL
2230 rc = -ELIBACC;
2231 goto out;
1da177e4
LT
2232 }
2233 }
2234
63c038c2 2235 /* get a reference to a tcp session */
7586b765 2236 srvTcp = cifs_get_tcp_session(volume_info);
63c038c2
JL
2237 if (IS_ERR(srvTcp)) {
2238 rc = PTR_ERR(srvTcp);
2239 goto out;
1da177e4
LT
2240 }
2241
7586b765 2242 pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username);
14fbf50d 2243 if (pSesInfo) {
1d9a8852
JL
2244 cFYI(1, ("Existing smb sess found (status=%d)",
2245 pSesInfo->status));
14fbf50d
JL
2246 /*
2247 * The existing SMB session already has a reference to srvTcp,
2248 * so we can put back the extra one we got before
2249 */
2250 cifs_put_tcp_session(srvTcp);
2251
88e7d705 2252 down(&pSesInfo->sesSem);
3b795210 2253 if (pSesInfo->need_reconnect) {
1d9a8852 2254 cFYI(1, ("Session needs reconnect"));
1d9a8852
JL
2255 rc = cifs_setup_session(xid, pSesInfo,
2256 cifs_sb->local_nls);
1d9a8852 2257 }
88e7d705 2258 up(&pSesInfo->sesSem);
1da177e4 2259 } else if (!rc) {
bf820679 2260 cFYI(1, ("Existing smb sess not found"));
1da177e4 2261 pSesInfo = sesInfoAlloc();
14fbf50d 2262 if (pSesInfo == NULL) {
1da177e4 2263 rc = -ENOMEM;
14fbf50d 2264 goto mount_fail_check;
1da177e4
LT
2265 }
2266
14fbf50d
JL
2267 /* new SMB session uses our srvTcp ref */
2268 pSesInfo->server = srvTcp;
63c038c2 2269 if (srvTcp->addr.sockAddr6.sin6_family == AF_INET6)
8ecaf67a 2270 sprintf(pSesInfo->serverName, NIP6_FMT,
63c038c2 2271 NIP6(srvTcp->addr.sockAddr6.sin6_addr));
8ecaf67a
JL
2272 else
2273 sprintf(pSesInfo->serverName, NIPQUAD_FMT,
63c038c2 2274 NIPQUAD(srvTcp->addr.sockAddr.sin_addr.s_addr));
14fbf50d
JL
2275
2276 write_lock(&cifs_tcp_ses_lock);
2277 list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
2278 write_unlock(&cifs_tcp_ses_lock);
2279
7586b765
JL
2280 /* volume_info->password freed at unmount */
2281 if (volume_info->password) {
2282 pSesInfo->password = volume_info->password;
14fbf50d 2283 /* set to NULL to prevent freeing on exit */
7586b765 2284 volume_info->password = NULL;
14fbf50d 2285 }
7586b765
JL
2286 if (volume_info->username)
2287 strncpy(pSesInfo->userName, volume_info->username,
14fbf50d 2288 MAX_USERNAME_SIZE);
7586b765
JL
2289 if (volume_info->domainname) {
2290 int len = strlen(volume_info->domainname);
14fbf50d
JL
2291 pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
2292 if (pSesInfo->domainName)
2293 strcpy(pSesInfo->domainName,
7586b765 2294 volume_info->domainname);
70fe7dc0 2295 }
7586b765
JL
2296 pSesInfo->linux_uid = volume_info->linux_uid;
2297 pSesInfo->overrideSecFlg = volume_info->secFlg;
14fbf50d
JL
2298 down(&pSesInfo->sesSem);
2299
2300 /* BB FIXME need to pass vol->secFlgs BB */
2301 rc = cifs_setup_session(xid, pSesInfo,
2302 cifs_sb->local_nls);
2303 up(&pSesInfo->sesSem);
1da177e4 2304 }
50c2f753 2305
1da177e4
LT
2306 /* search for existing tcon to this server share */
2307 if (!rc) {
7586b765 2308 setup_cifs_sb(volume_info, cifs_sb);
27adb44c 2309
7586b765 2310 tcon = cifs_find_tcon(pSesInfo, volume_info->UNC);
1da177e4 2311 if (tcon) {
bf820679 2312 cFYI(1, ("Found match on UNC path"));
f1987b44
JL
2313 /* existing tcon already has a reference */
2314 cifs_put_smb_ses(pSesInfo);
7586b765 2315 if (tcon->seal != volume_info->seal)
ab3f9929
SF
2316 cERROR(1, ("transport encryption setting "
2317 "conflicts with existing tid"));
1da177e4
LT
2318 } else {
2319 tcon = tconInfoAlloc();
3b795210 2320 if (tcon == NULL) {
1da177e4 2321 rc = -ENOMEM;
3b795210
SF
2322 goto mount_fail_check;
2323 }
ab3f9929 2324 tcon->ses = pSesInfo;
3b795210
SF
2325
2326 /* check for null share name ie connect to dfs root */
7586b765
JL
2327 if ((strchr(volume_info->UNC + 3, '\\') == NULL)
2328 && (strchr(volume_info->UNC + 3, '/') == NULL)) {
3b795210
SF
2329 /* rc = connect_to_dfs_path(...) */
2330 cFYI(1, ("DFS root not supported"));
2331 rc = -ENODEV;
2332 goto mount_fail_check;
2333 } else {
2334 /* BB Do we need to wrap sesSem around
2335 * this TCon call and Unix SetFS as
2336 * we do on SessSetup and reconnect? */
7586b765 2337 rc = CIFSTCon(xid, pSesInfo, volume_info->UNC,
3b795210
SF
2338 tcon, cifs_sb->local_nls);
2339 cFYI(1, ("CIFS Tcon rc = %d", rc));
7586b765 2340 if (volume_info->nodfs) {
3b795210
SF
2341 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2342 cFYI(1, ("DFS disabled (%d)",
2343 tcon->Flags));
1da177e4
LT
2344 }
2345 }
14fbf50d 2346 if (rc)
3b795210 2347 goto mount_fail_check;
7586b765 2348 tcon->seal = volume_info->seal;
f1987b44
JL
2349 write_lock(&cifs_tcp_ses_lock);
2350 list_add(&tcon->tcon_list, &pSesInfo->tcon_list);
2351 write_unlock(&cifs_tcp_ses_lock);
1da177e4 2352 }
3b795210
SF
2353
2354 /* we can have only one retry value for a connection
2355 to a share so for resources mounted more than once
2356 to the same server share the last value passed in
2357 for the retry flag is used */
7586b765
JL
2358 tcon->retry = volume_info->retry;
2359 tcon->nocase = volume_info->nocase;
2360 tcon->local_lease = volume_info->local_lease;
1da177e4 2361 }
4523cc30 2362 if (pSesInfo) {
1da177e4
LT
2363 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2364 sb->s_maxbytes = (u64) 1 << 63;
2365 } else
2366 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2367 }
2368
8af18971 2369 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
1da177e4
LT
2370 sb->s_time_gran = 100;
2371
3b795210 2372mount_fail_check:
14fbf50d 2373 /* on error free sesinfo and tcon struct if needed */
1da177e4 2374 if (rc) {
e7ddee90
JL
2375 /* If find_unc succeeded then rc == 0 so we can not end */
2376 /* up accidently freeing someone elses tcon struct */
2377 if (tcon)
f1987b44
JL
2378 cifs_put_tcon(tcon);
2379 else if (pSesInfo)
14fbf50d
JL
2380 cifs_put_smb_ses(pSesInfo);
2381 else
2382 cifs_put_tcp_session(srvTcp);
d82c2df5
SF
2383 goto out;
2384 }
d82c2df5 2385 cifs_sb->tcon = tcon;
d82c2df5
SF
2386
2387 /* do not care if following two calls succeed - informational */
2388 if (!tcon->ipc) {
2389 CIFSSMBQFSDeviceInfo(xid, tcon);
2390 CIFSSMBQFSAttributeInfo(xid, tcon);
2391 }
50c2f753 2392
d82c2df5
SF
2393 /* tell server which Unix caps we support */
2394 if (tcon->ses->capabilities & CAP_UNIX)
2395 /* reset of caps checks mount to see if unix extensions
2396 disabled for just this mount */
7586b765 2397 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
d82c2df5
SF
2398 else
2399 tcon->unix_ext = 0; /* server does not support them */
c18c842b 2400
d82c2df5
SF
2401 /* convert forward to back slashes in prepath here if needed */
2402 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2403 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
03a143c9 2404
d82c2df5
SF
2405 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2406 cifs_sb->rsize = 1024 * 127;
2407 cFYI(DBG2, ("no very large read support, rsize now 127K"));
1da177e4 2408 }
d82c2df5
SF
2409 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2410 cifs_sb->wsize = min(cifs_sb->wsize,
2411 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2412 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2413 cifs_sb->rsize = min(cifs_sb->rsize,
2414 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
1da177e4 2415
7586b765 2416 /* volume_info->password is freed above when existing session found
1da177e4
LT
2417 (in which case it is not needed anymore) but when new sesion is created
2418 the password ptr is put in the new session structure (in which case the
2419 password will be freed at unmount time) */
70fe7dc0
JL
2420out:
2421 /* zero out password before freeing */
7586b765
JL
2422 if (volume_info) {
2423 if (volume_info->password != NULL) {
2424 memset(volume_info->password, 0,
2425 strlen(volume_info->password));
2426 kfree(volume_info->password);
2427 }
2428 kfree(volume_info->UNC);
2429 kfree(volume_info->prepath);
2430 kfree(volume_info);
70fe7dc0 2431 }
1da177e4
LT
2432 FreeXid(xid);
2433 return rc;
2434}
2435
2436static int
2437CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
7c7b25bc 2438 char session_key[CIFS_SESS_KEY_SIZE],
1da177e4
LT
2439 const struct nls_table *nls_codepage)
2440{
2441 struct smb_hdr *smb_buffer;
2442 struct smb_hdr *smb_buffer_response;
2443 SESSION_SETUP_ANDX *pSMB;
2444 SESSION_SETUP_ANDX *pSMBr;
2445 char *bcc_ptr;
2446 char *user;
2447 char *domain;
2448 int rc = 0;
2449 int remaining_words = 0;
2450 int bytes_returned = 0;
2451 int len;
2452 __u32 capabilities;
2453 __u16 count;
2454
eeac8047 2455 cFYI(1, ("In sesssetup"));
4523cc30 2456 if (ses == NULL)
1da177e4
LT
2457 return -EINVAL;
2458 user = ses->userName;
2459 domain = ses->domainName;
2460 smb_buffer = cifs_buf_get();
582d21e5
SF
2461
2462 if (smb_buffer == NULL)
1da177e4 2463 return -ENOMEM;
582d21e5 2464
1da177e4
LT
2465 smb_buffer_response = smb_buffer;
2466 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2467
2468 /* send SMBsessionSetup here */
2469 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2470 NULL /* no tCon exists yet */ , 13 /* wct */ );
2471
1982c344 2472 smb_buffer->Mid = GetNextMid(ses->server);
1da177e4
LT
2473 pSMB->req_no_secext.AndXCommand = 0xFF;
2474 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2475 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2476
50c2f753
SF
2477 if (ses->server->secMode &
2478 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1da177e4
LT
2479 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2480
2481 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2482 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2483 if (ses->capabilities & CAP_UNICODE) {
2484 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2485 capabilities |= CAP_UNICODE;
2486 }
2487 if (ses->capabilities & CAP_STATUS32) {
2488 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2489 capabilities |= CAP_STATUS32;
2490 }
2491 if (ses->capabilities & CAP_DFS) {
2492 smb_buffer->Flags2 |= SMBFLG2_DFS;
2493 capabilities |= CAP_DFS;
2494 }
2495 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2496
50c2f753 2497 pSMB->req_no_secext.CaseInsensitivePasswordLength =
7c7b25bc 2498 cpu_to_le16(CIFS_SESS_KEY_SIZE);
1da177e4
LT
2499
2500 pSMB->req_no_secext.CaseSensitivePasswordLength =
7c7b25bc 2501 cpu_to_le16(CIFS_SESS_KEY_SIZE);
1da177e4 2502 bcc_ptr = pByteArea(smb_buffer);
7c7b25bc
SF
2503 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2504 bcc_ptr += CIFS_SESS_KEY_SIZE;
2505 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2506 bcc_ptr += CIFS_SESS_KEY_SIZE;
1da177e4
LT
2507
2508 if (ses->capabilities & CAP_UNICODE) {
2509 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2510 *bcc_ptr = 0;
2511 bcc_ptr++;
2512 }
4523cc30 2513 if (user == NULL)
3979877e 2514 bytes_returned = 0; /* skip null user */
50c2f753 2515 else
1da177e4 2516 bytes_returned =
50c2f753 2517 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
1da177e4
LT
2518 nls_codepage);
2519 /* convert number of 16 bit words to bytes */
2520 bcc_ptr += 2 * bytes_returned;
2521 bcc_ptr += 2; /* trailing null */
2522 if (domain == NULL)
2523 bytes_returned =
e89dc920 2524 cifs_strtoUCS((__le16 *) bcc_ptr,
1da177e4
LT
2525 "CIFS_LINUX_DOM", 32, nls_codepage);
2526 else
2527 bytes_returned =
e89dc920 2528 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
1da177e4
LT
2529 nls_codepage);
2530 bcc_ptr += 2 * bytes_returned;
2531 bcc_ptr += 2;
2532 bytes_returned =
e89dc920 2533 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
1da177e4
LT
2534 32, nls_codepage);
2535 bcc_ptr += 2 * bytes_returned;
2536 bytes_returned =
e9ff3990 2537 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
1da177e4
LT
2538 32, nls_codepage);
2539 bcc_ptr += 2 * bytes_returned;
2540 bcc_ptr += 2;
2541 bytes_returned =
e89dc920 2542 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
1da177e4
LT
2543 64, nls_codepage);
2544 bcc_ptr += 2 * bytes_returned;
2545 bcc_ptr += 2;
2546 } else {
50c2f753 2547 if (user != NULL) {
1da177e4
LT
2548 strncpy(bcc_ptr, user, 200);
2549 bcc_ptr += strnlen(user, 200);
2550 }
2551 *bcc_ptr = 0;
2552 bcc_ptr++;
2553 if (domain == NULL) {
2554 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2555 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2556 } else {
2557 strncpy(bcc_ptr, domain, 64);
2558 bcc_ptr += strnlen(domain, 64);
2559 *bcc_ptr = 0;
2560 bcc_ptr++;
2561 }
2562 strcpy(bcc_ptr, "Linux version ");
2563 bcc_ptr += strlen("Linux version ");
e9ff3990
SH
2564 strcpy(bcc_ptr, utsname()->release);
2565 bcc_ptr += strlen(utsname()->release) + 1;
1da177e4
LT
2566 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2567 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2568 }
2569 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2570 smb_buffer->smb_buf_length += count;
2571 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2572
2573 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
133672ef 2574 &bytes_returned, CIFS_LONG_OP);
1da177e4
LT
2575 if (rc) {
2576/* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2577 } else if ((smb_buffer_response->WordCount == 3)
2578 || (smb_buffer_response->WordCount == 4)) {
2579 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2580 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2581 if (action & GUEST_LOGIN)
50c2f753
SF
2582 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2583 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2584 (little endian) */
1da177e4 2585 cFYI(1, ("UID = %d ", ses->Suid));
50c2f753
SF
2586 /* response can have either 3 or 4 word count - Samba sends 3 */
2587 bcc_ptr = pByteArea(smb_buffer_response);
1da177e4
LT
2588 if ((pSMBr->resp.hdr.WordCount == 3)
2589 || ((pSMBr->resp.hdr.WordCount == 4)
2590 && (blob_len < pSMBr->resp.ByteCount))) {
2591 if (pSMBr->resp.hdr.WordCount == 4)
2592 bcc_ptr += blob_len;
2593
2594 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2595 if ((long) (bcc_ptr) % 2) {
2596 remaining_words =
50c2f753
SF
2597 (BCC(smb_buffer_response) - 1) / 2;
2598 /* Unicode strings must be word
2599 aligned */
2600 bcc_ptr++;
1da177e4
LT
2601 } else {
2602 remaining_words =
2603 BCC(smb_buffer_response) / 2;
2604 }
2605 len =
2606 UniStrnlen((wchar_t *) bcc_ptr,
2607 remaining_words - 1);
2608/* We look for obvious messed up bcc or strings in response so we do not go off
2609 the end since (at least) WIN2K and Windows XP have a major bug in not null
2610 terminating last Unicode string in response */
fb8c4b14 2611 if (ses->serverOS)
a424f8bf 2612 kfree(ses->serverOS);
50c2f753
SF
2613 ses->serverOS = kzalloc(2 * (len + 1),
2614 GFP_KERNEL);
fb8c4b14 2615 if (ses->serverOS == NULL)
433dc24f 2616 goto sesssetup_nomem;
1da177e4 2617 cifs_strfromUCS_le(ses->serverOS,
50c2f753
SF
2618 (__le16 *)bcc_ptr,
2619 len, nls_codepage);
1da177e4
LT
2620 bcc_ptr += 2 * (len + 1);
2621 remaining_words -= len + 1;
2622 ses->serverOS[2 * len] = 0;
2623 ses->serverOS[1 + (2 * len)] = 0;
2624 if (remaining_words > 0) {
2625 len = UniStrnlen((wchar_t *)bcc_ptr,
2626 remaining_words-1);
cd49b492 2627 kfree(ses->serverNOS);
50c2f753
SF
2628 ses->serverNOS = kzalloc(2 * (len + 1),
2629 GFP_KERNEL);
fb8c4b14 2630 if (ses->serverNOS == NULL)
433dc24f 2631 goto sesssetup_nomem;
1da177e4 2632 cifs_strfromUCS_le(ses->serverNOS,
50c2f753
SF
2633 (__le16 *)bcc_ptr,
2634 len, nls_codepage);
1da177e4
LT
2635 bcc_ptr += 2 * (len + 1);
2636 ses->serverNOS[2 * len] = 0;
2637 ses->serverNOS[1 + (2 * len)] = 0;
fb8c4b14 2638 if (strncmp(ses->serverNOS,
50c2f753 2639 "NT LAN Manager 4", 16) == 0) {
467a8f8d 2640 cFYI(1, ("NT4 server"));
1da177e4
LT
2641 ses->flags |= CIFS_SES_NT4;
2642 }
2643 remaining_words -= len + 1;
2644 if (remaining_words > 0) {
433dc24f 2645 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
50c2f753
SF
2646 /* last string is not always null terminated
2647 (for e.g. for Windows XP & 2000) */
fb8c4b14 2648 if (ses->serverDomain)
a424f8bf 2649 kfree(ses->serverDomain);
1da177e4 2650 ses->serverDomain =
50c2f753
SF
2651 kzalloc(2*(len+1),
2652 GFP_KERNEL);
fb8c4b14 2653 if (ses->serverDomain == NULL)
433dc24f 2654 goto sesssetup_nomem;
1da177e4 2655 cifs_strfromUCS_le(ses->serverDomain,
50c2f753
SF
2656 (__le16 *)bcc_ptr,
2657 len, nls_codepage);
1da177e4
LT
2658 bcc_ptr += 2 * (len + 1);
2659 ses->serverDomain[2*len] = 0;
2660 ses->serverDomain[1+(2*len)] = 0;
50c2f753
SF
2661 } else { /* else no more room so create
2662 dummy domain string */
fb8c4b14 2663 if (ses->serverDomain)
a424f8bf 2664 kfree(ses->serverDomain);
50c2f753 2665 ses->serverDomain =
e915fc49 2666 kzalloc(2, GFP_KERNEL);
a424f8bf 2667 }
50c2f753
SF
2668 } else { /* no room so create dummy domain
2669 and NOS string */
2670
433dc24f
SF
2671 /* if these kcallocs fail not much we
2672 can do, but better to not fail the
2673 sesssetup itself */
cd49b492 2674 kfree(ses->serverDomain);
1da177e4 2675 ses->serverDomain =
e915fc49 2676 kzalloc(2, GFP_KERNEL);
cd49b492 2677 kfree(ses->serverNOS);
1da177e4 2678 ses->serverNOS =
e915fc49 2679 kzalloc(2, GFP_KERNEL);
1da177e4
LT
2680 }
2681 } else { /* ASCII */
2682 len = strnlen(bcc_ptr, 1024);
2683 if (((long) bcc_ptr + len) - (long)
2684 pByteArea(smb_buffer_response)
2685 <= BCC(smb_buffer_response)) {
cd49b492 2686 kfree(ses->serverOS);
50c2f753
SF
2687 ses->serverOS = kzalloc(len + 1,
2688 GFP_KERNEL);
fb8c4b14 2689 if (ses->serverOS == NULL)
433dc24f 2690 goto sesssetup_nomem;
50c2f753 2691 strncpy(ses->serverOS, bcc_ptr, len);
1da177e4
LT
2692
2693 bcc_ptr += len;
50c2f753
SF
2694 /* null terminate the string */
2695 bcc_ptr[0] = 0;
1da177e4
LT
2696 bcc_ptr++;
2697
2698 len = strnlen(bcc_ptr, 1024);
cd49b492 2699 kfree(ses->serverNOS);
50c2f753
SF
2700 ses->serverNOS = kzalloc(len + 1,
2701 GFP_KERNEL);
fb8c4b14 2702 if (ses->serverNOS == NULL)
433dc24f 2703 goto sesssetup_nomem;
1da177e4
LT
2704 strncpy(ses->serverNOS, bcc_ptr, len);
2705 bcc_ptr += len;
2706 bcc_ptr[0] = 0;
2707 bcc_ptr++;
2708
2709 len = strnlen(bcc_ptr, 1024);
fb8c4b14 2710 if (ses->serverDomain)
a424f8bf 2711 kfree(ses->serverDomain);
50c2f753
SF
2712 ses->serverDomain = kzalloc(len + 1,
2713 GFP_KERNEL);
fb8c4b14 2714 if (ses->serverDomain == NULL)
433dc24f 2715 goto sesssetup_nomem;
50c2f753
SF
2716 strncpy(ses->serverDomain, bcc_ptr,
2717 len);
1da177e4
LT
2718 bcc_ptr += len;
2719 bcc_ptr[0] = 0;
2720 bcc_ptr++;
2721 } else
2722 cFYI(1,
50c2f753
SF
2723 ("Variable field of length %d "
2724 "extends beyond end of smb ",
1da177e4
LT
2725 len));
2726 }
2727 } else {
2728 cERROR(1,
50c2f753
SF
2729 (" Security Blob Length extends beyond "
2730 "end of SMB"));
1da177e4
LT
2731 }
2732 } else {
2733 cERROR(1,
2734 (" Invalid Word count %d: ",
2735 smb_buffer_response->WordCount));
2736 rc = -EIO;
2737 }
433dc24f
SF
2738sesssetup_nomem: /* do not return an error on nomem for the info strings,
2739 since that could make reconnection harder, and
2740 reconnection might be needed to free memory */
a8a11d39 2741 cifs_buf_release(smb_buffer);
1da177e4
LT
2742
2743 return rc;
2744}
2745
1da177e4
LT
2746static int
2747CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
4b18f2a9 2748 struct cifsSesInfo *ses, bool *pNTLMv2_flag,
1da177e4
LT
2749 const struct nls_table *nls_codepage)
2750{
2751 struct smb_hdr *smb_buffer;
2752 struct smb_hdr *smb_buffer_response;
2753 SESSION_SETUP_ANDX *pSMB;
2754 SESSION_SETUP_ANDX *pSMBr;
2755 char *bcc_ptr;
2756 char *domain;
2757 int rc = 0;
2758 int remaining_words = 0;
2759 int bytes_returned = 0;
2760 int len;
6345a3a8 2761 int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
1da177e4
LT
2762 PNEGOTIATE_MESSAGE SecurityBlob;
2763 PCHALLENGE_MESSAGE SecurityBlob2;
2764 __u32 negotiate_flags, capabilities;
2765 __u16 count;
2766
12b3b8ff 2767 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
fb8c4b14 2768 if (ses == NULL)
1da177e4
LT
2769 return -EINVAL;
2770 domain = ses->domainName;
4b18f2a9 2771 *pNTLMv2_flag = false;
1da177e4
LT
2772 smb_buffer = cifs_buf_get();
2773 if (smb_buffer == NULL) {
2774 return -ENOMEM;
2775 }
2776 smb_buffer_response = smb_buffer;
2777 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2778 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2779
2780 /* send SMBsessionSetup here */
2781 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2782 NULL /* no tCon exists yet */ , 12 /* wct */ );
1982c344
SF
2783
2784 smb_buffer->Mid = GetNextMid(ses->server);
1da177e4
LT
2785 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2786 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2787
2788 pSMB->req.AndXCommand = 0xFF;
2789 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2790 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2791
fb8c4b14 2792 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1da177e4
LT
2793 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2794
2795 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2796 CAP_EXTENDED_SECURITY;
2797 if (ses->capabilities & CAP_UNICODE) {
2798 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2799 capabilities |= CAP_UNICODE;
2800 }
2801 if (ses->capabilities & CAP_STATUS32) {
2802 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2803 capabilities |= CAP_STATUS32;
2804 }
2805 if (ses->capabilities & CAP_DFS) {
2806 smb_buffer->Flags2 |= SMBFLG2_DFS;
2807 capabilities |= CAP_DFS;
2808 }
2809 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2810
2811 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2812 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2813 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2814 SecurityBlob->MessageType = NtLmNegotiate;
2815 negotiate_flags =
2816 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
12b3b8ff
SF
2817 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2818 NTLMSSP_NEGOTIATE_56 |
1da177e4 2819 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
fb8c4b14 2820 if (sign_CIFS_PDUs)
1da177e4 2821 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
fb8c4b14 2822/* if (ntlmv2_support)
3979877e 2823 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
1da177e4
LT
2824 /* setup pointers to domain name and workstation name */
2825 bcc_ptr += SecurityBlobLength;
2826
2827 SecurityBlob->WorkstationName.Buffer = 0;
2828 SecurityBlob->WorkstationName.Length = 0;
2829 SecurityBlob->WorkstationName.MaximumLength = 0;
2830
12b3b8ff
SF
2831 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2832 along with username on auth request (ie the response to challenge) */
2833 SecurityBlob->DomainName.Buffer = 0;
2834 SecurityBlob->DomainName.Length = 0;
2835 SecurityBlob->DomainName.MaximumLength = 0;
1da177e4
LT
2836 if (ses->capabilities & CAP_UNICODE) {
2837 if ((long) bcc_ptr % 2) {
2838 *bcc_ptr = 0;
2839 bcc_ptr++;
2840 }
2841
2842 bytes_returned =
e89dc920 2843 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
1da177e4
LT
2844 32, nls_codepage);
2845 bcc_ptr += 2 * bytes_returned;
2846 bytes_returned =
e9ff3990 2847 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
1da177e4
LT
2848 nls_codepage);
2849 bcc_ptr += 2 * bytes_returned;
2850 bcc_ptr += 2; /* null terminate Linux version */
2851 bytes_returned =
e89dc920 2852 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
1da177e4
LT
2853 64, nls_codepage);
2854 bcc_ptr += 2 * bytes_returned;
2855 *(bcc_ptr + 1) = 0;
2856 *(bcc_ptr + 2) = 0;
2857 bcc_ptr += 2; /* null terminate network opsys string */
2858 *(bcc_ptr + 1) = 0;
2859 *(bcc_ptr + 2) = 0;
2860 bcc_ptr += 2; /* null domain */
2861 } else { /* ASCII */
2862 strcpy(bcc_ptr, "Linux version ");
2863 bcc_ptr += strlen("Linux version ");
e9ff3990
SH
2864 strcpy(bcc_ptr, utsname()->release);
2865 bcc_ptr += strlen(utsname()->release) + 1;
1da177e4
LT
2866 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2867 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2868 bcc_ptr++; /* empty domain field */
2869 *bcc_ptr = 0;
2870 }
2871 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2872 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2873 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2874 smb_buffer->smb_buf_length += count;
2875 pSMB->req.ByteCount = cpu_to_le16(count);
2876
2877 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
133672ef 2878 &bytes_returned, CIFS_LONG_OP);
1da177e4
LT
2879
2880 if (smb_buffer_response->Status.CifsError ==
2881 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2882 rc = 0;
2883
2884 if (rc) {
2885/* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2886 } else if ((smb_buffer_response->WordCount == 3)
2887 || (smb_buffer_response->WordCount == 4)) {
2888 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2889 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2890
2891 if (action & GUEST_LOGIN)
50c2f753
SF
2892 cFYI(1, (" Guest login"));
2893 /* Do we want to set anything in SesInfo struct when guest login? */
1da177e4 2894
50c2f753
SF
2895 bcc_ptr = pByteArea(smb_buffer_response);
2896 /* response can have either 3 or 4 word count - Samba sends 3 */
1da177e4
LT
2897
2898 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2899 if (SecurityBlob2->MessageType != NtLmChallenge) {
2900 cFYI(1,
2901 ("Unexpected NTLMSSP message type received %d",
2902 SecurityBlob2->MessageType));
2903 } else if (ses) {
50c2f753 2904 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
12b3b8ff 2905 cFYI(1, ("UID = %d", ses->Suid));
1da177e4
LT
2906 if ((pSMBr->resp.hdr.WordCount == 3)
2907 || ((pSMBr->resp.hdr.WordCount == 4)
2908 && (blob_len <
2909 pSMBr->resp.ByteCount))) {
2910
2911 if (pSMBr->resp.hdr.WordCount == 4) {
2912 bcc_ptr += blob_len;
12b3b8ff 2913 cFYI(1, ("Security Blob Length %d",
1da177e4
LT
2914 blob_len));
2915 }
2916
12b3b8ff 2917 cFYI(1, ("NTLMSSP Challenge rcvd"));
1da177e4
LT
2918
2919 memcpy(ses->server->cryptKey,
2920 SecurityBlob2->Challenge,
2921 CIFS_CRYPTO_KEY_SIZE);
50c2f753 2922 if (SecurityBlob2->NegotiateFlags &
12b3b8ff 2923 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
4b18f2a9 2924 *pNTLMv2_flag = true;
1da177e4 2925
50c2f753
SF
2926 if ((SecurityBlob2->NegotiateFlags &
2927 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
1da177e4 2928 || (sign_CIFS_PDUs > 1))
50c2f753
SF
2929 ses->server->secMode |=
2930 SECMODE_SIGN_REQUIRED;
2931 if ((SecurityBlob2->NegotiateFlags &
1da177e4 2932 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
50c2f753 2933 ses->server->secMode |=
1da177e4
LT
2934 SECMODE_SIGN_ENABLED;
2935
2936 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2937 if ((long) (bcc_ptr) % 2) {
2938 remaining_words =
2939 (BCC(smb_buffer_response)
2940 - 1) / 2;
50c2f753
SF
2941 /* Must word align unicode strings */
2942 bcc_ptr++;
1da177e4
LT
2943 } else {
2944 remaining_words =
2945 BCC
2946 (smb_buffer_response) / 2;
2947 }
2948 len =
2949 UniStrnlen((wchar_t *) bcc_ptr,
2950 remaining_words - 1);
2951/* We look for obvious messed up bcc or strings in response so we do not go off
2952 the end since (at least) WIN2K and Windows XP have a major bug in not null
2953 terminating last Unicode string in response */
fb8c4b14 2954 if (ses->serverOS)
a424f8bf 2955 kfree(ses->serverOS);
1da177e4 2956 ses->serverOS =
e915fc49 2957 kzalloc(2 * (len + 1), GFP_KERNEL);
1da177e4 2958 cifs_strfromUCS_le(ses->serverOS,
e89dc920 2959 (__le16 *)
1da177e4
LT
2960 bcc_ptr, len,
2961 nls_codepage);
2962 bcc_ptr += 2 * (len + 1);
2963 remaining_words -= len + 1;
2964 ses->serverOS[2 * len] = 0;
2965 ses->serverOS[1 + (2 * len)] = 0;
2966 if (remaining_words > 0) {
2967 len = UniStrnlen((wchar_t *)
2968 bcc_ptr,
2969 remaining_words
2970 - 1);
cd49b492 2971 kfree(ses->serverNOS);
1da177e4 2972 ses->serverNOS =
e915fc49 2973 kzalloc(2 * (len + 1),
1da177e4
LT
2974 GFP_KERNEL);
2975 cifs_strfromUCS_le(ses->
2976 serverNOS,
e89dc920 2977 (__le16 *)
1da177e4
LT
2978 bcc_ptr,
2979 len,
2980 nls_codepage);
2981 bcc_ptr += 2 * (len + 1);
2982 ses->serverNOS[2 * len] = 0;
2983 ses->serverNOS[1 +
2984 (2 * len)] = 0;
2985 remaining_words -= len + 1;
2986 if (remaining_words > 0) {
50c2f753
SF
2987 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2988 /* last string not always null terminated
2989 (for e.g. for Windows XP & 2000) */
cd49b492 2990 kfree(ses->serverDomain);
1da177e4 2991 ses->serverDomain =
e915fc49 2992 kzalloc(2 *
1da177e4
LT
2993 (len +
2994 1),
2995 GFP_KERNEL);
2996 cifs_strfromUCS_le
e89dc920
SF
2997 (ses->serverDomain,
2998 (__le16 *)bcc_ptr,
2999 len, nls_codepage);
1da177e4
LT
3000 bcc_ptr +=
3001 2 * (len + 1);
e89dc920 3002 ses->serverDomain[2*len]
1da177e4 3003 = 0;
e89dc920
SF
3004 ses->serverDomain
3005 [1 + (2 * len)]
1da177e4
LT
3006 = 0;
3007 } /* else no more room so create dummy domain string */
a424f8bf 3008 else {
cd49b492 3009 kfree(ses->serverDomain);
1da177e4 3010 ses->serverDomain =
e915fc49 3011 kzalloc(2,
1da177e4 3012 GFP_KERNEL);
a424f8bf 3013 }
1da177e4 3014 } else { /* no room so create dummy domain and NOS string */
cd49b492 3015 kfree(ses->serverDomain);
1da177e4 3016 ses->serverDomain =
e915fc49 3017 kzalloc(2, GFP_KERNEL);
cd49b492 3018 kfree(ses->serverNOS);
1da177e4 3019 ses->serverNOS =
e915fc49 3020 kzalloc(2, GFP_KERNEL);
1da177e4
LT
3021 }
3022 } else { /* ASCII */
3023 len = strnlen(bcc_ptr, 1024);
3024 if (((long) bcc_ptr + len) - (long)
3025 pByteArea(smb_buffer_response)
3026 <= BCC(smb_buffer_response)) {
fb8c4b14 3027 if (ses->serverOS)
a424f8bf 3028 kfree(ses->serverOS);
1da177e4 3029 ses->serverOS =
e915fc49 3030 kzalloc(len + 1,
1da177e4
LT
3031 GFP_KERNEL);
3032 strncpy(ses->serverOS,
3033 bcc_ptr, len);
3034
3035 bcc_ptr += len;
3036 bcc_ptr[0] = 0; /* null terminate string */
3037 bcc_ptr++;
3038
3039 len = strnlen(bcc_ptr, 1024);
cd49b492 3040 kfree(ses->serverNOS);
1da177e4 3041 ses->serverNOS =
e915fc49 3042 kzalloc(len + 1,
1da177e4
LT
3043 GFP_KERNEL);
3044 strncpy(ses->serverNOS, bcc_ptr, len);
3045 bcc_ptr += len;
3046 bcc_ptr[0] = 0;
3047 bcc_ptr++;
3048
3049 len = strnlen(bcc_ptr, 1024);
cd49b492 3050 kfree(ses->serverDomain);
1da177e4 3051 ses->serverDomain =
e915fc49 3052 kzalloc(len + 1,
1da177e4 3053 GFP_KERNEL);
50c2f753
SF
3054 strncpy(ses->serverDomain,
3055 bcc_ptr, len);
1da177e4
LT
3056 bcc_ptr += len;
3057 bcc_ptr[0] = 0;
3058 bcc_ptr++;
3059 } else
3060 cFYI(1,
63135e08
SF
3061 ("field of length %d "
3062 "extends beyond end of smb",
1da177e4
LT
3063 len));
3064 }
3065 } else {
50c2f753
SF
3066 cERROR(1, ("Security Blob Length extends beyond"
3067 " end of SMB"));
1da177e4
LT
3068 }
3069 } else {
3070 cERROR(1, ("No session structure passed in."));
3071 }
3072 } else {
3073 cERROR(1,
5815449d 3074 (" Invalid Word count %d:",
1da177e4
LT
3075 smb_buffer_response->WordCount));
3076 rc = -EIO;
3077 }
3078
a8a11d39 3079 cifs_buf_release(smb_buffer);
1da177e4
LT
3080
3081 return rc;
3082}
3083static int
3084CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
4b18f2a9 3085 char *ntlm_session_key, bool ntlmv2_flag,
6345a3a8 3086 const struct nls_table *nls_codepage)
1da177e4
LT
3087{
3088 struct smb_hdr *smb_buffer;
3089 struct smb_hdr *smb_buffer_response;
3090 SESSION_SETUP_ANDX *pSMB;
3091 SESSION_SETUP_ANDX *pSMBr;
3092 char *bcc_ptr;
3093 char *user;
3094 char *domain;
3095 int rc = 0;
3096 int remaining_words = 0;
3097 int bytes_returned = 0;
3098 int len;
6345a3a8 3099 int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
1da177e4
LT
3100 PAUTHENTICATE_MESSAGE SecurityBlob;
3101 __u32 negotiate_flags, capabilities;
3102 __u16 count;
3103
3104 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
fb8c4b14 3105 if (ses == NULL)
1da177e4
LT
3106 return -EINVAL;
3107 user = ses->userName;
3108 domain = ses->domainName;
3109 smb_buffer = cifs_buf_get();
3110 if (smb_buffer == NULL) {
3111 return -ENOMEM;
3112 }
3113 smb_buffer_response = smb_buffer;
6345a3a8
CG
3114 pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
3115 pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
1da177e4
LT
3116
3117 /* send SMBsessionSetup here */
3118 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
3119 NULL /* no tCon exists yet */ , 12 /* wct */ );
1982c344
SF
3120
3121 smb_buffer->Mid = GetNextMid(ses->server);
1da177e4
LT
3122 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
3123 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
3124 pSMB->req.AndXCommand = 0xFF;
3125 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
3126 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
3127
3128 pSMB->req.hdr.Uid = ses->Suid;
3129
fb8c4b14 3130 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1da177e4
LT
3131 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3132
3133 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
6345a3a8 3134 CAP_EXTENDED_SECURITY;
1da177e4
LT
3135 if (ses->capabilities & CAP_UNICODE) {
3136 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3137 capabilities |= CAP_UNICODE;
3138 }
3139 if (ses->capabilities & CAP_STATUS32) {
3140 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3141 capabilities |= CAP_STATUS32;
3142 }
3143 if (ses->capabilities & CAP_DFS) {
3144 smb_buffer->Flags2 |= SMBFLG2_DFS;
3145 capabilities |= CAP_DFS;
3146 }
3147 pSMB->req.Capabilities = cpu_to_le32(capabilities);
3148
6345a3a8
CG
3149 bcc_ptr = (char *)&pSMB->req.SecurityBlob;
3150 SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
1da177e4
LT
3151 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
3152 SecurityBlob->MessageType = NtLmAuthenticate;
3153 bcc_ptr += SecurityBlobLength;
6345a3a8
CG
3154 negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
3155 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
3156 0x80000000 | NTLMSSP_NEGOTIATE_128;
fb8c4b14 3157 if (sign_CIFS_PDUs)
1da177e4 3158 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
fb8c4b14 3159 if (ntlmv2_flag)
1da177e4
LT
3160 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
3161
3162/* setup pointers to domain name and workstation name */
3163
3164 SecurityBlob->WorkstationName.Buffer = 0;
3165 SecurityBlob->WorkstationName.Length = 0;
3166 SecurityBlob->WorkstationName.MaximumLength = 0;
3167 SecurityBlob->SessionKey.Length = 0;
3168 SecurityBlob->SessionKey.MaximumLength = 0;
3169 SecurityBlob->SessionKey.Buffer = 0;
3170
3171 SecurityBlob->LmChallengeResponse.Length = 0;
3172 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
3173 SecurityBlob->LmChallengeResponse.Buffer = 0;
3174
3175 SecurityBlob->NtChallengeResponse.Length =
7c7b25bc 3176 cpu_to_le16(CIFS_SESS_KEY_SIZE);
1da177e4 3177 SecurityBlob->NtChallengeResponse.MaximumLength =
7c7b25bc
SF
3178 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3179 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
1da177e4
LT
3180 SecurityBlob->NtChallengeResponse.Buffer =
3181 cpu_to_le32(SecurityBlobLength);
7c7b25bc
SF
3182 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
3183 bcc_ptr += CIFS_SESS_KEY_SIZE;
1da177e4
LT
3184
3185 if (ses->capabilities & CAP_UNICODE) {
3186 if (domain == NULL) {
3187 SecurityBlob->DomainName.Buffer = 0;
3188 SecurityBlob->DomainName.Length = 0;
3189 SecurityBlob->DomainName.MaximumLength = 0;
3190 } else {
77159b4d 3191 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
1da177e4 3192 nls_codepage);
77159b4d 3193 ln *= 2;
1da177e4 3194 SecurityBlob->DomainName.MaximumLength =
77159b4d 3195 cpu_to_le16(ln);
1da177e4
LT
3196 SecurityBlob->DomainName.Buffer =
3197 cpu_to_le32(SecurityBlobLength);
77159b4d
SF
3198 bcc_ptr += ln;
3199 SecurityBlobLength += ln;
3200 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
1da177e4
LT
3201 }
3202 if (user == NULL) {
3203 SecurityBlob->UserName.Buffer = 0;
3204 SecurityBlob->UserName.Length = 0;
3205 SecurityBlob->UserName.MaximumLength = 0;
3206 } else {
77159b4d 3207 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
1da177e4 3208 nls_codepage);
77159b4d 3209 ln *= 2;
1da177e4 3210 SecurityBlob->UserName.MaximumLength =
77159b4d 3211 cpu_to_le16(ln);
1da177e4
LT
3212 SecurityBlob->UserName.Buffer =
3213 cpu_to_le32(SecurityBlobLength);
77159b4d
SF
3214 bcc_ptr += ln;
3215 SecurityBlobLength += ln;
3216 SecurityBlob->UserName.Length = cpu_to_le16(ln);
1da177e4
LT
3217 }
3218
63135e08
SF
3219 /* SecurityBlob->WorkstationName.Length =
3220 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
1da177e4 3221 SecurityBlob->WorkstationName.Length *= 2;
63135e08
SF
3222 SecurityBlob->WorkstationName.MaximumLength =
3223 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3224 SecurityBlob->WorkstationName.Buffer =
3225 cpu_to_le32(SecurityBlobLength);
1da177e4
LT
3226 bcc_ptr += SecurityBlob->WorkstationName.Length;
3227 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
63135e08
SF
3228 SecurityBlob->WorkstationName.Length =
3229 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
1da177e4
LT
3230
3231 if ((long) bcc_ptr % 2) {
3232 *bcc_ptr = 0;
3233 bcc_ptr++;
3234 }
3235 bytes_returned =
e89dc920 3236 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
1da177e4
LT
3237 32, nls_codepage);
3238 bcc_ptr += 2 * bytes_returned;
3239 bytes_returned =
e9ff3990 3240 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
1da177e4
LT
3241 nls_codepage);
3242 bcc_ptr += 2 * bytes_returned;
3243 bcc_ptr += 2; /* null term version string */
3244 bytes_returned =
e89dc920 3245 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
1da177e4
LT
3246 64, nls_codepage);
3247 bcc_ptr += 2 * bytes_returned;
3248 *(bcc_ptr + 1) = 0;
3249 *(bcc_ptr + 2) = 0;
3250 bcc_ptr += 2; /* null terminate network opsys string */
3251 *(bcc_ptr + 1) = 0;
3252 *(bcc_ptr + 2) = 0;
3253 bcc_ptr += 2; /* null domain */
3254 } else { /* ASCII */
3255 if (domain == NULL) {
3256 SecurityBlob->DomainName.Buffer = 0;
3257 SecurityBlob->DomainName.Length = 0;
3258 SecurityBlob->DomainName.MaximumLength = 0;
3259 } else {
77159b4d 3260 __u16 ln;
1da177e4
LT
3261 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3262 strncpy(bcc_ptr, domain, 63);
77159b4d 3263 ln = strnlen(domain, 64);
1da177e4 3264 SecurityBlob->DomainName.MaximumLength =
77159b4d 3265 cpu_to_le16(ln);
1da177e4
LT
3266 SecurityBlob->DomainName.Buffer =
3267 cpu_to_le32(SecurityBlobLength);
77159b4d
SF
3268 bcc_ptr += ln;
3269 SecurityBlobLength += ln;
3270 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
1da177e4
LT
3271 }
3272 if (user == NULL) {
3273 SecurityBlob->UserName.Buffer = 0;
3274 SecurityBlob->UserName.Length = 0;
3275 SecurityBlob->UserName.MaximumLength = 0;
3276 } else {
77159b4d 3277 __u16 ln;
1da177e4 3278 strncpy(bcc_ptr, user, 63);
77159b4d
SF
3279 ln = strnlen(user, 64);
3280 SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
1da177e4 3281 SecurityBlob->UserName.Buffer =
77159b4d
SF
3282 cpu_to_le32(SecurityBlobLength);
3283 bcc_ptr += ln;
3284 SecurityBlobLength += ln;
3285 SecurityBlob->UserName.Length = cpu_to_le16(ln);
1da177e4
LT
3286 }
3287 /* BB fill in our workstation name if known BB */
3288
3289 strcpy(bcc_ptr, "Linux version ");
3290 bcc_ptr += strlen("Linux version ");
e9ff3990
SH
3291 strcpy(bcc_ptr, utsname()->release);
3292 bcc_ptr += strlen(utsname()->release) + 1;
1da177e4
LT
3293 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3294 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3295 bcc_ptr++; /* null domain */
3296 *bcc_ptr = 0;
3297 }
3298 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3299 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3300 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3301 smb_buffer->smb_buf_length += count;
3302 pSMB->req.ByteCount = cpu_to_le16(count);
3303
3304 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
133672ef 3305 &bytes_returned, CIFS_LONG_OP);
1da177e4 3306 if (rc) {
6345a3a8
CG
3307/* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3308 } else if ((smb_buffer_response->WordCount == 3) ||
3309 (smb_buffer_response->WordCount == 4)) {
1da177e4 3310 __u16 action = le16_to_cpu(pSMBr->resp.Action);
6345a3a8 3311 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
1da177e4 3312 if (action & GUEST_LOGIN)
50c2f753
SF
3313 cFYI(1, (" Guest login")); /* BB Should we set anything
3314 in SesInfo struct ? */
3315/* if (SecurityBlob2->MessageType != NtLm??) {
3316 cFYI("Unexpected message type on auth response is %d"));
3317 } */
3318
1da177e4
LT
3319 if (ses) {
3320 cFYI(1,
50c2f753 3321 ("Check challenge UID %d vs auth response UID %d",
1da177e4 3322 ses->Suid, smb_buffer_response->Uid));
50c2f753
SF
3323 /* UID left in wire format */
3324 ses->Suid = smb_buffer_response->Uid;
3325 bcc_ptr = pByteArea(smb_buffer_response);
3326 /* response can have either 3 or 4 word count - Samba sends 3 */
1da177e4
LT
3327 if ((pSMBr->resp.hdr.WordCount == 3)
3328 || ((pSMBr->resp.hdr.WordCount == 4)
3329 && (blob_len <
3330 pSMBr->resp.ByteCount))) {
3331 if (pSMBr->resp.hdr.WordCount == 4) {
3332 bcc_ptr +=
3333 blob_len;
3334 cFYI(1,
3335 ("Security Blob Length %d ",
3336 blob_len));
3337 }
3338
3339 cFYI(1,
3340 ("NTLMSSP response to Authenticate "));
3341
3342 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3343 if ((long) (bcc_ptr) % 2) {
3344 remaining_words =
3345 (BCC(smb_buffer_response)
3346 - 1) / 2;
3347 bcc_ptr++; /* Unicode strings must be word aligned */
3348 } else {
3349 remaining_words = BCC(smb_buffer_response) / 2;
3350 }
77159b4d
SF
3351 len = UniStrnlen((wchar_t *) bcc_ptr,
3352 remaining_words - 1);
1da177e4
LT
3353/* We look for obvious messed up bcc or strings in response so we do not go off
3354 the end since (at least) WIN2K and Windows XP have a major bug in not null
3355 terminating last Unicode string in response */
fb8c4b14 3356 if (ses->serverOS)
08775834 3357 kfree(ses->serverOS);
1da177e4 3358 ses->serverOS =
e915fc49 3359 kzalloc(2 * (len + 1), GFP_KERNEL);
1da177e4 3360 cifs_strfromUCS_le(ses->serverOS,
e89dc920 3361 (__le16 *)
1da177e4
LT
3362 bcc_ptr, len,
3363 nls_codepage);
3364 bcc_ptr += 2 * (len + 1);
3365 remaining_words -= len + 1;
3366 ses->serverOS[2 * len] = 0;
3367 ses->serverOS[1 + (2 * len)] = 0;
3368 if (remaining_words > 0) {
3369 len = UniStrnlen((wchar_t *)
3370 bcc_ptr,
3371 remaining_words
3372 - 1);
cd49b492 3373 kfree(ses->serverNOS);
1da177e4 3374 ses->serverNOS =
e915fc49 3375 kzalloc(2 * (len + 1),
1da177e4
LT
3376 GFP_KERNEL);
3377 cifs_strfromUCS_le(ses->
3378 serverNOS,
e89dc920 3379 (__le16 *)
1da177e4
LT
3380 bcc_ptr,
3381 len,
3382 nls_codepage);
3383 bcc_ptr += 2 * (len + 1);
3384 ses->serverNOS[2 * len] = 0;
3385 ses->serverNOS[1+(2*len)] = 0;
3386 remaining_words -= len + 1;
3387 if (remaining_words > 0) {
50c2f753 3388 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
1da177e4 3389 /* last string not always null terminated (e.g. for Windows XP & 2000) */
fb8c4b14 3390 if (ses->serverDomain)
a424f8bf 3391 kfree(ses->serverDomain);
1da177e4 3392 ses->serverDomain =
e915fc49 3393 kzalloc(2 *
1da177e4
LT
3394 (len +
3395 1),
3396 GFP_KERNEL);
3397 cifs_strfromUCS_le
3398 (ses->
3399 serverDomain,
e89dc920 3400 (__le16 *)
1da177e4
LT
3401 bcc_ptr, len,
3402 nls_codepage);
3403 bcc_ptr +=
3404 2 * (len + 1);
3405 ses->
3406 serverDomain[2
3407 * len]
3408 = 0;
3409 ses->
3410 serverDomain[1
3411 +
3412 (2
3413 *
3414 len)]
3415 = 0;
3416 } /* else no more room so create dummy domain string */
a424f8bf 3417 else {
fb8c4b14 3418 if (ses->serverDomain)
a424f8bf 3419 kfree(ses->serverDomain);
e915fc49 3420 ses->serverDomain = kzalloc(2,GFP_KERNEL);
a424f8bf 3421 }
1da177e4 3422 } else { /* no room so create dummy domain and NOS string */
fb8c4b14 3423 if (ses->serverDomain)
a424f8bf 3424 kfree(ses->serverDomain);
e915fc49 3425 ses->serverDomain = kzalloc(2, GFP_KERNEL);
cd49b492 3426 kfree(ses->serverNOS);
e915fc49 3427 ses->serverNOS = kzalloc(2, GFP_KERNEL);
1da177e4
LT
3428 }
3429 } else { /* ASCII */
3430 len = strnlen(bcc_ptr, 1024);
50c2f753
SF
3431 if (((long) bcc_ptr + len) -
3432 (long) pByteArea(smb_buffer_response)
63135e08 3433 <= BCC(smb_buffer_response)) {
fb8c4b14 3434 if (ses->serverOS)
a424f8bf 3435 kfree(ses->serverOS);
77159b4d 3436 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
1da177e4
LT
3437 strncpy(ses->serverOS,bcc_ptr, len);
3438
3439 bcc_ptr += len;
3440 bcc_ptr[0] = 0; /* null terminate the string */
3441 bcc_ptr++;
3442
3443 len = strnlen(bcc_ptr, 1024);
cd49b492 3444 kfree(ses->serverNOS);
50c2f753
SF
3445 ses->serverNOS = kzalloc(len+1,
3446 GFP_KERNEL);
63135e08
SF
3447 strncpy(ses->serverNOS,
3448 bcc_ptr, len);
1da177e4
LT
3449 bcc_ptr += len;
3450 bcc_ptr[0] = 0;
3451 bcc_ptr++;
3452
3453 len = strnlen(bcc_ptr, 1024);
fb8c4b14 3454 if (ses->serverDomain)
a424f8bf 3455 kfree(ses->serverDomain);
63135e08
SF
3456 ses->serverDomain =
3457 kzalloc(len+1,
3458 GFP_KERNEL);
3459 strncpy(ses->serverDomain,
3460 bcc_ptr, len);
1da177e4
LT
3461 bcc_ptr += len;
3462 bcc_ptr[0] = 0;
3463 bcc_ptr++;
3464 } else
6345a3a8 3465 cFYI(1, ("field of length %d "
63135e08 3466 "extends beyond end of smb ",
1da177e4
LT
3467 len));
3468 }
3469 } else {
6345a3a8 3470 cERROR(1, ("Security Blob extends beyond end "
63135e08 3471 "of SMB"));
1da177e4
LT
3472 }
3473 } else {
3474 cERROR(1, ("No session structure passed in."));
3475 }
3476 } else {
6345a3a8 3477 cERROR(1, ("Invalid Word count %d: ",
1da177e4
LT
3478 smb_buffer_response->WordCount));
3479 rc = -EIO;
3480 }
3481
a8a11d39 3482 cifs_buf_release(smb_buffer);
1da177e4
LT
3483
3484 return rc;
3485}
3486
3487int
3488CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3489 const char *tree, struct cifsTconInfo *tcon,
3490 const struct nls_table *nls_codepage)
3491{
3492 struct smb_hdr *smb_buffer;
3493 struct smb_hdr *smb_buffer_response;
3494 TCONX_REQ *pSMB;
3495 TCONX_RSP *pSMBr;
3496 unsigned char *bcc_ptr;
3497 int rc = 0;
3498 int length;
3499 __u16 count;
3500
3501 if (ses == NULL)
3502 return -EIO;
3503
3504 smb_buffer = cifs_buf_get();
3505 if (smb_buffer == NULL) {
3506 return -ENOMEM;
3507 }
3508 smb_buffer_response = smb_buffer;
3509
3510 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3511 NULL /*no tid */ , 4 /*wct */ );
1982c344
SF
3512
3513 smb_buffer->Mid = GetNextMid(ses->server);
1da177e4
LT
3514 smb_buffer->Uid = ses->Suid;
3515 pSMB = (TCONX_REQ *) smb_buffer;
3516 pSMBr = (TCONX_RSP *) smb_buffer_response;
3517
3518 pSMB->AndXCommand = 0xFF;
3519 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
1da177e4 3520 bcc_ptr = &pSMB->Password[0];
fb8c4b14 3521 if ((ses->server->secMode) & SECMODE_USER) {
eeac8047 3522 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
7c7b25bc 3523 *bcc_ptr = 0; /* password is null byte */
eeac8047 3524 bcc_ptr++; /* skip password */
7c7b25bc 3525 /* already aligned so no need to do it below */
eeac8047 3526 } else {
7c7b25bc 3527 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
eeac8047
SF
3528 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3529 specified as required (when that support is added to
3530 the vfs in the future) as only NTLM or the much
7c7b25bc 3531 weaker LANMAN (which we do not send by default) is accepted
eeac8047
SF
3532 by Samba (not sure whether other servers allow
3533 NTLMv2 password here) */
7c7b25bc 3534#ifdef CONFIG_CIFS_WEAK_PW_HASH
50c2f753 3535 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
7c7b25bc
SF
3536 (ses->server->secType == LANMAN))
3537 calc_lanman_hash(ses, bcc_ptr);
3538 else
3539#endif /* CIFS_WEAK_PW_HASH */
eeac8047
SF
3540 SMBNTencrypt(ses->password,
3541 ses->server->cryptKey,
3542 bcc_ptr);
3543
7c7b25bc 3544 bcc_ptr += CIFS_SESS_KEY_SIZE;
fb8c4b14 3545 if (ses->capabilities & CAP_UNICODE) {
7c7b25bc
SF
3546 /* must align unicode strings */
3547 *bcc_ptr = 0; /* null byte password */
3548 bcc_ptr++;
3549 }
eeac8047 3550 }
1da177e4 3551
50c2f753 3552 if (ses->server->secMode &
a878fb22 3553 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1da177e4
LT
3554 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3555
3556 if (ses->capabilities & CAP_STATUS32) {
3557 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3558 }
3559 if (ses->capabilities & CAP_DFS) {
3560 smb_buffer->Flags2 |= SMBFLG2_DFS;
3561 }
3562 if (ses->capabilities & CAP_UNICODE) {
3563 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3564 length =
50c2f753
SF
3565 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3566 6 /* max utf8 char length in bytes */ *
a878fb22
SF
3567 (/* server len*/ + 256 /* share len */), nls_codepage);
3568 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
1da177e4
LT
3569 bcc_ptr += 2; /* skip trailing null */
3570 } else { /* ASCII */
1da177e4
LT
3571 strcpy(bcc_ptr, tree);
3572 bcc_ptr += strlen(tree) + 1;
3573 }
3574 strcpy(bcc_ptr, "?????");
3575 bcc_ptr += strlen("?????");
3576 bcc_ptr += 1;
3577 count = bcc_ptr - &pSMB->Password[0];
3578 pSMB->hdr.smb_buf_length += count;
3579 pSMB->ByteCount = cpu_to_le16(count);
3580
133672ef
SF
3581 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3582 CIFS_STD_OP);
1da177e4
LT
3583
3584 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3585 /* above now done in SendReceive */
3586 if ((rc == 0) && (tcon != NULL)) {
3587 tcon->tidStatus = CifsGood;
3b795210 3588 tcon->need_reconnect = false;
1da177e4
LT
3589 tcon->tid = smb_buffer_response->Tid;
3590 bcc_ptr = pByteArea(smb_buffer_response);
3591 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
50c2f753 3592 /* skip service field (NB: this field is always ASCII) */
7f8ed420
SF
3593 if (length == 3) {
3594 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3595 (bcc_ptr[2] == 'C')) {
3596 cFYI(1, ("IPC connection"));
3597 tcon->ipc = 1;
3598 }
3599 } else if (length == 2) {
3600 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3601 /* the most common case */
3602 cFYI(1, ("disk share connection"));
3603 }
3604 }
50c2f753 3605 bcc_ptr += length + 1;
1da177e4
LT
3606 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3607 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3608 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3609 if ((bcc_ptr + (2 * length)) -
3610 pByteArea(smb_buffer_response) <=
3611 BCC(smb_buffer_response)) {
f99d49ad 3612 kfree(tcon->nativeFileSystem);
1da177e4 3613 tcon->nativeFileSystem =
e915fc49 3614 kzalloc(length + 2, GFP_KERNEL);
88f370a6
SF
3615 if (tcon->nativeFileSystem)
3616 cifs_strfromUCS_le(
3617 tcon->nativeFileSystem,
3618 (__le16 *) bcc_ptr,
3619 length, nls_codepage);
1da177e4
LT
3620 bcc_ptr += 2 * length;
3621 bcc_ptr[0] = 0; /* null terminate the string */
3622 bcc_ptr[1] = 0;
3623 bcc_ptr += 2;
3624 }
50c2f753 3625 /* else do not bother copying these information fields*/
1da177e4
LT
3626 } else {
3627 length = strnlen(bcc_ptr, 1024);
3628 if ((bcc_ptr + length) -
3629 pByteArea(smb_buffer_response) <=
3630 BCC(smb_buffer_response)) {
f99d49ad 3631 kfree(tcon->nativeFileSystem);
1da177e4 3632 tcon->nativeFileSystem =
e915fc49 3633 kzalloc(length + 1, GFP_KERNEL);
88f370a6
SF
3634 if (tcon->nativeFileSystem)
3635 strncpy(tcon->nativeFileSystem, bcc_ptr,
3636 length);
1da177e4 3637 }
50c2f753 3638 /* else do not bother copying these information fields*/
1da177e4 3639 }
fb8c4b14 3640 if ((smb_buffer_response->WordCount == 3) ||
1a4e15a0
SF
3641 (smb_buffer_response->WordCount == 7))
3642 /* field is in same location */
3979877e
SF
3643 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3644 else
3645 tcon->Flags = 0;
1da177e4
LT
3646 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3647 } else if ((rc == 0) && tcon == NULL) {
50c2f753 3648 /* all we need to save for IPC$ connection */
1da177e4
LT
3649 ses->ipc_tid = smb_buffer_response->Tid;
3650 }
3651
a8a11d39 3652 cifs_buf_release(smb_buffer);
1da177e4
LT
3653 return rc;
3654}
3655
3656int
3657cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3658{
3659 int rc = 0;
50c2f753 3660 char *tmp;
1da177e4 3661
f1987b44
JL
3662 if (cifs_sb->tcon)
3663 cifs_put_tcon(cifs_sb->tcon);
50c2f753 3664
1da177e4 3665 cifs_sb->tcon = NULL;
2fe87f02
SF
3666 tmp = cifs_sb->prepath;
3667 cifs_sb->prepathlen = 0;
3668 cifs_sb->prepath = NULL;
3669 kfree(tmp);
1da177e4 3670
88e7d705 3671 return rc;
50c2f753 3672}
1da177e4
LT
3673
3674int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
50c2f753 3675 struct nls_table *nls_info)
1da177e4
LT
3676{
3677 int rc = 0;
7c7b25bc 3678 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
4b18f2a9 3679 bool ntlmv2_flag = false;
ad009ac9 3680 int first_time = 0;
cb7691b6 3681 struct TCP_Server_Info *server = pSesInfo->server;
1da177e4
LT
3682
3683 /* what if server changes its buffer size after dropping the session? */
cb7691b6 3684 if (server->maxBuf == 0) /* no need to send on reconnect */ {
1da177e4 3685 rc = CIFSSMBNegotiate(xid, pSesInfo);
cb7691b6
JL
3686 if (rc == -EAGAIN) {
3687 /* retry only once on 1st time connection */
1da177e4 3688 rc = CIFSSMBNegotiate(xid, pSesInfo);
50c2f753 3689 if (rc == -EAGAIN)
1da177e4
LT
3690 rc = -EHOSTDOWN;
3691 }
fb8c4b14 3692 if (rc == 0) {
1da177e4 3693 spin_lock(&GlobalMid_Lock);
cb7691b6
JL
3694 if (server->tcpStatus != CifsExiting)
3695 server->tcpStatus = CifsGood;
1da177e4
LT
3696 else
3697 rc = -EHOSTDOWN;
3698 spin_unlock(&GlobalMid_Lock);
3699
3700 }
ad009ac9 3701 first_time = 1;
1da177e4 3702 }
26b994fa
SF
3703
3704 if (rc)
3705 goto ss_err_exit;
3706
3707 pSesInfo->flags = 0;
cb7691b6 3708 pSesInfo->capabilities = server->capabilities;
26b994fa
SF
3709 if (linuxExtEnabled == 0)
3710 pSesInfo->capabilities &= (~CAP_UNIX);
ad009ac9 3711 /* pSesInfo->sequence_number = 0;*/
26b994fa 3712 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
cb7691b6
JL
3713 server->secMode, server->capabilities, server->timeAdj));
3714
26b994fa
SF
3715 if (experimEnabled < 2)
3716 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
3717 else if (extended_security
3718 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
cb7691b6 3719 && (server->secType == NTLMSSP)) {
26b994fa
SF
3720 rc = -EOPNOTSUPP;
3721 } else if (extended_security
3722 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
cb7691b6 3723 && (server->secType == RawNTLMSSP)) {
26b994fa
SF
3724 cFYI(1, ("NTLMSSP sesssetup"));
3725 rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag,
3726 nls_info);
3727 if (!rc) {
3728 if (ntlmv2_flag) {
3729 char *v2_response;
3730 cFYI(1, ("more secure NTLM ver2 hash"));
3731 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3732 nls_info)) {
3733 rc = -ENOMEM;
3734 goto ss_err_exit;
3735 } else
3736 v2_response = kmalloc(16 + 64 /* blob*/,
3737 GFP_KERNEL);
3738 if (v2_response) {
3739 CalcNTLMv2_response(pSesInfo,
3740 v2_response);
3741 /* if (first_time)
3742 cifs_calculate_ntlmv2_mac_key */
3743 kfree(v2_response);
1da177e4 3744 /* BB Put dummy sig in SessSetup PDU? */
1da177e4 3745 } else {
26b994fa
SF
3746 rc = -ENOMEM;
3747 goto ss_err_exit;
1da177e4 3748 }
26b994fa
SF
3749
3750 } else {
3751 SMBNTencrypt(pSesInfo->password,
cb7691b6 3752 server->cryptKey,
26b994fa
SF
3753 ntlm_session_key);
3754
3755 if (first_time)
3756 cifs_calculate_mac_key(
cb7691b6 3757 &server->mac_signing_key,
26b994fa
SF
3758 ntlm_session_key,
3759 pSesInfo->password);
3760 }
1da177e4
LT
3761 /* for better security the weaker lanman hash not sent
3762 in AuthSessSetup so we no longer calculate it */
3763
26b994fa
SF
3764 rc = CIFSNTLMSSPAuthSessSetup(xid, pSesInfo,
3765 ntlm_session_key,
3766 ntlmv2_flag,
3767 nls_info);
3768 }
3769 } else { /* old style NTLM 0.12 session setup */
cb7691b6 3770 SMBNTencrypt(pSesInfo->password, server->cryptKey,
26b994fa 3771 ntlm_session_key);
1da177e4 3772
26b994fa 3773 if (first_time)
cb7691b6
JL
3774 cifs_calculate_mac_key(&server->mac_signing_key,
3775 ntlm_session_key,
3776 pSesInfo->password);
ad009ac9 3777
26b994fa
SF
3778 rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info);
3779 }
3780 if (rc) {
3781 cERROR(1, ("Send error in SessSetup = %d", rc));
3782 } else {
3783 cFYI(1, ("CIFS Session Established successfully"));
469ee614 3784 spin_lock(&GlobalMid_Lock);
1da177e4 3785 pSesInfo->status = CifsGood;
3b795210 3786 pSesInfo->need_reconnect = false;
469ee614 3787 spin_unlock(&GlobalMid_Lock);
1da177e4 3788 }
26b994fa 3789
1da177e4
LT
3790ss_err_exit:
3791 return rc;
3792}
3793
This page took 0.515451 seconds and 5 git commands to generate.