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