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