]> bbs.cooldavid.org Git - net-next-2.6.git/blame - fs/cifs/connect.c
cifs: prevent cifsd from exiting prematurely
[net-next-2.6.git] / fs / cifs / connect.c
CommitLineData
1da177e4
LT
1/*
2 * fs/cifs/connect.c
3 *
d185cda7 4 * Copyright (C) International Business Machines Corp., 2002,2009
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>
5a0e3ad6 26#include <linux/slab.h>
1da177e4
LT
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>
5c2503a8 36#include <linux/namei.h>
1da177e4
LT
37#include <asm/uaccess.h>
38#include <asm/processor.h>
50b64e3b 39#include <linux/inet.h>
0e2bedaa 40#include <net/ipv6.h>
1da177e4
LT
41#include "cifspdu.h"
42#include "cifsglob.h"
43#include "cifsproto.h"
44#include "cifs_unicode.h"
45#include "cifs_debug.h"
46#include "cifs_fs_sb.h"
47#include "ntlmssp.h"
48#include "nterr.h"
49#include "rfc1002pdu.h"
a2653eba 50#include "cn_cifs.h"
488f1d2d 51#include "fscache.h"
1da177e4
LT
52
53#define CIFS_PORT 445
54#define RFC1001_PORT 139
55
1da177e4
LT
56extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
57 unsigned char *p24);
58
59extern mempool_t *cifs_req_poolp;
60
61struct smb_vol {
62 char *username;
63 char *password;
64 char *domainname;
65 char *UNC;
66 char *UNCip;
1da177e4
LT
67 char *iocharset; /* local code page for mapping to and from Unicode */
68 char source_rfc1001_name[16]; /* netbios name of client */
a10faeb2 69 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
3e4b3e1f 70 uid_t cred_uid;
1da177e4
LT
71 uid_t linux_uid;
72 gid_t linux_gid;
73 mode_t file_mode;
74 mode_t dir_mode;
189acaae 75 unsigned secFlg;
4b18f2a9
SF
76 bool retry:1;
77 bool intr:1;
78 bool setuids:1;
79 bool override_uid:1;
80 bool override_gid:1;
d0a9c078 81 bool dynperm:1;
4b18f2a9
SF
82 bool noperm:1;
83 bool no_psx_acl:1; /* set if posix acl support should be disabled */
84 bool cifs_acl:1;
85 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
86 bool server_ino:1; /* use inode numbers from server ie UniqueId */
87 bool direct_io:1;
95b1cb90
SF
88 bool remap:1; /* set to remap seven reserved chars in filenames */
89 bool posix_paths:1; /* unset to not ask for posix pathnames. */
4b18f2a9
SF
90 bool no_linux_ext:1;
91 bool sfu_emul:1;
95b1cb90
SF
92 bool nullauth:1; /* attempt to authenticate with null user */
93 bool nocase:1; /* request case insensitive filenames */
94 bool nobrl:1; /* disable sending byte range locks to srv */
13a6e42a 95 bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
95b1cb90 96 bool seal:1; /* request transport encryption on share */
84210e91
SF
97 bool nodfs:1; /* Do not request DFS, even if available */
98 bool local_lease:1; /* check leases only on local system, not remote */
edf1ae40
SF
99 bool noblocksnd:1;
100 bool noautotune:1;
be652445 101 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
fa1df75d 102 bool fsc:1; /* enable fscache */
1da177e4
LT
103 unsigned int rsize;
104 unsigned int wsize;
6a5fa236 105 bool sockopt_tcp_nodelay:1;
1da177e4 106 unsigned short int port;
fb8c4b14 107 char *prepath;
a5fc4ce0 108 struct nls_table *local_nls;
1da177e4
LT
109};
110
bcf4b106 111static int ipv4_connect(struct TCP_Server_Info *server);
d5c5605c 112static int ipv6_connect(struct TCP_Server_Info *server);
1da177e4 113
d5c5605c
JL
114/*
115 * cifs tcp session reconnection
116 *
117 * mark tcp session as reconnecting so temporarily locked
118 * mark all smb sessions as reconnecting for tcp session
119 * reconnect tcp session
120 * wake up waiters on reconnection? - (not needed currently)
121 */
2cd646a2 122static int
1da177e4
LT
123cifs_reconnect(struct TCP_Server_Info *server)
124{
125 int rc = 0;
f1987b44 126 struct list_head *tmp, *tmp2;
1da177e4
LT
127 struct cifsSesInfo *ses;
128 struct cifsTconInfo *tcon;
fb8c4b14 129 struct mid_q_entry *mid_entry;
50c2f753 130
1da177e4 131 spin_lock(&GlobalMid_Lock);
469ee614 132 if (server->tcpStatus == CifsExiting) {
fb8c4b14 133 /* the demux thread will exit normally
1da177e4
LT
134 next time through the loop */
135 spin_unlock(&GlobalMid_Lock);
136 return rc;
137 } else
138 server->tcpStatus = CifsNeedReconnect;
139 spin_unlock(&GlobalMid_Lock);
140 server->maxBuf = 0;
141
b6b38f70 142 cFYI(1, "Reconnecting tcp session");
1da177e4
LT
143
144 /* before reconnecting the tcp session, mark the smb session (uid)
145 and the tid bad so they are not used until reconnected */
14fbf50d
JL
146 read_lock(&cifs_tcp_ses_lock);
147 list_for_each(tmp, &server->smb_ses_list) {
148 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
149 ses->need_reconnect = true;
150 ses->ipc_tid = 0;
f1987b44
JL
151 list_for_each(tmp2, &ses->tcon_list) {
152 tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list);
3b795210 153 tcon->need_reconnect = true;
1da177e4 154 }
1da177e4 155 }
f1987b44 156 read_unlock(&cifs_tcp_ses_lock);
1da177e4 157 /* do not want to be sending data on a socket we are freeing */
72ca545b 158 mutex_lock(&server->srv_mutex);
fb8c4b14 159 if (server->ssocket) {
b6b38f70
JP
160 cFYI(1, "State: 0x%x Flags: 0x%lx", server->ssocket->state,
161 server->ssocket->flags);
91cf45f0 162 kernel_sock_shutdown(server->ssocket, SHUT_WR);
b6b38f70 163 cFYI(1, "Post shutdown state: 0x%x Flags: 0x%lx",
467a8f8d 164 server->ssocket->state,
b6b38f70 165 server->ssocket->flags);
1da177e4
LT
166 sock_release(server->ssocket);
167 server->ssocket = NULL;
168 }
169
170 spin_lock(&GlobalMid_Lock);
171 list_for_each(tmp, &server->pending_mid_q) {
172 mid_entry = list_entry(tmp, struct
173 mid_q_entry,
174 qhead);
ad8b15f0 175 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
09d1db5c
SF
176 /* Mark other intransit requests as needing
177 retry so we do not immediately mark the
178 session bad again (ie after we reconnect
179 below) as they timeout too */
ad8b15f0 180 mid_entry->midState = MID_RETRY_NEEDED;
1da177e4
LT
181 }
182 }
183 spin_unlock(&GlobalMid_Lock);
72ca545b 184 mutex_unlock(&server->srv_mutex);
1da177e4 185
469ee614
JL
186 while ((server->tcpStatus != CifsExiting) &&
187 (server->tcpStatus != CifsGood)) {
6c3d8909 188 try_to_freeze();
bcf4b106 189 if (server->addr.sockAddr6.sin6_family == AF_INET6)
d5c5605c 190 rc = ipv6_connect(server);
bcf4b106
JL
191 else
192 rc = ipv4_connect(server);
fb8c4b14 193 if (rc) {
b6b38f70 194 cFYI(1, "reconnect error %d", rc);
0cb766ae 195 msleep(3000);
1da177e4
LT
196 } else {
197 atomic_inc(&tcpSesReconnectCount);
198 spin_lock(&GlobalMid_Lock);
469ee614 199 if (server->tcpStatus != CifsExiting)
1da177e4 200 server->tcpStatus = CifsGood;
ad009ac9 201 server->sequence_number = 0;
fb8c4b14 202 spin_unlock(&GlobalMid_Lock);
1da177e4
LT
203 /* atomic_set(&server->inFlight,0);*/
204 wake_up(&server->response_q);
205 }
206 }
207 return rc;
208}
209
fb8c4b14 210/*
e4eb295d
SF
211 return codes:
212 0 not a transact2, or all data present
213 >0 transact2 with that much data missing
214 -EINVAL = invalid transact2
215
216 */
fb8c4b14 217static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
e4eb295d 218{
fb8c4b14
SF
219 struct smb_t2_rsp *pSMBt;
220 int total_data_size;
e4eb295d
SF
221 int data_in_this_rsp;
222 int remaining;
223
fb8c4b14 224 if (pSMB->Command != SMB_COM_TRANSACTION2)
e4eb295d
SF
225 return 0;
226
fb8c4b14
SF
227 /* check for plausible wct, bcc and t2 data and parm sizes */
228 /* check for parm and data offset going beyond end of smb */
229 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
b6b38f70 230 cFYI(1, "invalid transact2 word count");
e4eb295d
SF
231 return -EINVAL;
232 }
233
234 pSMBt = (struct smb_t2_rsp *)pSMB;
235
236 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
237 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
238
239 remaining = total_data_size - data_in_this_rsp;
240
fb8c4b14 241 if (remaining == 0)
e4eb295d 242 return 0;
fb8c4b14 243 else if (remaining < 0) {
b6b38f70
JP
244 cFYI(1, "total data %d smaller than data in frame %d",
245 total_data_size, data_in_this_rsp);
e4eb295d
SF
246 return -EINVAL;
247 } else {
b6b38f70
JP
248 cFYI(1, "missing %d bytes from transact2, check next response",
249 remaining);
fb8c4b14 250 if (total_data_size > maxBufSize) {
b6b38f70
JP
251 cERROR(1, "TotalDataSize %d is over maximum buffer %d",
252 total_data_size, maxBufSize);
fb8c4b14 253 return -EINVAL;
e4eb295d
SF
254 }
255 return remaining;
256 }
257}
258
fb8c4b14 259static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
e4eb295d
SF
260{
261 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
262 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
263 int total_data_size;
264 int total_in_buf;
265 int remaining;
266 int total_in_buf2;
fb8c4b14
SF
267 char *data_area_of_target;
268 char *data_area_of_buf2;
e4eb295d
SF
269 __u16 byte_count;
270
271 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
272
fb8c4b14 273 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
b6b38f70 274 cFYI(1, "total data size of primary and secondary t2 differ");
e4eb295d
SF
275 }
276
277 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
278
279 remaining = total_data_size - total_in_buf;
50c2f753 280
fb8c4b14 281 if (remaining < 0)
e4eb295d
SF
282 return -EINVAL;
283
fb8c4b14 284 if (remaining == 0) /* nothing to do, ignore */
e4eb295d 285 return 0;
50c2f753 286
e4eb295d 287 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
fb8c4b14 288 if (remaining < total_in_buf2) {
b6b38f70 289 cFYI(1, "transact2 2nd response contains too much data");
e4eb295d
SF
290 }
291
292 /* find end of first SMB data area */
fb8c4b14 293 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
e4eb295d
SF
294 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
295 /* validate target area */
296
297 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
fb8c4b14 298 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
e4eb295d
SF
299
300 data_area_of_target += total_in_buf;
301
302 /* copy second buffer into end of first buffer */
fb8c4b14 303 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
e4eb295d
SF
304 total_in_buf += total_in_buf2;
305 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
306 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
307 byte_count += total_in_buf2;
308 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
309
70ca734a 310 byte_count = pTargetSMB->smb_buf_length;
e4eb295d
SF
311 byte_count += total_in_buf2;
312
313 /* BB also add check that we are not beyond maximum buffer size */
50c2f753 314
70ca734a 315 pTargetSMB->smb_buf_length = byte_count;
e4eb295d 316
fb8c4b14 317 if (remaining == total_in_buf2) {
b6b38f70 318 cFYI(1, "found the last secondary response");
e4eb295d
SF
319 return 0; /* we are done */
320 } else /* more responses to go */
321 return 1;
322
323}
324
1da177e4
LT
325static int
326cifs_demultiplex_thread(struct TCP_Server_Info *server)
327{
328 int length;
329 unsigned int pdu_length, total_read;
330 struct smb_hdr *smb_buffer = NULL;
b8643e1b
SF
331 struct smb_hdr *bigbuf = NULL;
332 struct smb_hdr *smallbuf = NULL;
1da177e4
LT
333 struct msghdr smb_msg;
334 struct kvec iov;
335 struct socket *csocket = server->ssocket;
336 struct list_head *tmp;
337 struct cifsSesInfo *ses;
338 struct task_struct *task_to_wake = NULL;
339 struct mid_q_entry *mid_entry;
70ca734a 340 char temp;
4b18f2a9
SF
341 bool isLargeBuf = false;
342 bool isMultiRsp;
e4eb295d 343 int reconnect;
1da177e4 344
1da177e4 345 current->flags |= PF_MEMALLOC;
b6b38f70 346 cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
93d0ec85
JL
347
348 length = atomic_inc_return(&tcpSesAllocCount);
349 if (length > 1)
26f57364
SF
350 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
351 GFP_KERNEL);
1da177e4 352
83144186 353 set_freezable();
469ee614 354 while (server->tcpStatus != CifsExiting) {
ede1327e
SF
355 if (try_to_freeze())
356 continue;
b8643e1b
SF
357 if (bigbuf == NULL) {
358 bigbuf = cifs_buf_get();
0fd1ffe0 359 if (!bigbuf) {
b6b38f70 360 cERROR(1, "No memory for large SMB response");
b8643e1b
SF
361 msleep(3000);
362 /* retry will check if exiting */
363 continue;
364 }
0fd1ffe0
PM
365 } else if (isLargeBuf) {
366 /* we are reusing a dirty large buf, clear its start */
26f57364 367 memset(bigbuf, 0, sizeof(struct smb_hdr));
1da177e4 368 }
b8643e1b
SF
369
370 if (smallbuf == NULL) {
371 smallbuf = cifs_small_buf_get();
0fd1ffe0 372 if (!smallbuf) {
b6b38f70 373 cERROR(1, "No memory for SMB response");
b8643e1b
SF
374 msleep(1000);
375 /* retry will check if exiting */
376 continue;
377 }
378 /* beginning of smb buffer is cleared in our buf_get */
379 } else /* if existing small buf clear beginning */
26f57364 380 memset(smallbuf, 0, sizeof(struct smb_hdr));
b8643e1b 381
4b18f2a9
SF
382 isLargeBuf = false;
383 isMultiRsp = false;
b8643e1b 384 smb_buffer = smallbuf;
1da177e4
LT
385 iov.iov_base = smb_buffer;
386 iov.iov_len = 4;
387 smb_msg.msg_control = NULL;
388 smb_msg.msg_controllen = 0;
f01d5e14
SF
389 pdu_length = 4; /* enough to get RFC1001 header */
390incomplete_rcv:
1da177e4
LT
391 length =
392 kernel_recvmsg(csocket, &smb_msg,
f01d5e14 393 &iov, 1, pdu_length, 0 /* BB other flags? */);
1da177e4 394
469ee614 395 if (server->tcpStatus == CifsExiting) {
1da177e4
LT
396 break;
397 } else if (server->tcpStatus == CifsNeedReconnect) {
b6b38f70 398 cFYI(1, "Reconnect after server stopped responding");
1da177e4 399 cifs_reconnect(server);
b6b38f70 400 cFYI(1, "call to reconnect done");
1da177e4
LT
401 csocket = server->ssocket;
402 continue;
522bbe65
JL
403 } else if (length == -ERESTARTSYS ||
404 length == -EAGAIN ||
405 length == -EINTR) {
b8643e1b 406 msleep(1); /* minimum sleep to prevent looping
1da177e4
LT
407 allowing socket to clear and app threads to set
408 tcpStatus CifsNeedReconnect if server hung */
c527c8a7
SF
409 if (pdu_length < 4) {
410 iov.iov_base = (4 - pdu_length) +
411 (char *)smb_buffer;
412 iov.iov_len = pdu_length;
413 smb_msg.msg_control = NULL;
414 smb_msg.msg_controllen = 0;
c18c732e 415 goto incomplete_rcv;
c527c8a7 416 } else
c18c732e 417 continue;
1da177e4 418 } else if (length <= 0) {
0fd1ffe0 419 if (server->tcpStatus == CifsNew) {
b6b38f70 420 cFYI(1, "tcp session abend after SMBnegprot");
09d1db5c
SF
421 /* some servers kill the TCP session rather than
422 returning an SMB negprot error, in which
423 case reconnecting here is not going to help,
424 and so simply return error to mount */
1da177e4
LT
425 break;
426 }
b6b38f70
JP
427 cFYI(1, "Reconnect after unexpected peek error %d",
428 length);
1da177e4
LT
429 cifs_reconnect(server);
430 csocket = server->ssocket;
431 wake_up(&server->response_q);
432 continue;
2a974680 433 } else if (length < pdu_length) {
b6b38f70
JP
434 cFYI(1, "requested %d bytes but only got %d bytes",
435 pdu_length, length);
f01d5e14 436 pdu_length -= length;
f01d5e14
SF
437 msleep(1);
438 goto incomplete_rcv;
46810cbf 439 }
1da177e4 440
70ca734a
SF
441 /* The right amount was read from socket - 4 bytes */
442 /* so we can now interpret the length field */
46810cbf 443
70ca734a
SF
444 /* the first byte big endian of the length field,
445 is actually not part of the length but the type
446 with the most common, zero, as regular data */
447 temp = *((char *) smb_buffer);
46810cbf 448
fb8c4b14 449 /* Note that FC 1001 length is big endian on the wire,
70ca734a
SF
450 but we convert it here so it is always manipulated
451 as host byte order */
5ca33c6a 452 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
70ca734a
SF
453 smb_buffer->smb_buf_length = pdu_length;
454
b6b38f70 455 cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
46810cbf 456
70ca734a 457 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
fb8c4b14 458 continue;
70ca734a 459 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
b6b38f70 460 cFYI(1, "Good RFC 1002 session rsp");
e4eb295d 461 continue;
70ca734a 462 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
fb8c4b14 463 /* we get this from Windows 98 instead of
46810cbf 464 an error on SMB negprot response */
b6b38f70
JP
465 cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
466 pdu_length);
fb8c4b14
SF
467 if (server->tcpStatus == CifsNew) {
468 /* if nack on negprot (rather than
46810cbf
SF
469 ret of smb negprot error) reconnecting
470 not going to help, ret error to mount */
471 break;
472 } else {
473 /* give server a second to
474 clean up before reconnect attempt */
475 msleep(1000);
476 /* always try 445 first on reconnect
477 since we get NACK on some if we ever
fb8c4b14 478 connected to port 139 (the NACK is
46810cbf
SF
479 since we do not begin with RFC1001
480 session initialize frame) */
fb8c4b14 481 server->addr.sockAddr.sin_port =
46810cbf 482 htons(CIFS_PORT);
1da177e4
LT
483 cifs_reconnect(server);
484 csocket = server->ssocket;
46810cbf 485 wake_up(&server->response_q);
1da177e4 486 continue;
46810cbf 487 }
70ca734a 488 } else if (temp != (char) 0) {
b6b38f70 489 cERROR(1, "Unknown RFC 1002 frame");
70ca734a
SF
490 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
491 length);
46810cbf
SF
492 cifs_reconnect(server);
493 csocket = server->ssocket;
494 continue;
e4eb295d
SF
495 }
496
497 /* else we have an SMB response */
fb8c4b14 498 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
26f57364 499 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
b6b38f70
JP
500 cERROR(1, "Invalid size SMB length %d pdu_length %d",
501 length, pdu_length+4);
e4eb295d
SF
502 cifs_reconnect(server);
503 csocket = server->ssocket;
504 wake_up(&server->response_q);
505 continue;
fb8c4b14 506 }
e4eb295d
SF
507
508 /* else length ok */
509 reconnect = 0;
510
fb8c4b14 511 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
4b18f2a9 512 isLargeBuf = true;
e4eb295d
SF
513 memcpy(bigbuf, smallbuf, 4);
514 smb_buffer = bigbuf;
515 }
516 length = 0;
517 iov.iov_base = 4 + (char *)smb_buffer;
518 iov.iov_len = pdu_length;
fb8c4b14 519 for (total_read = 0; total_read < pdu_length;
e4eb295d
SF
520 total_read += length) {
521 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
522 pdu_length - total_read, 0);
522bbe65 523 if (server->tcpStatus == CifsExiting) {
e4eb295d
SF
524 /* then will exit */
525 reconnect = 2;
526 break;
527 } else if (server->tcpStatus == CifsNeedReconnect) {
46810cbf
SF
528 cifs_reconnect(server);
529 csocket = server->ssocket;
fb8c4b14 530 /* Reconnect wakes up rspns q */
e4eb295d
SF
531 /* Now we will reread sock */
532 reconnect = 1;
533 break;
522bbe65
JL
534 } else if (length == -ERESTARTSYS ||
535 length == -EAGAIN ||
536 length == -EINTR) {
e4eb295d 537 msleep(1); /* minimum sleep to prevent looping,
fb8c4b14 538 allowing socket to clear and app
e4eb295d
SF
539 threads to set tcpStatus
540 CifsNeedReconnect if server hung*/
c18c732e 541 length = 0;
46810cbf 542 continue;
e4eb295d 543 } else if (length <= 0) {
b6b38f70
JP
544 cERROR(1, "Received no data, expecting %d",
545 pdu_length - total_read);
e4eb295d
SF
546 cifs_reconnect(server);
547 csocket = server->ssocket;
548 reconnect = 1;
549 break;
46810cbf 550 }
e4eb295d 551 }
fb8c4b14 552 if (reconnect == 2)
e4eb295d 553 break;
fb8c4b14 554 else if (reconnect == 1)
e4eb295d 555 continue;
1da177e4 556
e4eb295d 557 length += 4; /* account for rfc1002 hdr */
50c2f753 558
09d1db5c 559
e4eb295d 560 dump_smb(smb_buffer, length);
184ed211 561 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
b387eaeb 562 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
e4eb295d
SF
563 continue;
564 }
1da177e4 565
e4eb295d
SF
566
567 task_to_wake = NULL;
568 spin_lock(&GlobalMid_Lock);
569 list_for_each(tmp, &server->pending_mid_q) {
570 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
571
50c2f753 572 if ((mid_entry->mid == smb_buffer->Mid) &&
e4eb295d
SF
573 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
574 (mid_entry->command == smb_buffer->Command)) {
fb8c4b14 575 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
e4eb295d 576 /* We have a multipart transact2 resp */
4b18f2a9 577 isMultiRsp = true;
fb8c4b14 578 if (mid_entry->resp_buf) {
e4eb295d 579 /* merge response - fix up 1st*/
50c2f753 580 if (coalesce_t2(smb_buffer,
e4eb295d 581 mid_entry->resp_buf)) {
4b18f2a9
SF
582 mid_entry->multiRsp =
583 true;
e4eb295d
SF
584 break;
585 } else {
586 /* all parts received */
4b18f2a9
SF
587 mid_entry->multiEnd =
588 true;
50c2f753 589 goto multi_t2_fnd;
e4eb295d
SF
590 }
591 } else {
fb8c4b14 592 if (!isLargeBuf) {
b6b38f70 593 cERROR(1, "1st trans2 resp needs bigbuf");
e4eb295d 594 /* BB maybe we can fix this up, switch
50c2f753 595 to already allocated large buffer? */
e4eb295d 596 } else {
cd63499c 597 /* Have first buffer */
e4eb295d
SF
598 mid_entry->resp_buf =
599 smb_buffer;
4b18f2a9
SF
600 mid_entry->largeBuf =
601 true;
e4eb295d
SF
602 bigbuf = NULL;
603 }
604 }
605 break;
50c2f753 606 }
e4eb295d 607 mid_entry->resp_buf = smb_buffer;
4b18f2a9 608 mid_entry->largeBuf = isLargeBuf;
e4eb295d
SF
609multi_t2_fnd:
610 task_to_wake = mid_entry->tsk;
611 mid_entry->midState = MID_RESPONSE_RECEIVED;
1047abc1
SF
612#ifdef CONFIG_CIFS_STATS2
613 mid_entry->when_received = jiffies;
614#endif
3a5ff61c
SF
615 /* so we do not time out requests to server
616 which is still responding (since server could
617 be busy but not dead) */
618 server->lstrp = jiffies;
e4eb295d 619 break;
46810cbf 620 }
1da177e4 621 }
e4eb295d
SF
622 spin_unlock(&GlobalMid_Lock);
623 if (task_to_wake) {
cd63499c 624 /* Was previous buf put in mpx struct for multi-rsp? */
fb8c4b14 625 if (!isMultiRsp) {
cd63499c 626 /* smb buffer will be freed by user thread */
26f57364 627 if (isLargeBuf)
cd63499c 628 bigbuf = NULL;
26f57364 629 else
cd63499c
SF
630 smallbuf = NULL;
631 }
e4eb295d 632 wake_up_process(task_to_wake);
4b18f2a9
SF
633 } else if (!is_valid_oplock_break(smb_buffer, server) &&
634 !isMultiRsp) {
b6b38f70
JP
635 cERROR(1, "No task to wake, unknown frame received! "
636 "NumMids %d", midCount.counter);
50c2f753 637 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
70ca734a 638 sizeof(struct smb_hdr));
3979877e
SF
639#ifdef CONFIG_CIFS_DEBUG2
640 cifs_dump_detail(smb_buffer);
641 cifs_dump_mids(server);
642#endif /* CIFS_DEBUG2 */
50c2f753 643
e4eb295d
SF
644 }
645 } /* end while !EXITING */
646
e7ddee90
JL
647 /* take it off the list, if it's not already */
648 write_lock(&cifs_tcp_ses_lock);
649 list_del_init(&server->tcp_ses_list);
650 write_unlock(&cifs_tcp_ses_lock);
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 683
14fbf50d
JL
684 /*
685 * BB: we shouldn't have to do any of this. It shouldn't be
686 * possible to exit from the thread with active SMB sessions
687 */
688 read_lock(&cifs_tcp_ses_lock);
1da177e4 689 if (list_empty(&server->pending_mid_q)) {
09d1db5c
SF
690 /* loop through server session structures attached to this and
691 mark them dead */
14fbf50d
JL
692 list_for_each(tmp, &server->smb_ses_list) {
693 ses = list_entry(tmp, struct cifsSesInfo,
694 smb_ses_list);
695 ses->status = CifsExiting;
696 ses->server = NULL;
1da177e4 697 }
14fbf50d 698 read_unlock(&cifs_tcp_ses_lock);
1da177e4 699 } else {
31ca3bc3
SF
700 /* although we can not zero the server struct pointer yet,
701 since there are active requests which may depnd on them,
702 mark the corresponding SMB sessions as exiting too */
14fbf50d 703 list_for_each(tmp, &server->smb_ses_list) {
31ca3bc3 704 ses = list_entry(tmp, struct cifsSesInfo,
14fbf50d
JL
705 smb_ses_list);
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) {
b6b38f70
JP
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);
14fbf50d 721 read_unlock(&cifs_tcp_ses_lock);
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 */
b6b38f70 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) */
14fbf50d
JL
743 /* BB: This shouldn't be necessary, see above */
744 read_lock(&cifs_tcp_ses_lock);
745 list_for_each(tmp, &server->smb_ses_list) {
746 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
747 ses->server = NULL;
31ca3bc3 748 }
14fbf50d 749 read_unlock(&cifs_tcp_ses_lock);
31ca3bc3 750
c359cf3c 751 kfree(server->hostname);
b1c8d2b4 752 task_to_wake = xchg(&server->tsk, NULL);
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
b1c8d2b4
JL
760 /* if server->tsk was NULL then wait for a signal before exiting */
761 if (!task_to_wake) {
762 set_current_state(TASK_INTERRUPTIBLE);
763 while (!signal_pending(current)) {
764 schedule();
765 set_current_state(TASK_INTERRUPTIBLE);
766 }
767 set_current_state(TASK_RUNNING);
768 }
769
0468a2cf 770 module_put_and_exit(0);
1da177e4
LT
771}
772
c359cf3c
JL
773/* extract the host portion of the UNC string */
774static char *
775extract_hostname(const char *unc)
776{
777 const char *src;
778 char *dst, *delim;
779 unsigned int len;
780
781 /* skip double chars at beginning of string */
782 /* BB: check validity of these bytes? */
783 src = unc + 2;
784
785 /* delimiter between hostname and sharename is always '\\' now */
786 delim = strchr(src, '\\');
787 if (!delim)
788 return ERR_PTR(-EINVAL);
789
790 len = delim - src;
791 dst = kmalloc((len + 1), GFP_KERNEL);
792 if (dst == NULL)
793 return ERR_PTR(-ENOMEM);
794
795 memcpy(dst, src, len);
796 dst[len] = '\0';
797
798 return dst;
799}
800
1da177e4 801static int
50c2f753
SF
802cifs_parse_mount_options(char *options, const char *devname,
803 struct smb_vol *vol)
1da177e4
LT
804{
805 char *value;
806 char *data;
807 unsigned int temp_len, i, j;
808 char separator[2];
9b9d6b24
JL
809 short int override_uid = -1;
810 short int override_gid = -1;
811 bool uid_specified = false;
812 bool gid_specified = false;
1da177e4
LT
813
814 separator[0] = ',';
50c2f753 815 separator[1] = 0;
1da177e4 816
12e36b2f 817 if (Local_System_Name[0] != 0)
50c2f753 818 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
2cd646a2 819 else {
12e36b2f 820 char *nodename = utsname()->nodename;
50c2f753
SF
821 int n = strnlen(nodename, 15);
822 memset(vol->source_rfc1001_name, 0x20, 15);
823 for (i = 0; i < n; i++) {
2cd646a2
SF
824 /* does not have to be perfect mapping since field is
825 informational, only used for servers that do not support
826 port 445 and it can be overridden at mount time */
12e36b2f 827 vol->source_rfc1001_name[i] = toupper(nodename[i]);
2cd646a2 828 }
1da177e4
LT
829 }
830 vol->source_rfc1001_name[15] = 0;
a10faeb2
SF
831 /* null target name indicates to use *SMBSERVR default called name
832 if we end up sending RFC1001 session initialize */
833 vol->target_rfc1001_name[0] = 0;
3e4b3e1f
JL
834 vol->cred_uid = current_uid();
835 vol->linux_uid = current_uid();
a001e5b5 836 vol->linux_gid = current_gid();
f55ed1a8
JL
837
838 /* default to only allowing write access to owner of the mount */
839 vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
1da177e4
LT
840
841 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
ac67055e
JA
842 /* default is always to request posix paths. */
843 vol->posix_paths = 1;
a0c9217f
JL
844 /* default to using server inode numbers where available */
845 vol->server_ino = 1;
ac67055e 846
1da177e4
LT
847 if (!options)
848 return 1;
849
50c2f753 850 if (strncmp(options, "sep=", 4) == 0) {
fb8c4b14 851 if (options[4] != 0) {
1da177e4
LT
852 separator[0] = options[4];
853 options += 5;
854 } else {
b6b38f70 855 cFYI(1, "Null separator not allowed");
1da177e4
LT
856 }
857 }
50c2f753 858
1da177e4
LT
859 while ((data = strsep(&options, separator)) != NULL) {
860 if (!*data)
861 continue;
862 if ((value = strchr(data, '=')) != NULL)
863 *value++ = '\0';
864
50c2f753
SF
865 /* Have to parse this before we parse for "user" */
866 if (strnicmp(data, "user_xattr", 10) == 0) {
1da177e4 867 vol->no_xattr = 0;
50c2f753 868 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
1da177e4
LT
869 vol->no_xattr = 1;
870 } else if (strnicmp(data, "user", 4) == 0) {
4b952a9b 871 if (!value) {
1da177e4
LT
872 printk(KERN_WARNING
873 "CIFS: invalid or missing username\n");
874 return 1; /* needs_arg; */
fb8c4b14 875 } else if (!*value) {
4b952a9b
SF
876 /* null user, ie anonymous, authentication */
877 vol->nullauth = 1;
1da177e4
LT
878 }
879 if (strnlen(value, 200) < 200) {
880 vol->username = value;
881 } else {
882 printk(KERN_WARNING "CIFS: username too long\n");
883 return 1;
884 }
885 } else if (strnicmp(data, "pass", 4) == 0) {
886 if (!value) {
887 vol->password = NULL;
888 continue;
fb8c4b14 889 } else if (value[0] == 0) {
1da177e4
LT
890 /* check if string begins with double comma
891 since that would mean the password really
892 does start with a comma, and would not
893 indicate an empty string */
fb8c4b14 894 if (value[1] != separator[0]) {
1da177e4
LT
895 vol->password = NULL;
896 continue;
897 }
898 }
899 temp_len = strlen(value);
900 /* removed password length check, NTLM passwords
901 can be arbitrarily long */
902
50c2f753 903 /* if comma in password, the string will be
1da177e4
LT
904 prematurely null terminated. Commas in password are
905 specified across the cifs mount interface by a double
906 comma ie ,, and a comma used as in other cases ie ','
907 as a parameter delimiter/separator is single and due
908 to the strsep above is temporarily zeroed. */
909
910 /* NB: password legally can have multiple commas and
911 the only illegal character in a password is null */
912
50c2f753 913 if ((value[temp_len] == 0) &&
09d1db5c 914 (value[temp_len+1] == separator[0])) {
1da177e4
LT
915 /* reinsert comma */
916 value[temp_len] = separator[0];
50c2f753
SF
917 temp_len += 2; /* move after second comma */
918 while (value[temp_len] != 0) {
1da177e4 919 if (value[temp_len] == separator[0]) {
50c2f753 920 if (value[temp_len+1] ==
09d1db5c
SF
921 separator[0]) {
922 /* skip second comma */
923 temp_len++;
50c2f753 924 } else {
1da177e4
LT
925 /* single comma indicating start
926 of next parm */
927 break;
928 }
929 }
930 temp_len++;
931 }
fb8c4b14 932 if (value[temp_len] == 0) {
1da177e4
LT
933 options = NULL;
934 } else {
935 value[temp_len] = 0;
936 /* point option to start of next parm */
937 options = value + temp_len + 1;
938 }
50c2f753 939 /* go from value to value + temp_len condensing
1da177e4
LT
940 double commas to singles. Note that this ends up
941 allocating a few bytes too many, which is ok */
e915fc49 942 vol->password = kzalloc(temp_len, 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 }
50c2f753 948 for (i = 0, j = 0; i < temp_len; i++, j++) {
1da177e4 949 vol->password[j] = value[i];
fb8c4b14 950 if (value[i] == separator[0]
09d1db5c 951 && value[i+1] == separator[0]) {
1da177e4
LT
952 /* skip second comma */
953 i++;
954 }
955 }
956 vol->password[j] = 0;
957 } else {
e915fc49 958 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
fb8c4b14 959 if (vol->password == NULL) {
50c2f753
SF
960 printk(KERN_WARNING "CIFS: no memory "
961 "for password\n");
433dc24f
SF
962 return 1;
963 }
1da177e4
LT
964 strcpy(vol->password, value);
965 }
58f7f68f
JL
966 } else if (!strnicmp(data, "ip", 2) ||
967 !strnicmp(data, "addr", 4)) {
1da177e4
LT
968 if (!value || !*value) {
969 vol->UNCip = NULL;
50b64e3b
JL
970 } else if (strnlen(value, INET6_ADDRSTRLEN) <
971 INET6_ADDRSTRLEN) {
1da177e4
LT
972 vol->UNCip = value;
973 } else {
50c2f753
SF
974 printk(KERN_WARNING "CIFS: ip address "
975 "too long\n");
1da177e4
LT
976 return 1;
977 }
50c2f753
SF
978 } else if (strnicmp(data, "sec", 3) == 0) {
979 if (!value || !*value) {
b6b38f70 980 cERROR(1, "no security value specified");
50c2f753
SF
981 continue;
982 } else if (strnicmp(value, "krb5i", 5) == 0) {
983 vol->secFlg |= CIFSSEC_MAY_KRB5 |
189acaae 984 CIFSSEC_MUST_SIGN;
bf820679 985 } else if (strnicmp(value, "krb5p", 5) == 0) {
50c2f753
SF
986 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
987 CIFSSEC_MAY_KRB5; */
b6b38f70 988 cERROR(1, "Krb5 cifs privacy not supported");
bf820679
SF
989 return 1;
990 } else if (strnicmp(value, "krb5", 4) == 0) {
750d1151 991 vol->secFlg |= CIFSSEC_MAY_KRB5;
ac683924
SF
992#ifdef CONFIG_CIFS_EXPERIMENTAL
993 } else if (strnicmp(value, "ntlmsspi", 8) == 0) {
994 vol->secFlg |= CIFSSEC_MAY_NTLMSSP |
995 CIFSSEC_MUST_SIGN;
996 } else if (strnicmp(value, "ntlmssp", 7) == 0) {
997 vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
998#endif
bf820679 999 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
750d1151 1000 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
189acaae 1001 CIFSSEC_MUST_SIGN;
bf820679 1002 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
750d1151 1003 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
bf820679 1004 } else if (strnicmp(value, "ntlmi", 5) == 0) {
750d1151 1005 vol->secFlg |= CIFSSEC_MAY_NTLM |
189acaae 1006 CIFSSEC_MUST_SIGN;
bf820679
SF
1007 } else if (strnicmp(value, "ntlm", 4) == 0) {
1008 /* ntlm is default so can be turned off too */
750d1151 1009 vol->secFlg |= CIFSSEC_MAY_NTLM;
bf820679 1010 } else if (strnicmp(value, "nontlm", 6) == 0) {
189acaae 1011 /* BB is there a better way to do this? */
750d1151 1012 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
189acaae
SF
1013#ifdef CONFIG_CIFS_WEAK_PW_HASH
1014 } else if (strnicmp(value, "lanman", 6) == 0) {
50c2f753 1015 vol->secFlg |= CIFSSEC_MAY_LANMAN;
189acaae 1016#endif
bf820679 1017 } else if (strnicmp(value, "none", 4) == 0) {
189acaae 1018 vol->nullauth = 1;
50c2f753 1019 } else {
b6b38f70 1020 cERROR(1, "bad security option: %s", value);
50c2f753
SF
1021 return 1;
1022 }
1da177e4
LT
1023 } else if ((strnicmp(data, "unc", 3) == 0)
1024 || (strnicmp(data, "target", 6) == 0)
1025 || (strnicmp(data, "path", 4) == 0)) {
1026 if (!value || !*value) {
50c2f753
SF
1027 printk(KERN_WARNING "CIFS: invalid path to "
1028 "network resource\n");
1da177e4
LT
1029 return 1; /* needs_arg; */
1030 }
1031 if ((temp_len = strnlen(value, 300)) < 300) {
50c2f753 1032 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
4523cc30 1033 if (vol->UNC == NULL)
1da177e4 1034 return 1;
50c2f753 1035 strcpy(vol->UNC, value);
1da177e4
LT
1036 if (strncmp(vol->UNC, "//", 2) == 0) {
1037 vol->UNC[0] = '\\';
1038 vol->UNC[1] = '\\';
50c2f753 1039 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1da177e4 1040 printk(KERN_WARNING
50c2f753
SF
1041 "CIFS: UNC Path does not begin "
1042 "with // or \\\\ \n");
1da177e4
LT
1043 return 1;
1044 }
1045 } else {
1046 printk(KERN_WARNING "CIFS: UNC name too long\n");
1047 return 1;
1048 }
1049 } else if ((strnicmp(data, "domain", 3) == 0)
1050 || (strnicmp(data, "workgroup", 5) == 0)) {
1051 if (!value || !*value) {
1052 printk(KERN_WARNING "CIFS: invalid domain name\n");
1053 return 1; /* needs_arg; */
1054 }
1055 /* BB are there cases in which a comma can be valid in
1056 a domain name and need special handling? */
3979877e 1057 if (strnlen(value, 256) < 256) {
1da177e4 1058 vol->domainname = value;
b6b38f70 1059 cFYI(1, "Domain name set");
1da177e4 1060 } else {
50c2f753
SF
1061 printk(KERN_WARNING "CIFS: domain name too "
1062 "long\n");
1da177e4
LT
1063 return 1;
1064 }
50c2f753
SF
1065 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1066 if (!value || !*value) {
1067 printk(KERN_WARNING
1068 "CIFS: invalid path prefix\n");
1069 return 1; /* needs_argument */
1070 }
1071 if ((temp_len = strnlen(value, 1024)) < 1024) {
4523cc30 1072 if (value[0] != '/')
2fe87f02 1073 temp_len++; /* missing leading slash */
50c2f753
SF
1074 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1075 if (vol->prepath == NULL)
1076 return 1;
4523cc30 1077 if (value[0] != '/') {
2fe87f02 1078 vol->prepath[0] = '/';
50c2f753 1079 strcpy(vol->prepath+1, value);
2fe87f02 1080 } else
50c2f753 1081 strcpy(vol->prepath, value);
b6b38f70 1082 cFYI(1, "prefix path %s", vol->prepath);
50c2f753
SF
1083 } else {
1084 printk(KERN_WARNING "CIFS: prefix too long\n");
1085 return 1;
1086 }
1da177e4
LT
1087 } else if (strnicmp(data, "iocharset", 9) == 0) {
1088 if (!value || !*value) {
63135e08
SF
1089 printk(KERN_WARNING "CIFS: invalid iocharset "
1090 "specified\n");
1da177e4
LT
1091 return 1; /* needs_arg; */
1092 }
1093 if (strnlen(value, 65) < 65) {
50c2f753 1094 if (strnicmp(value, "default", 7))
1da177e4 1095 vol->iocharset = value;
50c2f753
SF
1096 /* if iocharset not set then load_nls_default
1097 is used by caller */
b6b38f70 1098 cFYI(1, "iocharset set to %s", value);
1da177e4 1099 } else {
63135e08
SF
1100 printk(KERN_WARNING "CIFS: iocharset name "
1101 "too long.\n");
1da177e4
LT
1102 return 1;
1103 }
9b9d6b24
JL
1104 } else if (!strnicmp(data, "uid", 3) && value && *value) {
1105 vol->linux_uid = simple_strtoul(value, &value, 0);
1106 uid_specified = true;
1107 } else if (!strnicmp(data, "forceuid", 8)) {
1108 override_uid = 1;
1109 } else if (!strnicmp(data, "noforceuid", 10)) {
1110 override_uid = 0;
1111 } else if (!strnicmp(data, "gid", 3) && value && *value) {
1112 vol->linux_gid = simple_strtoul(value, &value, 0);
1113 gid_specified = true;
1114 } else if (!strnicmp(data, "forcegid", 8)) {
1115 override_gid = 1;
1116 } else if (!strnicmp(data, "noforcegid", 10)) {
1117 override_gid = 0;
1da177e4
LT
1118 } else if (strnicmp(data, "file_mode", 4) == 0) {
1119 if (value && *value) {
1120 vol->file_mode =
1121 simple_strtoul(value, &value, 0);
1122 }
1123 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1124 if (value && *value) {
1125 vol->dir_mode =
1126 simple_strtoul(value, &value, 0);
1127 }
1128 } else if (strnicmp(data, "dirmode", 4) == 0) {
1129 if (value && *value) {
1130 vol->dir_mode =
1131 simple_strtoul(value, &value, 0);
1132 }
1133 } else if (strnicmp(data, "port", 4) == 0) {
1134 if (value && *value) {
1135 vol->port =
1136 simple_strtoul(value, &value, 0);
1137 }
1138 } else if (strnicmp(data, "rsize", 5) == 0) {
1139 if (value && *value) {
1140 vol->rsize =
1141 simple_strtoul(value, &value, 0);
1142 }
1143 } else if (strnicmp(data, "wsize", 5) == 0) {
1144 if (value && *value) {
1145 vol->wsize =
1146 simple_strtoul(value, &value, 0);
1147 }
1148 } else if (strnicmp(data, "sockopt", 5) == 0) {
6a5fa236 1149 if (!value || !*value) {
b6b38f70 1150 cERROR(1, "no socket option specified");
6a5fa236
SF
1151 continue;
1152 } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
1153 vol->sockopt_tcp_nodelay = 1;
1da177e4
LT
1154 }
1155 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1156 if (!value || !*value || (*value == ' ')) {
b6b38f70 1157 cFYI(1, "invalid (empty) netbiosname");
1da177e4 1158 } else {
50c2f753
SF
1159 memset(vol->source_rfc1001_name, 0x20, 15);
1160 for (i = 0; i < 15; i++) {
1161 /* BB are there cases in which a comma can be
1da177e4
LT
1162 valid in this workstation netbios name (and need
1163 special handling)? */
1164
1165 /* We do not uppercase netbiosname for user */
50c2f753 1166 if (value[i] == 0)
1da177e4 1167 break;
50c2f753
SF
1168 else
1169 vol->source_rfc1001_name[i] =
1170 value[i];
1da177e4
LT
1171 }
1172 /* The string has 16th byte zero still from
1173 set at top of the function */
50c2f753
SF
1174 if ((i == 15) && (value[i] != 0))
1175 printk(KERN_WARNING "CIFS: netbiosname"
1176 " longer than 15 truncated.\n");
a10faeb2
SF
1177 }
1178 } else if (strnicmp(data, "servern", 7) == 0) {
1179 /* servernetbiosname specified override *SMBSERVER */
1180 if (!value || !*value || (*value == ' ')) {
b6b38f70 1181 cFYI(1, "empty server netbiosname specified");
a10faeb2
SF
1182 } else {
1183 /* last byte, type, is 0x20 for servr type */
50c2f753 1184 memset(vol->target_rfc1001_name, 0x20, 16);
a10faeb2 1185
50c2f753 1186 for (i = 0; i < 15; i++) {
a10faeb2 1187 /* BB are there cases in which a comma can be
50c2f753
SF
1188 valid in this workstation netbios name
1189 (and need special handling)? */
a10faeb2 1190
50c2f753
SF
1191 /* user or mount helper must uppercase
1192 the netbiosname */
1193 if (value[i] == 0)
a10faeb2
SF
1194 break;
1195 else
50c2f753
SF
1196 vol->target_rfc1001_name[i] =
1197 value[i];
a10faeb2
SF
1198 }
1199 /* The string has 16th byte zero still from
1200 set at top of the function */
50c2f753
SF
1201 if ((i == 15) && (value[i] != 0))
1202 printk(KERN_WARNING "CIFS: server net"
1203 "biosname longer than 15 truncated.\n");
1da177e4
LT
1204 }
1205 } else if (strnicmp(data, "credentials", 4) == 0) {
1206 /* ignore */
1207 } else if (strnicmp(data, "version", 3) == 0) {
1208 /* ignore */
50c2f753 1209 } else if (strnicmp(data, "guest", 5) == 0) {
1da177e4 1210 /* ignore */
71a394fa
SF
1211 } else if (strnicmp(data, "rw", 2) == 0) {
1212 /* ignore */
1213 } else if (strnicmp(data, "ro", 2) == 0) {
1214 /* ignore */
edf1ae40
SF
1215 } else if (strnicmp(data, "noblocksend", 11) == 0) {
1216 vol->noblocksnd = 1;
1217 } else if (strnicmp(data, "noautotune", 10) == 0) {
1218 vol->noautotune = 1;
1da177e4
LT
1219 } else if ((strnicmp(data, "suid", 4) == 0) ||
1220 (strnicmp(data, "nosuid", 6) == 0) ||
1221 (strnicmp(data, "exec", 4) == 0) ||
1222 (strnicmp(data, "noexec", 6) == 0) ||
1223 (strnicmp(data, "nodev", 5) == 0) ||
1224 (strnicmp(data, "noauto", 6) == 0) ||
1225 (strnicmp(data, "dev", 3) == 0)) {
1226 /* The mount tool or mount.cifs helper (if present)
50c2f753
SF
1227 uses these opts to set flags, and the flags are read
1228 by the kernel vfs layer before we get here (ie
1229 before read super) so there is no point trying to
1230 parse these options again and set anything and it
1231 is ok to just ignore them */
1da177e4 1232 continue;
1da177e4
LT
1233 } else if (strnicmp(data, "hard", 4) == 0) {
1234 vol->retry = 1;
1235 } else if (strnicmp(data, "soft", 4) == 0) {
1236 vol->retry = 0;
1237 } else if (strnicmp(data, "perm", 4) == 0) {
1238 vol->noperm = 0;
1239 } else if (strnicmp(data, "noperm", 6) == 0) {
1240 vol->noperm = 1;
6a0b4824
SF
1241 } else if (strnicmp(data, "mapchars", 8) == 0) {
1242 vol->remap = 1;
1243 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1244 vol->remap = 0;
50c2f753
SF
1245 } else if (strnicmp(data, "sfu", 3) == 0) {
1246 vol->sfu_emul = 1;
1247 } else if (strnicmp(data, "nosfu", 5) == 0) {
1248 vol->sfu_emul = 0;
2c1b8615
SF
1249 } else if (strnicmp(data, "nodfs", 5) == 0) {
1250 vol->nodfs = 1;
ac67055e
JA
1251 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1252 vol->posix_paths = 1;
1253 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1254 vol->posix_paths = 0;
c18c842b
SF
1255 } else if (strnicmp(data, "nounix", 6) == 0) {
1256 vol->no_linux_ext = 1;
1257 } else if (strnicmp(data, "nolinux", 7) == 0) {
1258 vol->no_linux_ext = 1;
50c2f753 1259 } else if ((strnicmp(data, "nocase", 6) == 0) ||
a10faeb2 1260 (strnicmp(data, "ignorecase", 10) == 0)) {
50c2f753 1261 vol->nocase = 1;
f636a348
JL
1262 } else if (strnicmp(data, "mand", 4) == 0) {
1263 /* ignore */
1264 } else if (strnicmp(data, "nomand", 6) == 0) {
1265 /* ignore */
1266 } else if (strnicmp(data, "_netdev", 7) == 0) {
1267 /* ignore */
c46fa8ac
SF
1268 } else if (strnicmp(data, "brl", 3) == 0) {
1269 vol->nobrl = 0;
50c2f753 1270 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1c955187 1271 (strnicmp(data, "nolock", 6) == 0)) {
c46fa8ac 1272 vol->nobrl = 1;
d3485d37
SF
1273 /* turn off mandatory locking in mode
1274 if remote locking is turned off since the
1275 local vfs will do advisory */
50c2f753
SF
1276 if (vol->file_mode ==
1277 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
d3485d37 1278 vol->file_mode = S_IALLUGO;
13a6e42a
SF
1279 } else if (strnicmp(data, "forcemandatorylock", 9) == 0) {
1280 /* will take the shorter form "forcemand" as well */
1281 /* This mount option will force use of mandatory
1282 (DOS/Windows style) byte range locks, instead of
1283 using posix advisory byte range locks, even if the
1284 Unix extensions are available and posix locks would
1285 be supported otherwise. If Unix extensions are not
1286 negotiated this has no effect since mandatory locks
1287 would be used (mandatory locks is all that those
1288 those servers support) */
1289 vol->mand_lock = 1;
1da177e4
LT
1290 } else if (strnicmp(data, "setuids", 7) == 0) {
1291 vol->setuids = 1;
1292 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1293 vol->setuids = 0;
d0a9c078
JL
1294 } else if (strnicmp(data, "dynperm", 7) == 0) {
1295 vol->dynperm = true;
1296 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1297 vol->dynperm = false;
1da177e4
LT
1298 } else if (strnicmp(data, "nohard", 6) == 0) {
1299 vol->retry = 0;
1300 } else if (strnicmp(data, "nosoft", 6) == 0) {
1301 vol->retry = 1;
1302 } else if (strnicmp(data, "nointr", 6) == 0) {
1303 vol->intr = 0;
1304 } else if (strnicmp(data, "intr", 4) == 0) {
1305 vol->intr = 1;
be652445
SF
1306 } else if (strnicmp(data, "nostrictsync", 12) == 0) {
1307 vol->nostrictsync = 1;
1308 } else if (strnicmp(data, "strictsync", 10) == 0) {
1309 vol->nostrictsync = 0;
50c2f753 1310 } else if (strnicmp(data, "serverino", 7) == 0) {
1da177e4 1311 vol->server_ino = 1;
50c2f753 1312 } else if (strnicmp(data, "noserverino", 9) == 0) {
1da177e4 1313 vol->server_ino = 0;
50c2f753 1314 } else if (strnicmp(data, "cifsacl", 7) == 0) {
0a4b92c0
SF
1315 vol->cifs_acl = 1;
1316 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1317 vol->cifs_acl = 0;
50c2f753 1318 } else if (strnicmp(data, "acl", 3) == 0) {
1da177e4 1319 vol->no_psx_acl = 0;
50c2f753 1320 } else if (strnicmp(data, "noacl", 5) == 0) {
1da177e4 1321 vol->no_psx_acl = 1;
84210e91
SF
1322#ifdef CONFIG_CIFS_EXPERIMENTAL
1323 } else if (strnicmp(data, "locallease", 6) == 0) {
1324 vol->local_lease = 1;
1325#endif
50c2f753 1326 } else if (strnicmp(data, "sign", 4) == 0) {
750d1151 1327 vol->secFlg |= CIFSSEC_MUST_SIGN;
95b1cb90
SF
1328 } else if (strnicmp(data, "seal", 4) == 0) {
1329 /* we do not do the following in secFlags because seal
1330 is a per tree connection (mount) not a per socket
1331 or per-smb connection option in the protocol */
1332 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1333 vol->seal = 1;
50c2f753 1334 } else if (strnicmp(data, "direct", 6) == 0) {
1da177e4 1335 vol->direct_io = 1;
50c2f753 1336 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1da177e4 1337 vol->direct_io = 1;
1da177e4 1338 } else if (strnicmp(data, "noac", 4) == 0) {
50c2f753
SF
1339 printk(KERN_WARNING "CIFS: Mount option noac not "
1340 "supported. Instead set "
1341 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
fa1df75d
SJ
1342 } else if (strnicmp(data, "fsc", 3) == 0) {
1343 vol->fsc = true;
1da177e4 1344 } else
50c2f753
SF
1345 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1346 data);
1da177e4
LT
1347 }
1348 if (vol->UNC == NULL) {
4523cc30 1349 if (devname == NULL) {
50c2f753
SF
1350 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1351 "target\n");
1da177e4
LT
1352 return 1;
1353 }
1354 if ((temp_len = strnlen(devname, 300)) < 300) {
50c2f753 1355 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
4523cc30 1356 if (vol->UNC == NULL)
1da177e4 1357 return 1;
50c2f753 1358 strcpy(vol->UNC, devname);
1da177e4
LT
1359 if (strncmp(vol->UNC, "//", 2) == 0) {
1360 vol->UNC[0] = '\\';
1361 vol->UNC[1] = '\\';
1362 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
50c2f753
SF
1363 printk(KERN_WARNING "CIFS: UNC Path does not "
1364 "begin with // or \\\\ \n");
1da177e4
LT
1365 return 1;
1366 }
7c5e628f
IM
1367 value = strpbrk(vol->UNC+2, "/\\");
1368 if (value)
1369 *value = '\\';
1da177e4
LT
1370 } else {
1371 printk(KERN_WARNING "CIFS: UNC name too long\n");
1372 return 1;
1373 }
1374 }
fb8c4b14 1375 if (vol->UNCip == NULL)
1da177e4
LT
1376 vol->UNCip = &vol->UNC[2];
1377
9b9d6b24
JL
1378 if (uid_specified)
1379 vol->override_uid = override_uid;
1380 else if (override_uid == 1)
1381 printk(KERN_NOTICE "CIFS: ignoring forceuid mount option "
1382 "specified with no uid= option.\n");
1383
1384 if (gid_specified)
1385 vol->override_gid = override_gid;
1386 else if (override_gid == 1)
1387 printk(KERN_NOTICE "CIFS: ignoring forcegid mount option "
1388 "specified with no gid= option.\n");
1389
1da177e4
LT
1390 return 0;
1391}
1392
4515148e
JL
1393static bool
1394match_address(struct TCP_Server_Info *server, struct sockaddr *addr)
1395{
1396 struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1397 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1398
1399 switch (addr->sa_family) {
1400 case AF_INET:
1401 if (addr4->sin_addr.s_addr !=
1402 server->addr.sockAddr.sin_addr.s_addr)
1403 return false;
1404 if (addr4->sin_port &&
1405 addr4->sin_port != server->addr.sockAddr.sin_port)
1406 return false;
1407 break;
1408 case AF_INET6:
1409 if (!ipv6_addr_equal(&addr6->sin6_addr,
1410 &server->addr.sockAddr6.sin6_addr))
1411 return false;
1412 if (addr6->sin6_scope_id !=
1413 server->addr.sockAddr6.sin6_scope_id)
1414 return false;
1415 if (addr6->sin6_port &&
1416 addr6->sin6_port != server->addr.sockAddr6.sin6_port)
1417 return false;
1418 break;
1419 }
1420
1421 return true;
1422}
1423
daf5b0b6
JL
1424static bool
1425match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
1426{
1427 unsigned int secFlags;
1428
1429 if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
1430 secFlags = vol->secFlg;
1431 else
1432 secFlags = global_secflags | vol->secFlg;
1433
1434 switch (server->secType) {
1435 case LANMAN:
1436 if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
1437 return false;
1438 break;
1439 case NTLMv2:
1440 if (!(secFlags & CIFSSEC_MAY_NTLMV2))
1441 return false;
1442 break;
1443 case NTLM:
1444 if (!(secFlags & CIFSSEC_MAY_NTLM))
1445 return false;
1446 break;
1447 case Kerberos:
1448 if (!(secFlags & CIFSSEC_MAY_KRB5))
1449 return false;
1450 break;
1451 case RawNTLMSSP:
1452 if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
1453 return false;
1454 break;
1455 default:
1456 /* shouldn't happen */
1457 return false;
1458 }
1459
1460 /* now check if signing mode is acceptible */
1461 if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
1462 (server->secMode & SECMODE_SIGN_REQUIRED))
1463 return false;
1464 else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
1465 (server->secMode &
1466 (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
1467 return false;
1468
1469 return true;
1470}
1471
e7ddee90 1472static struct TCP_Server_Info *
daf5b0b6 1473cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1da177e4 1474{
e7ddee90 1475 struct TCP_Server_Info *server;
e7ddee90
JL
1476
1477 write_lock(&cifs_tcp_ses_lock);
4515148e 1478 list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
e7ddee90
JL
1479 /*
1480 * the demux thread can exit on its own while still in CifsNew
1481 * so don't accept any sockets in that state. Since the
1482 * tcpStatus never changes back to CifsNew it's safe to check
1483 * for this without a lock.
1484 */
1485 if (server->tcpStatus == CifsNew)
1b20d672 1486 continue;
1da177e4 1487
4515148e
JL
1488 if (!match_address(server, addr))
1489 continue;
1b20d672 1490
daf5b0b6
JL
1491 if (!match_security(server, vol))
1492 continue;
1493
e7ddee90
JL
1494 ++server->srv_count;
1495 write_unlock(&cifs_tcp_ses_lock);
b6b38f70 1496 cFYI(1, "Existing tcp session with server found");
e7ddee90 1497 return server;
1da177e4 1498 }
e7ddee90 1499 write_unlock(&cifs_tcp_ses_lock);
1da177e4
LT
1500 return NULL;
1501}
1b20d672 1502
14fbf50d 1503static void
e7ddee90 1504cifs_put_tcp_session(struct TCP_Server_Info *server)
1da177e4 1505{
e7ddee90 1506 struct task_struct *task;
1b20d672 1507
e7ddee90
JL
1508 write_lock(&cifs_tcp_ses_lock);
1509 if (--server->srv_count > 0) {
1510 write_unlock(&cifs_tcp_ses_lock);
1511 return;
1da177e4 1512 }
1b20d672 1513
e7ddee90
JL
1514 list_del_init(&server->tcp_ses_list);
1515 write_unlock(&cifs_tcp_ses_lock);
dea570e0 1516
e7ddee90
JL
1517 spin_lock(&GlobalMid_Lock);
1518 server->tcpStatus = CifsExiting;
1519 spin_unlock(&GlobalMid_Lock);
dea570e0 1520
488f1d2d
SJ
1521 cifs_fscache_release_client_cookie(server);
1522
e7ddee90
JL
1523 task = xchg(&server->tsk, NULL);
1524 if (task)
1525 force_sig(SIGKILL, task);
1da177e4
LT
1526}
1527
63c038c2
JL
1528static struct TCP_Server_Info *
1529cifs_get_tcp_session(struct smb_vol *volume_info)
1530{
1531 struct TCP_Server_Info *tcp_ses = NULL;
a9ac49d3 1532 struct sockaddr_storage addr;
63c038c2
JL
1533 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
1534 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
1535 int rc;
1536
a9ac49d3 1537 memset(&addr, 0, sizeof(struct sockaddr_storage));
63c038c2 1538
b6b38f70 1539 cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
63c038c2 1540
1e68b2b2 1541 if (volume_info->UNCip && volume_info->UNC) {
50d97160
JL
1542 rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
1543 volume_info->UNCip,
67b7626a 1544 strlen(volume_info->UNCip),
50d97160 1545 volume_info->port);
1e68b2b2 1546 if (!rc) {
63c038c2
JL
1547 /* we failed translating address */
1548 rc = -EINVAL;
1549 goto out_err;
1550 }
63c038c2
JL
1551 } else if (volume_info->UNCip) {
1552 /* BB using ip addr as tcp_ses name to connect to the
1553 DFS root below */
b6b38f70 1554 cERROR(1, "Connecting to DFS root not implemented yet");
63c038c2
JL
1555 rc = -EINVAL;
1556 goto out_err;
1557 } else /* which tcp_sess DFS root would we conect to */ {
b6b38f70
JP
1558 cERROR(1, "CIFS mount error: No UNC path (e.g. -o "
1559 "unc=//192.168.1.100/public) specified");
63c038c2
JL
1560 rc = -EINVAL;
1561 goto out_err;
1562 }
1563
1564 /* see if we already have a matching tcp_ses */
daf5b0b6 1565 tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info);
63c038c2
JL
1566 if (tcp_ses)
1567 return tcp_ses;
1568
1569 tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1570 if (!tcp_ses) {
1571 rc = -ENOMEM;
1572 goto out_err;
1573 }
1574
1575 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1576 if (IS_ERR(tcp_ses->hostname)) {
1577 rc = PTR_ERR(tcp_ses->hostname);
1578 goto out_err;
1579 }
1580
1581 tcp_ses->noblocksnd = volume_info->noblocksnd;
1582 tcp_ses->noautotune = volume_info->noautotune;
6a5fa236 1583 tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
63c038c2
JL
1584 atomic_set(&tcp_ses->inFlight, 0);
1585 init_waitqueue_head(&tcp_ses->response_q);
1586 init_waitqueue_head(&tcp_ses->request_q);
1587 INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
1588 mutex_init(&tcp_ses->srv_mutex);
1589 memcpy(tcp_ses->workstation_RFC1001_name,
1590 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1591 memcpy(tcp_ses->server_RFC1001_name,
1592 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1593 tcp_ses->sequence_number = 0;
1594 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1595 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1596
1597 /*
1598 * at this point we are the only ones with the pointer
1599 * to the struct since the kernel thread not created yet
1600 * no need to spinlock this init of tcpStatus or srv_count
1601 */
1602 tcp_ses->tcpStatus = CifsNew;
1603 ++tcp_ses->srv_count;
1604
a9ac49d3 1605 if (addr.ss_family == AF_INET6) {
b6b38f70 1606 cFYI(1, "attempting ipv6 connect");
63c038c2
JL
1607 /* BB should we allow ipv6 on port 139? */
1608 /* other OS never observed in Wild doing 139 with v6 */
1609 memcpy(&tcp_ses->addr.sockAddr6, sin_server6,
1610 sizeof(struct sockaddr_in6));
d5c5605c 1611 rc = ipv6_connect(tcp_ses);
63c038c2
JL
1612 } else {
1613 memcpy(&tcp_ses->addr.sockAddr, sin_server,
1614 sizeof(struct sockaddr_in));
bcf4b106 1615 rc = ipv4_connect(tcp_ses);
63c038c2
JL
1616 }
1617 if (rc < 0) {
b6b38f70 1618 cERROR(1, "Error connecting to socket. Aborting operation");
63c038c2
JL
1619 goto out_err;
1620 }
1621
1622 /*
1623 * since we're in a cifs function already, we know that
1624 * this will succeed. No need for try_module_get().
1625 */
1626 __module_get(THIS_MODULE);
1627 tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread,
1628 tcp_ses, "cifsd");
1629 if (IS_ERR(tcp_ses->tsk)) {
1630 rc = PTR_ERR(tcp_ses->tsk);
b6b38f70 1631 cERROR(1, "error %d create cifsd thread", rc);
63c038c2
JL
1632 module_put(THIS_MODULE);
1633 goto out_err;
1634 }
1635
1636 /* thread spawned, put it on the list */
1637 write_lock(&cifs_tcp_ses_lock);
1638 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1639 write_unlock(&cifs_tcp_ses_lock);
1640
488f1d2d
SJ
1641 cifs_fscache_get_client_cookie(tcp_ses);
1642
63c038c2
JL
1643 return tcp_ses;
1644
1645out_err:
1646 if (tcp_ses) {
8347a5cd
SF
1647 if (!IS_ERR(tcp_ses->hostname))
1648 kfree(tcp_ses->hostname);
63c038c2
JL
1649 if (tcp_ses->ssocket)
1650 sock_release(tcp_ses->ssocket);
1651 kfree(tcp_ses);
1652 }
1653 return ERR_PTR(rc);
1654}
1655
14fbf50d 1656static struct cifsSesInfo *
4ff67b72 1657cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1da177e4 1658{
14fbf50d 1659 struct cifsSesInfo *ses;
dea570e0 1660
14fbf50d 1661 write_lock(&cifs_tcp_ses_lock);
4ff67b72
JL
1662 list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1663 switch (server->secType) {
1664 case Kerberos:
3e4b3e1f 1665 if (vol->cred_uid != ses->cred_uid)
4ff67b72
JL
1666 continue;
1667 break;
1668 default:
1669 /* anything else takes username/password */
1670 if (strncmp(ses->userName, vol->username,
1671 MAX_USERNAME_SIZE))
1672 continue;
1673 if (strlen(vol->username) != 0 &&
24e6cf92 1674 ses->password != NULL &&
fc87a406
JL
1675 strncmp(ses->password,
1676 vol->password ? vol->password : "",
4ff67b72
JL
1677 MAX_PASSWORD_SIZE))
1678 continue;
1679 }
14fbf50d
JL
1680 ++ses->ses_count;
1681 write_unlock(&cifs_tcp_ses_lock);
1682 return ses;
1683 }
1684 write_unlock(&cifs_tcp_ses_lock);
1685 return NULL;
1686}
dea570e0 1687
14fbf50d
JL
1688static void
1689cifs_put_smb_ses(struct cifsSesInfo *ses)
1690{
1691 int xid;
1692 struct TCP_Server_Info *server = ses->server;
dea570e0 1693
36988c76 1694 cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
14fbf50d
JL
1695 write_lock(&cifs_tcp_ses_lock);
1696 if (--ses->ses_count > 0) {
1697 write_unlock(&cifs_tcp_ses_lock);
1698 return;
1699 }
dea570e0 1700
14fbf50d
JL
1701 list_del_init(&ses->smb_ses_list);
1702 write_unlock(&cifs_tcp_ses_lock);
dea570e0 1703
14fbf50d
JL
1704 if (ses->status == CifsGood) {
1705 xid = GetXid();
1706 CIFSSMBLogoff(xid, ses);
1707 _FreeXid(xid);
1708 }
1709 sesInfoFree(ses);
1710 cifs_put_tcp_session(server);
1711}
dea570e0 1712
36988c76
JL
1713static struct cifsSesInfo *
1714cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1715{
1716 int rc = -ENOMEM, xid;
1717 struct cifsSesInfo *ses;
1718
1719 xid = GetXid();
1720
4ff67b72 1721 ses = cifs_find_smb_ses(server, volume_info);
36988c76
JL
1722 if (ses) {
1723 cFYI(1, "Existing smb sess found (status=%d)", ses->status);
1724
1725 /* existing SMB ses has a server reference already */
1726 cifs_put_tcp_session(server);
1727
1728 mutex_lock(&ses->session_mutex);
198b5682
JL
1729 rc = cifs_negotiate_protocol(xid, ses);
1730 if (rc) {
1731 mutex_unlock(&ses->session_mutex);
1732 /* problem -- put our ses reference */
1733 cifs_put_smb_ses(ses);
1734 FreeXid(xid);
1735 return ERR_PTR(rc);
1736 }
36988c76
JL
1737 if (ses->need_reconnect) {
1738 cFYI(1, "Session needs reconnect");
1739 rc = cifs_setup_session(xid, ses,
1740 volume_info->local_nls);
1741 if (rc) {
1742 mutex_unlock(&ses->session_mutex);
1743 /* problem -- put our reference */
1744 cifs_put_smb_ses(ses);
1745 FreeXid(xid);
1746 return ERR_PTR(rc);
1747 }
1748 }
1749 mutex_unlock(&ses->session_mutex);
1750 FreeXid(xid);
1751 return ses;
1752 }
1753
1754 cFYI(1, "Existing smb sess not found");
1755 ses = sesInfoAlloc();
1756 if (ses == NULL)
1757 goto get_ses_fail;
1758
1759 /* new SMB session uses our server ref */
1760 ses->server = server;
1761 if (server->addr.sockAddr6.sin6_family == AF_INET6)
1762 sprintf(ses->serverName, "%pI6",
1763 &server->addr.sockAddr6.sin6_addr);
1764 else
1765 sprintf(ses->serverName, "%pI4",
1766 &server->addr.sockAddr.sin_addr.s_addr);
1767
1768 if (volume_info->username)
1769 strncpy(ses->userName, volume_info->username,
1770 MAX_USERNAME_SIZE);
1771
1772 /* volume_info->password freed at unmount */
1773 if (volume_info->password) {
1774 ses->password = kstrdup(volume_info->password, GFP_KERNEL);
1775 if (!ses->password)
1776 goto get_ses_fail;
1777 }
1778 if (volume_info->domainname) {
1779 int len = strlen(volume_info->domainname);
1780 ses->domainName = kmalloc(len + 1, GFP_KERNEL);
1781 if (ses->domainName)
1782 strcpy(ses->domainName, volume_info->domainname);
1783 }
3e4b3e1f 1784 ses->cred_uid = volume_info->cred_uid;
36988c76
JL
1785 ses->linux_uid = volume_info->linux_uid;
1786 ses->overrideSecFlg = volume_info->secFlg;
1787
1788 mutex_lock(&ses->session_mutex);
198b5682
JL
1789 rc = cifs_negotiate_protocol(xid, ses);
1790 if (!rc)
1791 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
36988c76 1792 mutex_unlock(&ses->session_mutex);
c8e56f1f 1793 if (rc)
36988c76
JL
1794 goto get_ses_fail;
1795
1796 /* success, put it on the list */
1797 write_lock(&cifs_tcp_ses_lock);
1798 list_add(&ses->smb_ses_list, &server->smb_ses_list);
1799 write_unlock(&cifs_tcp_ses_lock);
1800
1801 FreeXid(xid);
1802 return ses;
1803
1804get_ses_fail:
1805 sesInfoFree(ses);
1806 FreeXid(xid);
1807 return ERR_PTR(rc);
1808}
1809
f1987b44
JL
1810static struct cifsTconInfo *
1811cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1812{
1813 struct list_head *tmp;
1814 struct cifsTconInfo *tcon;
1815
1816 write_lock(&cifs_tcp_ses_lock);
1817 list_for_each(tmp, &ses->tcon_list) {
1818 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1819 if (tcon->tidStatus == CifsExiting)
1820 continue;
1821 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
dea570e0
SF
1822 continue;
1823
f1987b44
JL
1824 ++tcon->tc_count;
1825 write_unlock(&cifs_tcp_ses_lock);
dea570e0 1826 return tcon;
1da177e4 1827 }
f1987b44 1828 write_unlock(&cifs_tcp_ses_lock);
1da177e4
LT
1829 return NULL;
1830}
1831
f1987b44
JL
1832static void
1833cifs_put_tcon(struct cifsTconInfo *tcon)
1834{
1835 int xid;
1836 struct cifsSesInfo *ses = tcon->ses;
1837
d00c28de 1838 cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
f1987b44
JL
1839 write_lock(&cifs_tcp_ses_lock);
1840 if (--tcon->tc_count > 0) {
1841 write_unlock(&cifs_tcp_ses_lock);
1842 return;
1843 }
1844
1845 list_del_init(&tcon->tcon_list);
1846 write_unlock(&cifs_tcp_ses_lock);
1847
1848 xid = GetXid();
1849 CIFSSMBTDis(xid, tcon);
1850 _FreeXid(xid);
1851
d03382ce 1852 cifs_fscache_release_super_cookie(tcon);
9f841593 1853 tconInfoFree(tcon);
f1987b44
JL
1854 cifs_put_smb_ses(ses);
1855}
1856
d00c28de
JL
1857static struct cifsTconInfo *
1858cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
1859{
1860 int rc, xid;
1861 struct cifsTconInfo *tcon;
1862
1863 tcon = cifs_find_tcon(ses, volume_info->UNC);
1864 if (tcon) {
1865 cFYI(1, "Found match on UNC path");
1866 /* existing tcon already has a reference */
1867 cifs_put_smb_ses(ses);
1868 if (tcon->seal != volume_info->seal)
1869 cERROR(1, "transport encryption setting "
1870 "conflicts with existing tid");
1871 return tcon;
1872 }
1873
1874 tcon = tconInfoAlloc();
1875 if (tcon == NULL) {
1876 rc = -ENOMEM;
1877 goto out_fail;
1878 }
1879
1880 tcon->ses = ses;
1881 if (volume_info->password) {
1882 tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
1883 if (!tcon->password) {
1884 rc = -ENOMEM;
1885 goto out_fail;
1886 }
1887 }
1888
1889 if (strchr(volume_info->UNC + 3, '\\') == NULL
1890 && strchr(volume_info->UNC + 3, '/') == NULL) {
1891 cERROR(1, "Missing share name");
1892 rc = -ENODEV;
1893 goto out_fail;
1894 }
1895
1896 /* BB Do we need to wrap session_mutex around
1897 * this TCon call and Unix SetFS as
1898 * we do on SessSetup and reconnect? */
1899 xid = GetXid();
1900 rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls);
1901 FreeXid(xid);
1902 cFYI(1, "CIFS Tcon rc = %d", rc);
1903 if (rc)
1904 goto out_fail;
1905
1906 if (volume_info->nodfs) {
1907 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
1908 cFYI(1, "DFS disabled (%d)", tcon->Flags);
1909 }
1910 tcon->seal = volume_info->seal;
1911 /* we can have only one retry value for a connection
1912 to a share so for resources mounted more than once
1913 to the same server share the last value passed in
1914 for the retry flag is used */
1915 tcon->retry = volume_info->retry;
1916 tcon->nocase = volume_info->nocase;
1917 tcon->local_lease = volume_info->local_lease;
1918
1919 write_lock(&cifs_tcp_ses_lock);
1920 list_add(&tcon->tcon_list, &ses->tcon_list);
1921 write_unlock(&cifs_tcp_ses_lock);
1922
d03382ce
SJ
1923 cifs_fscache_get_super_cookie(tcon);
1924
d00c28de
JL
1925 return tcon;
1926
1927out_fail:
1928 tconInfoFree(tcon);
1929 return ERR_PTR(rc);
1930}
1931
1932
1da177e4 1933int
50c2f753
SF
1934get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1935 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
366781c1 1936 struct dfs_info3_param **preferrals, int remap)
1da177e4
LT
1937{
1938 char *temp_unc;
1939 int rc = 0;
1940
1941 *pnum_referrals = 0;
366781c1 1942 *preferrals = NULL;
1da177e4
LT
1943
1944 if (pSesInfo->ipc_tid == 0) {
1945 temp_unc = kmalloc(2 /* for slashes */ +
50c2f753
SF
1946 strnlen(pSesInfo->serverName,
1947 SERVER_NAME_LEN_WITH_NULL * 2)
1da177e4
LT
1948 + 1 + 4 /* slash IPC$ */ + 2,
1949 GFP_KERNEL);
1950 if (temp_unc == NULL)
1951 return -ENOMEM;
1952 temp_unc[0] = '\\';
1953 temp_unc[1] = '\\';
1954 strcpy(temp_unc + 2, pSesInfo->serverName);
1955 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1956 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
b6b38f70 1957 cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid);
1da177e4
LT
1958 kfree(temp_unc);
1959 }
1960 if (rc == 0)
c2cf07d5 1961 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
737b758c 1962 pnum_referrals, nls_codepage, remap);
366781c1
SF
1963 /* BB map targetUNCs to dfs_info3 structures, here or
1964 in CIFSGetDFSRefer BB */
1da177e4
LT
1965
1966 return rc;
1967}
1968
09e50d55
JL
1969#ifdef CONFIG_DEBUG_LOCK_ALLOC
1970static struct lock_class_key cifs_key[2];
1971static struct lock_class_key cifs_slock_key[2];
1972
1973static inline void
1974cifs_reclassify_socket4(struct socket *sock)
1975{
1976 struct sock *sk = sock->sk;
1977 BUG_ON(sock_owned_by_user(sk));
1978 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
1979 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
1980}
1981
1982static inline void
1983cifs_reclassify_socket6(struct socket *sock)
1984{
1985 struct sock *sk = sock->sk;
1986 BUG_ON(sock_owned_by_user(sk));
1987 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
1988 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
1989}
1990#else
1991static inline void
1992cifs_reclassify_socket4(struct socket *sock)
1993{
1994}
1995
1996static inline void
1997cifs_reclassify_socket6(struct socket *sock)
1998{
1999}
2000#endif
2001
1da177e4 2002/* See RFC1001 section 14 on representation of Netbios names */
50c2f753 2003static void rfc1002mangle(char *target, char *source, unsigned int length)
1da177e4 2004{
50c2f753 2005 unsigned int i, j;
1da177e4 2006
50c2f753 2007 for (i = 0, j = 0; i < (length); i++) {
1da177e4
LT
2008 /* mask a nibble at a time and encode */
2009 target[j] = 'A' + (0x0F & (source[i] >> 4));
2010 target[j+1] = 'A' + (0x0F & source[i]);
50c2f753 2011 j += 2;
1da177e4
LT
2012 }
2013
2014}
2015
2016
2017static int
bcf4b106 2018ipv4_connect(struct TCP_Server_Info *server)
1da177e4
LT
2019{
2020 int rc = 0;
6a5fa236 2021 int val;
bcf4b106 2022 bool connected = false;
1da177e4 2023 __be16 orig_port = 0;
bcf4b106 2024 struct socket *socket = server->ssocket;
1da177e4 2025
bcf4b106 2026 if (socket == NULL) {
50c2f753 2027 rc = sock_create_kern(PF_INET, SOCK_STREAM,
bcf4b106 2028 IPPROTO_TCP, &socket);
1da177e4 2029 if (rc < 0) {
b6b38f70 2030 cERROR(1, "Error %d creating socket", rc);
1da177e4 2031 return rc;
1da177e4 2032 }
bcf4b106
JL
2033
2034 /* BB other socket options to set KEEPALIVE, NODELAY? */
b6b38f70 2035 cFYI(1, "Socket created");
bcf4b106
JL
2036 server->ssocket = socket;
2037 socket->sk->sk_allocation = GFP_NOFS;
2038 cifs_reclassify_socket4(socket);
1da177e4
LT
2039 }
2040
bcf4b106
JL
2041 /* user overrode default port */
2042 if (server->addr.sockAddr.sin_port) {
2043 rc = socket->ops->connect(socket, (struct sockaddr *)
2044 &server->addr.sockAddr,
2045 sizeof(struct sockaddr_in), 0);
1da177e4 2046 if (rc >= 0)
bcf4b106 2047 connected = true;
50c2f753 2048 }
1da177e4 2049
fb8c4b14 2050 if (!connected) {
50c2f753 2051 /* save original port so we can retry user specified port
1da177e4 2052 later if fall back ports fail this time */
bcf4b106 2053 orig_port = server->addr.sockAddr.sin_port;
1da177e4
LT
2054
2055 /* do not retry on the same port we just failed on */
bcf4b106
JL
2056 if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
2057 server->addr.sockAddr.sin_port = htons(CIFS_PORT);
2058 rc = socket->ops->connect(socket,
2059 (struct sockaddr *)
2060 &server->addr.sockAddr,
2061 sizeof(struct sockaddr_in), 0);
1da177e4 2062 if (rc >= 0)
bcf4b106 2063 connected = true;
1da177e4
LT
2064 }
2065 }
2066 if (!connected) {
bcf4b106
JL
2067 server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
2068 rc = socket->ops->connect(socket, (struct sockaddr *)
2069 &server->addr.sockAddr,
6345a3a8 2070 sizeof(struct sockaddr_in), 0);
50c2f753 2071 if (rc >= 0)
bcf4b106 2072 connected = true;
1da177e4
LT
2073 }
2074
2075 /* give up here - unless we want to retry on different
2076 protocol families some day */
2077 if (!connected) {
fb8c4b14 2078 if (orig_port)
bcf4b106 2079 server->addr.sockAddr.sin_port = orig_port;
b6b38f70 2080 cFYI(1, "Error %d connecting to server via ipv4", rc);
bcf4b106
JL
2081 sock_release(socket);
2082 server->ssocket = NULL;
1da177e4
LT
2083 return rc;
2084 }
bcf4b106
JL
2085
2086
2087 /*
2088 * Eventually check for other socket options to change from
2089 * the default. sock_setsockopt not used because it expects
2090 * user space buffer
2091 */
2092 socket->sk->sk_rcvtimeo = 7 * HZ;
da505c38 2093 socket->sk->sk_sndtimeo = 5 * HZ;
edf1ae40 2094
b387eaeb 2095 /* make the bufsizes depend on wsize/rsize and max requests */
bcf4b106
JL
2096 if (server->noautotune) {
2097 if (socket->sk->sk_sndbuf < (200 * 1024))
2098 socket->sk->sk_sndbuf = 200 * 1024;
2099 if (socket->sk->sk_rcvbuf < (140 * 1024))
2100 socket->sk->sk_rcvbuf = 140 * 1024;
edf1ae40 2101 }
1da177e4 2102
6a5fa236
SF
2103 if (server->tcp_nodelay) {
2104 val = 1;
2105 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2106 (char *)&val, sizeof(val));
2107 if (rc)
b6b38f70 2108 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
6a5fa236
SF
2109 }
2110
b6b38f70 2111 cFYI(1, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
bcf4b106 2112 socket->sk->sk_sndbuf,
b6b38f70 2113 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
bcf4b106 2114
1da177e4 2115 /* send RFC1001 sessinit */
bcf4b106 2116 if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) {
1da177e4 2117 /* some servers require RFC1001 sessinit before sending
50c2f753 2118 negprot - BB check reconnection in case where second
1da177e4 2119 sessinit is sent but no second negprot */
50c2f753
SF
2120 struct rfc1002_session_packet *ses_init_buf;
2121 struct smb_hdr *smb_buf;
2122 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2123 GFP_KERNEL);
fb8c4b14 2124 if (ses_init_buf) {
1da177e4 2125 ses_init_buf->trailer.session_req.called_len = 32;
bcf4b106
JL
2126 if (server->server_RFC1001_name &&
2127 server->server_RFC1001_name[0] != 0)
8ecaf67a
JL
2128 rfc1002mangle(ses_init_buf->trailer.
2129 session_req.called_name,
bcf4b106 2130 server->server_RFC1001_name,
8ecaf67a 2131 RFC1001_NAME_LEN_WITH_NULL);
bcf4b106 2132 else
8ecaf67a
JL
2133 rfc1002mangle(ses_init_buf->trailer.
2134 session_req.called_name,
2135 DEFAULT_CIFS_CALLED_NAME,
2136 RFC1001_NAME_LEN_WITH_NULL);
a10faeb2 2137
1da177e4 2138 ses_init_buf->trailer.session_req.calling_len = 32;
bcf4b106 2139
1da177e4
LT
2140 /* calling name ends in null (byte 16) from old smb
2141 convention. */
bcf4b106
JL
2142 if (server->workstation_RFC1001_name &&
2143 server->workstation_RFC1001_name[0] != 0)
8ecaf67a
JL
2144 rfc1002mangle(ses_init_buf->trailer.
2145 session_req.calling_name,
bcf4b106 2146 server->workstation_RFC1001_name,
8ecaf67a 2147 RFC1001_NAME_LEN_WITH_NULL);
bcf4b106 2148 else
8ecaf67a
JL
2149 rfc1002mangle(ses_init_buf->trailer.
2150 session_req.calling_name,
2151 "LINUX_CIFS_CLNT",
2152 RFC1001_NAME_LEN_WITH_NULL);
bcf4b106 2153
1da177e4
LT
2154 ses_init_buf->trailer.session_req.scope1 = 0;
2155 ses_init_buf->trailer.session_req.scope2 = 0;
2156 smb_buf = (struct smb_hdr *)ses_init_buf;
2157 /* sizeof RFC1002_SESSION_REQUEST with no scope */
2158 smb_buf->smb_buf_length = 0x81000044;
0496e02d 2159 rc = smb_send(server, smb_buf, 0x44);
1da177e4 2160 kfree(ses_init_buf);
50c2f753 2161 msleep(1); /* RFC1001 layer in at least one server
083d3a2c
SF
2162 requires very short break before negprot
2163 presumably because not expecting negprot
2164 to follow so fast. This is a simple
50c2f753 2165 solution that works without
083d3a2c
SF
2166 complicating the code and causes no
2167 significant slowing down on mount
2168 for everyone else */
1da177e4 2169 }
50c2f753 2170 /* else the negprot may still work without this
1da177e4 2171 even though malloc failed */
50c2f753 2172
1da177e4 2173 }
50c2f753 2174
1da177e4
LT
2175 return rc;
2176}
2177
2178static int
d5c5605c 2179ipv6_connect(struct TCP_Server_Info *server)
1da177e4
LT
2180{
2181 int rc = 0;
6a5fa236 2182 int val;
d5c5605c 2183 bool connected = false;
1da177e4 2184 __be16 orig_port = 0;
d5c5605c 2185 struct socket *socket = server->ssocket;
1da177e4 2186
d5c5605c 2187 if (socket == NULL) {
50c2f753 2188 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
d5c5605c 2189 IPPROTO_TCP, &socket);
1da177e4 2190 if (rc < 0) {
b6b38f70 2191 cERROR(1, "Error %d creating ipv6 socket", rc);
d5c5605c 2192 socket = NULL;
1da177e4 2193 return rc;
1da177e4 2194 }
1da177e4 2195
d5c5605c 2196 /* BB other socket options to set KEEPALIVE, NODELAY? */
b6b38f70 2197 cFYI(1, "ipv6 Socket created");
d5c5605c
JL
2198 server->ssocket = socket;
2199 socket->sk->sk_allocation = GFP_NOFS;
2200 cifs_reclassify_socket6(socket);
2201 }
1da177e4 2202
d5c5605c
JL
2203 /* user overrode default port */
2204 if (server->addr.sockAddr6.sin6_port) {
2205 rc = socket->ops->connect(socket,
2206 (struct sockaddr *) &server->addr.sockAddr6,
6345a3a8 2207 sizeof(struct sockaddr_in6), 0);
1da177e4 2208 if (rc >= 0)
d5c5605c 2209 connected = true;
50c2f753 2210 }
1da177e4 2211
fb8c4b14 2212 if (!connected) {
50c2f753 2213 /* save original port so we can retry user specified port
1da177e4
LT
2214 later if fall back ports fail this time */
2215
d5c5605c 2216 orig_port = server->addr.sockAddr6.sin6_port;
1da177e4 2217 /* do not retry on the same port we just failed on */
d5c5605c
JL
2218 if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) {
2219 server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
2220 rc = socket->ops->connect(socket, (struct sockaddr *)
2221 &server->addr.sockAddr6,
6345a3a8 2222 sizeof(struct sockaddr_in6), 0);
1da177e4 2223 if (rc >= 0)
d5c5605c 2224 connected = true;
1da177e4
LT
2225 }
2226 }
2227 if (!connected) {
d5c5605c
JL
2228 server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT);
2229 rc = socket->ops->connect(socket, (struct sockaddr *)
2230 &server->addr.sockAddr6,
2231 sizeof(struct sockaddr_in6), 0);
50c2f753 2232 if (rc >= 0)
d5c5605c 2233 connected = true;
1da177e4
LT
2234 }
2235
2236 /* give up here - unless we want to retry on different
2237 protocol families some day */
2238 if (!connected) {
fb8c4b14 2239 if (orig_port)
d5c5605c 2240 server->addr.sockAddr6.sin6_port = orig_port;
b6b38f70 2241 cFYI(1, "Error %d connecting to server via ipv6", rc);
d5c5605c
JL
2242 sock_release(socket);
2243 server->ssocket = NULL;
1da177e4
LT
2244 return rc;
2245 }
edf1ae40 2246
d5c5605c
JL
2247 /*
2248 * Eventually check for other socket options to change from
2249 * the default. sock_setsockopt not used because it expects
2250 * user space buffer
2251 */
2252 socket->sk->sk_rcvtimeo = 7 * HZ;
da505c38 2253 socket->sk->sk_sndtimeo = 5 * HZ;
6a5fa236
SF
2254
2255 if (server->tcp_nodelay) {
2256 val = 1;
2257 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2258 (char *)&val, sizeof(val));
2259 if (rc)
b6b38f70 2260 cFYI(1, "set TCP_NODELAY socket option error %d", rc);
6a5fa236
SF
2261 }
2262
d5c5605c 2263 server->ssocket = socket;
50c2f753 2264
1da177e4
LT
2265 return rc;
2266}
2267
50c2f753
SF
2268void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2269 struct super_block *sb, struct smb_vol *vol_info)
8af18971
SF
2270{
2271 /* if we are reconnecting then should we check to see if
2272 * any requested capabilities changed locally e.g. via
2273 * remount but we can not do much about it here
2274 * if they have (even if we could detect it by the following)
2275 * Perhaps we could add a backpointer to array of sb from tcon
2276 * or if we change to make all sb to same share the same
2277 * sb as NFS - then we only have one backpointer to sb.
2278 * What if we wanted to mount the server share twice once with
2279 * and once without posixacls or posix paths? */
2280 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
50c2f753 2281
c18c842b
SF
2282 if (vol_info && vol_info->no_linux_ext) {
2283 tcon->fsUnixInfo.Capability = 0;
2284 tcon->unix_ext = 0; /* Unix Extensions disabled */
b6b38f70 2285 cFYI(1, "Linux protocol extensions disabled");
c18c842b
SF
2286 return;
2287 } else if (vol_info)
2288 tcon->unix_ext = 1; /* Unix Extensions supported */
2289
2290 if (tcon->unix_ext == 0) {
b6b38f70 2291 cFYI(1, "Unix extensions disabled so not set on reconnect");
c18c842b
SF
2292 return;
2293 }
50c2f753 2294
fb8c4b14 2295 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
8af18971 2296 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
50c2f753 2297
8af18971
SF
2298 /* check for reconnect case in which we do not
2299 want to change the mount behavior if we can avoid it */
fb8c4b14 2300 if (vol_info == NULL) {
50c2f753 2301 /* turn off POSIX ACL and PATHNAMES if not set
8af18971
SF
2302 originally at mount time */
2303 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
2304 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
11b6d645
IM
2305 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2306 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
b6b38f70 2307 cERROR(1, "POSIXPATH support change");
8af18971 2308 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
11b6d645 2309 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
b6b38f70
JP
2310 cERROR(1, "possible reconnect error");
2311 cERROR(1, "server disabled POSIX path support");
11b6d645 2312 }
8af18971 2313 }
50c2f753 2314
8af18971 2315 cap &= CIFS_UNIX_CAP_MASK;
75865f8c 2316 if (vol_info && vol_info->no_psx_acl)
8af18971 2317 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
75865f8c 2318 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
b6b38f70 2319 cFYI(1, "negotiated posix acl support");
fb8c4b14 2320 if (sb)
8af18971
SF
2321 sb->s_flags |= MS_POSIXACL;
2322 }
2323
75865f8c 2324 if (vol_info && vol_info->posix_paths == 0)
8af18971 2325 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
75865f8c 2326 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
b6b38f70 2327 cFYI(1, "negotiate posix pathnames");
75865f8c 2328 if (sb)
50c2f753 2329 CIFS_SB(sb)->mnt_cifs_flags |=
8af18971
SF
2330 CIFS_MOUNT_POSIX_PATHS;
2331 }
50c2f753 2332
984acfe1
SF
2333 /* We might be setting the path sep back to a different
2334 form if we are reconnecting and the server switched its
50c2f753 2335 posix path capability for this share */
75865f8c 2336 if (sb && (CIFS_SB(sb)->prepathlen > 0))
984acfe1 2337 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
75865f8c
SF
2338
2339 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2340 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2341 CIFS_SB(sb)->rsize = 127 * 1024;
b6b38f70 2342 cFYI(DBG2, "larger reads not supported by srv");
75865f8c
SF
2343 }
2344 }
50c2f753
SF
2345
2346
b6b38f70 2347 cFYI(1, "Negotiate caps 0x%x", (int)cap);
8af18971 2348#ifdef CONFIG_CIFS_DEBUG2
75865f8c 2349 if (cap & CIFS_UNIX_FCNTL_CAP)
b6b38f70 2350 cFYI(1, "FCNTL cap");
75865f8c 2351 if (cap & CIFS_UNIX_EXTATTR_CAP)
b6b38f70 2352 cFYI(1, "EXTATTR cap");
75865f8c 2353 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
b6b38f70 2354 cFYI(1, "POSIX path cap");
75865f8c 2355 if (cap & CIFS_UNIX_XATTR_CAP)
b6b38f70 2356 cFYI(1, "XATTR cap");
75865f8c 2357 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
b6b38f70 2358 cFYI(1, "POSIX ACL cap");
75865f8c 2359 if (cap & CIFS_UNIX_LARGE_READ_CAP)
b6b38f70 2360 cFYI(1, "very large read cap");
75865f8c 2361 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
b6b38f70 2362 cFYI(1, "very large write cap");
8af18971
SF
2363#endif /* CIFS_DEBUG2 */
2364 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
442aa310 2365 if (vol_info == NULL) {
b6b38f70 2366 cFYI(1, "resetting capabilities failed");
442aa310 2367 } else
b6b38f70 2368 cERROR(1, "Negotiating Unix capabilities "
5a44b319
SF
2369 "with the server failed. Consider "
2370 "mounting with the Unix Extensions\n"
2371 "disabled, if problems are found, "
2372 "by specifying the nounix mount "
b6b38f70 2373 "option.");
5a44b319 2374
8af18971
SF
2375 }
2376 }
2377}
2378
03a143c9
SF
2379static void
2380convert_delimiter(char *path, char delim)
2381{
2382 int i;
c2d68ea6 2383 char old_delim;
03a143c9
SF
2384
2385 if (path == NULL)
2386 return;
2387
582d21e5 2388 if (delim == '/')
c2d68ea6
SF
2389 old_delim = '\\';
2390 else
2391 old_delim = '/';
2392
03a143c9 2393 for (i = 0; path[i] != '\0'; i++) {
c2d68ea6 2394 if (path[i] == old_delim)
03a143c9
SF
2395 path[i] = delim;
2396 }
2397}
2398
3b795210
SF
2399static void setup_cifs_sb(struct smb_vol *pvolume_info,
2400 struct cifs_sb_info *cifs_sb)
b1c8d2b4 2401{
3b795210 2402 if (pvolume_info->rsize > CIFSMaxBufSize) {
b6b38f70
JP
2403 cERROR(1, "rsize %d too large, using MaxBufSize",
2404 pvolume_info->rsize);
3b795210
SF
2405 cifs_sb->rsize = CIFSMaxBufSize;
2406 } else if ((pvolume_info->rsize) &&
2407 (pvolume_info->rsize <= CIFSMaxBufSize))
2408 cifs_sb->rsize = pvolume_info->rsize;
2409 else /* default */
2410 cifs_sb->rsize = CIFSMaxBufSize;
2411
2412 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
b6b38f70
JP
2413 cERROR(1, "wsize %d too large, using 4096 instead",
2414 pvolume_info->wsize);
3b795210
SF
2415 cifs_sb->wsize = 4096;
2416 } else if (pvolume_info->wsize)
2417 cifs_sb->wsize = pvolume_info->wsize;
2418 else
2419 cifs_sb->wsize = min_t(const int,
2420 PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2421 127*1024);
2422 /* old default of CIFSMaxBufSize was too small now
2423 that SMB Write2 can send multiple pages in kvec.
2424 RFC1001 does not describe what happens when frame
2425 bigger than 128K is sent so use that as max in
2426 conjunction with 52K kvec constraint on arch with 4K
2427 page size */
2428
2429 if (cifs_sb->rsize < 2048) {
2430 cifs_sb->rsize = 2048;
2431 /* Windows ME may prefer this */
b6b38f70 2432 cFYI(1, "readsize set to minimum: 2048");
3b795210
SF
2433 }
2434 /* calculate prepath */
2435 cifs_sb->prepath = pvolume_info->prepath;
2436 if (cifs_sb->prepath) {
2437 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2438 /* we can not convert the / to \ in the path
2439 separators in the prefixpath yet because we do not
2440 know (until reset_cifs_unix_caps is called later)
2441 whether POSIX PATH CAP is available. We normalize
2442 the / to \ after reset_cifs_unix_caps is called */
2443 pvolume_info->prepath = NULL;
2444 } else
2445 cifs_sb->prepathlen = 0;
2446 cifs_sb->mnt_uid = pvolume_info->linux_uid;
2447 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2448 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
2449 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
b6b38f70
JP
2450 cFYI(1, "file mode: 0x%x dir mode: 0x%x",
2451 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
3b795210
SF
2452
2453 if (pvolume_info->noperm)
2454 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2455 if (pvolume_info->setuids)
2456 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2457 if (pvolume_info->server_ino)
2458 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2459 if (pvolume_info->remap)
2460 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2461 if (pvolume_info->no_xattr)
2462 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2463 if (pvolume_info->sfu_emul)
2464 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2465 if (pvolume_info->nobrl)
2466 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
be652445 2467 if (pvolume_info->nostrictsync)
4717bed6 2468 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
13a6e42a
SF
2469 if (pvolume_info->mand_lock)
2470 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
3b795210
SF
2471 if (pvolume_info->cifs_acl)
2472 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2473 if (pvolume_info->override_uid)
2474 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2475 if (pvolume_info->override_gid)
2476 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2477 if (pvolume_info->dynperm)
2478 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
fa1df75d
SJ
2479 if (pvolume_info->fsc)
2480 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
3b795210 2481 if (pvolume_info->direct_io) {
b6b38f70 2482 cFYI(1, "mounting share using direct i/o");
3b795210
SF
2483 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2484 }
2485
2486 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
b6b38f70
JP
2487 cERROR(1, "mount option dynperm ignored if cifsacl "
2488 "mount option supported");
b1c8d2b4
JL
2489}
2490
e4cce94c
IM
2491static int
2492is_path_accessible(int xid, struct cifsTconInfo *tcon,
2493 struct cifs_sb_info *cifs_sb, const char *full_path)
2494{
2495 int rc;
e4cce94c
IM
2496 FILE_ALL_INFO *pfile_info;
2497
e4cce94c
IM
2498 pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
2499 if (pfile_info == NULL)
2500 return -ENOMEM;
2501
2502 rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info,
2503 0 /* not legacy */, cifs_sb->local_nls,
2504 cifs_sb->mnt_cifs_flags &
2505 CIFS_MOUNT_MAP_SPECIAL_CHR);
2506 kfree(pfile_info);
2507 return rc;
2508}
2509
1bfe73c2
IM
2510static void
2511cleanup_volume_info(struct smb_vol **pvolume_info)
2512{
2513 struct smb_vol *volume_info;
2514
ad6cca6d 2515 if (!pvolume_info || !*pvolume_info)
1bfe73c2
IM
2516 return;
2517
2518 volume_info = *pvolume_info;
2519 kzfree(volume_info->password);
2520 kfree(volume_info->UNC);
2521 kfree(volume_info->prepath);
2522 kfree(volume_info);
2523 *pvolume_info = NULL;
2524 return;
2525}
2526
2d6d589d 2527#ifdef CONFIG_CIFS_DFS_UPCALL
1bfe73c2
IM
2528/* build_path_to_root returns full path to root when
2529 * we do not have an exiting connection (tcon) */
2530static char *
2531build_unc_path_to_root(const struct smb_vol *volume_info,
2532 const struct cifs_sb_info *cifs_sb)
2533{
2534 char *full_path;
2535
2536 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
2537 full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL);
2538 if (full_path == NULL)
2539 return ERR_PTR(-ENOMEM);
2540
2541 strncpy(full_path, volume_info->UNC, unc_len);
2542 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
2543 int i;
2544 for (i = 0; i < unc_len; i++) {
2545 if (full_path[i] == '\\')
2546 full_path[i] = '/';
2547 }
2548 }
2549
2550 if (cifs_sb->prepathlen)
2551 strncpy(full_path + unc_len, cifs_sb->prepath,
2552 cifs_sb->prepathlen);
2553
2554 full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
2555 return full_path;
2556}
2d6d589d 2557#endif
1bfe73c2 2558
1da177e4
LT
2559int
2560cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1bfe73c2 2561 char *mount_data_global, const char *devname)
1da177e4 2562{
a2934c7b 2563 int rc;
1da177e4 2564 int xid;
7586b765 2565 struct smb_vol *volume_info;
a2934c7b
JL
2566 struct cifsSesInfo *pSesInfo;
2567 struct cifsTconInfo *tcon;
2568 struct TCP_Server_Info *srvTcp;
e4cce94c 2569 char *full_path;
2d6d589d
SF
2570 char *mount_data = mount_data_global;
2571#ifdef CONFIG_CIFS_DFS_UPCALL
1bfe73c2
IM
2572 struct dfs_info3_param *referrals = NULL;
2573 unsigned int num_referrals = 0;
5c2503a8 2574 int referral_walks_count = 0;
1bfe73c2 2575try_mount_again:
2d6d589d 2576#endif
a2934c7b
JL
2577 rc = 0;
2578 tcon = NULL;
2579 pSesInfo = NULL;
2580 srvTcp = NULL;
1bfe73c2 2581 full_path = NULL;
1da177e4
LT
2582
2583 xid = GetXid();
2584
7586b765
JL
2585 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2586 if (!volume_info) {
2587 rc = -ENOMEM;
2588 goto out;
2589 }
50c2f753 2590
7586b765 2591 if (cifs_parse_mount_options(mount_data, devname, volume_info)) {
70fe7dc0
JL
2592 rc = -EINVAL;
2593 goto out;
1da177e4
LT
2594 }
2595
7586b765 2596 if (volume_info->nullauth) {
b6b38f70 2597 cFYI(1, "null user");
7586b765
JL
2598 volume_info->username = "";
2599 } else if (volume_info->username) {
1da177e4 2600 /* BB fixme parse for domain name here */
b6b38f70 2601 cFYI(1, "Username: %s", volume_info->username);
1da177e4 2602 } else {
bf820679 2603 cifserror("No username specified");
50c2f753
SF
2604 /* In userspace mount helper we can get user name from alternate
2605 locations such as env variables and files on disk */
70fe7dc0
JL
2606 rc = -EINVAL;
2607 goto out;
1da177e4
LT
2608 }
2609
1da177e4 2610 /* this is needed for ASCII cp to Unicode converts */
7586b765 2611 if (volume_info->iocharset == NULL) {
a5fc4ce0
JL
2612 /* load_nls_default cannot return null */
2613 volume_info->local_nls = load_nls_default();
1da177e4 2614 } else {
a5fc4ce0
JL
2615 volume_info->local_nls = load_nls(volume_info->iocharset);
2616 if (volume_info->local_nls == NULL) {
b6b38f70
JP
2617 cERROR(1, "CIFS mount error: iocharset %s not found",
2618 volume_info->iocharset);
70fe7dc0
JL
2619 rc = -ELIBACC;
2620 goto out;
1da177e4
LT
2621 }
2622 }
a5fc4ce0 2623 cifs_sb->local_nls = volume_info->local_nls;
1da177e4 2624
63c038c2 2625 /* get a reference to a tcp session */
7586b765 2626 srvTcp = cifs_get_tcp_session(volume_info);
63c038c2
JL
2627 if (IS_ERR(srvTcp)) {
2628 rc = PTR_ERR(srvTcp);
2629 goto out;
1da177e4
LT
2630 }
2631
36988c76
JL
2632 /* get a reference to a SMB session */
2633 pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
2634 if (IS_ERR(pSesInfo)) {
2635 rc = PTR_ERR(pSesInfo);
2636 pSesInfo = NULL;
2637 goto mount_fail_check;
1da177e4 2638 }
50c2f753 2639
d00c28de
JL
2640 setup_cifs_sb(volume_info, cifs_sb);
2641 if (pSesInfo->capabilities & CAP_LARGE_FILES)
2642 sb->s_maxbytes = MAX_LFS_FILESIZE;
2643 else
2644 sb->s_maxbytes = MAX_NON_LFS;
1da177e4 2645
8af18971 2646 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
1da177e4
LT
2647 sb->s_time_gran = 100;
2648
d00c28de
JL
2649 /* search for existing tcon to this server share */
2650 tcon = cifs_get_tcon(pSesInfo, volume_info);
2651 if (IS_ERR(tcon)) {
2652 rc = PTR_ERR(tcon);
2653 tcon = NULL;
1bfe73c2 2654 goto remote_path_check;
d00c28de 2655 }
1bfe73c2 2656
d82c2df5 2657 cifs_sb->tcon = tcon;
c18c842b 2658
d82c2df5
SF
2659 /* do not care if following two calls succeed - informational */
2660 if (!tcon->ipc) {
2661 CIFSSMBQFSDeviceInfo(xid, tcon);
2662 CIFSSMBQFSAttributeInfo(xid, tcon);
2663 }
03a143c9 2664
d82c2df5
SF
2665 /* tell server which Unix caps we support */
2666 if (tcon->ses->capabilities & CAP_UNIX)
2667 /* reset of caps checks mount to see if unix extensions
2668 disabled for just this mount */
7586b765 2669 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
d82c2df5
SF
2670 else
2671 tcon->unix_ext = 0; /* server does not support them */
c18c842b 2672
d82c2df5
SF
2673 /* convert forward to back slashes in prepath here if needed */
2674 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2675 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
03a143c9 2676
d82c2df5
SF
2677 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2678 cifs_sb->rsize = 1024 * 127;
b6b38f70 2679 cFYI(DBG2, "no very large read support, rsize now 127K");
1da177e4 2680 }
d82c2df5
SF
2681 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2682 cifs_sb->wsize = min(cifs_sb->wsize,
2683 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2684 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2685 cifs_sb->rsize = min(cifs_sb->rsize,
2686 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
1da177e4 2687
1bfe73c2
IM
2688remote_path_check:
2689 /* check if a whole path (including prepath) is not remote */
2690 if (!rc && cifs_sb->prepathlen && tcon) {
e4cce94c
IM
2691 /* build_path_to_root works only when we have a valid tcon */
2692 full_path = cifs_build_path_to_root(cifs_sb);
2693 if (full_path == NULL) {
2694 rc = -ENOMEM;
2695 goto mount_fail_check;
2696 }
2697 rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
1bfe73c2 2698 if (rc != -EREMOTE) {
e4cce94c
IM
2699 kfree(full_path);
2700 goto mount_fail_check;
2701 }
2702 kfree(full_path);
2703 }
2704
1bfe73c2
IM
2705 /* get referral if needed */
2706 if (rc == -EREMOTE) {
d036f50f 2707#ifdef CONFIG_CIFS_DFS_UPCALL
5c2503a8
IM
2708 if (referral_walks_count > MAX_NESTED_LINKS) {
2709 /*
2710 * BB: when we implement proper loop detection,
2711 * we will remove this check. But now we need it
2712 * to prevent an indefinite loop if 'DFS tree' is
2713 * misconfigured (i.e. has loops).
2714 */
2715 rc = -ELOOP;
2716 goto mount_fail_check;
2717 }
1bfe73c2
IM
2718 /* convert forward to back slashes in prepath here if needed */
2719 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2720 convert_delimiter(cifs_sb->prepath,
2721 CIFS_DIR_SEP(cifs_sb));
2722 full_path = build_unc_path_to_root(volume_info, cifs_sb);
2723 if (IS_ERR(full_path)) {
2724 rc = PTR_ERR(full_path);
2725 goto mount_fail_check;
2726 }
2727
b6b38f70 2728 cFYI(1, "Getting referral for: %s", full_path);
1bfe73c2
IM
2729 rc = get_dfs_path(xid, pSesInfo , full_path + 1,
2730 cifs_sb->local_nls, &num_referrals, &referrals,
2731 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
2732 if (!rc && num_referrals > 0) {
2733 char *fake_devname = NULL;
2734
2735 if (mount_data != mount_data_global)
2736 kfree(mount_data);
7b91e266 2737
1bfe73c2
IM
2738 mount_data = cifs_compose_mount_options(
2739 cifs_sb->mountdata, full_path + 1,
2740 referrals, &fake_devname);
7b91e266 2741
1bfe73c2 2742 free_dfs_info_array(referrals, num_referrals);
7b91e266
JL
2743 kfree(fake_devname);
2744 kfree(full_path);
2745
2746 if (IS_ERR(mount_data)) {
2747 rc = PTR_ERR(mount_data);
2748 mount_data = NULL;
2749 goto mount_fail_check;
2750 }
1bfe73c2
IM
2751
2752 if (tcon)
2753 cifs_put_tcon(tcon);
2754 else if (pSesInfo)
2755 cifs_put_smb_ses(pSesInfo);
2756
2757 cleanup_volume_info(&volume_info);
5c2503a8 2758 referral_walks_count++;
a2934c7b 2759 FreeXid(xid);
1bfe73c2
IM
2760 goto try_mount_again;
2761 }
d036f50f
SF
2762#else /* No DFS support, return error on mount */
2763 rc = -EOPNOTSUPP;
2764#endif
1bfe73c2
IM
2765 }
2766
2767mount_fail_check:
2768 /* on error free sesinfo and tcon struct if needed */
2769 if (rc) {
2770 if (mount_data != mount_data_global)
2771 kfree(mount_data);
2772 /* If find_unc succeeded then rc == 0 so we can not end */
2773 /* up accidently freeing someone elses tcon struct */
2774 if (tcon)
2775 cifs_put_tcon(tcon);
2776 else if (pSesInfo)
2777 cifs_put_smb_ses(pSesInfo);
2778 else
2779 cifs_put_tcp_session(srvTcp);
2780 goto out;
2781 }
2782
7586b765 2783 /* volume_info->password is freed above when existing session found
1da177e4
LT
2784 (in which case it is not needed anymore) but when new sesion is created
2785 the password ptr is put in the new session structure (in which case the
2786 password will be freed at unmount time) */
70fe7dc0
JL
2787out:
2788 /* zero out password before freeing */
1bfe73c2 2789 cleanup_volume_info(&volume_info);
1da177e4
LT
2790 FreeXid(xid);
2791 return rc;
2792}
2793
1da177e4
LT
2794int
2795CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2796 const char *tree, struct cifsTconInfo *tcon,
2797 const struct nls_table *nls_codepage)
2798{
2799 struct smb_hdr *smb_buffer;
2800 struct smb_hdr *smb_buffer_response;
2801 TCONX_REQ *pSMB;
2802 TCONX_RSP *pSMBr;
2803 unsigned char *bcc_ptr;
2804 int rc = 0;
cc20c031 2805 int length, bytes_left;
1da177e4
LT
2806 __u16 count;
2807
2808 if (ses == NULL)
2809 return -EIO;
2810
2811 smb_buffer = cifs_buf_get();
ca43e3be 2812 if (smb_buffer == NULL)
1da177e4 2813 return -ENOMEM;
ca43e3be 2814
1da177e4
LT
2815 smb_buffer_response = smb_buffer;
2816
2817 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
2818 NULL /*no tid */ , 4 /*wct */ );
1982c344
SF
2819
2820 smb_buffer->Mid = GetNextMid(ses->server);
1da177e4
LT
2821 smb_buffer->Uid = ses->Suid;
2822 pSMB = (TCONX_REQ *) smb_buffer;
2823 pSMBr = (TCONX_RSP *) smb_buffer_response;
2824
2825 pSMB->AndXCommand = 0xFF;
2826 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
1da177e4 2827 bcc_ptr = &pSMB->Password[0];
fb8c4b14 2828 if ((ses->server->secMode) & SECMODE_USER) {
eeac8047 2829 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
7c7b25bc 2830 *bcc_ptr = 0; /* password is null byte */
eeac8047 2831 bcc_ptr++; /* skip password */
7c7b25bc 2832 /* already aligned so no need to do it below */
eeac8047 2833 } else {
7c7b25bc 2834 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
eeac8047
SF
2835 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
2836 specified as required (when that support is added to
2837 the vfs in the future) as only NTLM or the much
7c7b25bc 2838 weaker LANMAN (which we do not send by default) is accepted
eeac8047
SF
2839 by Samba (not sure whether other servers allow
2840 NTLMv2 password here) */
7c7b25bc 2841#ifdef CONFIG_CIFS_WEAK_PW_HASH
04912d6a 2842 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
00e485b0
JL
2843 (ses->server->secType == LANMAN))
2844 calc_lanman_hash(tcon->password, ses->server->cryptKey,
4e53a3fb
JL
2845 ses->server->secMode &
2846 SECMODE_PW_ENCRYPT ? true : false,
2847 bcc_ptr);
7c7b25bc
SF
2848 else
2849#endif /* CIFS_WEAK_PW_HASH */
00e485b0 2850 SMBNTencrypt(tcon->password, ses->server->cryptKey,
eeac8047
SF
2851 bcc_ptr);
2852
7c7b25bc 2853 bcc_ptr += CIFS_SESS_KEY_SIZE;
fb8c4b14 2854 if (ses->capabilities & CAP_UNICODE) {
7c7b25bc
SF
2855 /* must align unicode strings */
2856 *bcc_ptr = 0; /* null byte password */
2857 bcc_ptr++;
2858 }
eeac8047 2859 }
1da177e4 2860
50c2f753 2861 if (ses->server->secMode &
a878fb22 2862 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1da177e4
LT
2863 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2864
2865 if (ses->capabilities & CAP_STATUS32) {
2866 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2867 }
2868 if (ses->capabilities & CAP_DFS) {
2869 smb_buffer->Flags2 |= SMBFLG2_DFS;
2870 }
2871 if (ses->capabilities & CAP_UNICODE) {
2872 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2873 length =
50c2f753
SF
2874 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
2875 6 /* max utf8 char length in bytes */ *
a878fb22
SF
2876 (/* server len*/ + 256 /* share len */), nls_codepage);
2877 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
1da177e4
LT
2878 bcc_ptr += 2; /* skip trailing null */
2879 } else { /* ASCII */
1da177e4
LT
2880 strcpy(bcc_ptr, tree);
2881 bcc_ptr += strlen(tree) + 1;
2882 }
2883 strcpy(bcc_ptr, "?????");
2884 bcc_ptr += strlen("?????");
2885 bcc_ptr += 1;
2886 count = bcc_ptr - &pSMB->Password[0];
2887 pSMB->hdr.smb_buf_length += count;
2888 pSMB->ByteCount = cpu_to_le16(count);
2889
133672ef
SF
2890 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
2891 CIFS_STD_OP);
1da177e4 2892
1da177e4
LT
2893 /* above now done in SendReceive */
2894 if ((rc == 0) && (tcon != NULL)) {
0e0d2cf3
SF
2895 bool is_unicode;
2896
1da177e4 2897 tcon->tidStatus = CifsGood;
3b795210 2898 tcon->need_reconnect = false;
1da177e4
LT
2899 tcon->tid = smb_buffer_response->Tid;
2900 bcc_ptr = pByteArea(smb_buffer_response);
cc20c031
JL
2901 bytes_left = BCC(smb_buffer_response);
2902 length = strnlen(bcc_ptr, bytes_left - 2);
0e0d2cf3
SF
2903 if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
2904 is_unicode = true;
2905 else
2906 is_unicode = false;
2907
cc20c031 2908
50c2f753 2909 /* skip service field (NB: this field is always ASCII) */
7f8ed420
SF
2910 if (length == 3) {
2911 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
2912 (bcc_ptr[2] == 'C')) {
b6b38f70 2913 cFYI(1, "IPC connection");
7f8ed420
SF
2914 tcon->ipc = 1;
2915 }
2916 } else if (length == 2) {
2917 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
2918 /* the most common case */
b6b38f70 2919 cFYI(1, "disk share connection");
7f8ed420
SF
2920 }
2921 }
50c2f753 2922 bcc_ptr += length + 1;
cc20c031 2923 bytes_left -= (length + 1);
1da177e4 2924 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
cc20c031
JL
2925
2926 /* mostly informational -- no need to fail on error here */
90a98b2f 2927 kfree(tcon->nativeFileSystem);
d185cda7 2928 tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr,
0e0d2cf3 2929 bytes_left, is_unicode,
cc20c031
JL
2930 nls_codepage);
2931
b6b38f70 2932 cFYI(1, "nativeFileSystem=%s", tcon->nativeFileSystem);
cc20c031 2933
fb8c4b14 2934 if ((smb_buffer_response->WordCount == 3) ||
1a4e15a0
SF
2935 (smb_buffer_response->WordCount == 7))
2936 /* field is in same location */
3979877e
SF
2937 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
2938 else
2939 tcon->Flags = 0;
b6b38f70 2940 cFYI(1, "Tcon flags: 0x%x ", tcon->Flags);
1da177e4 2941 } else if ((rc == 0) && tcon == NULL) {
50c2f753 2942 /* all we need to save for IPC$ connection */
1da177e4
LT
2943 ses->ipc_tid = smb_buffer_response->Tid;
2944 }
2945
a8a11d39 2946 cifs_buf_release(smb_buffer);
1da177e4
LT
2947 return rc;
2948}
2949
2950int
2951cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
2952{
2953 int rc = 0;
50c2f753 2954 char *tmp;
1da177e4 2955
f1987b44
JL
2956 if (cifs_sb->tcon)
2957 cifs_put_tcon(cifs_sb->tcon);
50c2f753 2958
1da177e4 2959 cifs_sb->tcon = NULL;
2fe87f02
SF
2960 tmp = cifs_sb->prepath;
2961 cifs_sb->prepathlen = 0;
2962 cifs_sb->prepath = NULL;
2963 kfree(tmp);
1da177e4 2964
88e7d705 2965 return rc;
50c2f753 2966}
1da177e4 2967
198b5682 2968int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
1da177e4
LT
2969{
2970 int rc = 0;
198b5682 2971 struct TCP_Server_Info *server = ses->server;
1da177e4 2972
198b5682
JL
2973 /* only send once per connect */
2974 if (server->maxBuf != 0)
2975 return 0;
2976
2977 rc = CIFSSMBNegotiate(xid, ses);
2978 if (rc == -EAGAIN) {
2979 /* retry only once on 1st time connection */
2980 rc = CIFSSMBNegotiate(xid, ses);
2981 if (rc == -EAGAIN)
2982 rc = -EHOSTDOWN;
1da177e4 2983 }
198b5682
JL
2984 if (rc == 0) {
2985 spin_lock(&GlobalMid_Lock);
2986 if (server->tcpStatus != CifsExiting)
2987 server->tcpStatus = CifsGood;
2988 else
2989 rc = -EHOSTDOWN;
2990 spin_unlock(&GlobalMid_Lock);
26b994fa 2991
198b5682
JL
2992 }
2993
2994 return rc;
2995}
2996
2997
2998int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
2999 struct nls_table *nls_info)
3000{
3001 int rc = 0;
3002 struct TCP_Server_Info *server = ses->server;
26b994fa 3003
198b5682
JL
3004 ses->flags = 0;
3005 ses->capabilities = server->capabilities;
26b994fa 3006 if (linuxExtEnabled == 0)
198b5682 3007 ses->capabilities &= (~CAP_UNIX);
20418acd 3008
b6b38f70
JP
3009 cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3010 server->secMode, server->capabilities, server->timeAdj);
cb7691b6 3011
198b5682 3012 rc = CIFS_SessSetup(xid, ses, nls_info);
26b994fa 3013 if (rc) {
b6b38f70 3014 cERROR(1, "Send error in SessSetup = %d", rc);
26b994fa 3015 } else {
b6b38f70 3016 cFYI(1, "CIFS Session Established successfully");
20418acd 3017 spin_lock(&GlobalMid_Lock);
198b5682
JL
3018 ses->status = CifsGood;
3019 ses->need_reconnect = false;
20418acd 3020 spin_unlock(&GlobalMid_Lock);
1da177e4 3021 }
26b994fa 3022
1da177e4
LT
3023 return rc;
3024}
3025