[CIFS] Remove sparse endian warnings
[linux-2.6/linux-acpi-2.6/ibm-acpi-2.6.git] / fs / cifs / connect.c
blob9dcdb0c707ea5992d87c8397148c975ddbde9227
1 /*
2 * fs/cifs/connect.c
4 * Copyright (C) International Business Machines Corp., 2002,2009
5 * Author(s): Steve French (sfrench@us.ibm.com)
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.
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.
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
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
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>
26 #include <linux/pagemap.h>
27 #include <linux/ctype.h>
28 #include <linux/utsname.h>
29 #include <linux/mempool.h>
30 #include <linux/delay.h>
31 #include <linux/completion.h>
32 #include <linux/kthread.h>
33 #include <linux/pagevec.h>
34 #include <linux/freezer.h>
35 #include <linux/namei.h>
36 #include <asm/uaccess.h>
37 #include <asm/processor.h>
38 #include <net/ipv6.h>
39 #include "cifspdu.h"
40 #include "cifsglob.h"
41 #include "cifsproto.h"
42 #include "cifs_unicode.h"
43 #include "cifs_debug.h"
44 #include "cifs_fs_sb.h"
45 #include "ntlmssp.h"
46 #include "nterr.h"
47 #include "rfc1002pdu.h"
48 #include "cn_cifs.h"
50 #define CIFS_PORT 445
51 #define RFC1001_PORT 139
53 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
54 unsigned char *p24);
56 extern mempool_t *cifs_req_poolp;
58 struct smb_vol {
59 char *username;
60 char *password;
61 char *domainname;
62 char *UNC;
63 char *UNCip;
64 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
65 char *iocharset; /* local code page for mapping to and from Unicode */
66 char source_rfc1001_name[16]; /* netbios name of client */
67 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
68 uid_t linux_uid;
69 gid_t linux_gid;
70 mode_t file_mode;
71 mode_t dir_mode;
72 unsigned secFlg;
73 bool rw:1;
74 bool retry:1;
75 bool intr:1;
76 bool setuids:1;
77 bool override_uid:1;
78 bool override_gid:1;
79 bool dynperm:1;
80 bool noperm:1;
81 bool no_psx_acl:1; /* set if posix acl support should be disabled */
82 bool cifs_acl:1;
83 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
84 bool server_ino:1; /* use inode numbers from server ie UniqueId */
85 bool direct_io:1;
86 bool remap:1; /* set to remap seven reserved chars in filenames */
87 bool posix_paths:1; /* unset to not ask for posix pathnames. */
88 bool no_linux_ext:1;
89 bool sfu_emul:1;
90 bool nullauth:1; /* attempt to authenticate with null user */
91 bool nocase:1; /* request case insensitive filenames */
92 bool nobrl:1; /* disable sending byte range locks to srv */
93 bool mand_lock:1; /* send mandatory not posix byte range lock reqs */
94 bool seal:1; /* request transport encryption on share */
95 bool nodfs:1; /* Do not request DFS, even if available */
96 bool local_lease:1; /* check leases only on local system, not remote */
97 bool noblocksnd:1;
98 bool noautotune:1;
99 bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
100 unsigned int rsize;
101 unsigned int wsize;
102 unsigned int sockopt;
103 unsigned short int port;
104 char *prepath;
107 static int ipv4_connect(struct TCP_Server_Info *server);
108 static int ipv6_connect(struct TCP_Server_Info *server);
111 * cifs tcp session reconnection
113 * mark tcp session as reconnecting so temporarily locked
114 * mark all smb sessions as reconnecting for tcp session
115 * reconnect tcp session
116 * wake up waiters on reconnection? - (not needed currently)
118 static int
119 cifs_reconnect(struct TCP_Server_Info *server)
121 int rc = 0;
122 struct list_head *tmp, *tmp2;
123 struct cifsSesInfo *ses;
124 struct cifsTconInfo *tcon;
125 struct mid_q_entry *mid_entry;
127 spin_lock(&GlobalMid_Lock);
128 if (server->tcpStatus == CifsExiting) {
129 /* the demux thread will exit normally
130 next time through the loop */
131 spin_unlock(&GlobalMid_Lock);
132 return rc;
133 } else
134 server->tcpStatus = CifsNeedReconnect;
135 spin_unlock(&GlobalMid_Lock);
136 server->maxBuf = 0;
138 cFYI(1, ("Reconnecting tcp session"));
140 /* before reconnecting the tcp session, mark the smb session (uid)
141 and the tid bad so they are not used until reconnected */
142 read_lock(&cifs_tcp_ses_lock);
143 list_for_each(tmp, &server->smb_ses_list) {
144 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
145 ses->need_reconnect = true;
146 ses->ipc_tid = 0;
147 list_for_each(tmp2, &ses->tcon_list) {
148 tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list);
149 tcon->need_reconnect = true;
152 read_unlock(&cifs_tcp_ses_lock);
153 /* do not want to be sending data on a socket we are freeing */
154 mutex_lock(&server->srv_mutex);
155 if (server->ssocket) {
156 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
157 server->ssocket->flags));
158 kernel_sock_shutdown(server->ssocket, SHUT_WR);
159 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
160 server->ssocket->state,
161 server->ssocket->flags));
162 sock_release(server->ssocket);
163 server->ssocket = NULL;
166 spin_lock(&GlobalMid_Lock);
167 list_for_each(tmp, &server->pending_mid_q) {
168 mid_entry = list_entry(tmp, struct
169 mid_q_entry,
170 qhead);
171 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
172 /* Mark other intransit requests as needing
173 retry so we do not immediately mark the
174 session bad again (ie after we reconnect
175 below) as they timeout too */
176 mid_entry->midState = MID_RETRY_NEEDED;
179 spin_unlock(&GlobalMid_Lock);
180 mutex_unlock(&server->srv_mutex);
182 while ((server->tcpStatus != CifsExiting) &&
183 (server->tcpStatus != CifsGood)) {
184 try_to_freeze();
185 if (server->addr.sockAddr6.sin6_family == AF_INET6)
186 rc = ipv6_connect(server);
187 else
188 rc = ipv4_connect(server);
189 if (rc) {
190 cFYI(1, ("reconnect error %d", rc));
191 msleep(3000);
192 } else {
193 atomic_inc(&tcpSesReconnectCount);
194 spin_lock(&GlobalMid_Lock);
195 if (server->tcpStatus != CifsExiting)
196 server->tcpStatus = CifsGood;
197 server->sequence_number = 0;
198 spin_unlock(&GlobalMid_Lock);
199 /* atomic_set(&server->inFlight,0);*/
200 wake_up(&server->response_q);
203 return rc;
207 return codes:
208 0 not a transact2, or all data present
209 >0 transact2 with that much data missing
210 -EINVAL = invalid transact2
213 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
215 struct smb_t2_rsp *pSMBt;
216 int total_data_size;
217 int data_in_this_rsp;
218 int remaining;
220 if (pSMB->Command != SMB_COM_TRANSACTION2)
221 return 0;
223 /* check for plausible wct, bcc and t2 data and parm sizes */
224 /* check for parm and data offset going beyond end of smb */
225 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
226 cFYI(1, ("invalid transact2 word count"));
227 return -EINVAL;
230 pSMBt = (struct smb_t2_rsp *)pSMB;
232 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
233 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
235 remaining = total_data_size - data_in_this_rsp;
237 if (remaining == 0)
238 return 0;
239 else if (remaining < 0) {
240 cFYI(1, ("total data %d smaller than data in frame %d",
241 total_data_size, data_in_this_rsp));
242 return -EINVAL;
243 } else {
244 cFYI(1, ("missing %d bytes from transact2, check next response",
245 remaining));
246 if (total_data_size > maxBufSize) {
247 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
248 total_data_size, maxBufSize));
249 return -EINVAL;
251 return remaining;
255 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
257 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
258 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
259 int total_data_size;
260 int total_in_buf;
261 int remaining;
262 int total_in_buf2;
263 char *data_area_of_target;
264 char *data_area_of_buf2;
265 __u16 byte_count;
267 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
269 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
270 cFYI(1, ("total data size of primary and secondary t2 differ"));
273 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
275 remaining = total_data_size - total_in_buf;
277 if (remaining < 0)
278 return -EINVAL;
280 if (remaining == 0) /* nothing to do, ignore */
281 return 0;
283 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
284 if (remaining < total_in_buf2) {
285 cFYI(1, ("transact2 2nd response contains too much data"));
288 /* find end of first SMB data area */
289 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
290 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
291 /* validate target area */
293 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
294 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
296 data_area_of_target += total_in_buf;
298 /* copy second buffer into end of first buffer */
299 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
300 total_in_buf += total_in_buf2;
301 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
302 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
303 byte_count += total_in_buf2;
304 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
306 byte_count = pTargetSMB->smb_buf_length;
307 byte_count += total_in_buf2;
309 /* BB also add check that we are not beyond maximum buffer size */
311 pTargetSMB->smb_buf_length = byte_count;
313 if (remaining == total_in_buf2) {
314 cFYI(1, ("found the last secondary response"));
315 return 0; /* we are done */
316 } else /* more responses to go */
317 return 1;
321 static int
322 cifs_demultiplex_thread(struct TCP_Server_Info *server)
324 int length;
325 unsigned int pdu_length, total_read;
326 struct smb_hdr *smb_buffer = NULL;
327 struct smb_hdr *bigbuf = NULL;
328 struct smb_hdr *smallbuf = NULL;
329 struct msghdr smb_msg;
330 struct kvec iov;
331 struct socket *csocket = server->ssocket;
332 struct list_head *tmp;
333 struct cifsSesInfo *ses;
334 struct task_struct *task_to_wake = NULL;
335 struct mid_q_entry *mid_entry;
336 char temp;
337 bool isLargeBuf = false;
338 bool isMultiRsp;
339 int reconnect;
341 current->flags |= PF_MEMALLOC;
342 cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
344 length = atomic_inc_return(&tcpSesAllocCount);
345 if (length > 1)
346 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
347 GFP_KERNEL);
349 set_freezable();
350 while (server->tcpStatus != CifsExiting) {
351 if (try_to_freeze())
352 continue;
353 if (bigbuf == NULL) {
354 bigbuf = cifs_buf_get();
355 if (!bigbuf) {
356 cERROR(1, ("No memory for large SMB response"));
357 msleep(3000);
358 /* retry will check if exiting */
359 continue;
361 } else if (isLargeBuf) {
362 /* we are reusing a dirty large buf, clear its start */
363 memset(bigbuf, 0, sizeof(struct smb_hdr));
366 if (smallbuf == NULL) {
367 smallbuf = cifs_small_buf_get();
368 if (!smallbuf) {
369 cERROR(1, ("No memory for SMB response"));
370 msleep(1000);
371 /* retry will check if exiting */
372 continue;
374 /* beginning of smb buffer is cleared in our buf_get */
375 } else /* if existing small buf clear beginning */
376 memset(smallbuf, 0, sizeof(struct smb_hdr));
378 isLargeBuf = false;
379 isMultiRsp = false;
380 smb_buffer = smallbuf;
381 iov.iov_base = smb_buffer;
382 iov.iov_len = 4;
383 smb_msg.msg_control = NULL;
384 smb_msg.msg_controllen = 0;
385 pdu_length = 4; /* enough to get RFC1001 header */
386 incomplete_rcv:
387 length =
388 kernel_recvmsg(csocket, &smb_msg,
389 &iov, 1, pdu_length, 0 /* BB other flags? */);
391 if (server->tcpStatus == CifsExiting) {
392 break;
393 } else if (server->tcpStatus == CifsNeedReconnect) {
394 cFYI(1, ("Reconnect after server stopped responding"));
395 cifs_reconnect(server);
396 cFYI(1, ("call to reconnect done"));
397 csocket = server->ssocket;
398 continue;
399 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
400 msleep(1); /* minimum sleep to prevent looping
401 allowing socket to clear and app threads to set
402 tcpStatus CifsNeedReconnect if server hung */
403 if (pdu_length < 4) {
404 iov.iov_base = (4 - pdu_length) +
405 (char *)smb_buffer;
406 iov.iov_len = pdu_length;
407 smb_msg.msg_control = NULL;
408 smb_msg.msg_controllen = 0;
409 goto incomplete_rcv;
410 } else
411 continue;
412 } else if (length <= 0) {
413 if (server->tcpStatus == CifsNew) {
414 cFYI(1, ("tcp session abend after SMBnegprot"));
415 /* some servers kill the TCP session rather than
416 returning an SMB negprot error, in which
417 case reconnecting here is not going to help,
418 and so simply return error to mount */
419 break;
421 if (!try_to_freeze() && (length == -EINTR)) {
422 cFYI(1, ("cifsd thread killed"));
423 break;
425 cFYI(1, ("Reconnect after unexpected peek error %d",
426 length));
427 cifs_reconnect(server);
428 csocket = server->ssocket;
429 wake_up(&server->response_q);
430 continue;
431 } else if (length < pdu_length) {
432 cFYI(1, ("requested %d bytes but only got %d bytes",
433 pdu_length, length));
434 pdu_length -= length;
435 msleep(1);
436 goto incomplete_rcv;
439 /* The right amount was read from socket - 4 bytes */
440 /* so we can now interpret the length field */
442 /* the first byte big endian of the length field,
443 is actually not part of the length but the type
444 with the most common, zero, as regular data */
445 temp = *((char *) smb_buffer);
447 /* Note that FC 1001 length is big endian on the wire,
448 but we convert it here so it is always manipulated
449 as host byte order */
450 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
451 smb_buffer->smb_buf_length = pdu_length;
453 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
455 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
456 continue;
457 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
458 cFYI(1, ("Good RFC 1002 session rsp"));
459 continue;
460 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
461 /* we get this from Windows 98 instead of
462 an error on SMB negprot response */
463 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
464 pdu_length));
465 if (server->tcpStatus == CifsNew) {
466 /* if nack on negprot (rather than
467 ret of smb negprot error) reconnecting
468 not going to help, ret error to mount */
469 break;
470 } else {
471 /* give server a second to
472 clean up before reconnect attempt */
473 msleep(1000);
474 /* always try 445 first on reconnect
475 since we get NACK on some if we ever
476 connected to port 139 (the NACK is
477 since we do not begin with RFC1001
478 session initialize frame) */
479 server->addr.sockAddr.sin_port =
480 htons(CIFS_PORT);
481 cifs_reconnect(server);
482 csocket = server->ssocket;
483 wake_up(&server->response_q);
484 continue;
486 } else if (temp != (char) 0) {
487 cERROR(1, ("Unknown RFC 1002 frame"));
488 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
489 length);
490 cifs_reconnect(server);
491 csocket = server->ssocket;
492 continue;
495 /* else we have an SMB response */
496 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
497 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
498 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
499 length, pdu_length+4));
500 cifs_reconnect(server);
501 csocket = server->ssocket;
502 wake_up(&server->response_q);
503 continue;
506 /* else length ok */
507 reconnect = 0;
509 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
510 isLargeBuf = true;
511 memcpy(bigbuf, smallbuf, 4);
512 smb_buffer = bigbuf;
514 length = 0;
515 iov.iov_base = 4 + (char *)smb_buffer;
516 iov.iov_len = pdu_length;
517 for (total_read = 0; total_read < pdu_length;
518 total_read += length) {
519 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
520 pdu_length - total_read, 0);
521 if ((server->tcpStatus == CifsExiting) ||
522 (length == -EINTR)) {
523 /* then will exit */
524 reconnect = 2;
525 break;
526 } else if (server->tcpStatus == CifsNeedReconnect) {
527 cifs_reconnect(server);
528 csocket = server->ssocket;
529 /* Reconnect wakes up rspns q */
530 /* Now we will reread sock */
531 reconnect = 1;
532 break;
533 } else if ((length == -ERESTARTSYS) ||
534 (length == -EAGAIN)) {
535 msleep(1); /* minimum sleep to prevent looping,
536 allowing socket to clear and app
537 threads to set tcpStatus
538 CifsNeedReconnect if server hung*/
539 length = 0;
540 continue;
541 } else if (length <= 0) {
542 cERROR(1, ("Received no data, expecting %d",
543 pdu_length - total_read));
544 cifs_reconnect(server);
545 csocket = server->ssocket;
546 reconnect = 1;
547 break;
550 if (reconnect == 2)
551 break;
552 else if (reconnect == 1)
553 continue;
555 length += 4; /* account for rfc1002 hdr */
558 dump_smb(smb_buffer, length);
559 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
560 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
561 continue;
565 task_to_wake = NULL;
566 spin_lock(&GlobalMid_Lock);
567 list_for_each(tmp, &server->pending_mid_q) {
568 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
570 if ((mid_entry->mid == smb_buffer->Mid) &&
571 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
572 (mid_entry->command == smb_buffer->Command)) {
573 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
574 /* We have a multipart transact2 resp */
575 isMultiRsp = true;
576 if (mid_entry->resp_buf) {
577 /* merge response - fix up 1st*/
578 if (coalesce_t2(smb_buffer,
579 mid_entry->resp_buf)) {
580 mid_entry->multiRsp =
581 true;
582 break;
583 } else {
584 /* all parts received */
585 mid_entry->multiEnd =
586 true;
587 goto multi_t2_fnd;
589 } else {
590 if (!isLargeBuf) {
591 cERROR(1,("1st trans2 resp needs bigbuf"));
592 /* BB maybe we can fix this up, switch
593 to already allocated large buffer? */
594 } else {
595 /* Have first buffer */
596 mid_entry->resp_buf =
597 smb_buffer;
598 mid_entry->largeBuf =
599 true;
600 bigbuf = NULL;
603 break;
605 mid_entry->resp_buf = smb_buffer;
606 mid_entry->largeBuf = isLargeBuf;
607 multi_t2_fnd:
608 task_to_wake = mid_entry->tsk;
609 mid_entry->midState = MID_RESPONSE_RECEIVED;
610 #ifdef CONFIG_CIFS_STATS2
611 mid_entry->when_received = jiffies;
612 #endif
613 /* so we do not time out requests to server
614 which is still responding (since server could
615 be busy but not dead) */
616 server->lstrp = jiffies;
617 break;
620 spin_unlock(&GlobalMid_Lock);
621 if (task_to_wake) {
622 /* Was previous buf put in mpx struct for multi-rsp? */
623 if (!isMultiRsp) {
624 /* smb buffer will be freed by user thread */
625 if (isLargeBuf)
626 bigbuf = NULL;
627 else
628 smallbuf = NULL;
630 wake_up_process(task_to_wake);
631 } else if (!is_valid_oplock_break(smb_buffer, server) &&
632 !isMultiRsp) {
633 cERROR(1, ("No task to wake, unknown frame received! "
634 "NumMids %d", midCount.counter));
635 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
636 sizeof(struct smb_hdr));
637 #ifdef CONFIG_CIFS_DEBUG2
638 cifs_dump_detail(smb_buffer);
639 cifs_dump_mids(server);
640 #endif /* CIFS_DEBUG2 */
643 } /* end while !EXITING */
645 /* take it off the list, if it's not already */
646 write_lock(&cifs_tcp_ses_lock);
647 list_del_init(&server->tcp_ses_list);
648 write_unlock(&cifs_tcp_ses_lock);
650 spin_lock(&GlobalMid_Lock);
651 server->tcpStatus = CifsExiting;
652 spin_unlock(&GlobalMid_Lock);
653 wake_up_all(&server->response_q);
655 /* check if we have blocked requests that need to free */
656 /* Note that cifs_max_pending is normally 50, but
657 can be set at module install time to as little as two */
658 spin_lock(&GlobalMid_Lock);
659 if (atomic_read(&server->inFlight) >= cifs_max_pending)
660 atomic_set(&server->inFlight, cifs_max_pending - 1);
661 /* We do not want to set the max_pending too low or we
662 could end up with the counter going negative */
663 spin_unlock(&GlobalMid_Lock);
664 /* Although there should not be any requests blocked on
665 this queue it can not hurt to be paranoid and try to wake up requests
666 that may haven been blocked when more than 50 at time were on the wire
667 to the same server - they now will see the session is in exit state
668 and get out of SendReceive. */
669 wake_up_all(&server->request_q);
670 /* give those requests time to exit */
671 msleep(125);
673 if (server->ssocket) {
674 sock_release(csocket);
675 server->ssocket = NULL;
677 /* buffer usuallly freed in free_mid - need to free it here on exit */
678 cifs_buf_release(bigbuf);
679 if (smallbuf) /* no sense logging a debug message if NULL */
680 cifs_small_buf_release(smallbuf);
683 * BB: we shouldn't have to do any of this. It shouldn't be
684 * possible to exit from the thread with active SMB sessions
686 read_lock(&cifs_tcp_ses_lock);
687 if (list_empty(&server->pending_mid_q)) {
688 /* loop through server session structures attached to this and
689 mark them dead */
690 list_for_each(tmp, &server->smb_ses_list) {
691 ses = list_entry(tmp, struct cifsSesInfo,
692 smb_ses_list);
693 ses->status = CifsExiting;
694 ses->server = NULL;
696 read_unlock(&cifs_tcp_ses_lock);
697 } else {
698 /* although we can not zero the server struct pointer yet,
699 since there are active requests which may depnd on them,
700 mark the corresponding SMB sessions as exiting too */
701 list_for_each(tmp, &server->smb_ses_list) {
702 ses = list_entry(tmp, struct cifsSesInfo,
703 smb_ses_list);
704 ses->status = CifsExiting;
707 spin_lock(&GlobalMid_Lock);
708 list_for_each(tmp, &server->pending_mid_q) {
709 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
710 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
711 cFYI(1, ("Clearing Mid 0x%x - waking up ",
712 mid_entry->mid));
713 task_to_wake = mid_entry->tsk;
714 if (task_to_wake)
715 wake_up_process(task_to_wake);
718 spin_unlock(&GlobalMid_Lock);
719 read_unlock(&cifs_tcp_ses_lock);
720 /* 1/8th of sec is more than enough time for them to exit */
721 msleep(125);
724 if (!list_empty(&server->pending_mid_q)) {
725 /* mpx threads have not exited yet give them
726 at least the smb send timeout time for long ops */
727 /* due to delays on oplock break requests, we need
728 to wait at least 45 seconds before giving up
729 on a request getting a response and going ahead
730 and killing cifsd */
731 cFYI(1, ("Wait for exit from demultiplex thread"));
732 msleep(46000);
733 /* if threads still have not exited they are probably never
734 coming home not much else we can do but free the memory */
737 /* last chance to mark ses pointers invalid
738 if there are any pointing to this (e.g
739 if a crazy root user tried to kill cifsd
740 kernel thread explicitly this might happen) */
741 /* BB: This shouldn't be necessary, see above */
742 read_lock(&cifs_tcp_ses_lock);
743 list_for_each(tmp, &server->smb_ses_list) {
744 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
745 ses->server = NULL;
747 read_unlock(&cifs_tcp_ses_lock);
749 kfree(server->hostname);
750 task_to_wake = xchg(&server->tsk, NULL);
751 kfree(server);
753 length = atomic_dec_return(&tcpSesAllocCount);
754 if (length > 0)
755 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
756 GFP_KERNEL);
758 /* if server->tsk was NULL then wait for a signal before exiting */
759 if (!task_to_wake) {
760 set_current_state(TASK_INTERRUPTIBLE);
761 while (!signal_pending(current)) {
762 schedule();
763 set_current_state(TASK_INTERRUPTIBLE);
765 set_current_state(TASK_RUNNING);
768 module_put_and_exit(0);
771 /* extract the host portion of the UNC string */
772 static char *
773 extract_hostname(const char *unc)
775 const char *src;
776 char *dst, *delim;
777 unsigned int len;
779 /* skip double chars at beginning of string */
780 /* BB: check validity of these bytes? */
781 src = unc + 2;
783 /* delimiter between hostname and sharename is always '\\' now */
784 delim = strchr(src, '\\');
785 if (!delim)
786 return ERR_PTR(-EINVAL);
788 len = delim - src;
789 dst = kmalloc((len + 1), GFP_KERNEL);
790 if (dst == NULL)
791 return ERR_PTR(-ENOMEM);
793 memcpy(dst, src, len);
794 dst[len] = '\0';
796 return dst;
799 static int
800 cifs_parse_mount_options(char *options, const char *devname,
801 struct smb_vol *vol)
803 char *value;
804 char *data;
805 unsigned int temp_len, i, j;
806 char separator[2];
808 separator[0] = ',';
809 separator[1] = 0;
811 if (Local_System_Name[0] != 0)
812 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
813 else {
814 char *nodename = utsname()->nodename;
815 int n = strnlen(nodename, 15);
816 memset(vol->source_rfc1001_name, 0x20, 15);
817 for (i = 0; i < n; i++) {
818 /* does not have to be perfect mapping since field is
819 informational, only used for servers that do not support
820 port 445 and it can be overridden at mount time */
821 vol->source_rfc1001_name[i] = toupper(nodename[i]);
824 vol->source_rfc1001_name[15] = 0;
825 /* null target name indicates to use *SMBSERVR default called name
826 if we end up sending RFC1001 session initialize */
827 vol->target_rfc1001_name[0] = 0;
828 vol->linux_uid = current_uid(); /* use current_euid() instead? */
829 vol->linux_gid = current_gid();
830 vol->dir_mode = S_IRWXUGO;
831 /* 2767 perms indicate mandatory locking support */
832 vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
834 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
835 vol->rw = true;
836 /* default is always to request posix paths. */
837 vol->posix_paths = 1;
839 if (!options)
840 return 1;
842 if (strncmp(options, "sep=", 4) == 0) {
843 if (options[4] != 0) {
844 separator[0] = options[4];
845 options += 5;
846 } else {
847 cFYI(1, ("Null separator not allowed"));
851 while ((data = strsep(&options, separator)) != NULL) {
852 if (!*data)
853 continue;
854 if ((value = strchr(data, '=')) != NULL)
855 *value++ = '\0';
857 /* Have to parse this before we parse for "user" */
858 if (strnicmp(data, "user_xattr", 10) == 0) {
859 vol->no_xattr = 0;
860 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
861 vol->no_xattr = 1;
862 } else if (strnicmp(data, "user", 4) == 0) {
863 if (!value) {
864 printk(KERN_WARNING
865 "CIFS: invalid or missing username\n");
866 return 1; /* needs_arg; */
867 } else if (!*value) {
868 /* null user, ie anonymous, authentication */
869 vol->nullauth = 1;
871 if (strnlen(value, 200) < 200) {
872 vol->username = value;
873 } else {
874 printk(KERN_WARNING "CIFS: username too long\n");
875 return 1;
877 } else if (strnicmp(data, "pass", 4) == 0) {
878 if (!value) {
879 vol->password = NULL;
880 continue;
881 } else if (value[0] == 0) {
882 /* check if string begins with double comma
883 since that would mean the password really
884 does start with a comma, and would not
885 indicate an empty string */
886 if (value[1] != separator[0]) {
887 vol->password = NULL;
888 continue;
891 temp_len = strlen(value);
892 /* removed password length check, NTLM passwords
893 can be arbitrarily long */
895 /* if comma in password, the string will be
896 prematurely null terminated. Commas in password are
897 specified across the cifs mount interface by a double
898 comma ie ,, and a comma used as in other cases ie ','
899 as a parameter delimiter/separator is single and due
900 to the strsep above is temporarily zeroed. */
902 /* NB: password legally can have multiple commas and
903 the only illegal character in a password is null */
905 if ((value[temp_len] == 0) &&
906 (value[temp_len+1] == separator[0])) {
907 /* reinsert comma */
908 value[temp_len] = separator[0];
909 temp_len += 2; /* move after second comma */
910 while (value[temp_len] != 0) {
911 if (value[temp_len] == separator[0]) {
912 if (value[temp_len+1] ==
913 separator[0]) {
914 /* skip second comma */
915 temp_len++;
916 } else {
917 /* single comma indicating start
918 of next parm */
919 break;
922 temp_len++;
924 if (value[temp_len] == 0) {
925 options = NULL;
926 } else {
927 value[temp_len] = 0;
928 /* point option to start of next parm */
929 options = value + temp_len + 1;
931 /* go from value to value + temp_len condensing
932 double commas to singles. Note that this ends up
933 allocating a few bytes too many, which is ok */
934 vol->password = kzalloc(temp_len, GFP_KERNEL);
935 if (vol->password == NULL) {
936 printk(KERN_WARNING "CIFS: no memory "
937 "for password\n");
938 return 1;
940 for (i = 0, j = 0; i < temp_len; i++, j++) {
941 vol->password[j] = value[i];
942 if (value[i] == separator[0]
943 && value[i+1] == separator[0]) {
944 /* skip second comma */
945 i++;
948 vol->password[j] = 0;
949 } else {
950 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
951 if (vol->password == NULL) {
952 printk(KERN_WARNING "CIFS: no memory "
953 "for password\n");
954 return 1;
956 strcpy(vol->password, value);
958 } else if (strnicmp(data, "ip", 2) == 0) {
959 if (!value || !*value) {
960 vol->UNCip = NULL;
961 } else if (strnlen(value, 35) < 35) {
962 vol->UNCip = value;
963 } else {
964 printk(KERN_WARNING "CIFS: ip address "
965 "too long\n");
966 return 1;
968 } else if (strnicmp(data, "sec", 3) == 0) {
969 if (!value || !*value) {
970 cERROR(1, ("no security value specified"));
971 continue;
972 } else if (strnicmp(value, "krb5i", 5) == 0) {
973 vol->secFlg |= CIFSSEC_MAY_KRB5 |
974 CIFSSEC_MUST_SIGN;
975 } else if (strnicmp(value, "krb5p", 5) == 0) {
976 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
977 CIFSSEC_MAY_KRB5; */
978 cERROR(1, ("Krb5 cifs privacy not supported"));
979 return 1;
980 } else if (strnicmp(value, "krb5", 4) == 0) {
981 vol->secFlg |= CIFSSEC_MAY_KRB5;
982 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
983 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
984 CIFSSEC_MUST_SIGN;
985 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
986 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
987 } else if (strnicmp(value, "ntlmi", 5) == 0) {
988 vol->secFlg |= CIFSSEC_MAY_NTLM |
989 CIFSSEC_MUST_SIGN;
990 } else if (strnicmp(value, "ntlm", 4) == 0) {
991 /* ntlm is default so can be turned off too */
992 vol->secFlg |= CIFSSEC_MAY_NTLM;
993 } else if (strnicmp(value, "nontlm", 6) == 0) {
994 /* BB is there a better way to do this? */
995 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
996 #ifdef CONFIG_CIFS_WEAK_PW_HASH
997 } else if (strnicmp(value, "lanman", 6) == 0) {
998 vol->secFlg |= CIFSSEC_MAY_LANMAN;
999 #endif
1000 } else if (strnicmp(value, "none", 4) == 0) {
1001 vol->nullauth = 1;
1002 } else {
1003 cERROR(1, ("bad security option: %s", value));
1004 return 1;
1006 } else if ((strnicmp(data, "unc", 3) == 0)
1007 || (strnicmp(data, "target", 6) == 0)
1008 || (strnicmp(data, "path", 4) == 0)) {
1009 if (!value || !*value) {
1010 printk(KERN_WARNING "CIFS: invalid path to "
1011 "network resource\n");
1012 return 1; /* needs_arg; */
1014 if ((temp_len = strnlen(value, 300)) < 300) {
1015 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1016 if (vol->UNC == NULL)
1017 return 1;
1018 strcpy(vol->UNC, value);
1019 if (strncmp(vol->UNC, "//", 2) == 0) {
1020 vol->UNC[0] = '\\';
1021 vol->UNC[1] = '\\';
1022 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1023 printk(KERN_WARNING
1024 "CIFS: UNC Path does not begin "
1025 "with // or \\\\ \n");
1026 return 1;
1028 } else {
1029 printk(KERN_WARNING "CIFS: UNC name too long\n");
1030 return 1;
1032 } else if ((strnicmp(data, "domain", 3) == 0)
1033 || (strnicmp(data, "workgroup", 5) == 0)) {
1034 if (!value || !*value) {
1035 printk(KERN_WARNING "CIFS: invalid domain name\n");
1036 return 1; /* needs_arg; */
1038 /* BB are there cases in which a comma can be valid in
1039 a domain name and need special handling? */
1040 if (strnlen(value, 256) < 256) {
1041 vol->domainname = value;
1042 cFYI(1, ("Domain name set"));
1043 } else {
1044 printk(KERN_WARNING "CIFS: domain name too "
1045 "long\n");
1046 return 1;
1048 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1049 if (!value || !*value) {
1050 printk(KERN_WARNING
1051 "CIFS: invalid path prefix\n");
1052 return 1; /* needs_argument */
1054 if ((temp_len = strnlen(value, 1024)) < 1024) {
1055 if (value[0] != '/')
1056 temp_len++; /* missing leading slash */
1057 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1058 if (vol->prepath == NULL)
1059 return 1;
1060 if (value[0] != '/') {
1061 vol->prepath[0] = '/';
1062 strcpy(vol->prepath+1, value);
1063 } else
1064 strcpy(vol->prepath, value);
1065 cFYI(1, ("prefix path %s", vol->prepath));
1066 } else {
1067 printk(KERN_WARNING "CIFS: prefix too long\n");
1068 return 1;
1070 } else if (strnicmp(data, "iocharset", 9) == 0) {
1071 if (!value || !*value) {
1072 printk(KERN_WARNING "CIFS: invalid iocharset "
1073 "specified\n");
1074 return 1; /* needs_arg; */
1076 if (strnlen(value, 65) < 65) {
1077 if (strnicmp(value, "default", 7))
1078 vol->iocharset = value;
1079 /* if iocharset not set then load_nls_default
1080 is used by caller */
1081 cFYI(1, ("iocharset set to %s", value));
1082 } else {
1083 printk(KERN_WARNING "CIFS: iocharset name "
1084 "too long.\n");
1085 return 1;
1087 } else if (strnicmp(data, "uid", 3) == 0) {
1088 if (value && *value) {
1089 vol->linux_uid =
1090 simple_strtoul(value, &value, 0);
1091 vol->override_uid = 1;
1093 } else if (strnicmp(data, "gid", 3) == 0) {
1094 if (value && *value) {
1095 vol->linux_gid =
1096 simple_strtoul(value, &value, 0);
1097 vol->override_gid = 1;
1099 } else if (strnicmp(data, "file_mode", 4) == 0) {
1100 if (value && *value) {
1101 vol->file_mode =
1102 simple_strtoul(value, &value, 0);
1104 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1105 if (value && *value) {
1106 vol->dir_mode =
1107 simple_strtoul(value, &value, 0);
1109 } else if (strnicmp(data, "dirmode", 4) == 0) {
1110 if (value && *value) {
1111 vol->dir_mode =
1112 simple_strtoul(value, &value, 0);
1114 } else if (strnicmp(data, "port", 4) == 0) {
1115 if (value && *value) {
1116 vol->port =
1117 simple_strtoul(value, &value, 0);
1119 } else if (strnicmp(data, "rsize", 5) == 0) {
1120 if (value && *value) {
1121 vol->rsize =
1122 simple_strtoul(value, &value, 0);
1124 } else if (strnicmp(data, "wsize", 5) == 0) {
1125 if (value && *value) {
1126 vol->wsize =
1127 simple_strtoul(value, &value, 0);
1129 } else if (strnicmp(data, "sockopt", 5) == 0) {
1130 if (value && *value) {
1131 vol->sockopt =
1132 simple_strtoul(value, &value, 0);
1134 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1135 if (!value || !*value || (*value == ' ')) {
1136 cFYI(1, ("invalid (empty) netbiosname"));
1137 } else {
1138 memset(vol->source_rfc1001_name, 0x20, 15);
1139 for (i = 0; i < 15; i++) {
1140 /* BB are there cases in which a comma can be
1141 valid in this workstation netbios name (and need
1142 special handling)? */
1144 /* We do not uppercase netbiosname for user */
1145 if (value[i] == 0)
1146 break;
1147 else
1148 vol->source_rfc1001_name[i] =
1149 value[i];
1151 /* The string has 16th byte zero still from
1152 set at top of the function */
1153 if ((i == 15) && (value[i] != 0))
1154 printk(KERN_WARNING "CIFS: netbiosname"
1155 " longer than 15 truncated.\n");
1157 } else if (strnicmp(data, "servern", 7) == 0) {
1158 /* servernetbiosname specified override *SMBSERVER */
1159 if (!value || !*value || (*value == ' ')) {
1160 cFYI(1, ("empty server netbiosname specified"));
1161 } else {
1162 /* last byte, type, is 0x20 for servr type */
1163 memset(vol->target_rfc1001_name, 0x20, 16);
1165 for (i = 0; i < 15; i++) {
1166 /* BB are there cases in which a comma can be
1167 valid in this workstation netbios name
1168 (and need special handling)? */
1170 /* user or mount helper must uppercase
1171 the netbiosname */
1172 if (value[i] == 0)
1173 break;
1174 else
1175 vol->target_rfc1001_name[i] =
1176 value[i];
1178 /* The string has 16th byte zero still from
1179 set at top of the function */
1180 if ((i == 15) && (value[i] != 0))
1181 printk(KERN_WARNING "CIFS: server net"
1182 "biosname longer than 15 truncated.\n");
1184 } else if (strnicmp(data, "credentials", 4) == 0) {
1185 /* ignore */
1186 } else if (strnicmp(data, "version", 3) == 0) {
1187 /* ignore */
1188 } else if (strnicmp(data, "guest", 5) == 0) {
1189 /* ignore */
1190 } else if (strnicmp(data, "rw", 2) == 0) {
1191 vol->rw = true;
1192 } else if (strnicmp(data, "noblocksend", 11) == 0) {
1193 vol->noblocksnd = 1;
1194 } else if (strnicmp(data, "noautotune", 10) == 0) {
1195 vol->noautotune = 1;
1196 } else if ((strnicmp(data, "suid", 4) == 0) ||
1197 (strnicmp(data, "nosuid", 6) == 0) ||
1198 (strnicmp(data, "exec", 4) == 0) ||
1199 (strnicmp(data, "noexec", 6) == 0) ||
1200 (strnicmp(data, "nodev", 5) == 0) ||
1201 (strnicmp(data, "noauto", 6) == 0) ||
1202 (strnicmp(data, "dev", 3) == 0)) {
1203 /* The mount tool or mount.cifs helper (if present)
1204 uses these opts to set flags, and the flags are read
1205 by the kernel vfs layer before we get here (ie
1206 before read super) so there is no point trying to
1207 parse these options again and set anything and it
1208 is ok to just ignore them */
1209 continue;
1210 } else if (strnicmp(data, "ro", 2) == 0) {
1211 vol->rw = false;
1212 } else if (strnicmp(data, "hard", 4) == 0) {
1213 vol->retry = 1;
1214 } else if (strnicmp(data, "soft", 4) == 0) {
1215 vol->retry = 0;
1216 } else if (strnicmp(data, "perm", 4) == 0) {
1217 vol->noperm = 0;
1218 } else if (strnicmp(data, "noperm", 6) == 0) {
1219 vol->noperm = 1;
1220 } else if (strnicmp(data, "mapchars", 8) == 0) {
1221 vol->remap = 1;
1222 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1223 vol->remap = 0;
1224 } else if (strnicmp(data, "sfu", 3) == 0) {
1225 vol->sfu_emul = 1;
1226 } else if (strnicmp(data, "nosfu", 5) == 0) {
1227 vol->sfu_emul = 0;
1228 } else if (strnicmp(data, "nodfs", 5) == 0) {
1229 vol->nodfs = 1;
1230 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1231 vol->posix_paths = 1;
1232 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1233 vol->posix_paths = 0;
1234 } else if (strnicmp(data, "nounix", 6) == 0) {
1235 vol->no_linux_ext = 1;
1236 } else if (strnicmp(data, "nolinux", 7) == 0) {
1237 vol->no_linux_ext = 1;
1238 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1239 (strnicmp(data, "ignorecase", 10) == 0)) {
1240 vol->nocase = 1;
1241 } else if (strnicmp(data, "brl", 3) == 0) {
1242 vol->nobrl = 0;
1243 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1244 (strnicmp(data, "nolock", 6) == 0)) {
1245 vol->nobrl = 1;
1246 /* turn off mandatory locking in mode
1247 if remote locking is turned off since the
1248 local vfs will do advisory */
1249 if (vol->file_mode ==
1250 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1251 vol->file_mode = S_IALLUGO;
1252 } else if (strnicmp(data, "forcemandatorylock", 9) == 0) {
1253 /* will take the shorter form "forcemand" as well */
1254 /* This mount option will force use of mandatory
1255 (DOS/Windows style) byte range locks, instead of
1256 using posix advisory byte range locks, even if the
1257 Unix extensions are available and posix locks would
1258 be supported otherwise. If Unix extensions are not
1259 negotiated this has no effect since mandatory locks
1260 would be used (mandatory locks is all that those
1261 those servers support) */
1262 vol->mand_lock = 1;
1263 } else if (strnicmp(data, "setuids", 7) == 0) {
1264 vol->setuids = 1;
1265 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1266 vol->setuids = 0;
1267 } else if (strnicmp(data, "dynperm", 7) == 0) {
1268 vol->dynperm = true;
1269 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1270 vol->dynperm = false;
1271 } else if (strnicmp(data, "nohard", 6) == 0) {
1272 vol->retry = 0;
1273 } else if (strnicmp(data, "nosoft", 6) == 0) {
1274 vol->retry = 1;
1275 } else if (strnicmp(data, "nointr", 6) == 0) {
1276 vol->intr = 0;
1277 } else if (strnicmp(data, "intr", 4) == 0) {
1278 vol->intr = 1;
1279 } else if (strnicmp(data, "nostrictsync", 12) == 0) {
1280 vol->nostrictsync = 1;
1281 } else if (strnicmp(data, "strictsync", 10) == 0) {
1282 vol->nostrictsync = 0;
1283 } else if (strnicmp(data, "serverino", 7) == 0) {
1284 vol->server_ino = 1;
1285 } else if (strnicmp(data, "noserverino", 9) == 0) {
1286 vol->server_ino = 0;
1287 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1288 vol->cifs_acl = 1;
1289 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1290 vol->cifs_acl = 0;
1291 } else if (strnicmp(data, "acl", 3) == 0) {
1292 vol->no_psx_acl = 0;
1293 } else if (strnicmp(data, "noacl", 5) == 0) {
1294 vol->no_psx_acl = 1;
1295 #ifdef CONFIG_CIFS_EXPERIMENTAL
1296 } else if (strnicmp(data, "locallease", 6) == 0) {
1297 vol->local_lease = 1;
1298 #endif
1299 } else if (strnicmp(data, "sign", 4) == 0) {
1300 vol->secFlg |= CIFSSEC_MUST_SIGN;
1301 } else if (strnicmp(data, "seal", 4) == 0) {
1302 /* we do not do the following in secFlags because seal
1303 is a per tree connection (mount) not a per socket
1304 or per-smb connection option in the protocol */
1305 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1306 vol->seal = 1;
1307 } else if (strnicmp(data, "direct", 6) == 0) {
1308 vol->direct_io = 1;
1309 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1310 vol->direct_io = 1;
1311 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1312 if (!value || !*value) {
1313 vol->in6_addr = NULL;
1314 } else if (strnlen(value, 49) == 48) {
1315 vol->in6_addr = value;
1316 } else {
1317 printk(KERN_WARNING "CIFS: ip v6 address not "
1318 "48 characters long\n");
1319 return 1;
1321 } else if (strnicmp(data, "noac", 4) == 0) {
1322 printk(KERN_WARNING "CIFS: Mount option noac not "
1323 "supported. Instead set "
1324 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1325 } else
1326 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1327 data);
1329 if (vol->UNC == NULL) {
1330 if (devname == NULL) {
1331 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1332 "target\n");
1333 return 1;
1335 if ((temp_len = strnlen(devname, 300)) < 300) {
1336 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1337 if (vol->UNC == NULL)
1338 return 1;
1339 strcpy(vol->UNC, devname);
1340 if (strncmp(vol->UNC, "//", 2) == 0) {
1341 vol->UNC[0] = '\\';
1342 vol->UNC[1] = '\\';
1343 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1344 printk(KERN_WARNING "CIFS: UNC Path does not "
1345 "begin with // or \\\\ \n");
1346 return 1;
1348 value = strpbrk(vol->UNC+2, "/\\");
1349 if (value)
1350 *value = '\\';
1351 } else {
1352 printk(KERN_WARNING "CIFS: UNC name too long\n");
1353 return 1;
1356 if (vol->UNCip == NULL)
1357 vol->UNCip = &vol->UNC[2];
1359 return 0;
1362 static struct TCP_Server_Info *
1363 cifs_find_tcp_session(struct sockaddr_storage *addr)
1365 struct list_head *tmp;
1366 struct TCP_Server_Info *server;
1367 struct sockaddr_in *addr4 = (struct sockaddr_in *) addr;
1368 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr;
1370 write_lock(&cifs_tcp_ses_lock);
1371 list_for_each(tmp, &cifs_tcp_ses_list) {
1372 server = list_entry(tmp, struct TCP_Server_Info,
1373 tcp_ses_list);
1375 * the demux thread can exit on its own while still in CifsNew
1376 * so don't accept any sockets in that state. Since the
1377 * tcpStatus never changes back to CifsNew it's safe to check
1378 * for this without a lock.
1380 if (server->tcpStatus == CifsNew)
1381 continue;
1383 if (addr->ss_family == AF_INET &&
1384 (addr4->sin_addr.s_addr !=
1385 server->addr.sockAddr.sin_addr.s_addr))
1386 continue;
1387 else if (addr->ss_family == AF_INET6 &&
1388 !ipv6_addr_equal(&server->addr.sockAddr6.sin6_addr,
1389 &addr6->sin6_addr))
1390 continue;
1392 ++server->srv_count;
1393 write_unlock(&cifs_tcp_ses_lock);
1394 cFYI(1, ("Existing tcp session with server found"));
1395 return server;
1397 write_unlock(&cifs_tcp_ses_lock);
1398 return NULL;
1401 static void
1402 cifs_put_tcp_session(struct TCP_Server_Info *server)
1404 struct task_struct *task;
1406 write_lock(&cifs_tcp_ses_lock);
1407 if (--server->srv_count > 0) {
1408 write_unlock(&cifs_tcp_ses_lock);
1409 return;
1412 list_del_init(&server->tcp_ses_list);
1413 write_unlock(&cifs_tcp_ses_lock);
1415 spin_lock(&GlobalMid_Lock);
1416 server->tcpStatus = CifsExiting;
1417 spin_unlock(&GlobalMid_Lock);
1419 task = xchg(&server->tsk, NULL);
1420 if (task)
1421 force_sig(SIGKILL, task);
1424 static struct TCP_Server_Info *
1425 cifs_get_tcp_session(struct smb_vol *volume_info)
1427 struct TCP_Server_Info *tcp_ses = NULL;
1428 struct sockaddr_storage addr;
1429 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
1430 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
1431 int rc;
1433 memset(&addr, 0, sizeof(struct sockaddr_storage));
1435 if (volume_info->UNCip && volume_info->UNC) {
1436 rc = cifs_inet_pton(AF_INET, volume_info->UNCip,
1437 &sin_server->sin_addr.s_addr);
1439 if (rc <= 0) {
1440 /* not ipv4 address, try ipv6 */
1441 rc = cifs_inet_pton(AF_INET6, volume_info->UNCip,
1442 &sin_server6->sin6_addr.in6_u);
1443 if (rc > 0)
1444 addr.ss_family = AF_INET6;
1445 } else {
1446 addr.ss_family = AF_INET;
1449 if (rc <= 0) {
1450 /* we failed translating address */
1451 rc = -EINVAL;
1452 goto out_err;
1455 cFYI(1, ("UNC: %s ip: %s", volume_info->UNC,
1456 volume_info->UNCip));
1457 } else if (volume_info->UNCip) {
1458 /* BB using ip addr as tcp_ses name to connect to the
1459 DFS root below */
1460 cERROR(1, ("Connecting to DFS root not implemented yet"));
1461 rc = -EINVAL;
1462 goto out_err;
1463 } else /* which tcp_sess DFS root would we conect to */ {
1464 cERROR(1,
1465 ("CIFS mount error: No UNC path (e.g. -o "
1466 "unc=//192.168.1.100/public) specified"));
1467 rc = -EINVAL;
1468 goto out_err;
1471 /* see if we already have a matching tcp_ses */
1472 tcp_ses = cifs_find_tcp_session(&addr);
1473 if (tcp_ses)
1474 return tcp_ses;
1476 tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1477 if (!tcp_ses) {
1478 rc = -ENOMEM;
1479 goto out_err;
1482 tcp_ses->hostname = extract_hostname(volume_info->UNC);
1483 if (IS_ERR(tcp_ses->hostname)) {
1484 rc = PTR_ERR(tcp_ses->hostname);
1485 goto out_err;
1488 tcp_ses->noblocksnd = volume_info->noblocksnd;
1489 tcp_ses->noautotune = volume_info->noautotune;
1490 atomic_set(&tcp_ses->inFlight, 0);
1491 init_waitqueue_head(&tcp_ses->response_q);
1492 init_waitqueue_head(&tcp_ses->request_q);
1493 INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
1494 mutex_init(&tcp_ses->srv_mutex);
1495 memcpy(tcp_ses->workstation_RFC1001_name,
1496 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1497 memcpy(tcp_ses->server_RFC1001_name,
1498 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1499 tcp_ses->sequence_number = 0;
1500 INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1501 INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1504 * at this point we are the only ones with the pointer
1505 * to the struct since the kernel thread not created yet
1506 * no need to spinlock this init of tcpStatus or srv_count
1508 tcp_ses->tcpStatus = CifsNew;
1509 ++tcp_ses->srv_count;
1511 if (addr.ss_family == AF_INET6) {
1512 cFYI(1, ("attempting ipv6 connect"));
1513 /* BB should we allow ipv6 on port 139? */
1514 /* other OS never observed in Wild doing 139 with v6 */
1515 memcpy(&tcp_ses->addr.sockAddr6, sin_server6,
1516 sizeof(struct sockaddr_in6));
1517 sin_server6->sin6_port = htons(volume_info->port);
1518 rc = ipv6_connect(tcp_ses);
1519 } else {
1520 memcpy(&tcp_ses->addr.sockAddr, sin_server,
1521 sizeof(struct sockaddr_in));
1522 sin_server->sin_port = htons(volume_info->port);
1523 rc = ipv4_connect(tcp_ses);
1525 if (rc < 0) {
1526 cERROR(1, ("Error connecting to socket. Aborting operation"));
1527 goto out_err;
1531 * since we're in a cifs function already, we know that
1532 * this will succeed. No need for try_module_get().
1534 __module_get(THIS_MODULE);
1535 tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread,
1536 tcp_ses, "cifsd");
1537 if (IS_ERR(tcp_ses->tsk)) {
1538 rc = PTR_ERR(tcp_ses->tsk);
1539 cERROR(1, ("error %d create cifsd thread", rc));
1540 module_put(THIS_MODULE);
1541 goto out_err;
1544 /* thread spawned, put it on the list */
1545 write_lock(&cifs_tcp_ses_lock);
1546 list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1547 write_unlock(&cifs_tcp_ses_lock);
1549 return tcp_ses;
1551 out_err:
1552 if (tcp_ses) {
1553 kfree(tcp_ses->hostname);
1554 if (tcp_ses->ssocket)
1555 sock_release(tcp_ses->ssocket);
1556 kfree(tcp_ses);
1558 return ERR_PTR(rc);
1561 static struct cifsSesInfo *
1562 cifs_find_smb_ses(struct TCP_Server_Info *server, char *username)
1564 struct list_head *tmp;
1565 struct cifsSesInfo *ses;
1567 write_lock(&cifs_tcp_ses_lock);
1568 list_for_each(tmp, &server->smb_ses_list) {
1569 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
1570 if (strncmp(ses->userName, username, MAX_USERNAME_SIZE))
1571 continue;
1573 ++ses->ses_count;
1574 write_unlock(&cifs_tcp_ses_lock);
1575 return ses;
1577 write_unlock(&cifs_tcp_ses_lock);
1578 return NULL;
1581 static void
1582 cifs_put_smb_ses(struct cifsSesInfo *ses)
1584 int xid;
1585 struct TCP_Server_Info *server = ses->server;
1587 write_lock(&cifs_tcp_ses_lock);
1588 if (--ses->ses_count > 0) {
1589 write_unlock(&cifs_tcp_ses_lock);
1590 return;
1593 list_del_init(&ses->smb_ses_list);
1594 write_unlock(&cifs_tcp_ses_lock);
1596 if (ses->status == CifsGood) {
1597 xid = GetXid();
1598 CIFSSMBLogoff(xid, ses);
1599 _FreeXid(xid);
1601 sesInfoFree(ses);
1602 cifs_put_tcp_session(server);
1605 static struct cifsTconInfo *
1606 cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1608 struct list_head *tmp;
1609 struct cifsTconInfo *tcon;
1611 write_lock(&cifs_tcp_ses_lock);
1612 list_for_each(tmp, &ses->tcon_list) {
1613 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1614 if (tcon->tidStatus == CifsExiting)
1615 continue;
1616 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
1617 continue;
1619 ++tcon->tc_count;
1620 write_unlock(&cifs_tcp_ses_lock);
1621 return tcon;
1623 write_unlock(&cifs_tcp_ses_lock);
1624 return NULL;
1627 static void
1628 cifs_put_tcon(struct cifsTconInfo *tcon)
1630 int xid;
1631 struct cifsSesInfo *ses = tcon->ses;
1633 write_lock(&cifs_tcp_ses_lock);
1634 if (--tcon->tc_count > 0) {
1635 write_unlock(&cifs_tcp_ses_lock);
1636 return;
1639 list_del_init(&tcon->tcon_list);
1640 write_unlock(&cifs_tcp_ses_lock);
1642 xid = GetXid();
1643 CIFSSMBTDis(xid, tcon);
1644 _FreeXid(xid);
1646 DeleteTconOplockQEntries(tcon);
1647 tconInfoFree(tcon);
1648 cifs_put_smb_ses(ses);
1652 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1653 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1654 struct dfs_info3_param **preferrals, int remap)
1656 char *temp_unc;
1657 int rc = 0;
1659 *pnum_referrals = 0;
1660 *preferrals = NULL;
1662 if (pSesInfo->ipc_tid == 0) {
1663 temp_unc = kmalloc(2 /* for slashes */ +
1664 strnlen(pSesInfo->serverName,
1665 SERVER_NAME_LEN_WITH_NULL * 2)
1666 + 1 + 4 /* slash IPC$ */ + 2,
1667 GFP_KERNEL);
1668 if (temp_unc == NULL)
1669 return -ENOMEM;
1670 temp_unc[0] = '\\';
1671 temp_unc[1] = '\\';
1672 strcpy(temp_unc + 2, pSesInfo->serverName);
1673 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1674 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1675 cFYI(1,
1676 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1677 kfree(temp_unc);
1679 if (rc == 0)
1680 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1681 pnum_referrals, nls_codepage, remap);
1682 /* BB map targetUNCs to dfs_info3 structures, here or
1683 in CIFSGetDFSRefer BB */
1685 return rc;
1688 #ifdef CONFIG_DEBUG_LOCK_ALLOC
1689 static struct lock_class_key cifs_key[2];
1690 static struct lock_class_key cifs_slock_key[2];
1692 static inline void
1693 cifs_reclassify_socket4(struct socket *sock)
1695 struct sock *sk = sock->sk;
1696 BUG_ON(sock_owned_by_user(sk));
1697 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
1698 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
1701 static inline void
1702 cifs_reclassify_socket6(struct socket *sock)
1704 struct sock *sk = sock->sk;
1705 BUG_ON(sock_owned_by_user(sk));
1706 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
1707 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
1709 #else
1710 static inline void
1711 cifs_reclassify_socket4(struct socket *sock)
1715 static inline void
1716 cifs_reclassify_socket6(struct socket *sock)
1719 #endif
1721 /* See RFC1001 section 14 on representation of Netbios names */
1722 static void rfc1002mangle(char *target, char *source, unsigned int length)
1724 unsigned int i, j;
1726 for (i = 0, j = 0; i < (length); i++) {
1727 /* mask a nibble at a time and encode */
1728 target[j] = 'A' + (0x0F & (source[i] >> 4));
1729 target[j+1] = 'A' + (0x0F & source[i]);
1730 j += 2;
1736 static int
1737 ipv4_connect(struct TCP_Server_Info *server)
1739 int rc = 0;
1740 bool connected = false;
1741 __be16 orig_port = 0;
1742 struct socket *socket = server->ssocket;
1744 if (socket == NULL) {
1745 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1746 IPPROTO_TCP, &socket);
1747 if (rc < 0) {
1748 cERROR(1, ("Error %d creating socket", rc));
1749 return rc;
1752 /* BB other socket options to set KEEPALIVE, NODELAY? */
1753 cFYI(1, ("Socket created"));
1754 server->ssocket = socket;
1755 socket->sk->sk_allocation = GFP_NOFS;
1756 cifs_reclassify_socket4(socket);
1759 /* user overrode default port */
1760 if (server->addr.sockAddr.sin_port) {
1761 rc = socket->ops->connect(socket, (struct sockaddr *)
1762 &server->addr.sockAddr,
1763 sizeof(struct sockaddr_in), 0);
1764 if (rc >= 0)
1765 connected = true;
1768 if (!connected) {
1769 /* save original port so we can retry user specified port
1770 later if fall back ports fail this time */
1771 orig_port = server->addr.sockAddr.sin_port;
1773 /* do not retry on the same port we just failed on */
1774 if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
1775 server->addr.sockAddr.sin_port = htons(CIFS_PORT);
1776 rc = socket->ops->connect(socket,
1777 (struct sockaddr *)
1778 &server->addr.sockAddr,
1779 sizeof(struct sockaddr_in), 0);
1780 if (rc >= 0)
1781 connected = true;
1784 if (!connected) {
1785 server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
1786 rc = socket->ops->connect(socket, (struct sockaddr *)
1787 &server->addr.sockAddr,
1788 sizeof(struct sockaddr_in), 0);
1789 if (rc >= 0)
1790 connected = true;
1793 /* give up here - unless we want to retry on different
1794 protocol families some day */
1795 if (!connected) {
1796 if (orig_port)
1797 server->addr.sockAddr.sin_port = orig_port;
1798 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1799 sock_release(socket);
1800 server->ssocket = NULL;
1801 return rc;
1806 * Eventually check for other socket options to change from
1807 * the default. sock_setsockopt not used because it expects
1808 * user space buffer
1810 socket->sk->sk_rcvtimeo = 7 * HZ;
1811 socket->sk->sk_sndtimeo = 5 * HZ;
1813 /* make the bufsizes depend on wsize/rsize and max requests */
1814 if (server->noautotune) {
1815 if (socket->sk->sk_sndbuf < (200 * 1024))
1816 socket->sk->sk_sndbuf = 200 * 1024;
1817 if (socket->sk->sk_rcvbuf < (140 * 1024))
1818 socket->sk->sk_rcvbuf = 140 * 1024;
1821 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1822 socket->sk->sk_sndbuf,
1823 socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo));
1825 /* send RFC1001 sessinit */
1826 if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) {
1827 /* some servers require RFC1001 sessinit before sending
1828 negprot - BB check reconnection in case where second
1829 sessinit is sent but no second negprot */
1830 struct rfc1002_session_packet *ses_init_buf;
1831 struct smb_hdr *smb_buf;
1832 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1833 GFP_KERNEL);
1834 if (ses_init_buf) {
1835 ses_init_buf->trailer.session_req.called_len = 32;
1836 if (server->server_RFC1001_name &&
1837 server->server_RFC1001_name[0] != 0)
1838 rfc1002mangle(ses_init_buf->trailer.
1839 session_req.called_name,
1840 server->server_RFC1001_name,
1841 RFC1001_NAME_LEN_WITH_NULL);
1842 else
1843 rfc1002mangle(ses_init_buf->trailer.
1844 session_req.called_name,
1845 DEFAULT_CIFS_CALLED_NAME,
1846 RFC1001_NAME_LEN_WITH_NULL);
1848 ses_init_buf->trailer.session_req.calling_len = 32;
1850 /* calling name ends in null (byte 16) from old smb
1851 convention. */
1852 if (server->workstation_RFC1001_name &&
1853 server->workstation_RFC1001_name[0] != 0)
1854 rfc1002mangle(ses_init_buf->trailer.
1855 session_req.calling_name,
1856 server->workstation_RFC1001_name,
1857 RFC1001_NAME_LEN_WITH_NULL);
1858 else
1859 rfc1002mangle(ses_init_buf->trailer.
1860 session_req.calling_name,
1861 "LINUX_CIFS_CLNT",
1862 RFC1001_NAME_LEN_WITH_NULL);
1864 ses_init_buf->trailer.session_req.scope1 = 0;
1865 ses_init_buf->trailer.session_req.scope2 = 0;
1866 smb_buf = (struct smb_hdr *)ses_init_buf;
1867 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1868 smb_buf->smb_buf_length = 0x81000044;
1869 rc = smb_send(server, smb_buf, 0x44);
1870 kfree(ses_init_buf);
1871 msleep(1); /* RFC1001 layer in at least one server
1872 requires very short break before negprot
1873 presumably because not expecting negprot
1874 to follow so fast. This is a simple
1875 solution that works without
1876 complicating the code and causes no
1877 significant slowing down on mount
1878 for everyone else */
1880 /* else the negprot may still work without this
1881 even though malloc failed */
1885 return rc;
1888 static int
1889 ipv6_connect(struct TCP_Server_Info *server)
1891 int rc = 0;
1892 bool connected = false;
1893 __be16 orig_port = 0;
1894 struct socket *socket = server->ssocket;
1896 if (socket == NULL) {
1897 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1898 IPPROTO_TCP, &socket);
1899 if (rc < 0) {
1900 cERROR(1, ("Error %d creating ipv6 socket", rc));
1901 socket = NULL;
1902 return rc;
1905 /* BB other socket options to set KEEPALIVE, NODELAY? */
1906 cFYI(1, ("ipv6 Socket created"));
1907 server->ssocket = socket;
1908 socket->sk->sk_allocation = GFP_NOFS;
1909 cifs_reclassify_socket6(socket);
1912 /* user overrode default port */
1913 if (server->addr.sockAddr6.sin6_port) {
1914 rc = socket->ops->connect(socket,
1915 (struct sockaddr *) &server->addr.sockAddr6,
1916 sizeof(struct sockaddr_in6), 0);
1917 if (rc >= 0)
1918 connected = true;
1921 if (!connected) {
1922 /* save original port so we can retry user specified port
1923 later if fall back ports fail this time */
1925 orig_port = server->addr.sockAddr6.sin6_port;
1926 /* do not retry on the same port we just failed on */
1927 if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) {
1928 server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
1929 rc = socket->ops->connect(socket, (struct sockaddr *)
1930 &server->addr.sockAddr6,
1931 sizeof(struct sockaddr_in6), 0);
1932 if (rc >= 0)
1933 connected = true;
1936 if (!connected) {
1937 server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT);
1938 rc = socket->ops->connect(socket, (struct sockaddr *)
1939 &server->addr.sockAddr6,
1940 sizeof(struct sockaddr_in6), 0);
1941 if (rc >= 0)
1942 connected = true;
1945 /* give up here - unless we want to retry on different
1946 protocol families some day */
1947 if (!connected) {
1948 if (orig_port)
1949 server->addr.sockAddr6.sin6_port = orig_port;
1950 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1951 sock_release(socket);
1952 server->ssocket = NULL;
1953 return rc;
1957 * Eventually check for other socket options to change from
1958 * the default. sock_setsockopt not used because it expects
1959 * user space buffer
1961 socket->sk->sk_rcvtimeo = 7 * HZ;
1962 socket->sk->sk_sndtimeo = 5 * HZ;
1963 server->ssocket = socket;
1965 return rc;
1968 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1969 struct super_block *sb, struct smb_vol *vol_info)
1971 /* if we are reconnecting then should we check to see if
1972 * any requested capabilities changed locally e.g. via
1973 * remount but we can not do much about it here
1974 * if they have (even if we could detect it by the following)
1975 * Perhaps we could add a backpointer to array of sb from tcon
1976 * or if we change to make all sb to same share the same
1977 * sb as NFS - then we only have one backpointer to sb.
1978 * What if we wanted to mount the server share twice once with
1979 * and once without posixacls or posix paths? */
1980 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1982 if (vol_info && vol_info->no_linux_ext) {
1983 tcon->fsUnixInfo.Capability = 0;
1984 tcon->unix_ext = 0; /* Unix Extensions disabled */
1985 cFYI(1, ("Linux protocol extensions disabled"));
1986 return;
1987 } else if (vol_info)
1988 tcon->unix_ext = 1; /* Unix Extensions supported */
1990 if (tcon->unix_ext == 0) {
1991 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1992 return;
1995 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1996 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1998 /* check for reconnect case in which we do not
1999 want to change the mount behavior if we can avoid it */
2000 if (vol_info == NULL) {
2001 /* turn off POSIX ACL and PATHNAMES if not set
2002 originally at mount time */
2003 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
2004 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2005 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2006 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2007 cERROR(1, ("POSIXPATH support change"));
2008 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2009 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2010 cERROR(1, ("possible reconnect error"));
2011 cERROR(1,
2012 ("server disabled POSIX path support"));
2016 cap &= CIFS_UNIX_CAP_MASK;
2017 if (vol_info && vol_info->no_psx_acl)
2018 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2019 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
2020 cFYI(1, ("negotiated posix acl support"));
2021 if (sb)
2022 sb->s_flags |= MS_POSIXACL;
2025 if (vol_info && vol_info->posix_paths == 0)
2026 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2027 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2028 cFYI(1, ("negotiate posix pathnames"));
2029 if (sb)
2030 CIFS_SB(sb)->mnt_cifs_flags |=
2031 CIFS_MOUNT_POSIX_PATHS;
2034 /* We might be setting the path sep back to a different
2035 form if we are reconnecting and the server switched its
2036 posix path capability for this share */
2037 if (sb && (CIFS_SB(sb)->prepathlen > 0))
2038 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
2040 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2041 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2042 CIFS_SB(sb)->rsize = 127 * 1024;
2043 cFYI(DBG2,
2044 ("larger reads not supported by srv"));
2049 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
2050 #ifdef CONFIG_CIFS_DEBUG2
2051 if (cap & CIFS_UNIX_FCNTL_CAP)
2052 cFYI(1, ("FCNTL cap"));
2053 if (cap & CIFS_UNIX_EXTATTR_CAP)
2054 cFYI(1, ("EXTATTR cap"));
2055 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2056 cFYI(1, ("POSIX path cap"));
2057 if (cap & CIFS_UNIX_XATTR_CAP)
2058 cFYI(1, ("XATTR cap"));
2059 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
2060 cFYI(1, ("POSIX ACL cap"));
2061 if (cap & CIFS_UNIX_LARGE_READ_CAP)
2062 cFYI(1, ("very large read cap"));
2063 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
2064 cFYI(1, ("very large write cap"));
2065 #endif /* CIFS_DEBUG2 */
2066 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
2067 if (vol_info == NULL) {
2068 cFYI(1, ("resetting capabilities failed"));
2069 } else
2070 cERROR(1, ("Negotiating Unix capabilities "
2071 "with the server failed. Consider "
2072 "mounting with the Unix Extensions\n"
2073 "disabled, if problems are found, "
2074 "by specifying the nounix mount "
2075 "option."));
2081 static void
2082 convert_delimiter(char *path, char delim)
2084 int i;
2085 char old_delim;
2087 if (path == NULL)
2088 return;
2090 if (delim == '/')
2091 old_delim = '\\';
2092 else
2093 old_delim = '/';
2095 for (i = 0; path[i] != '\0'; i++) {
2096 if (path[i] == old_delim)
2097 path[i] = delim;
2101 static void setup_cifs_sb(struct smb_vol *pvolume_info,
2102 struct cifs_sb_info *cifs_sb)
2104 if (pvolume_info->rsize > CIFSMaxBufSize) {
2105 cERROR(1, ("rsize %d too large, using MaxBufSize",
2106 pvolume_info->rsize));
2107 cifs_sb->rsize = CIFSMaxBufSize;
2108 } else if ((pvolume_info->rsize) &&
2109 (pvolume_info->rsize <= CIFSMaxBufSize))
2110 cifs_sb->rsize = pvolume_info->rsize;
2111 else /* default */
2112 cifs_sb->rsize = CIFSMaxBufSize;
2114 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2115 cERROR(1, ("wsize %d too large, using 4096 instead",
2116 pvolume_info->wsize));
2117 cifs_sb->wsize = 4096;
2118 } else if (pvolume_info->wsize)
2119 cifs_sb->wsize = pvolume_info->wsize;
2120 else
2121 cifs_sb->wsize = min_t(const int,
2122 PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2123 127*1024);
2124 /* old default of CIFSMaxBufSize was too small now
2125 that SMB Write2 can send multiple pages in kvec.
2126 RFC1001 does not describe what happens when frame
2127 bigger than 128K is sent so use that as max in
2128 conjunction with 52K kvec constraint on arch with 4K
2129 page size */
2131 if (cifs_sb->rsize < 2048) {
2132 cifs_sb->rsize = 2048;
2133 /* Windows ME may prefer this */
2134 cFYI(1, ("readsize set to minimum: 2048"));
2136 /* calculate prepath */
2137 cifs_sb->prepath = pvolume_info->prepath;
2138 if (cifs_sb->prepath) {
2139 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2140 /* we can not convert the / to \ in the path
2141 separators in the prefixpath yet because we do not
2142 know (until reset_cifs_unix_caps is called later)
2143 whether POSIX PATH CAP is available. We normalize
2144 the / to \ after reset_cifs_unix_caps is called */
2145 pvolume_info->prepath = NULL;
2146 } else
2147 cifs_sb->prepathlen = 0;
2148 cifs_sb->mnt_uid = pvolume_info->linux_uid;
2149 cifs_sb->mnt_gid = pvolume_info->linux_gid;
2150 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
2151 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
2152 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2153 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2155 if (pvolume_info->noperm)
2156 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2157 if (pvolume_info->setuids)
2158 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2159 if (pvolume_info->server_ino)
2160 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2161 if (pvolume_info->remap)
2162 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2163 if (pvolume_info->no_xattr)
2164 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2165 if (pvolume_info->sfu_emul)
2166 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2167 if (pvolume_info->nobrl)
2168 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2169 if (pvolume_info->nostrictsync)
2170 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
2171 if (pvolume_info->mand_lock)
2172 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
2173 if (pvolume_info->cifs_acl)
2174 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2175 if (pvolume_info->override_uid)
2176 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2177 if (pvolume_info->override_gid)
2178 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2179 if (pvolume_info->dynperm)
2180 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2181 if (pvolume_info->direct_io) {
2182 cFYI(1, ("mounting share using direct i/o"));
2183 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2186 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2187 cERROR(1, ("mount option dynperm ignored if cifsacl "
2188 "mount option supported"));
2191 static int
2192 is_path_accessible(int xid, struct cifsTconInfo *tcon,
2193 struct cifs_sb_info *cifs_sb, const char *full_path)
2195 int rc;
2196 __u64 inode_num;
2197 FILE_ALL_INFO *pfile_info;
2199 rc = CIFSGetSrvInodeNumber(xid, tcon, full_path, &inode_num,
2200 cifs_sb->local_nls,
2201 cifs_sb->mnt_cifs_flags &
2202 CIFS_MOUNT_MAP_SPECIAL_CHR);
2203 if (rc != -EOPNOTSUPP)
2204 return rc;
2206 pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
2207 if (pfile_info == NULL)
2208 return -ENOMEM;
2210 rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info,
2211 0 /* not legacy */, cifs_sb->local_nls,
2212 cifs_sb->mnt_cifs_flags &
2213 CIFS_MOUNT_MAP_SPECIAL_CHR);
2214 kfree(pfile_info);
2215 return rc;
2218 static void
2219 cleanup_volume_info(struct smb_vol **pvolume_info)
2221 struct smb_vol *volume_info;
2223 if (!pvolume_info && !*pvolume_info)
2224 return;
2226 volume_info = *pvolume_info;
2227 kzfree(volume_info->password);
2228 kfree(volume_info->UNC);
2229 kfree(volume_info->prepath);
2230 kfree(volume_info);
2231 *pvolume_info = NULL;
2232 return;
2235 #ifdef CONFIG_CIFS_DFS_UPCALL
2236 /* build_path_to_root returns full path to root when
2237 * we do not have an exiting connection (tcon) */
2238 static char *
2239 build_unc_path_to_root(const struct smb_vol *volume_info,
2240 const struct cifs_sb_info *cifs_sb)
2242 char *full_path;
2244 int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
2245 full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL);
2246 if (full_path == NULL)
2247 return ERR_PTR(-ENOMEM);
2249 strncpy(full_path, volume_info->UNC, unc_len);
2250 if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
2251 int i;
2252 for (i = 0; i < unc_len; i++) {
2253 if (full_path[i] == '\\')
2254 full_path[i] = '/';
2258 if (cifs_sb->prepathlen)
2259 strncpy(full_path + unc_len, cifs_sb->prepath,
2260 cifs_sb->prepathlen);
2262 full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
2263 return full_path;
2265 #endif
2268 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2269 char *mount_data_global, const char *devname)
2271 int rc = 0;
2272 int xid;
2273 struct smb_vol *volume_info;
2274 struct cifsSesInfo *pSesInfo = NULL;
2275 struct cifsTconInfo *tcon = NULL;
2276 struct TCP_Server_Info *srvTcp = NULL;
2277 char *full_path;
2278 char *mount_data = mount_data_global;
2279 #ifdef CONFIG_CIFS_DFS_UPCALL
2280 struct dfs_info3_param *referrals = NULL;
2281 unsigned int num_referrals = 0;
2282 int referral_walks_count = 0;
2283 try_mount_again:
2284 #endif
2285 full_path = NULL;
2287 xid = GetXid();
2289 volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2290 if (!volume_info) {
2291 rc = -ENOMEM;
2292 goto out;
2295 if (cifs_parse_mount_options(mount_data, devname, volume_info)) {
2296 rc = -EINVAL;
2297 goto out;
2300 if (volume_info->nullauth) {
2301 cFYI(1, ("null user"));
2302 volume_info->username = "";
2303 } else if (volume_info->username) {
2304 /* BB fixme parse for domain name here */
2305 cFYI(1, ("Username: %s", volume_info->username));
2306 } else {
2307 cifserror("No username specified");
2308 /* In userspace mount helper we can get user name from alternate
2309 locations such as env variables and files on disk */
2310 rc = -EINVAL;
2311 goto out;
2315 /* this is needed for ASCII cp to Unicode converts */
2316 if (volume_info->iocharset == NULL) {
2317 cifs_sb->local_nls = load_nls_default();
2318 /* load_nls_default can not return null */
2319 } else {
2320 cifs_sb->local_nls = load_nls(volume_info->iocharset);
2321 if (cifs_sb->local_nls == NULL) {
2322 cERROR(1, ("CIFS mount error: iocharset %s not found",
2323 volume_info->iocharset));
2324 rc = -ELIBACC;
2325 goto out;
2329 /* get a reference to a tcp session */
2330 srvTcp = cifs_get_tcp_session(volume_info);
2331 if (IS_ERR(srvTcp)) {
2332 rc = PTR_ERR(srvTcp);
2333 goto out;
2336 pSesInfo = cifs_find_smb_ses(srvTcp, volume_info->username);
2337 if (pSesInfo) {
2338 cFYI(1, ("Existing smb sess found (status=%d)",
2339 pSesInfo->status));
2341 * The existing SMB session already has a reference to srvTcp,
2342 * so we can put back the extra one we got before
2344 cifs_put_tcp_session(srvTcp);
2346 down(&pSesInfo->sesSem);
2347 if (pSesInfo->need_reconnect) {
2348 cFYI(1, ("Session needs reconnect"));
2349 rc = cifs_setup_session(xid, pSesInfo,
2350 cifs_sb->local_nls);
2352 up(&pSesInfo->sesSem);
2353 } else if (!rc) {
2354 cFYI(1, ("Existing smb sess not found"));
2355 pSesInfo = sesInfoAlloc();
2356 if (pSesInfo == NULL) {
2357 rc = -ENOMEM;
2358 goto mount_fail_check;
2361 /* new SMB session uses our srvTcp ref */
2362 pSesInfo->server = srvTcp;
2363 if (srvTcp->addr.sockAddr6.sin6_family == AF_INET6)
2364 sprintf(pSesInfo->serverName, "%pI6",
2365 &srvTcp->addr.sockAddr6.sin6_addr);
2366 else
2367 sprintf(pSesInfo->serverName, "%pI4",
2368 &srvTcp->addr.sockAddr.sin_addr.s_addr);
2370 write_lock(&cifs_tcp_ses_lock);
2371 list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
2372 write_unlock(&cifs_tcp_ses_lock);
2374 /* volume_info->password freed at unmount */
2375 if (volume_info->password) {
2376 pSesInfo->password = kstrdup(volume_info->password,
2377 GFP_KERNEL);
2378 if (!pSesInfo->password) {
2379 rc = -ENOMEM;
2380 goto mount_fail_check;
2383 if (volume_info->username)
2384 strncpy(pSesInfo->userName, volume_info->username,
2385 MAX_USERNAME_SIZE);
2386 if (volume_info->domainname) {
2387 int len = strlen(volume_info->domainname);
2388 pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
2389 if (pSesInfo->domainName)
2390 strcpy(pSesInfo->domainName,
2391 volume_info->domainname);
2393 pSesInfo->linux_uid = volume_info->linux_uid;
2394 pSesInfo->overrideSecFlg = volume_info->secFlg;
2395 down(&pSesInfo->sesSem);
2397 /* BB FIXME need to pass vol->secFlgs BB */
2398 rc = cifs_setup_session(xid, pSesInfo,
2399 cifs_sb->local_nls);
2400 up(&pSesInfo->sesSem);
2403 /* search for existing tcon to this server share */
2404 if (!rc) {
2405 setup_cifs_sb(volume_info, cifs_sb);
2407 tcon = cifs_find_tcon(pSesInfo, volume_info->UNC);
2408 if (tcon) {
2409 cFYI(1, ("Found match on UNC path"));
2410 /* existing tcon already has a reference */
2411 cifs_put_smb_ses(pSesInfo);
2412 if (tcon->seal != volume_info->seal)
2413 cERROR(1, ("transport encryption setting "
2414 "conflicts with existing tid"));
2415 } else {
2416 tcon = tconInfoAlloc();
2417 if (tcon == NULL) {
2418 rc = -ENOMEM;
2419 goto mount_fail_check;
2422 tcon->ses = pSesInfo;
2423 if (volume_info->password) {
2424 tcon->password = kstrdup(volume_info->password,
2425 GFP_KERNEL);
2426 if (!tcon->password) {
2427 rc = -ENOMEM;
2428 goto mount_fail_check;
2432 if ((strchr(volume_info->UNC + 3, '\\') == NULL)
2433 && (strchr(volume_info->UNC + 3, '/') == NULL)) {
2434 cERROR(1, ("Missing share name"));
2435 rc = -ENODEV;
2436 goto mount_fail_check;
2437 } else {
2438 /* BB Do we need to wrap sesSem around
2439 * this TCon call and Unix SetFS as
2440 * we do on SessSetup and reconnect? */
2441 rc = CIFSTCon(xid, pSesInfo, volume_info->UNC,
2442 tcon, cifs_sb->local_nls);
2443 cFYI(1, ("CIFS Tcon rc = %d", rc));
2444 if (volume_info->nodfs) {
2445 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2446 cFYI(1, ("DFS disabled (%d)",
2447 tcon->Flags));
2450 if (rc)
2451 goto remote_path_check;
2452 tcon->seal = volume_info->seal;
2453 write_lock(&cifs_tcp_ses_lock);
2454 list_add(&tcon->tcon_list, &pSesInfo->tcon_list);
2455 write_unlock(&cifs_tcp_ses_lock);
2458 /* we can have only one retry value for a connection
2459 to a share so for resources mounted more than once
2460 to the same server share the last value passed in
2461 for the retry flag is used */
2462 tcon->retry = volume_info->retry;
2463 tcon->nocase = volume_info->nocase;
2464 tcon->local_lease = volume_info->local_lease;
2466 if (pSesInfo) {
2467 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2468 sb->s_maxbytes = (u64) 1 << 63;
2469 } else
2470 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2473 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2474 sb->s_time_gran = 100;
2476 if (rc)
2477 goto remote_path_check;
2479 cifs_sb->tcon = tcon;
2481 /* do not care if following two calls succeed - informational */
2482 if (!tcon->ipc) {
2483 CIFSSMBQFSDeviceInfo(xid, tcon);
2484 CIFSSMBQFSAttributeInfo(xid, tcon);
2487 /* tell server which Unix caps we support */
2488 if (tcon->ses->capabilities & CAP_UNIX)
2489 /* reset of caps checks mount to see if unix extensions
2490 disabled for just this mount */
2491 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
2492 else
2493 tcon->unix_ext = 0; /* server does not support them */
2495 /* convert forward to back slashes in prepath here if needed */
2496 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2497 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
2499 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2500 cifs_sb->rsize = 1024 * 127;
2501 cFYI(DBG2, ("no very large read support, rsize now 127K"));
2503 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2504 cifs_sb->wsize = min(cifs_sb->wsize,
2505 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2506 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2507 cifs_sb->rsize = min(cifs_sb->rsize,
2508 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2510 remote_path_check:
2511 /* check if a whole path (including prepath) is not remote */
2512 if (!rc && cifs_sb->prepathlen && tcon) {
2513 /* build_path_to_root works only when we have a valid tcon */
2514 full_path = cifs_build_path_to_root(cifs_sb);
2515 if (full_path == NULL) {
2516 rc = -ENOMEM;
2517 goto mount_fail_check;
2519 rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
2520 if (rc != -EREMOTE) {
2521 kfree(full_path);
2522 goto mount_fail_check;
2524 kfree(full_path);
2527 /* get referral if needed */
2528 if (rc == -EREMOTE) {
2529 #ifdef CONFIG_CIFS_DFS_UPCALL
2530 if (referral_walks_count > MAX_NESTED_LINKS) {
2532 * BB: when we implement proper loop detection,
2533 * we will remove this check. But now we need it
2534 * to prevent an indefinite loop if 'DFS tree' is
2535 * misconfigured (i.e. has loops).
2537 rc = -ELOOP;
2538 goto mount_fail_check;
2540 /* convert forward to back slashes in prepath here if needed */
2541 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2542 convert_delimiter(cifs_sb->prepath,
2543 CIFS_DIR_SEP(cifs_sb));
2544 full_path = build_unc_path_to_root(volume_info, cifs_sb);
2545 if (IS_ERR(full_path)) {
2546 rc = PTR_ERR(full_path);
2547 goto mount_fail_check;
2550 cFYI(1, ("Getting referral for: %s", full_path));
2551 rc = get_dfs_path(xid, pSesInfo , full_path + 1,
2552 cifs_sb->local_nls, &num_referrals, &referrals,
2553 cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
2554 if (!rc && num_referrals > 0) {
2555 char *fake_devname = NULL;
2557 if (mount_data != mount_data_global)
2558 kfree(mount_data);
2559 mount_data = cifs_compose_mount_options(
2560 cifs_sb->mountdata, full_path + 1,
2561 referrals, &fake_devname);
2562 kfree(fake_devname);
2563 free_dfs_info_array(referrals, num_referrals);
2565 if (tcon)
2566 cifs_put_tcon(tcon);
2567 else if (pSesInfo)
2568 cifs_put_smb_ses(pSesInfo);
2570 cleanup_volume_info(&volume_info);
2571 FreeXid(xid);
2572 kfree(full_path);
2573 referral_walks_count++;
2574 goto try_mount_again;
2576 #else /* No DFS support, return error on mount */
2577 rc = -EOPNOTSUPP;
2578 #endif
2581 mount_fail_check:
2582 /* on error free sesinfo and tcon struct if needed */
2583 if (rc) {
2584 if (mount_data != mount_data_global)
2585 kfree(mount_data);
2586 /* If find_unc succeeded then rc == 0 so we can not end */
2587 /* up accidently freeing someone elses tcon struct */
2588 if (tcon)
2589 cifs_put_tcon(tcon);
2590 else if (pSesInfo)
2591 cifs_put_smb_ses(pSesInfo);
2592 else
2593 cifs_put_tcp_session(srvTcp);
2594 goto out;
2597 /* volume_info->password is freed above when existing session found
2598 (in which case it is not needed anymore) but when new sesion is created
2599 the password ptr is put in the new session structure (in which case the
2600 password will be freed at unmount time) */
2601 out:
2602 /* zero out password before freeing */
2603 cleanup_volume_info(&volume_info);
2604 FreeXid(xid);
2605 return rc;
2608 static int
2609 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2610 struct cifsSesInfo *ses, bool *pNTLMv2_flag,
2611 const struct nls_table *nls_codepage)
2613 struct smb_hdr *smb_buffer;
2614 struct smb_hdr *smb_buffer_response;
2615 SESSION_SETUP_ANDX *pSMB;
2616 SESSION_SETUP_ANDX *pSMBr;
2617 char *bcc_ptr;
2618 char *domain;
2619 int rc = 0;
2620 int remaining_words = 0;
2621 int bytes_returned = 0;
2622 int len;
2623 int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
2624 PNEGOTIATE_MESSAGE SecurityBlob;
2625 PCHALLENGE_MESSAGE SecurityBlob2;
2626 __u32 negotiate_flags, capabilities;
2627 __u16 count;
2629 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2630 if (ses == NULL)
2631 return -EINVAL;
2632 domain = ses->domainName;
2633 *pNTLMv2_flag = false;
2634 smb_buffer = cifs_buf_get();
2635 if (smb_buffer == NULL) {
2636 return -ENOMEM;
2638 smb_buffer_response = smb_buffer;
2639 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2640 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2642 /* send SMBsessionSetup here */
2643 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2644 NULL /* no tCon exists yet */ , 12 /* wct */ );
2646 smb_buffer->Mid = GetNextMid(ses->server);
2647 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2648 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2650 pSMB->req.AndXCommand = 0xFF;
2651 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2652 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2654 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2655 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2657 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2658 CAP_EXTENDED_SECURITY;
2659 if (ses->capabilities & CAP_UNICODE) {
2660 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2661 capabilities |= CAP_UNICODE;
2663 if (ses->capabilities & CAP_STATUS32) {
2664 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2665 capabilities |= CAP_STATUS32;
2667 if (ses->capabilities & CAP_DFS) {
2668 smb_buffer->Flags2 |= SMBFLG2_DFS;
2669 capabilities |= CAP_DFS;
2671 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2673 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2674 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2675 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2676 SecurityBlob->MessageType = NtLmNegotiate;
2677 negotiate_flags =
2678 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2679 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2680 NTLMSSP_NEGOTIATE_56 |
2681 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2682 if (sign_CIFS_PDUs)
2683 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2684 /* setup pointers to domain name and workstation name */
2685 bcc_ptr += SecurityBlobLength;
2687 SecurityBlob->WorkstationName.BufferOffset = 0;
2688 SecurityBlob->WorkstationName.Length = 0;
2689 SecurityBlob->WorkstationName.MaximumLength = 0;
2691 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2692 along with username on auth request (ie the response to challenge) */
2693 SecurityBlob->DomainName.BufferOffset = 0;
2694 SecurityBlob->DomainName.Length = 0;
2695 SecurityBlob->DomainName.MaximumLength = 0;
2696 if (ses->capabilities & CAP_UNICODE) {
2697 if ((long) bcc_ptr % 2) {
2698 *bcc_ptr = 0;
2699 bcc_ptr++;
2702 bytes_returned =
2703 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2704 32, nls_codepage);
2705 bcc_ptr += 2 * bytes_returned;
2706 bytes_returned =
2707 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2708 nls_codepage);
2709 bcc_ptr += 2 * bytes_returned;
2710 bcc_ptr += 2; /* null terminate Linux version */
2711 bytes_returned =
2712 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2713 64, nls_codepage);
2714 bcc_ptr += 2 * bytes_returned;
2715 *(bcc_ptr + 1) = 0;
2716 *(bcc_ptr + 2) = 0;
2717 bcc_ptr += 2; /* null terminate network opsys string */
2718 *(bcc_ptr + 1) = 0;
2719 *(bcc_ptr + 2) = 0;
2720 bcc_ptr += 2; /* null domain */
2721 } else { /* ASCII */
2722 strcpy(bcc_ptr, "Linux version ");
2723 bcc_ptr += strlen("Linux version ");
2724 strcpy(bcc_ptr, utsname()->release);
2725 bcc_ptr += strlen(utsname()->release) + 1;
2726 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2727 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2728 bcc_ptr++; /* empty domain field */
2729 *bcc_ptr = 0;
2731 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2732 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2733 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2734 smb_buffer->smb_buf_length += count;
2735 pSMB->req.ByteCount = cpu_to_le16(count);
2737 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2738 &bytes_returned, CIFS_LONG_OP);
2740 if (smb_buffer_response->Status.CifsError ==
2741 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2742 rc = 0;
2744 if (rc) {
2745 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2746 } else if ((smb_buffer_response->WordCount == 3)
2747 || (smb_buffer_response->WordCount == 4)) {
2748 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2749 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2751 if (action & GUEST_LOGIN)
2752 cFYI(1, ("Guest login"));
2753 /* Do we want to set anything in SesInfo struct when guest login? */
2755 bcc_ptr = pByteArea(smb_buffer_response);
2756 /* response can have either 3 or 4 word count - Samba sends 3 */
2758 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2759 if (SecurityBlob2->MessageType != NtLmChallenge) {
2760 cFYI(1, ("Unexpected NTLMSSP message type received %d",
2761 SecurityBlob2->MessageType));
2762 } else if (ses) {
2763 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2764 cFYI(1, ("UID = %d", ses->Suid));
2765 if ((pSMBr->resp.hdr.WordCount == 3)
2766 || ((pSMBr->resp.hdr.WordCount == 4)
2767 && (blob_len <
2768 pSMBr->resp.ByteCount))) {
2770 if (pSMBr->resp.hdr.WordCount == 4) {
2771 bcc_ptr += blob_len;
2772 cFYI(1, ("Security Blob Length %d",
2773 blob_len));
2776 cFYI(1, ("NTLMSSP Challenge rcvd"));
2778 memcpy(ses->server->cryptKey,
2779 SecurityBlob2->Challenge,
2780 CIFS_CRYPTO_KEY_SIZE);
2781 /* NTLMV2 flag is not for NTLMv2 password hash */
2782 /* if (SecurityBlob2->NegotiateFlags &
2783 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2784 *pNTLMv2_flag = true; */ /* BB wrong */
2786 if ((SecurityBlob2->NegotiateFlags &
2787 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2788 || (sign_CIFS_PDUs > 1))
2789 ses->server->secMode |=
2790 SECMODE_SIGN_REQUIRED;
2791 if ((SecurityBlob2->NegotiateFlags &
2792 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2793 ses->server->secMode |=
2794 SECMODE_SIGN_ENABLED;
2796 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2797 if ((long) (bcc_ptr) % 2) {
2798 remaining_words =
2799 (BCC(smb_buffer_response)
2800 - 1) / 2;
2801 /* Must word align unicode strings */
2802 bcc_ptr++;
2803 } else {
2804 remaining_words =
2806 (smb_buffer_response) / 2;
2808 len =
2809 UniStrnlen((wchar_t *) bcc_ptr,
2810 remaining_words - 1);
2811 /* We look for obvious messed up bcc or strings in response so we do not go off
2812 the end since (at least) WIN2K and Windows XP have a major bug in not null
2813 terminating last Unicode string in response */
2814 kfree(ses->serverOS);
2815 ses->serverOS =
2816 kzalloc(2 * (len + 1), GFP_KERNEL);
2817 cifs_strfromUCS_le(ses->serverOS,
2818 (__le16 *)
2819 bcc_ptr, len,
2820 nls_codepage);
2821 bcc_ptr += 2 * (len + 1);
2822 remaining_words -= len + 1;
2823 ses->serverOS[2 * len] = 0;
2824 ses->serverOS[1 + (2 * len)] = 0;
2825 if (remaining_words > 0) {
2826 len = UniStrnlen((wchar_t *)
2827 bcc_ptr,
2828 remaining_words
2829 - 1);
2830 kfree(ses->serverNOS);
2831 ses->serverNOS =
2832 kzalloc(2 * (len + 1),
2833 GFP_KERNEL);
2834 cifs_strfromUCS_le(ses->
2835 serverNOS,
2836 (__le16 *)
2837 bcc_ptr,
2838 len,
2839 nls_codepage);
2840 bcc_ptr += 2 * (len + 1);
2841 ses->serverNOS[2 * len] = 0;
2842 ses->serverNOS[1 +
2843 (2 * len)] = 0;
2844 remaining_words -= len + 1;
2845 if (remaining_words > 0) {
2846 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2847 /* last string not always null terminated
2848 (for e.g. for Windows XP & 2000) */
2849 kfree(ses->serverDomain);
2850 ses->serverDomain =
2851 kzalloc(2 *
2852 (len +
2854 GFP_KERNEL);
2855 cifs_strfromUCS_le
2856 (ses->serverDomain,
2857 (__le16 *)bcc_ptr,
2858 len, nls_codepage);
2859 bcc_ptr +=
2860 2 * (len + 1);
2861 ses->serverDomain[2*len]
2862 = 0;
2863 ses->serverDomain
2864 [1 + (2 * len)]
2865 = 0;
2866 } /* else no more room so create dummy domain string */
2867 else {
2868 kfree(ses->serverDomain);
2869 ses->serverDomain =
2870 kzalloc(2,
2871 GFP_KERNEL);
2873 } else { /* no room so create dummy domain and NOS string */
2874 kfree(ses->serverDomain);
2875 ses->serverDomain =
2876 kzalloc(2, GFP_KERNEL);
2877 kfree(ses->serverNOS);
2878 ses->serverNOS =
2879 kzalloc(2, GFP_KERNEL);
2881 } else { /* ASCII */
2882 len = strnlen(bcc_ptr, 1024);
2883 if (((long) bcc_ptr + len) - (long)
2884 pByteArea(smb_buffer_response)
2885 <= BCC(smb_buffer_response)) {
2886 kfree(ses->serverOS);
2887 ses->serverOS =
2888 kzalloc(len + 1,
2889 GFP_KERNEL);
2890 strncpy(ses->serverOS,
2891 bcc_ptr, len);
2893 bcc_ptr += len;
2894 bcc_ptr[0] = 0; /* null terminate string */
2895 bcc_ptr++;
2897 len = strnlen(bcc_ptr, 1024);
2898 kfree(ses->serverNOS);
2899 ses->serverNOS =
2900 kzalloc(len + 1,
2901 GFP_KERNEL);
2902 strncpy(ses->serverNOS, bcc_ptr, len);
2903 bcc_ptr += len;
2904 bcc_ptr[0] = 0;
2905 bcc_ptr++;
2907 len = strnlen(bcc_ptr, 1024);
2908 kfree(ses->serverDomain);
2909 ses->serverDomain =
2910 kzalloc(len + 1,
2911 GFP_KERNEL);
2912 strncpy(ses->serverDomain,
2913 bcc_ptr, len);
2914 bcc_ptr += len;
2915 bcc_ptr[0] = 0;
2916 bcc_ptr++;
2917 } else
2918 cFYI(1,
2919 ("field of length %d "
2920 "extends beyond end of smb",
2921 len));
2923 } else {
2924 cERROR(1, ("Security Blob Length extends beyond"
2925 " end of SMB"));
2927 } else {
2928 cERROR(1, ("No session structure passed in."));
2930 } else {
2931 cERROR(1, ("Invalid Word count %d:",
2932 smb_buffer_response->WordCount));
2933 rc = -EIO;
2936 cifs_buf_release(smb_buffer);
2938 return rc;
2941 static int
2942 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2943 char *ntlm_session_key, bool ntlmv2_flag,
2944 const struct nls_table *nls_codepage)
2946 struct smb_hdr *smb_buffer;
2947 struct smb_hdr *smb_buffer_response;
2948 SESSION_SETUP_ANDX *pSMB;
2949 SESSION_SETUP_ANDX *pSMBr;
2950 char *bcc_ptr;
2951 char *user;
2952 char *domain;
2953 int rc = 0;
2954 int remaining_words = 0;
2955 int bytes_returned = 0;
2956 int len;
2957 int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
2958 PAUTHENTICATE_MESSAGE SecurityBlob;
2959 __u32 negotiate_flags, capabilities;
2960 __u16 count;
2962 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2963 if (ses == NULL)
2964 return -EINVAL;
2965 user = ses->userName;
2966 domain = ses->domainName;
2967 smb_buffer = cifs_buf_get();
2968 if (smb_buffer == NULL) {
2969 return -ENOMEM;
2971 smb_buffer_response = smb_buffer;
2972 pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
2973 pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
2975 /* send SMBsessionSetup here */
2976 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2977 NULL /* no tCon exists yet */ , 12 /* wct */ );
2979 smb_buffer->Mid = GetNextMid(ses->server);
2980 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2981 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2982 pSMB->req.AndXCommand = 0xFF;
2983 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2984 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2986 pSMB->req.hdr.Uid = ses->Suid;
2988 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2989 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2991 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2992 CAP_EXTENDED_SECURITY;
2993 if (ses->capabilities & CAP_UNICODE) {
2994 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2995 capabilities |= CAP_UNICODE;
2997 if (ses->capabilities & CAP_STATUS32) {
2998 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2999 capabilities |= CAP_STATUS32;
3001 if (ses->capabilities & CAP_DFS) {
3002 smb_buffer->Flags2 |= SMBFLG2_DFS;
3003 capabilities |= CAP_DFS;
3005 pSMB->req.Capabilities = cpu_to_le32(capabilities);
3007 bcc_ptr = (char *)&pSMB->req.SecurityBlob;
3008 SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
3009 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
3010 SecurityBlob->MessageType = NtLmAuthenticate;
3011 bcc_ptr += SecurityBlobLength;
3012 negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
3013 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
3014 NTLMSSP_NEGOTIATE_56 | NTLMSSP_NEGOTIATE_128 |
3015 NTLMSSP_NEGOTIATE_EXTENDED_SEC;
3016 if (sign_CIFS_PDUs)
3017 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
3019 /* setup pointers to domain name and workstation name */
3021 SecurityBlob->WorkstationName.BufferOffset = 0;
3022 SecurityBlob->WorkstationName.Length = 0;
3023 SecurityBlob->WorkstationName.MaximumLength = 0;
3024 SecurityBlob->SessionKey.Length = 0;
3025 SecurityBlob->SessionKey.MaximumLength = 0;
3026 SecurityBlob->SessionKey.BufferOffset = 0;
3028 SecurityBlob->LmChallengeResponse.Length = 0;
3029 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
3030 SecurityBlob->LmChallengeResponse.BufferOffset = 0;
3032 SecurityBlob->NtChallengeResponse.Length =
3033 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3034 SecurityBlob->NtChallengeResponse.MaximumLength =
3035 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3036 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
3037 SecurityBlob->NtChallengeResponse.BufferOffset =
3038 cpu_to_le32(SecurityBlobLength);
3039 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
3040 bcc_ptr += CIFS_SESS_KEY_SIZE;
3042 if (ses->capabilities & CAP_UNICODE) {
3043 if (domain == NULL) {
3044 SecurityBlob->DomainName.BufferOffset = 0;
3045 SecurityBlob->DomainName.Length = 0;
3046 SecurityBlob->DomainName.MaximumLength = 0;
3047 } else {
3048 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
3049 nls_codepage);
3050 ln *= 2;
3051 SecurityBlob->DomainName.MaximumLength =
3052 cpu_to_le16(ln);
3053 SecurityBlob->DomainName.BufferOffset =
3054 cpu_to_le32(SecurityBlobLength);
3055 bcc_ptr += ln;
3056 SecurityBlobLength += ln;
3057 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3059 if (user == NULL) {
3060 SecurityBlob->UserName.BufferOffset = 0;
3061 SecurityBlob->UserName.Length = 0;
3062 SecurityBlob->UserName.MaximumLength = 0;
3063 } else {
3064 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
3065 nls_codepage);
3066 ln *= 2;
3067 SecurityBlob->UserName.MaximumLength =
3068 cpu_to_le16(ln);
3069 SecurityBlob->UserName.BufferOffset =
3070 cpu_to_le32(SecurityBlobLength);
3071 bcc_ptr += ln;
3072 SecurityBlobLength += ln;
3073 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3076 /* SecurityBlob->WorkstationName.Length =
3077 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3078 SecurityBlob->WorkstationName.Length *= 2;
3079 SecurityBlob->WorkstationName.MaximumLength =
3080 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3081 SecurityBlob->WorkstationName.BufferOffset =
3082 cpu_to_le32(SecurityBlobLength);
3083 bcc_ptr += SecurityBlob->WorkstationName.Length;
3084 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3085 SecurityBlob->WorkstationName.Length =
3086 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3088 if ((long) bcc_ptr % 2) {
3089 *bcc_ptr = 0;
3090 bcc_ptr++;
3092 bytes_returned =
3093 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3094 32, nls_codepage);
3095 bcc_ptr += 2 * bytes_returned;
3096 bytes_returned =
3097 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3098 nls_codepage);
3099 bcc_ptr += 2 * bytes_returned;
3100 bcc_ptr += 2; /* null term version string */
3101 bytes_returned =
3102 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3103 64, nls_codepage);
3104 bcc_ptr += 2 * bytes_returned;
3105 *(bcc_ptr + 1) = 0;
3106 *(bcc_ptr + 2) = 0;
3107 bcc_ptr += 2; /* null terminate network opsys string */
3108 *(bcc_ptr + 1) = 0;
3109 *(bcc_ptr + 2) = 0;
3110 bcc_ptr += 2; /* null domain */
3111 } else { /* ASCII */
3112 if (domain == NULL) {
3113 SecurityBlob->DomainName.BufferOffset = 0;
3114 SecurityBlob->DomainName.Length = 0;
3115 SecurityBlob->DomainName.MaximumLength = 0;
3116 } else {
3117 __u16 ln;
3118 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3119 strncpy(bcc_ptr, domain, 63);
3120 ln = strnlen(domain, 64);
3121 SecurityBlob->DomainName.MaximumLength =
3122 cpu_to_le16(ln);
3123 SecurityBlob->DomainName.BufferOffset =
3124 cpu_to_le32(SecurityBlobLength);
3125 bcc_ptr += ln;
3126 SecurityBlobLength += ln;
3127 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3129 if (user == NULL) {
3130 SecurityBlob->UserName.BufferOffset = 0;
3131 SecurityBlob->UserName.Length = 0;
3132 SecurityBlob->UserName.MaximumLength = 0;
3133 } else {
3134 __u16 ln;
3135 strncpy(bcc_ptr, user, 63);
3136 ln = strnlen(user, 64);
3137 SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
3138 SecurityBlob->UserName.BufferOffset =
3139 cpu_to_le32(SecurityBlobLength);
3140 bcc_ptr += ln;
3141 SecurityBlobLength += ln;
3142 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3144 /* BB fill in our workstation name if known BB */
3146 strcpy(bcc_ptr, "Linux version ");
3147 bcc_ptr += strlen("Linux version ");
3148 strcpy(bcc_ptr, utsname()->release);
3149 bcc_ptr += strlen(utsname()->release) + 1;
3150 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3151 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3152 bcc_ptr++; /* null domain */
3153 *bcc_ptr = 0;
3155 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3156 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3157 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3158 smb_buffer->smb_buf_length += count;
3159 pSMB->req.ByteCount = cpu_to_le16(count);
3161 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3162 &bytes_returned, CIFS_LONG_OP);
3163 if (rc) {
3164 /* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3165 } else if ((smb_buffer_response->WordCount == 3) ||
3166 (smb_buffer_response->WordCount == 4)) {
3167 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3168 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3169 if (action & GUEST_LOGIN)
3170 cFYI(1, ("Guest login")); /* BB Should we set anything
3171 in SesInfo struct ? */
3172 /* if (SecurityBlob2->MessageType != NtLm??) {
3173 cFYI("Unexpected message type on auth response is %d"));
3174 } */
3176 if (ses) {
3177 cFYI(1,
3178 ("Check challenge UID %d vs auth response UID %d",
3179 ses->Suid, smb_buffer_response->Uid));
3180 /* UID left in wire format */
3181 ses->Suid = smb_buffer_response->Uid;
3182 bcc_ptr = pByteArea(smb_buffer_response);
3183 /* response can have either 3 or 4 word count - Samba sends 3 */
3184 if ((pSMBr->resp.hdr.WordCount == 3)
3185 || ((pSMBr->resp.hdr.WordCount == 4)
3186 && (blob_len <
3187 pSMBr->resp.ByteCount))) {
3188 if (pSMBr->resp.hdr.WordCount == 4) {
3189 bcc_ptr +=
3190 blob_len;
3191 cFYI(1,
3192 ("Security Blob Length %d ",
3193 blob_len));
3196 cFYI(1,
3197 ("NTLMSSP response to Authenticate "));
3199 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3200 if ((long) (bcc_ptr) % 2) {
3201 remaining_words =
3202 (BCC(smb_buffer_response)
3203 - 1) / 2;
3204 bcc_ptr++; /* Unicode strings must be word aligned */
3205 } else {
3206 remaining_words = BCC(smb_buffer_response) / 2;
3208 len = UniStrnlen((wchar_t *) bcc_ptr,
3209 remaining_words - 1);
3210 /* We look for obvious messed up bcc or strings in response so we do not go off
3211 the end since (at least) WIN2K and Windows XP have a major bug in not null
3212 terminating last Unicode string in response */
3213 kfree(ses->serverOS);
3214 ses->serverOS =
3215 kzalloc(2 * (len + 1), GFP_KERNEL);
3216 cifs_strfromUCS_le(ses->serverOS,
3217 (__le16 *)
3218 bcc_ptr, len,
3219 nls_codepage);
3220 bcc_ptr += 2 * (len + 1);
3221 remaining_words -= len + 1;
3222 ses->serverOS[2 * len] = 0;
3223 ses->serverOS[1 + (2 * len)] = 0;
3224 if (remaining_words > 0) {
3225 len = UniStrnlen((wchar_t *)
3226 bcc_ptr,
3227 remaining_words
3228 - 1);
3229 kfree(ses->serverNOS);
3230 ses->serverNOS =
3231 kzalloc(2 * (len + 1),
3232 GFP_KERNEL);
3233 cifs_strfromUCS_le(ses->
3234 serverNOS,
3235 (__le16 *)
3236 bcc_ptr,
3237 len,
3238 nls_codepage);
3239 bcc_ptr += 2 * (len + 1);
3240 ses->serverNOS[2 * len] = 0;
3241 ses->serverNOS[1+(2*len)] = 0;
3242 remaining_words -= len + 1;
3243 if (remaining_words > 0) {
3244 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3245 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3246 kfree(ses->serverDomain);
3247 ses->serverDomain =
3248 kzalloc(2 *
3249 (len +
3251 GFP_KERNEL);
3252 cifs_strfromUCS_le
3253 (ses->
3254 serverDomain,
3255 (__le16 *)
3256 bcc_ptr, len,
3257 nls_codepage);
3258 bcc_ptr +=
3259 2 * (len + 1);
3260 ses->
3261 serverDomain[2
3262 * len]
3263 = 0;
3264 ses->
3265 serverDomain[1
3269 len)]
3270 = 0;
3271 } /* else no more room so create dummy domain string */
3272 else {
3273 kfree(ses->serverDomain);
3274 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3276 } else { /* no room so create dummy domain and NOS string */
3277 kfree(ses->serverDomain);
3278 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3279 kfree(ses->serverNOS);
3280 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3282 } else { /* ASCII */
3283 len = strnlen(bcc_ptr, 1024);
3284 if (((long) bcc_ptr + len) -
3285 (long) pByteArea(smb_buffer_response)
3286 <= BCC(smb_buffer_response)) {
3287 kfree(ses->serverOS);
3288 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
3289 strncpy(ses->serverOS,bcc_ptr, len);
3291 bcc_ptr += len;
3292 bcc_ptr[0] = 0; /* null terminate the string */
3293 bcc_ptr++;
3295 len = strnlen(bcc_ptr, 1024);
3296 kfree(ses->serverNOS);
3297 ses->serverNOS = kzalloc(len+1,
3298 GFP_KERNEL);
3299 strncpy(ses->serverNOS,
3300 bcc_ptr, len);
3301 bcc_ptr += len;
3302 bcc_ptr[0] = 0;
3303 bcc_ptr++;
3305 len = strnlen(bcc_ptr, 1024);
3306 kfree(ses->serverDomain);
3307 ses->serverDomain =
3308 kzalloc(len+1,
3309 GFP_KERNEL);
3310 strncpy(ses->serverDomain,
3311 bcc_ptr, len);
3312 bcc_ptr += len;
3313 bcc_ptr[0] = 0;
3314 bcc_ptr++;
3315 } else
3316 cFYI(1, ("field of length %d "
3317 "extends beyond end of smb ",
3318 len));
3320 } else {
3321 cERROR(1, ("Security Blob extends beyond end "
3322 "of SMB"));
3324 } else {
3325 cERROR(1, ("No session structure passed in."));
3327 } else {
3328 cERROR(1, ("Invalid Word count %d: ",
3329 smb_buffer_response->WordCount));
3330 rc = -EIO;
3333 cifs_buf_release(smb_buffer);
3335 return rc;
3339 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3340 const char *tree, struct cifsTconInfo *tcon,
3341 const struct nls_table *nls_codepage)
3343 struct smb_hdr *smb_buffer;
3344 struct smb_hdr *smb_buffer_response;
3345 TCONX_REQ *pSMB;
3346 TCONX_RSP *pSMBr;
3347 unsigned char *bcc_ptr;
3348 int rc = 0;
3349 int length, bytes_left;
3350 __u16 count;
3352 if (ses == NULL)
3353 return -EIO;
3355 smb_buffer = cifs_buf_get();
3356 if (smb_buffer == NULL) {
3357 return -ENOMEM;
3359 smb_buffer_response = smb_buffer;
3361 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3362 NULL /*no tid */ , 4 /*wct */ );
3364 smb_buffer->Mid = GetNextMid(ses->server);
3365 smb_buffer->Uid = ses->Suid;
3366 pSMB = (TCONX_REQ *) smb_buffer;
3367 pSMBr = (TCONX_RSP *) smb_buffer_response;
3369 pSMB->AndXCommand = 0xFF;
3370 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3371 bcc_ptr = &pSMB->Password[0];
3372 if ((ses->server->secMode) & SECMODE_USER) {
3373 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3374 *bcc_ptr = 0; /* password is null byte */
3375 bcc_ptr++; /* skip password */
3376 /* already aligned so no need to do it below */
3377 } else {
3378 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3379 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3380 specified as required (when that support is added to
3381 the vfs in the future) as only NTLM or the much
3382 weaker LANMAN (which we do not send by default) is accepted
3383 by Samba (not sure whether other servers allow
3384 NTLMv2 password here) */
3385 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3386 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3387 (ses->server->secType == LANMAN))
3388 calc_lanman_hash(tcon->password, ses->server->cryptKey,
3389 ses->server->secMode &
3390 SECMODE_PW_ENCRYPT ? true : false,
3391 bcc_ptr);
3392 else
3393 #endif /* CIFS_WEAK_PW_HASH */
3394 SMBNTencrypt(tcon->password, ses->server->cryptKey,
3395 bcc_ptr);
3397 bcc_ptr += CIFS_SESS_KEY_SIZE;
3398 if (ses->capabilities & CAP_UNICODE) {
3399 /* must align unicode strings */
3400 *bcc_ptr = 0; /* null byte password */
3401 bcc_ptr++;
3405 if (ses->server->secMode &
3406 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3407 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3409 if (ses->capabilities & CAP_STATUS32) {
3410 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3412 if (ses->capabilities & CAP_DFS) {
3413 smb_buffer->Flags2 |= SMBFLG2_DFS;
3415 if (ses->capabilities & CAP_UNICODE) {
3416 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3417 length =
3418 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3419 6 /* max utf8 char length in bytes */ *
3420 (/* server len*/ + 256 /* share len */), nls_codepage);
3421 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3422 bcc_ptr += 2; /* skip trailing null */
3423 } else { /* ASCII */
3424 strcpy(bcc_ptr, tree);
3425 bcc_ptr += strlen(tree) + 1;
3427 strcpy(bcc_ptr, "?????");
3428 bcc_ptr += strlen("?????");
3429 bcc_ptr += 1;
3430 count = bcc_ptr - &pSMB->Password[0];
3431 pSMB->hdr.smb_buf_length += count;
3432 pSMB->ByteCount = cpu_to_le16(count);
3434 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3435 CIFS_STD_OP);
3437 /* above now done in SendReceive */
3438 if ((rc == 0) && (tcon != NULL)) {
3439 bool is_unicode;
3441 tcon->tidStatus = CifsGood;
3442 tcon->need_reconnect = false;
3443 tcon->tid = smb_buffer_response->Tid;
3444 bcc_ptr = pByteArea(smb_buffer_response);
3445 bytes_left = BCC(smb_buffer_response);
3446 length = strnlen(bcc_ptr, bytes_left - 2);
3447 if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
3448 is_unicode = true;
3449 else
3450 is_unicode = false;
3453 /* skip service field (NB: this field is always ASCII) */
3454 if (length == 3) {
3455 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3456 (bcc_ptr[2] == 'C')) {
3457 cFYI(1, ("IPC connection"));
3458 tcon->ipc = 1;
3460 } else if (length == 2) {
3461 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3462 /* the most common case */
3463 cFYI(1, ("disk share connection"));
3466 bcc_ptr += length + 1;
3467 bytes_left -= (length + 1);
3468 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3470 /* mostly informational -- no need to fail on error here */
3471 tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr,
3472 bytes_left, is_unicode,
3473 nls_codepage);
3475 cFYI(1, ("nativeFileSystem=%s", tcon->nativeFileSystem));
3477 if ((smb_buffer_response->WordCount == 3) ||
3478 (smb_buffer_response->WordCount == 7))
3479 /* field is in same location */
3480 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3481 else
3482 tcon->Flags = 0;
3483 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3484 } else if ((rc == 0) && tcon == NULL) {
3485 /* all we need to save for IPC$ connection */
3486 ses->ipc_tid = smb_buffer_response->Tid;
3489 cifs_buf_release(smb_buffer);
3490 return rc;
3494 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3496 int rc = 0;
3497 char *tmp;
3499 if (cifs_sb->tcon)
3500 cifs_put_tcon(cifs_sb->tcon);
3502 cifs_sb->tcon = NULL;
3503 tmp = cifs_sb->prepath;
3504 cifs_sb->prepathlen = 0;
3505 cifs_sb->prepath = NULL;
3506 kfree(tmp);
3508 return rc;
3511 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3512 struct nls_table *nls_info)
3514 int rc = 0;
3515 int first_time = 0;
3516 struct TCP_Server_Info *server = pSesInfo->server;
3518 /* what if server changes its buffer size after dropping the session? */
3519 if (server->maxBuf == 0) /* no need to send on reconnect */ {
3520 rc = CIFSSMBNegotiate(xid, pSesInfo);
3521 if (rc == -EAGAIN) {
3522 /* retry only once on 1st time connection */
3523 rc = CIFSSMBNegotiate(xid, pSesInfo);
3524 if (rc == -EAGAIN)
3525 rc = -EHOSTDOWN;
3527 if (rc == 0) {
3528 spin_lock(&GlobalMid_Lock);
3529 if (server->tcpStatus != CifsExiting)
3530 server->tcpStatus = CifsGood;
3531 else
3532 rc = -EHOSTDOWN;
3533 spin_unlock(&GlobalMid_Lock);
3536 first_time = 1;
3539 if (rc)
3540 goto ss_err_exit;
3542 pSesInfo->flags = 0;
3543 pSesInfo->capabilities = server->capabilities;
3544 if (linuxExtEnabled == 0)
3545 pSesInfo->capabilities &= (~CAP_UNIX);
3547 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3548 server->secMode, server->capabilities, server->timeAdj));
3550 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
3551 if (rc) {
3552 cERROR(1, ("Send error in SessSetup = %d", rc));
3553 } else {
3554 cFYI(1, ("CIFS Session Established successfully"));
3555 spin_lock(&GlobalMid_Lock);
3556 pSesInfo->status = CifsGood;
3557 pSesInfo->need_reconnect = false;
3558 spin_unlock(&GlobalMid_Lock);
3561 ss_err_exit:
3562 return rc;