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