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