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