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