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