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