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