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