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