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