4 * Copyright (C) International Business Machines Corp., 2002,2008
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
22 #include <linux/net.h>
23 #include <linux/string.h>
24 #include <linux/list.h>
25 #include <linux/wait.h>
26 #include <linux/ipv6.h>
27 #include <linux/pagemap.h>
28 #include <linux/ctype.h>
29 #include <linux/utsname.h>
30 #include <linux/mempool.h>
31 #include <linux/delay.h>
32 #include <linux/completion.h>
33 #include <linux/kthread.h>
34 #include <linux/pagevec.h>
35 #include <linux/freezer.h>
36 #include <asm/uaccess.h>
37 #include <asm/processor.h>
40 #include "cifsproto.h"
41 #include "cifs_unicode.h"
42 #include "cifs_debug.h"
43 #include "cifs_fs_sb.h"
46 #include "rfc1002pdu.h"
50 #define RFC1001_PORT 139
52 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
55 extern mempool_t *cifs_req_poolp;
63 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
64 char *iocharset; /* local code page for mapping to and from Unicode */
65 char source_rfc1001_name[16]; /* netbios name of client */
66 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
80 bool no_psx_acl:1; /* set if posix acl support should be disabled */
82 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
83 bool server_ino:1; /* use inode numbers from server ie UniqueId */
85 bool remap:1; /* set to remap seven reserved chars in filenames */
86 bool posix_paths:1; /* unset to not ask for posix pathnames. */
89 bool nullauth:1; /* attempt to authenticate with null user */
90 bool nocase:1; /* request case insensitive filenames */
91 bool nobrl:1; /* disable sending byte range locks to srv */
92 bool seal:1; /* request transport encryption on share */
93 bool nodfs:1; /* Do not request DFS, even if available */
94 bool local_lease:1; /* check leases only on local system, not remote */
100 unsigned short int port;
104 static int ipv4_connect(struct sockaddr_in *psin_server,
105 struct socket **csocket,
107 char *server_netb_name,
109 bool nosndbuf); /* ipv6 never set sndbuf size */
110 static int ipv6_connect(struct sockaddr_in6 *psin_server,
111 struct socket **csocket, bool noblocksnd);
115 * cifs tcp session reconnection
117 * mark tcp session as reconnecting so temporarily locked
118 * mark all smb sessions as reconnecting for tcp session
119 * reconnect tcp session
120 * wake up waiters on reconnection? - (not needed currently)
124 cifs_reconnect(struct TCP_Server_Info *server)
127 struct list_head *tmp;
128 struct cifsSesInfo *ses;
129 struct cifsTconInfo *tcon;
130 struct mid_q_entry *mid_entry;
132 spin_lock(&GlobalMid_Lock);
133 if (server->tcpStatus == CifsExiting) {
134 /* the demux thread will exit normally
135 next time through the loop */
136 spin_unlock(&GlobalMid_Lock);
139 server->tcpStatus = CifsNeedReconnect;
140 spin_unlock(&GlobalMid_Lock);
143 cFYI(1, ("Reconnecting tcp session"));
145 /* before reconnecting the tcp session, mark the smb session (uid)
146 and the tid bad so they are not used until reconnected */
147 read_lock(&GlobalSMBSeslock);
148 list_for_each(tmp, &GlobalSMBSessionList) {
149 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
151 if (ses->server == server) {
152 ses->need_reconnect = true;
156 /* else tcp and smb sessions need reconnection */
158 list_for_each(tmp, &GlobalTreeConnectionList) {
159 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
160 if ((tcon->ses) && (tcon->ses->server == server))
161 tcon->need_reconnect = true;
163 read_unlock(&GlobalSMBSeslock);
164 /* do not want to be sending data on a socket we are freeing */
165 down(&server->tcpSem);
166 if (server->ssocket) {
167 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
168 server->ssocket->flags));
169 kernel_sock_shutdown(server->ssocket, SHUT_WR);
170 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
171 server->ssocket->state,
172 server->ssocket->flags));
173 sock_release(server->ssocket);
174 server->ssocket = NULL;
177 spin_lock(&GlobalMid_Lock);
178 list_for_each(tmp, &server->pending_mid_q) {
179 mid_entry = list_entry(tmp, struct
182 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
183 /* Mark other intransit requests as needing
184 retry so we do not immediately mark the
185 session bad again (ie after we reconnect
186 below) as they timeout too */
187 mid_entry->midState = MID_RETRY_NEEDED;
190 spin_unlock(&GlobalMid_Lock);
193 while ((server->tcpStatus != CifsExiting) &&
194 (server->tcpStatus != CifsGood)) {
196 if (server->protocolType == IPV6) {
197 rc = ipv6_connect(&server->addr.sockAddr6,
198 &server->ssocket, server->noautotune);
200 rc = ipv4_connect(&server->addr.sockAddr,
202 server->workstation_RFC1001_name,
203 server->server_RFC1001_name,
204 server->noblocksnd, server->noautotune);
207 cFYI(1, ("reconnect error %d", rc));
210 atomic_inc(&tcpSesReconnectCount);
211 spin_lock(&GlobalMid_Lock);
212 if (server->tcpStatus != CifsExiting)
213 server->tcpStatus = CifsGood;
214 server->sequence_number = 0;
215 spin_unlock(&GlobalMid_Lock);
216 /* atomic_set(&server->inFlight,0);*/
217 wake_up(&server->response_q);
225 0 not a transact2, or all data present
226 >0 transact2 with that much data missing
227 -EINVAL = invalid transact2
230 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
232 struct smb_t2_rsp *pSMBt;
234 int data_in_this_rsp;
237 if (pSMB->Command != SMB_COM_TRANSACTION2)
240 /* check for plausible wct, bcc and t2 data and parm sizes */
241 /* check for parm and data offset going beyond end of smb */
242 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
243 cFYI(1, ("invalid transact2 word count"));
247 pSMBt = (struct smb_t2_rsp *)pSMB;
249 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
250 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
252 remaining = total_data_size - data_in_this_rsp;
256 else if (remaining < 0) {
257 cFYI(1, ("total data %d smaller than data in frame %d",
258 total_data_size, data_in_this_rsp));
261 cFYI(1, ("missing %d bytes from transact2, check next response",
263 if (total_data_size > maxBufSize) {
264 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
265 total_data_size, maxBufSize));
272 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
274 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
275 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
280 char *data_area_of_target;
281 char *data_area_of_buf2;
284 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
286 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
287 cFYI(1, ("total data size of primary and secondary t2 differ"));
290 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
292 remaining = total_data_size - total_in_buf;
297 if (remaining == 0) /* nothing to do, ignore */
300 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
301 if (remaining < total_in_buf2) {
302 cFYI(1, ("transact2 2nd response contains too much data"));
305 /* find end of first SMB data area */
306 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
307 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
308 /* validate target area */
310 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
311 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
313 data_area_of_target += total_in_buf;
315 /* copy second buffer into end of first buffer */
316 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
317 total_in_buf += total_in_buf2;
318 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
319 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
320 byte_count += total_in_buf2;
321 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
323 byte_count = pTargetSMB->smb_buf_length;
324 byte_count += total_in_buf2;
326 /* BB also add check that we are not beyond maximum buffer size */
328 pTargetSMB->smb_buf_length = byte_count;
330 if (remaining == total_in_buf2) {
331 cFYI(1, ("found the last secondary response"));
332 return 0; /* we are done */
333 } else /* more responses to go */
339 cifs_demultiplex_thread(struct TCP_Server_Info *server)
342 unsigned int pdu_length, total_read;
343 struct smb_hdr *smb_buffer = NULL;
344 struct smb_hdr *bigbuf = NULL;
345 struct smb_hdr *smallbuf = NULL;
346 struct msghdr smb_msg;
348 struct socket *csocket = server->ssocket;
349 struct list_head *tmp;
350 struct cifsSesInfo *ses;
351 struct task_struct *task_to_wake = NULL;
352 struct mid_q_entry *mid_entry;
354 bool isLargeBuf = false;
358 current->flags |= PF_MEMALLOC;
359 cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
361 length = atomic_inc_return(&tcpSesAllocCount);
363 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
367 while (server->tcpStatus != CifsExiting) {
370 if (bigbuf == NULL) {
371 bigbuf = cifs_buf_get();
373 cERROR(1, ("No memory for large SMB response"));
375 /* retry will check if exiting */
378 } else if (isLargeBuf) {
379 /* we are reusing a dirty large buf, clear its start */
380 memset(bigbuf, 0, sizeof(struct smb_hdr));
383 if (smallbuf == NULL) {
384 smallbuf = cifs_small_buf_get();
386 cERROR(1, ("No memory for SMB response"));
388 /* retry will check if exiting */
391 /* beginning of smb buffer is cleared in our buf_get */
392 } else /* if existing small buf clear beginning */
393 memset(smallbuf, 0, sizeof(struct smb_hdr));
397 smb_buffer = smallbuf;
398 iov.iov_base = smb_buffer;
400 smb_msg.msg_control = NULL;
401 smb_msg.msg_controllen = 0;
402 pdu_length = 4; /* enough to get RFC1001 header */
405 kernel_recvmsg(csocket, &smb_msg,
406 &iov, 1, pdu_length, 0 /* BB other flags? */);
408 if (server->tcpStatus == CifsExiting) {
410 } else if (server->tcpStatus == CifsNeedReconnect) {
411 cFYI(1, ("Reconnect after server stopped responding"));
412 cifs_reconnect(server);
413 cFYI(1, ("call to reconnect done"));
414 csocket = server->ssocket;
416 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
417 msleep(1); /* minimum sleep to prevent looping
418 allowing socket to clear and app threads to set
419 tcpStatus CifsNeedReconnect if server hung */
420 if (pdu_length < 4) {
421 iov.iov_base = (4 - pdu_length) +
423 iov.iov_len = pdu_length;
424 smb_msg.msg_control = NULL;
425 smb_msg.msg_controllen = 0;
429 } else if (length <= 0) {
430 if (server->tcpStatus == CifsNew) {
431 cFYI(1, ("tcp session abend after SMBnegprot"));
432 /* some servers kill the TCP session rather than
433 returning an SMB negprot error, in which
434 case reconnecting here is not going to help,
435 and so simply return error to mount */
438 if (!try_to_freeze() && (length == -EINTR)) {
439 cFYI(1, ("cifsd thread killed"));
442 cFYI(1, ("Reconnect after unexpected peek error %d",
444 cifs_reconnect(server);
445 csocket = server->ssocket;
446 wake_up(&server->response_q);
448 } else if (length < pdu_length) {
449 cFYI(1, ("requested %d bytes but only got %d bytes",
450 pdu_length, length));
451 pdu_length -= length;
456 /* The right amount was read from socket - 4 bytes */
457 /* so we can now interpret the length field */
459 /* the first byte big endian of the length field,
460 is actually not part of the length but the type
461 with the most common, zero, as regular data */
462 temp = *((char *) smb_buffer);
464 /* Note that FC 1001 length is big endian on the wire,
465 but we convert it here so it is always manipulated
466 as host byte order */
467 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
468 smb_buffer->smb_buf_length = pdu_length;
470 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
472 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
474 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
475 cFYI(1, ("Good RFC 1002 session rsp"));
477 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
478 /* we get this from Windows 98 instead of
479 an error on SMB negprot response */
480 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
482 if (server->tcpStatus == CifsNew) {
483 /* if nack on negprot (rather than
484 ret of smb negprot error) reconnecting
485 not going to help, ret error to mount */
488 /* give server a second to
489 clean up before reconnect attempt */
491 /* always try 445 first on reconnect
492 since we get NACK on some if we ever
493 connected to port 139 (the NACK is
494 since we do not begin with RFC1001
495 session initialize frame) */
496 server->addr.sockAddr.sin_port =
498 cifs_reconnect(server);
499 csocket = server->ssocket;
500 wake_up(&server->response_q);
503 } else if (temp != (char) 0) {
504 cERROR(1, ("Unknown RFC 1002 frame"));
505 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
507 cifs_reconnect(server);
508 csocket = server->ssocket;
512 /* else we have an SMB response */
513 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
514 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
515 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
516 length, pdu_length+4));
517 cifs_reconnect(server);
518 csocket = server->ssocket;
519 wake_up(&server->response_q);
526 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
528 memcpy(bigbuf, smallbuf, 4);
532 iov.iov_base = 4 + (char *)smb_buffer;
533 iov.iov_len = pdu_length;
534 for (total_read = 0; total_read < pdu_length;
535 total_read += length) {
536 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
537 pdu_length - total_read, 0);
538 if ((server->tcpStatus == CifsExiting) ||
539 (length == -EINTR)) {
543 } else if (server->tcpStatus == CifsNeedReconnect) {
544 cifs_reconnect(server);
545 csocket = server->ssocket;
546 /* Reconnect wakes up rspns q */
547 /* Now we will reread sock */
550 } else if ((length == -ERESTARTSYS) ||
551 (length == -EAGAIN)) {
552 msleep(1); /* minimum sleep to prevent looping,
553 allowing socket to clear and app
554 threads to set tcpStatus
555 CifsNeedReconnect if server hung*/
558 } else if (length <= 0) {
559 cERROR(1, ("Received no data, expecting %d",
560 pdu_length - total_read));
561 cifs_reconnect(server);
562 csocket = server->ssocket;
569 else if (reconnect == 1)
572 length += 4; /* account for rfc1002 hdr */
575 dump_smb(smb_buffer, length);
576 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
577 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
583 spin_lock(&GlobalMid_Lock);
584 list_for_each(tmp, &server->pending_mid_q) {
585 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
587 if ((mid_entry->mid == smb_buffer->Mid) &&
588 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
589 (mid_entry->command == smb_buffer->Command)) {
590 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
591 /* We have a multipart transact2 resp */
593 if (mid_entry->resp_buf) {
594 /* merge response - fix up 1st*/
595 if (coalesce_t2(smb_buffer,
596 mid_entry->resp_buf)) {
597 mid_entry->multiRsp =
601 /* all parts received */
602 mid_entry->multiEnd =
608 cERROR(1,("1st trans2 resp needs bigbuf"));
609 /* BB maybe we can fix this up, switch
610 to already allocated large buffer? */
612 /* Have first buffer */
613 mid_entry->resp_buf =
615 mid_entry->largeBuf =
622 mid_entry->resp_buf = smb_buffer;
623 mid_entry->largeBuf = isLargeBuf;
625 task_to_wake = mid_entry->tsk;
626 mid_entry->midState = MID_RESPONSE_RECEIVED;
627 #ifdef CONFIG_CIFS_STATS2
628 mid_entry->when_received = jiffies;
630 /* so we do not time out requests to server
631 which is still responding (since server could
632 be busy but not dead) */
633 server->lstrp = jiffies;
637 spin_unlock(&GlobalMid_Lock);
639 /* Was previous buf put in mpx struct for multi-rsp? */
641 /* smb buffer will be freed by user thread */
647 wake_up_process(task_to_wake);
648 } else if (!is_valid_oplock_break(smb_buffer, server) &&
650 cERROR(1, ("No task to wake, unknown frame received! "
651 "NumMids %d", midCount.counter));
652 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
653 sizeof(struct smb_hdr));
654 #ifdef CONFIG_CIFS_DEBUG2
655 cifs_dump_detail(smb_buffer);
656 cifs_dump_mids(server);
657 #endif /* CIFS_DEBUG2 */
660 } /* end while !EXITING */
662 spin_lock(&GlobalMid_Lock);
663 server->tcpStatus = CifsExiting;
664 spin_unlock(&GlobalMid_Lock);
665 wake_up_all(&server->response_q);
667 /* check if we have blocked requests that need to free */
668 /* Note that cifs_max_pending is normally 50, but
669 can be set at module install time to as little as two */
670 spin_lock(&GlobalMid_Lock);
671 if (atomic_read(&server->inFlight) >= cifs_max_pending)
672 atomic_set(&server->inFlight, cifs_max_pending - 1);
673 /* We do not want to set the max_pending too low or we
674 could end up with the counter going negative */
675 spin_unlock(&GlobalMid_Lock);
676 /* Although there should not be any requests blocked on
677 this queue it can not hurt to be paranoid and try to wake up requests
678 that may haven been blocked when more than 50 at time were on the wire
679 to the same server - they now will see the session is in exit state
680 and get out of SendReceive. */
681 wake_up_all(&server->request_q);
682 /* give those requests time to exit */
685 if (server->ssocket) {
686 sock_release(csocket);
687 server->ssocket = NULL;
689 /* buffer usuallly freed in free_mid - need to free it here on exit */
690 cifs_buf_release(bigbuf);
691 if (smallbuf) /* no sense logging a debug message if NULL */
692 cifs_small_buf_release(smallbuf);
694 read_lock(&GlobalSMBSeslock);
695 if (list_empty(&server->pending_mid_q)) {
696 /* loop through server session structures attached to this and
698 list_for_each(tmp, &GlobalSMBSessionList) {
700 list_entry(tmp, struct cifsSesInfo,
702 if (ses->server == server) {
703 ses->status = CifsExiting;
707 read_unlock(&GlobalSMBSeslock);
709 /* although we can not zero the server struct pointer yet,
710 since there are active requests which may depnd on them,
711 mark the corresponding SMB sessions as exiting too */
712 list_for_each(tmp, &GlobalSMBSessionList) {
713 ses = list_entry(tmp, struct cifsSesInfo,
715 if (ses->server == server)
716 ses->status = CifsExiting;
719 spin_lock(&GlobalMid_Lock);
720 list_for_each(tmp, &server->pending_mid_q) {
721 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
722 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
723 cFYI(1, ("Clearing Mid 0x%x - waking up ",
725 task_to_wake = mid_entry->tsk;
727 wake_up_process(task_to_wake);
730 spin_unlock(&GlobalMid_Lock);
731 read_unlock(&GlobalSMBSeslock);
732 /* 1/8th of sec is more than enough time for them to exit */
736 if (!list_empty(&server->pending_mid_q)) {
737 /* mpx threads have not exited yet give them
738 at least the smb send timeout time for long ops */
739 /* due to delays on oplock break requests, we need
740 to wait at least 45 seconds before giving up
741 on a request getting a response and going ahead
743 cFYI(1, ("Wait for exit from demultiplex thread"));
745 /* if threads still have not exited they are probably never
746 coming home not much else we can do but free the memory */
749 /* last chance to mark ses pointers invalid
750 if there are any pointing to this (e.g
751 if a crazy root user tried to kill cifsd
752 kernel thread explicitly this might happen) */
753 write_lock(&GlobalSMBSeslock);
754 list_for_each(tmp, &GlobalSMBSessionList) {
755 ses = list_entry(tmp, struct cifsSesInfo,
757 if (ses->server == server)
760 write_unlock(&GlobalSMBSeslock);
762 kfree(server->hostname);
763 task_to_wake = xchg(&server->tsk, NULL);
766 length = atomic_dec_return(&tcpSesAllocCount);
768 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
771 /* if server->tsk was NULL then wait for a signal before exiting */
773 set_current_state(TASK_INTERRUPTIBLE);
774 while (!signal_pending(current)) {
776 set_current_state(TASK_INTERRUPTIBLE);
778 set_current_state(TASK_RUNNING);
784 /* extract the host portion of the UNC string */
786 extract_hostname(const char *unc)
792 /* skip double chars at beginning of string */
793 /* BB: check validity of these bytes? */
796 /* delimiter between hostname and sharename is always '\\' now */
797 delim = strchr(src, '\\');
799 return ERR_PTR(-EINVAL);
802 dst = kmalloc((len + 1), GFP_KERNEL);
804 return ERR_PTR(-ENOMEM);
806 memcpy(dst, src, len);
813 cifs_parse_mount_options(char *options, const char *devname,
818 unsigned int temp_len, i, j;
824 if (Local_System_Name[0] != 0)
825 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
827 char *nodename = utsname()->nodename;
828 int n = strnlen(nodename, 15);
829 memset(vol->source_rfc1001_name, 0x20, 15);
830 for (i = 0; i < n; i++) {
831 /* does not have to be perfect mapping since field is
832 informational, only used for servers that do not support
833 port 445 and it can be overridden at mount time */
834 vol->source_rfc1001_name[i] = toupper(nodename[i]);
837 vol->source_rfc1001_name[15] = 0;
838 /* null target name indicates to use *SMBSERVR default called name
839 if we end up sending RFC1001 session initialize */
840 vol->target_rfc1001_name[0] = 0;
841 vol->linux_uid = current->uid; /* current->euid instead? */
842 vol->linux_gid = current->gid;
843 vol->dir_mode = S_IRWXUGO;
844 /* 2767 perms indicate mandatory locking support */
845 vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
847 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
849 /* default is always to request posix paths. */
850 vol->posix_paths = 1;
855 if (strncmp(options, "sep=", 4) == 0) {
856 if (options[4] != 0) {
857 separator[0] = options[4];
860 cFYI(1, ("Null separator not allowed"));
864 while ((data = strsep(&options, separator)) != NULL) {
867 if ((value = strchr(data, '=')) != NULL)
870 /* Have to parse this before we parse for "user" */
871 if (strnicmp(data, "user_xattr", 10) == 0) {
873 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
875 } else if (strnicmp(data, "user", 4) == 0) {
878 "CIFS: invalid or missing username\n");
879 return 1; /* needs_arg; */
880 } else if (!*value) {
881 /* null user, ie anonymous, authentication */
884 if (strnlen(value, 200) < 200) {
885 vol->username = value;
887 printk(KERN_WARNING "CIFS: username too long\n");
890 } else if (strnicmp(data, "pass", 4) == 0) {
892 vol->password = NULL;
894 } else if (value[0] == 0) {
895 /* check if string begins with double comma
896 since that would mean the password really
897 does start with a comma, and would not
898 indicate an empty string */
899 if (value[1] != separator[0]) {
900 vol->password = NULL;
904 temp_len = strlen(value);
905 /* removed password length check, NTLM passwords
906 can be arbitrarily long */
908 /* if comma in password, the string will be
909 prematurely null terminated. Commas in password are
910 specified across the cifs mount interface by a double
911 comma ie ,, and a comma used as in other cases ie ','
912 as a parameter delimiter/separator is single and due
913 to the strsep above is temporarily zeroed. */
915 /* NB: password legally can have multiple commas and
916 the only illegal character in a password is null */
918 if ((value[temp_len] == 0) &&
919 (value[temp_len+1] == separator[0])) {
921 value[temp_len] = separator[0];
922 temp_len += 2; /* move after second comma */
923 while (value[temp_len] != 0) {
924 if (value[temp_len] == separator[0]) {
925 if (value[temp_len+1] ==
927 /* skip second comma */
930 /* single comma indicating start
937 if (value[temp_len] == 0) {
941 /* point option to start of next parm */
942 options = value + temp_len + 1;
944 /* go from value to value + temp_len condensing
945 double commas to singles. Note that this ends up
946 allocating a few bytes too many, which is ok */
947 vol->password = kzalloc(temp_len, GFP_KERNEL);
948 if (vol->password == NULL) {
949 printk(KERN_WARNING "CIFS: no memory "
953 for (i = 0, j = 0; i < temp_len; i++, j++) {
954 vol->password[j] = value[i];
955 if (value[i] == separator[0]
956 && value[i+1] == separator[0]) {
957 /* skip second comma */
961 vol->password[j] = 0;
963 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
964 if (vol->password == NULL) {
965 printk(KERN_WARNING "CIFS: no memory "
969 strcpy(vol->password, value);
971 } else if (strnicmp(data, "ip", 2) == 0) {
972 if (!value || !*value) {
974 } else if (strnlen(value, 35) < 35) {
977 printk(KERN_WARNING "CIFS: ip address "
981 } else if (strnicmp(data, "sec", 3) == 0) {
982 if (!value || !*value) {
983 cERROR(1, ("no security value specified"));
985 } else if (strnicmp(value, "krb5i", 5) == 0) {
986 vol->secFlg |= CIFSSEC_MAY_KRB5 |
988 } else if (strnicmp(value, "krb5p", 5) == 0) {
989 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
991 cERROR(1, ("Krb5 cifs privacy not supported"));
993 } else if (strnicmp(value, "krb5", 4) == 0) {
994 vol->secFlg |= CIFSSEC_MAY_KRB5;
995 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
996 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
998 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
999 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
1000 } else if (strnicmp(value, "ntlmi", 5) == 0) {
1001 vol->secFlg |= CIFSSEC_MAY_NTLM |
1003 } else if (strnicmp(value, "ntlm", 4) == 0) {
1004 /* ntlm is default so can be turned off too */
1005 vol->secFlg |= CIFSSEC_MAY_NTLM;
1006 } else if (strnicmp(value, "nontlm", 6) == 0) {
1007 /* BB is there a better way to do this? */
1008 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
1009 #ifdef CONFIG_CIFS_WEAK_PW_HASH
1010 } else if (strnicmp(value, "lanman", 6) == 0) {
1011 vol->secFlg |= CIFSSEC_MAY_LANMAN;
1013 } else if (strnicmp(value, "none", 4) == 0) {
1016 cERROR(1, ("bad security option: %s", value));
1019 } else if ((strnicmp(data, "unc", 3) == 0)
1020 || (strnicmp(data, "target", 6) == 0)
1021 || (strnicmp(data, "path", 4) == 0)) {
1022 if (!value || !*value) {
1023 printk(KERN_WARNING "CIFS: invalid path to "
1024 "network resource\n");
1025 return 1; /* needs_arg; */
1027 if ((temp_len = strnlen(value, 300)) < 300) {
1028 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1029 if (vol->UNC == NULL)
1031 strcpy(vol->UNC, value);
1032 if (strncmp(vol->UNC, "//", 2) == 0) {
1035 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1037 "CIFS: UNC Path does not begin "
1038 "with // or \\\\ \n");
1042 printk(KERN_WARNING "CIFS: UNC name too long\n");
1045 } else if ((strnicmp(data, "domain", 3) == 0)
1046 || (strnicmp(data, "workgroup", 5) == 0)) {
1047 if (!value || !*value) {
1048 printk(KERN_WARNING "CIFS: invalid domain name\n");
1049 return 1; /* needs_arg; */
1051 /* BB are there cases in which a comma can be valid in
1052 a domain name and need special handling? */
1053 if (strnlen(value, 256) < 256) {
1054 vol->domainname = value;
1055 cFYI(1, ("Domain name set"));
1057 printk(KERN_WARNING "CIFS: domain name too "
1061 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1062 if (!value || !*value) {
1064 "CIFS: invalid path prefix\n");
1065 return 1; /* needs_argument */
1067 if ((temp_len = strnlen(value, 1024)) < 1024) {
1068 if (value[0] != '/')
1069 temp_len++; /* missing leading slash */
1070 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1071 if (vol->prepath == NULL)
1073 if (value[0] != '/') {
1074 vol->prepath[0] = '/';
1075 strcpy(vol->prepath+1, value);
1077 strcpy(vol->prepath, value);
1078 cFYI(1, ("prefix path %s", vol->prepath));
1080 printk(KERN_WARNING "CIFS: prefix too long\n");
1083 } else if (strnicmp(data, "iocharset", 9) == 0) {
1084 if (!value || !*value) {
1085 printk(KERN_WARNING "CIFS: invalid iocharset "
1087 return 1; /* needs_arg; */
1089 if (strnlen(value, 65) < 65) {
1090 if (strnicmp(value, "default", 7))
1091 vol->iocharset = value;
1092 /* if iocharset not set then load_nls_default
1093 is used by caller */
1094 cFYI(1, ("iocharset set to %s", value));
1096 printk(KERN_WARNING "CIFS: iocharset name "
1100 } else if (strnicmp(data, "uid", 3) == 0) {
1101 if (value && *value) {
1103 simple_strtoul(value, &value, 0);
1104 vol->override_uid = 1;
1106 } else if (strnicmp(data, "gid", 3) == 0) {
1107 if (value && *value) {
1109 simple_strtoul(value, &value, 0);
1110 vol->override_gid = 1;
1112 } else if (strnicmp(data, "file_mode", 4) == 0) {
1113 if (value && *value) {
1115 simple_strtoul(value, &value, 0);
1117 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1118 if (value && *value) {
1120 simple_strtoul(value, &value, 0);
1122 } else if (strnicmp(data, "dirmode", 4) == 0) {
1123 if (value && *value) {
1125 simple_strtoul(value, &value, 0);
1127 } else if (strnicmp(data, "port", 4) == 0) {
1128 if (value && *value) {
1130 simple_strtoul(value, &value, 0);
1132 } else if (strnicmp(data, "rsize", 5) == 0) {
1133 if (value && *value) {
1135 simple_strtoul(value, &value, 0);
1137 } else if (strnicmp(data, "wsize", 5) == 0) {
1138 if (value && *value) {
1140 simple_strtoul(value, &value, 0);
1142 } else if (strnicmp(data, "sockopt", 5) == 0) {
1143 if (value && *value) {
1145 simple_strtoul(value, &value, 0);
1147 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1148 if (!value || !*value || (*value == ' ')) {
1149 cFYI(1, ("invalid (empty) netbiosname"));
1151 memset(vol->source_rfc1001_name, 0x20, 15);
1152 for (i = 0; i < 15; i++) {
1153 /* BB are there cases in which a comma can be
1154 valid in this workstation netbios name (and need
1155 special handling)? */
1157 /* We do not uppercase netbiosname for user */
1161 vol->source_rfc1001_name[i] =
1164 /* The string has 16th byte zero still from
1165 set at top of the function */
1166 if ((i == 15) && (value[i] != 0))
1167 printk(KERN_WARNING "CIFS: netbiosname"
1168 " longer than 15 truncated.\n");
1170 } else if (strnicmp(data, "servern", 7) == 0) {
1171 /* servernetbiosname specified override *SMBSERVER */
1172 if (!value || !*value || (*value == ' ')) {
1173 cFYI(1, ("empty server netbiosname specified"));
1175 /* last byte, type, is 0x20 for servr type */
1176 memset(vol->target_rfc1001_name, 0x20, 16);
1178 for (i = 0; i < 15; i++) {
1179 /* BB are there cases in which a comma can be
1180 valid in this workstation netbios name
1181 (and need special handling)? */
1183 /* user or mount helper must uppercase
1188 vol->target_rfc1001_name[i] =
1191 /* The string has 16th byte zero still from
1192 set at top of the function */
1193 if ((i == 15) && (value[i] != 0))
1194 printk(KERN_WARNING "CIFS: server net"
1195 "biosname longer than 15 truncated.\n");
1197 } else if (strnicmp(data, "credentials", 4) == 0) {
1199 } else if (strnicmp(data, "version", 3) == 0) {
1201 } else if (strnicmp(data, "guest", 5) == 0) {
1203 } else if (strnicmp(data, "rw", 2) == 0) {
1205 } else if (strnicmp(data, "noblocksend", 11) == 0) {
1206 vol->noblocksnd = 1;
1207 } else if (strnicmp(data, "noautotune", 10) == 0) {
1208 vol->noautotune = 1;
1209 } else if ((strnicmp(data, "suid", 4) == 0) ||
1210 (strnicmp(data, "nosuid", 6) == 0) ||
1211 (strnicmp(data, "exec", 4) == 0) ||
1212 (strnicmp(data, "noexec", 6) == 0) ||
1213 (strnicmp(data, "nodev", 5) == 0) ||
1214 (strnicmp(data, "noauto", 6) == 0) ||
1215 (strnicmp(data, "dev", 3) == 0)) {
1216 /* The mount tool or mount.cifs helper (if present)
1217 uses these opts to set flags, and the flags are read
1218 by the kernel vfs layer before we get here (ie
1219 before read super) so there is no point trying to
1220 parse these options again and set anything and it
1221 is ok to just ignore them */
1223 } else if (strnicmp(data, "ro", 2) == 0) {
1225 } else if (strnicmp(data, "hard", 4) == 0) {
1227 } else if (strnicmp(data, "soft", 4) == 0) {
1229 } else if (strnicmp(data, "perm", 4) == 0) {
1231 } else if (strnicmp(data, "noperm", 6) == 0) {
1233 } else if (strnicmp(data, "mapchars", 8) == 0) {
1235 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1237 } else if (strnicmp(data, "sfu", 3) == 0) {
1239 } else if (strnicmp(data, "nosfu", 5) == 0) {
1241 } else if (strnicmp(data, "nodfs", 5) == 0) {
1243 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1244 vol->posix_paths = 1;
1245 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1246 vol->posix_paths = 0;
1247 } else if (strnicmp(data, "nounix", 6) == 0) {
1248 vol->no_linux_ext = 1;
1249 } else if (strnicmp(data, "nolinux", 7) == 0) {
1250 vol->no_linux_ext = 1;
1251 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1252 (strnicmp(data, "ignorecase", 10) == 0)) {
1254 } else if (strnicmp(data, "brl", 3) == 0) {
1256 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1257 (strnicmp(data, "nolock", 6) == 0)) {
1259 /* turn off mandatory locking in mode
1260 if remote locking is turned off since the
1261 local vfs will do advisory */
1262 if (vol->file_mode ==
1263 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1264 vol->file_mode = S_IALLUGO;
1265 } else if (strnicmp(data, "setuids", 7) == 0) {
1267 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1269 } else if (strnicmp(data, "dynperm", 7) == 0) {
1270 vol->dynperm = true;
1271 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1272 vol->dynperm = false;
1273 } else if (strnicmp(data, "nohard", 6) == 0) {
1275 } else if (strnicmp(data, "nosoft", 6) == 0) {
1277 } else if (strnicmp(data, "nointr", 6) == 0) {
1279 } else if (strnicmp(data, "intr", 4) == 0) {
1281 } else if (strnicmp(data, "serverino", 7) == 0) {
1282 vol->server_ino = 1;
1283 } else if (strnicmp(data, "noserverino", 9) == 0) {
1284 vol->server_ino = 0;
1285 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1287 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1289 } else if (strnicmp(data, "acl", 3) == 0) {
1290 vol->no_psx_acl = 0;
1291 } else if (strnicmp(data, "noacl", 5) == 0) {
1292 vol->no_psx_acl = 1;
1293 #ifdef CONFIG_CIFS_EXPERIMENTAL
1294 } else if (strnicmp(data, "locallease", 6) == 0) {
1295 vol->local_lease = 1;
1297 } else if (strnicmp(data, "sign", 4) == 0) {
1298 vol->secFlg |= CIFSSEC_MUST_SIGN;
1299 } else if (strnicmp(data, "seal", 4) == 0) {
1300 /* we do not do the following in secFlags because seal
1301 is a per tree connection (mount) not a per socket
1302 or per-smb connection option in the protocol */
1303 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1305 } else if (strnicmp(data, "direct", 6) == 0) {
1307 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1309 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1310 if (!value || !*value) {
1311 vol->in6_addr = NULL;
1312 } else if (strnlen(value, 49) == 48) {
1313 vol->in6_addr = value;
1315 printk(KERN_WARNING "CIFS: ip v6 address not "
1316 "48 characters long\n");
1319 } else if (strnicmp(data, "noac", 4) == 0) {
1320 printk(KERN_WARNING "CIFS: Mount option noac not "
1321 "supported. Instead set "
1322 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1324 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1327 if (vol->UNC == NULL) {
1328 if (devname == NULL) {
1329 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1333 if ((temp_len = strnlen(devname, 300)) < 300) {
1334 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1335 if (vol->UNC == NULL)
1337 strcpy(vol->UNC, devname);
1338 if (strncmp(vol->UNC, "//", 2) == 0) {
1341 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1342 printk(KERN_WARNING "CIFS: UNC Path does not "
1343 "begin with // or \\\\ \n");
1346 value = strpbrk(vol->UNC+2, "/\\");
1350 printk(KERN_WARNING "CIFS: UNC name too long\n");
1354 if (vol->UNCip == NULL)
1355 vol->UNCip = &vol->UNC[2];
1360 static struct cifsSesInfo *
1361 cifs_find_tcp_session(struct in_addr *target_ip_addr,
1362 struct in6_addr *target_ip6_addr,
1363 char *userName, struct TCP_Server_Info **psrvTcp)
1365 struct list_head *tmp;
1366 struct cifsSesInfo *ses;
1370 read_lock(&GlobalSMBSeslock);
1371 list_for_each(tmp, &GlobalSMBSessionList) {
1372 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1376 if (target_ip_addr &&
1377 ses->server->addr.sockAddr.sin_addr.s_addr != target_ip_addr->s_addr)
1379 else if (target_ip6_addr &&
1380 memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1381 target_ip6_addr, sizeof(*target_ip6_addr)))
1383 /* BB lock server and tcp session; increment use count here?? */
1385 /* found a match on the TCP session */
1386 *psrvTcp = ses->server;
1388 /* BB check if reconnection needed */
1389 if (strncmp(ses->userName, userName, MAX_USERNAME_SIZE) == 0) {
1390 read_unlock(&GlobalSMBSeslock);
1391 /* Found exact match on both TCP and
1395 /* else tcp and smb sessions need reconnection */
1397 read_unlock(&GlobalSMBSeslock);
1402 static struct cifsTconInfo *
1403 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1405 struct list_head *tmp;
1406 struct cifsTconInfo *tcon;
1409 read_lock(&GlobalSMBSeslock);
1411 list_for_each(tmp, &GlobalTreeConnectionList) {
1412 cFYI(1, ("Next tcon"));
1413 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1414 if (!tcon->ses || !tcon->ses->server)
1417 old_ip = tcon->ses->server->addr.sockAddr.sin_addr.s_addr;
1418 cFYI(1, ("old ip addr: %x == new ip %x ?",
1419 old_ip, new_target_ip_addr));
1421 if (old_ip != new_target_ip_addr)
1424 /* BB lock tcon, server, tcp session and increment use count? */
1425 /* found a match on the TCP session */
1426 /* BB check if reconnection needed */
1427 cFYI(1, ("IP match, old UNC: %s new: %s",
1428 tcon->treeName, uncName));
1430 if (strncmp(tcon->treeName, uncName, MAX_TREE_SIZE))
1433 cFYI(1, ("and old usr: %s new: %s",
1434 tcon->treeName, uncName));
1436 if (strncmp(tcon->ses->userName, userName, MAX_USERNAME_SIZE))
1439 /* matched smb session (user name) */
1440 read_unlock(&GlobalSMBSeslock);
1444 read_unlock(&GlobalSMBSeslock);
1449 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1450 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1451 struct dfs_info3_param **preferrals, int remap)
1456 *pnum_referrals = 0;
1459 if (pSesInfo->ipc_tid == 0) {
1460 temp_unc = kmalloc(2 /* for slashes */ +
1461 strnlen(pSesInfo->serverName,
1462 SERVER_NAME_LEN_WITH_NULL * 2)
1463 + 1 + 4 /* slash IPC$ */ + 2,
1465 if (temp_unc == NULL)
1469 strcpy(temp_unc + 2, pSesInfo->serverName);
1470 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1471 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1473 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1477 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1478 pnum_referrals, nls_codepage, remap);
1479 /* BB map targetUNCs to dfs_info3 structures, here or
1480 in CIFSGetDFSRefer BB */
1485 #ifdef CONFIG_DEBUG_LOCK_ALLOC
1486 static struct lock_class_key cifs_key[2];
1487 static struct lock_class_key cifs_slock_key[2];
1490 cifs_reclassify_socket4(struct socket *sock)
1492 struct sock *sk = sock->sk;
1493 BUG_ON(sock_owned_by_user(sk));
1494 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
1495 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
1499 cifs_reclassify_socket6(struct socket *sock)
1501 struct sock *sk = sock->sk;
1502 BUG_ON(sock_owned_by_user(sk));
1503 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
1504 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
1508 cifs_reclassify_socket4(struct socket *sock)
1513 cifs_reclassify_socket6(struct socket *sock)
1518 /* See RFC1001 section 14 on representation of Netbios names */
1519 static void rfc1002mangle(char *target, char *source, unsigned int length)
1523 for (i = 0, j = 0; i < (length); i++) {
1524 /* mask a nibble at a time and encode */
1525 target[j] = 'A' + (0x0F & (source[i] >> 4));
1526 target[j+1] = 'A' + (0x0F & source[i]);
1534 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1535 char *netbios_name, char *target_name,
1536 bool noblocksnd, bool noautotune)
1540 __be16 orig_port = 0;
1542 if (*csocket == NULL) {
1543 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1544 IPPROTO_TCP, csocket);
1546 cERROR(1, ("Error %d creating socket", rc));
1550 /* BB other socket options to set KEEPALIVE, NODELAY? */
1551 cFYI(1, ("Socket created"));
1552 (*csocket)->sk->sk_allocation = GFP_NOFS;
1553 cifs_reclassify_socket4(*csocket);
1557 psin_server->sin_family = AF_INET;
1558 if (psin_server->sin_port) { /* user overrode default port */
1559 rc = (*csocket)->ops->connect(*csocket,
1560 (struct sockaddr *) psin_server,
1561 sizeof(struct sockaddr_in), 0);
1567 /* save original port so we can retry user specified port
1568 later if fall back ports fail this time */
1569 orig_port = psin_server->sin_port;
1571 /* do not retry on the same port we just failed on */
1572 if (psin_server->sin_port != htons(CIFS_PORT)) {
1573 psin_server->sin_port = htons(CIFS_PORT);
1575 rc = (*csocket)->ops->connect(*csocket,
1576 (struct sockaddr *) psin_server,
1577 sizeof(struct sockaddr_in), 0);
1583 psin_server->sin_port = htons(RFC1001_PORT);
1584 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1586 sizeof(struct sockaddr_in), 0);
1591 /* give up here - unless we want to retry on different
1592 protocol families some day */
1595 psin_server->sin_port = orig_port;
1596 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1597 sock_release(*csocket);
1601 /* Eventually check for other socket options to change from
1602 the default. sock_setsockopt not used because it expects
1603 user space buffer */
1604 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1605 (*csocket)->sk->sk_sndbuf,
1606 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1607 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1609 (*csocket)->sk->sk_sndtimeo = 3 * HZ;
1611 /* make the bufsizes depend on wsize/rsize and max requests */
1613 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1614 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1615 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1616 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1619 /* send RFC1001 sessinit */
1620 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1621 /* some servers require RFC1001 sessinit before sending
1622 negprot - BB check reconnection in case where second
1623 sessinit is sent but no second negprot */
1624 struct rfc1002_session_packet *ses_init_buf;
1625 struct smb_hdr *smb_buf;
1626 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1629 ses_init_buf->trailer.session_req.called_len = 32;
1630 if (target_name && (target_name[0] != 0)) {
1631 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1634 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1635 DEFAULT_CIFS_CALLED_NAME, 16);
1638 ses_init_buf->trailer.session_req.calling_len = 32;
1639 /* calling name ends in null (byte 16) from old smb
1641 if (netbios_name && (netbios_name[0] != 0)) {
1642 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1645 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1646 "LINUX_CIFS_CLNT", 16);
1648 ses_init_buf->trailer.session_req.scope1 = 0;
1649 ses_init_buf->trailer.session_req.scope2 = 0;
1650 smb_buf = (struct smb_hdr *)ses_init_buf;
1651 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1652 smb_buf->smb_buf_length = 0x81000044;
1653 rc = smb_send(*csocket, smb_buf, 0x44,
1654 (struct sockaddr *)psin_server, noblocksnd);
1655 kfree(ses_init_buf);
1656 msleep(1); /* RFC1001 layer in at least one server
1657 requires very short break before negprot
1658 presumably because not expecting negprot
1659 to follow so fast. This is a simple
1660 solution that works without
1661 complicating the code and causes no
1662 significant slowing down on mount
1663 for everyone else */
1665 /* else the negprot may still work without this
1666 even though malloc failed */
1674 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket,
1679 __be16 orig_port = 0;
1681 if (*csocket == NULL) {
1682 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1683 IPPROTO_TCP, csocket);
1685 cERROR(1, ("Error %d creating ipv6 socket", rc));
1689 /* BB other socket options to set KEEPALIVE, NODELAY? */
1690 cFYI(1, ("ipv6 Socket created"));
1691 (*csocket)->sk->sk_allocation = GFP_NOFS;
1692 cifs_reclassify_socket6(*csocket);
1696 psin_server->sin6_family = AF_INET6;
1698 if (psin_server->sin6_port) { /* user overrode default port */
1699 rc = (*csocket)->ops->connect(*csocket,
1700 (struct sockaddr *) psin_server,
1701 sizeof(struct sockaddr_in6), 0);
1707 /* save original port so we can retry user specified port
1708 later if fall back ports fail this time */
1710 orig_port = psin_server->sin6_port;
1711 /* do not retry on the same port we just failed on */
1712 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1713 psin_server->sin6_port = htons(CIFS_PORT);
1715 rc = (*csocket)->ops->connect(*csocket,
1716 (struct sockaddr *) psin_server,
1717 sizeof(struct sockaddr_in6), 0);
1723 psin_server->sin6_port = htons(RFC1001_PORT);
1724 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1725 psin_server, sizeof(struct sockaddr_in6), 0);
1730 /* give up here - unless we want to retry on different
1731 protocol families some day */
1734 psin_server->sin6_port = orig_port;
1735 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1736 sock_release(*csocket);
1740 /* Eventually check for other socket options to change from
1741 the default. sock_setsockopt not used because it expects
1742 user space buffer */
1743 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1745 (*csocket)->sk->sk_sndtimeo = 3 * HZ;
1751 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1752 struct super_block *sb, struct smb_vol *vol_info)
1754 /* if we are reconnecting then should we check to see if
1755 * any requested capabilities changed locally e.g. via
1756 * remount but we can not do much about it here
1757 * if they have (even if we could detect it by the following)
1758 * Perhaps we could add a backpointer to array of sb from tcon
1759 * or if we change to make all sb to same share the same
1760 * sb as NFS - then we only have one backpointer to sb.
1761 * What if we wanted to mount the server share twice once with
1762 * and once without posixacls or posix paths? */
1763 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1765 if (vol_info && vol_info->no_linux_ext) {
1766 tcon->fsUnixInfo.Capability = 0;
1767 tcon->unix_ext = 0; /* Unix Extensions disabled */
1768 cFYI(1, ("Linux protocol extensions disabled"));
1770 } else if (vol_info)
1771 tcon->unix_ext = 1; /* Unix Extensions supported */
1773 if (tcon->unix_ext == 0) {
1774 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1778 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1779 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1781 /* check for reconnect case in which we do not
1782 want to change the mount behavior if we can avoid it */
1783 if (vol_info == NULL) {
1784 /* turn off POSIX ACL and PATHNAMES if not set
1785 originally at mount time */
1786 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1787 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1788 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
1789 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1790 cERROR(1, ("POSIXPATH support change"));
1791 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1792 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
1793 cERROR(1, ("possible reconnect error"));
1795 ("server disabled POSIX path support"));
1799 cap &= CIFS_UNIX_CAP_MASK;
1800 if (vol_info && vol_info->no_psx_acl)
1801 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1802 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
1803 cFYI(1, ("negotiated posix acl support"));
1805 sb->s_flags |= MS_POSIXACL;
1808 if (vol_info && vol_info->posix_paths == 0)
1809 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1810 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1811 cFYI(1, ("negotiate posix pathnames"));
1813 CIFS_SB(sb)->mnt_cifs_flags |=
1814 CIFS_MOUNT_POSIX_PATHS;
1817 /* We might be setting the path sep back to a different
1818 form if we are reconnecting and the server switched its
1819 posix path capability for this share */
1820 if (sb && (CIFS_SB(sb)->prepathlen > 0))
1821 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1823 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
1824 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
1825 CIFS_SB(sb)->rsize = 127 * 1024;
1827 ("larger reads not supported by srv"));
1832 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
1833 #ifdef CONFIG_CIFS_DEBUG2
1834 if (cap & CIFS_UNIX_FCNTL_CAP)
1835 cFYI(1, ("FCNTL cap"));
1836 if (cap & CIFS_UNIX_EXTATTR_CAP)
1837 cFYI(1, ("EXTATTR cap"));
1838 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1839 cFYI(1, ("POSIX path cap"));
1840 if (cap & CIFS_UNIX_XATTR_CAP)
1841 cFYI(1, ("XATTR cap"));
1842 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
1843 cFYI(1, ("POSIX ACL cap"));
1844 if (cap & CIFS_UNIX_LARGE_READ_CAP)
1845 cFYI(1, ("very large read cap"));
1846 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
1847 cFYI(1, ("very large write cap"));
1848 #endif /* CIFS_DEBUG2 */
1849 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1850 if (vol_info == NULL) {
1851 cFYI(1, ("resetting capabilities failed"));
1853 cERROR(1, ("Negotiating Unix capabilities "
1854 "with the server failed. Consider "
1855 "mounting with the Unix Extensions\n"
1856 "disabled, if problems are found, "
1857 "by specifying the nounix mount "
1865 convert_delimiter(char *path, char delim)
1878 for (i = 0; path[i] != '\0'; i++) {
1879 if (path[i] == old_delim)
1885 kill_cifsd(struct TCP_Server_Info *server)
1887 struct task_struct *task;
1889 task = xchg(&server->tsk, NULL);
1891 force_sig(SIGKILL, task);
1894 static void setup_cifs_sb(struct smb_vol *pvolume_info,
1895 struct cifs_sb_info *cifs_sb)
1897 if (pvolume_info->rsize > CIFSMaxBufSize) {
1898 cERROR(1, ("rsize %d too large, using MaxBufSize",
1899 pvolume_info->rsize));
1900 cifs_sb->rsize = CIFSMaxBufSize;
1901 } else if ((pvolume_info->rsize) &&
1902 (pvolume_info->rsize <= CIFSMaxBufSize))
1903 cifs_sb->rsize = pvolume_info->rsize;
1905 cifs_sb->rsize = CIFSMaxBufSize;
1907 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
1908 cERROR(1, ("wsize %d too large, using 4096 instead",
1909 pvolume_info->wsize));
1910 cifs_sb->wsize = 4096;
1911 } else if (pvolume_info->wsize)
1912 cifs_sb->wsize = pvolume_info->wsize;
1914 cifs_sb->wsize = min_t(const int,
1915 PAGEVEC_SIZE * PAGE_CACHE_SIZE,
1917 /* old default of CIFSMaxBufSize was too small now
1918 that SMB Write2 can send multiple pages in kvec.
1919 RFC1001 does not describe what happens when frame
1920 bigger than 128K is sent so use that as max in
1921 conjunction with 52K kvec constraint on arch with 4K
1924 if (cifs_sb->rsize < 2048) {
1925 cifs_sb->rsize = 2048;
1926 /* Windows ME may prefer this */
1927 cFYI(1, ("readsize set to minimum: 2048"));
1929 /* calculate prepath */
1930 cifs_sb->prepath = pvolume_info->prepath;
1931 if (cifs_sb->prepath) {
1932 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
1933 /* we can not convert the / to \ in the path
1934 separators in the prefixpath yet because we do not
1935 know (until reset_cifs_unix_caps is called later)
1936 whether POSIX PATH CAP is available. We normalize
1937 the / to \ after reset_cifs_unix_caps is called */
1938 pvolume_info->prepath = NULL;
1940 cifs_sb->prepathlen = 0;
1941 cifs_sb->mnt_uid = pvolume_info->linux_uid;
1942 cifs_sb->mnt_gid = pvolume_info->linux_gid;
1943 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
1944 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
1945 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
1946 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
1948 if (pvolume_info->noperm)
1949 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
1950 if (pvolume_info->setuids)
1951 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
1952 if (pvolume_info->server_ino)
1953 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
1954 if (pvolume_info->remap)
1955 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
1956 if (pvolume_info->no_xattr)
1957 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
1958 if (pvolume_info->sfu_emul)
1959 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
1960 if (pvolume_info->nobrl)
1961 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
1962 if (pvolume_info->cifs_acl)
1963 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
1964 if (pvolume_info->override_uid)
1965 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
1966 if (pvolume_info->override_gid)
1967 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
1968 if (pvolume_info->dynperm)
1969 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
1970 if (pvolume_info->direct_io) {
1971 cFYI(1, ("mounting share using direct i/o"));
1972 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
1975 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
1976 cERROR(1, ("mount option dynperm ignored if cifsacl "
1977 "mount option supported"));
1981 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1982 char *mount_data, const char *devname)
1986 int address_type = AF_INET;
1987 struct socket *csocket = NULL;
1988 struct sockaddr_in sin_server;
1989 struct sockaddr_in6 sin_server6;
1990 struct smb_vol volume_info;
1991 struct cifsSesInfo *pSesInfo = NULL;
1992 struct cifsSesInfo *existingCifsSes = NULL;
1993 struct cifsTconInfo *tcon = NULL;
1994 struct TCP_Server_Info *srvTcp = NULL;
1998 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
2000 memset(&volume_info, 0, sizeof(struct smb_vol));
2001 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
2006 if (volume_info.nullauth) {
2007 cFYI(1, ("null user"));
2008 volume_info.username = "";
2009 } else if (volume_info.username) {
2010 /* BB fixme parse for domain name here */
2011 cFYI(1, ("Username: %s", volume_info.username));
2013 cifserror("No username specified");
2014 /* In userspace mount helper we can get user name from alternate
2015 locations such as env variables and files on disk */
2020 if (volume_info.UNCip && volume_info.UNC) {
2021 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
2022 &sin_server.sin_addr.s_addr);
2025 /* not ipv4 address, try ipv6 */
2026 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
2027 &sin_server6.sin6_addr.in6_u);
2029 address_type = AF_INET6;
2031 address_type = AF_INET;
2035 /* we failed translating address */
2040 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
2043 } else if (volume_info.UNCip) {
2044 /* BB using ip addr as server name to connect to the
2046 cERROR(1, ("Connecting to DFS root not implemented yet"));
2049 } else /* which servers DFS root would we conect to */ {
2051 ("CIFS mount error: No UNC path (e.g. -o "
2052 "unc=//192.168.1.100/public) specified"));
2057 /* this is needed for ASCII cp to Unicode converts */
2058 if (volume_info.iocharset == NULL) {
2059 cifs_sb->local_nls = load_nls_default();
2060 /* load_nls_default can not return null */
2062 cifs_sb->local_nls = load_nls(volume_info.iocharset);
2063 if (cifs_sb->local_nls == NULL) {
2064 cERROR(1, ("CIFS mount error: iocharset %s not found",
2065 volume_info.iocharset));
2071 if (address_type == AF_INET)
2072 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
2073 NULL /* no ipv6 addr */,
2074 volume_info.username, &srvTcp);
2075 else if (address_type == AF_INET6) {
2076 cFYI(1, ("looking for ipv6 address"));
2077 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
2078 &sin_server6.sin6_addr,
2079 volume_info.username, &srvTcp);
2085 if (!srvTcp) { /* create socket */
2086 if (volume_info.port)
2087 sin_server.sin_port = htons(volume_info.port);
2089 sin_server.sin_port = 0;
2090 if (address_type == AF_INET6) {
2091 cFYI(1, ("attempting ipv6 connect"));
2092 /* BB should we allow ipv6 on port 139? */
2093 /* other OS never observed in Wild doing 139 with v6 */
2094 rc = ipv6_connect(&sin_server6, &csocket,
2095 volume_info.noblocksnd);
2097 rc = ipv4_connect(&sin_server, &csocket,
2098 volume_info.source_rfc1001_name,
2099 volume_info.target_rfc1001_name,
2100 volume_info.noblocksnd,
2101 volume_info.noautotune);
2103 cERROR(1, ("Error connecting to IPv4 socket. "
2104 "Aborting operation"));
2105 if (csocket != NULL)
2106 sock_release(csocket);
2110 srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
2113 sock_release(csocket);
2116 srvTcp->noblocksnd = volume_info.noblocksnd;
2117 srvTcp->noautotune = volume_info.noautotune;
2118 memcpy(&srvTcp->addr.sockAddr, &sin_server,
2119 sizeof(struct sockaddr_in));
2120 atomic_set(&srvTcp->inFlight, 0);
2121 /* BB Add code for ipv6 case too */
2122 srvTcp->ssocket = csocket;
2123 srvTcp->protocolType = IPV4;
2124 srvTcp->hostname = extract_hostname(volume_info.UNC);
2125 if (IS_ERR(srvTcp->hostname)) {
2126 rc = PTR_ERR(srvTcp->hostname);
2127 sock_release(csocket);
2130 init_waitqueue_head(&srvTcp->response_q);
2131 init_waitqueue_head(&srvTcp->request_q);
2132 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
2133 /* at this point we are the only ones with the pointer
2134 to the struct since the kernel thread not created yet
2135 so no need to spinlock this init of tcpStatus */
2136 srvTcp->tcpStatus = CifsNew;
2137 init_MUTEX(&srvTcp->tcpSem);
2138 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
2139 if (IS_ERR(srvTcp->tsk)) {
2140 rc = PTR_ERR(srvTcp->tsk);
2141 cERROR(1, ("error %d create cifsd thread", rc));
2143 sock_release(csocket);
2144 kfree(srvTcp->hostname);
2148 memcpy(srvTcp->workstation_RFC1001_name,
2149 volume_info.source_rfc1001_name, 16);
2150 memcpy(srvTcp->server_RFC1001_name,
2151 volume_info.target_rfc1001_name, 16);
2152 srvTcp->sequence_number = 0;
2156 if (existingCifsSes) {
2157 pSesInfo = existingCifsSes;
2158 cFYI(1, ("Existing smb sess found (status=%d)",
2160 down(&pSesInfo->sesSem);
2161 if (pSesInfo->need_reconnect) {
2162 cFYI(1, ("Session needs reconnect"));
2163 rc = cifs_setup_session(xid, pSesInfo,
2164 cifs_sb->local_nls);
2166 up(&pSesInfo->sesSem);
2168 cFYI(1, ("Existing smb sess not found"));
2169 pSesInfo = sesInfoAlloc();
2170 if (pSesInfo == NULL)
2173 pSesInfo->server = srvTcp;
2174 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
2175 NIPQUAD(sin_server.sin_addr.s_addr));
2179 /* volume_info.password freed at unmount */
2180 if (volume_info.password) {
2181 pSesInfo->password = volume_info.password;
2182 /* set to NULL to prevent freeing on exit */
2183 volume_info.password = NULL;
2185 if (volume_info.username)
2186 strncpy(pSesInfo->userName,
2187 volume_info.username,
2189 if (volume_info.domainname) {
2190 int len = strlen(volume_info.domainname);
2191 pSesInfo->domainName =
2192 kmalloc(len + 1, GFP_KERNEL);
2193 if (pSesInfo->domainName)
2194 strcpy(pSesInfo->domainName,
2195 volume_info.domainname);
2197 pSesInfo->linux_uid = volume_info.linux_uid;
2198 pSesInfo->overrideSecFlg = volume_info.secFlg;
2199 down(&pSesInfo->sesSem);
2200 /* BB FIXME need to pass vol->secFlgs BB */
2201 rc = cifs_setup_session(xid, pSesInfo,
2202 cifs_sb->local_nls);
2203 up(&pSesInfo->sesSem);
2205 atomic_inc(&srvTcp->socketUseCount);
2209 /* search for existing tcon to this server share */
2211 setup_cifs_sb(&volume_info, cifs_sb);
2214 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
2215 volume_info.username);
2217 cFYI(1, ("Found match on UNC path"));
2218 if (tcon->seal != volume_info.seal)
2219 cERROR(1, ("transport encryption setting "
2220 "conflicts with existing tid"));
2222 tcon = tconInfoAlloc();
2225 goto mount_fail_check;
2228 /* check for null share name ie connect to dfs root */
2230 /* BB check if works for exactly length 3 strings */
2231 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2232 && (strchr(volume_info.UNC + 3, '/') == NULL)) {
2233 /* rc = connect_to_dfs_path(...) */
2234 cFYI(1, ("DFS root not supported"));
2236 goto mount_fail_check;
2238 /* BB Do we need to wrap sesSem around
2239 * this TCon call and Unix SetFS as
2240 * we do on SessSetup and reconnect? */
2241 rc = CIFSTCon(xid, pSesInfo, volume_info.UNC,
2242 tcon, cifs_sb->local_nls);
2243 cFYI(1, ("CIFS Tcon rc = %d", rc));
2244 if (volume_info.nodfs) {
2245 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2246 cFYI(1, ("DFS disabled (%d)",
2251 atomic_inc(&pSesInfo->inUse);
2252 tcon->seal = volume_info.seal;
2254 goto mount_fail_check;
2257 /* we can have only one retry value for a connection
2258 to a share so for resources mounted more than once
2259 to the same server share the last value passed in
2260 for the retry flag is used */
2261 tcon->retry = volume_info.retry;
2262 tcon->nocase = volume_info.nocase;
2263 tcon->local_lease = volume_info.local_lease;
2266 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2267 sb->s_maxbytes = (u64) 1 << 63;
2269 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2272 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2273 sb->s_time_gran = 100;
2275 /* on error free sesinfo and tcon struct if needed */
2278 /* if session setup failed, use count is zero but
2279 we still need to free cifsd thread */
2280 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2281 spin_lock(&GlobalMid_Lock);
2282 srvTcp->tcpStatus = CifsExiting;
2283 spin_unlock(&GlobalMid_Lock);
2286 /* If find_unc succeeded then rc == 0 so we can not end */
2287 if (tcon) /* up accidently freeing someone elses tcon struct */
2289 if (existingCifsSes == NULL) {
2291 if ((pSesInfo->server) &&
2292 (pSesInfo->status == CifsGood)) {
2294 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2295 /* if the socketUseCount is now zero */
2296 if ((temp_rc == -ESHUTDOWN) &&
2298 kill_cifsd(pSesInfo->server);
2300 cFYI(1, ("No session or bad tcon"));
2301 if (pSesInfo->server) {
2302 spin_lock(&GlobalMid_Lock);
2303 srvTcp->tcpStatus = CifsExiting;
2304 spin_unlock(&GlobalMid_Lock);
2305 kill_cifsd(pSesInfo->server);
2308 sesInfoFree(pSesInfo);
2309 /* pSesInfo = NULL; */
2313 atomic_inc(&tcon->useCount);
2314 cifs_sb->tcon = tcon;
2315 tcon->ses = pSesInfo;
2317 /* do not care if following two calls succeed - informational */
2319 CIFSSMBQFSDeviceInfo(xid, tcon);
2320 CIFSSMBQFSAttributeInfo(xid, tcon);
2323 /* tell server which Unix caps we support */
2324 if (tcon->ses->capabilities & CAP_UNIX)
2325 /* reset of caps checks mount to see if unix extensions
2326 disabled for just this mount */
2327 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2329 tcon->unix_ext = 0; /* server does not support them */
2331 /* convert forward to back slashes in prepath here if needed */
2332 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2333 convert_delimiter(cifs_sb->prepath,
2334 CIFS_DIR_SEP(cifs_sb));
2336 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2337 cifs_sb->rsize = 1024 * 127;
2339 ("no very large read support, rsize now 127K"));
2341 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2342 cifs_sb->wsize = min(cifs_sb->wsize,
2343 (tcon->ses->server->maxBuf -
2344 MAX_CIFS_HDR_SIZE));
2345 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2346 cifs_sb->rsize = min(cifs_sb->rsize,
2347 (tcon->ses->server->maxBuf -
2348 MAX_CIFS_HDR_SIZE));
2351 /* volume_info.password is freed above when existing session found
2352 (in which case it is not needed anymore) but when new sesion is created
2353 the password ptr is put in the new session structure (in which case the
2354 password will be freed at unmount time) */
2356 /* zero out password before freeing */
2357 if (volume_info.password != NULL) {
2358 memset(volume_info.password, 0, strlen(volume_info.password));
2359 kfree(volume_info.password);
2361 kfree(volume_info.UNC);
2362 kfree(volume_info.prepath);
2368 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2369 char session_key[CIFS_SESS_KEY_SIZE],
2370 const struct nls_table *nls_codepage)
2372 struct smb_hdr *smb_buffer;
2373 struct smb_hdr *smb_buffer_response;
2374 SESSION_SETUP_ANDX *pSMB;
2375 SESSION_SETUP_ANDX *pSMBr;
2380 int remaining_words = 0;
2381 int bytes_returned = 0;
2386 cFYI(1, ("In sesssetup"));
2389 user = ses->userName;
2390 domain = ses->domainName;
2391 smb_buffer = cifs_buf_get();
2393 if (smb_buffer == NULL)
2396 smb_buffer_response = smb_buffer;
2397 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2399 /* send SMBsessionSetup here */
2400 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2401 NULL /* no tCon exists yet */ , 13 /* wct */ );
2403 smb_buffer->Mid = GetNextMid(ses->server);
2404 pSMB->req_no_secext.AndXCommand = 0xFF;
2405 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2406 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2408 if (ses->server->secMode &
2409 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2410 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2412 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2413 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2414 if (ses->capabilities & CAP_UNICODE) {
2415 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2416 capabilities |= CAP_UNICODE;
2418 if (ses->capabilities & CAP_STATUS32) {
2419 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2420 capabilities |= CAP_STATUS32;
2422 if (ses->capabilities & CAP_DFS) {
2423 smb_buffer->Flags2 |= SMBFLG2_DFS;
2424 capabilities |= CAP_DFS;
2426 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2428 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2429 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2431 pSMB->req_no_secext.CaseSensitivePasswordLength =
2432 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2433 bcc_ptr = pByteArea(smb_buffer);
2434 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2435 bcc_ptr += CIFS_SESS_KEY_SIZE;
2436 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2437 bcc_ptr += CIFS_SESS_KEY_SIZE;
2439 if (ses->capabilities & CAP_UNICODE) {
2440 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2445 bytes_returned = 0; /* skip null user */
2448 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2450 /* convert number of 16 bit words to bytes */
2451 bcc_ptr += 2 * bytes_returned;
2452 bcc_ptr += 2; /* trailing null */
2455 cifs_strtoUCS((__le16 *) bcc_ptr,
2456 "CIFS_LINUX_DOM", 32, nls_codepage);
2459 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2461 bcc_ptr += 2 * bytes_returned;
2464 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2466 bcc_ptr += 2 * bytes_returned;
2468 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2470 bcc_ptr += 2 * bytes_returned;
2473 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2475 bcc_ptr += 2 * bytes_returned;
2479 strncpy(bcc_ptr, user, 200);
2480 bcc_ptr += strnlen(user, 200);
2484 if (domain == NULL) {
2485 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2486 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2488 strncpy(bcc_ptr, domain, 64);
2489 bcc_ptr += strnlen(domain, 64);
2493 strcpy(bcc_ptr, "Linux version ");
2494 bcc_ptr += strlen("Linux version ");
2495 strcpy(bcc_ptr, utsname()->release);
2496 bcc_ptr += strlen(utsname()->release) + 1;
2497 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2498 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2500 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2501 smb_buffer->smb_buf_length += count;
2502 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2504 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2505 &bytes_returned, CIFS_LONG_OP);
2507 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2508 } else if ((smb_buffer_response->WordCount == 3)
2509 || (smb_buffer_response->WordCount == 4)) {
2510 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2511 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2512 if (action & GUEST_LOGIN)
2513 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2514 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2516 cFYI(1, ("UID = %d ", ses->Suid));
2517 /* response can have either 3 or 4 word count - Samba sends 3 */
2518 bcc_ptr = pByteArea(smb_buffer_response);
2519 if ((pSMBr->resp.hdr.WordCount == 3)
2520 || ((pSMBr->resp.hdr.WordCount == 4)
2521 && (blob_len < pSMBr->resp.ByteCount))) {
2522 if (pSMBr->resp.hdr.WordCount == 4)
2523 bcc_ptr += blob_len;
2525 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2526 if ((long) (bcc_ptr) % 2) {
2528 (BCC(smb_buffer_response) - 1) / 2;
2529 /* Unicode strings must be word
2534 BCC(smb_buffer_response) / 2;
2537 UniStrnlen((wchar_t *) bcc_ptr,
2538 remaining_words - 1);
2539 /* We look for obvious messed up bcc or strings in response so we do not go off
2540 the end since (at least) WIN2K and Windows XP have a major bug in not null
2541 terminating last Unicode string in response */
2543 kfree(ses->serverOS);
2544 ses->serverOS = kzalloc(2 * (len + 1),
2546 if (ses->serverOS == NULL)
2547 goto sesssetup_nomem;
2548 cifs_strfromUCS_le(ses->serverOS,
2551 bcc_ptr += 2 * (len + 1);
2552 remaining_words -= len + 1;
2553 ses->serverOS[2 * len] = 0;
2554 ses->serverOS[1 + (2 * len)] = 0;
2555 if (remaining_words > 0) {
2556 len = UniStrnlen((wchar_t *)bcc_ptr,
2558 kfree(ses->serverNOS);
2559 ses->serverNOS = kzalloc(2 * (len + 1),
2561 if (ses->serverNOS == NULL)
2562 goto sesssetup_nomem;
2563 cifs_strfromUCS_le(ses->serverNOS,
2566 bcc_ptr += 2 * (len + 1);
2567 ses->serverNOS[2 * len] = 0;
2568 ses->serverNOS[1 + (2 * len)] = 0;
2569 if (strncmp(ses->serverNOS,
2570 "NT LAN Manager 4", 16) == 0) {
2571 cFYI(1, ("NT4 server"));
2572 ses->flags |= CIFS_SES_NT4;
2574 remaining_words -= len + 1;
2575 if (remaining_words > 0) {
2576 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2577 /* last string is not always null terminated
2578 (for e.g. for Windows XP & 2000) */
2579 if (ses->serverDomain)
2580 kfree(ses->serverDomain);
2584 if (ses->serverDomain == NULL)
2585 goto sesssetup_nomem;
2586 cifs_strfromUCS_le(ses->serverDomain,
2589 bcc_ptr += 2 * (len + 1);
2590 ses->serverDomain[2*len] = 0;
2591 ses->serverDomain[1+(2*len)] = 0;
2592 } else { /* else no more room so create
2593 dummy domain string */
2594 if (ses->serverDomain)
2595 kfree(ses->serverDomain);
2597 kzalloc(2, GFP_KERNEL);
2599 } else { /* no room so create dummy domain
2602 /* if these kcallocs fail not much we
2603 can do, but better to not fail the
2605 kfree(ses->serverDomain);
2607 kzalloc(2, GFP_KERNEL);
2608 kfree(ses->serverNOS);
2610 kzalloc(2, GFP_KERNEL);
2612 } else { /* ASCII */
2613 len = strnlen(bcc_ptr, 1024);
2614 if (((long) bcc_ptr + len) - (long)
2615 pByteArea(smb_buffer_response)
2616 <= BCC(smb_buffer_response)) {
2617 kfree(ses->serverOS);
2618 ses->serverOS = kzalloc(len + 1,
2620 if (ses->serverOS == NULL)
2621 goto sesssetup_nomem;
2622 strncpy(ses->serverOS, bcc_ptr, len);
2625 /* null terminate the string */
2629 len = strnlen(bcc_ptr, 1024);
2630 kfree(ses->serverNOS);
2631 ses->serverNOS = kzalloc(len + 1,
2633 if (ses->serverNOS == NULL)
2634 goto sesssetup_nomem;
2635 strncpy(ses->serverNOS, bcc_ptr, len);
2640 len = strnlen(bcc_ptr, 1024);
2641 if (ses->serverDomain)
2642 kfree(ses->serverDomain);
2643 ses->serverDomain = kzalloc(len + 1,
2645 if (ses->serverDomain == NULL)
2646 goto sesssetup_nomem;
2647 strncpy(ses->serverDomain, bcc_ptr,
2654 ("Variable field of length %d "
2655 "extends beyond end of smb ",
2660 (" Security Blob Length extends beyond "
2665 (" Invalid Word count %d: ",
2666 smb_buffer_response->WordCount));
2669 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2670 since that could make reconnection harder, and
2671 reconnection might be needed to free memory */
2672 cifs_buf_release(smb_buffer);
2678 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2679 struct cifsSesInfo *ses, bool *pNTLMv2_flag,
2680 const struct nls_table *nls_codepage)
2682 struct smb_hdr *smb_buffer;
2683 struct smb_hdr *smb_buffer_response;
2684 SESSION_SETUP_ANDX *pSMB;
2685 SESSION_SETUP_ANDX *pSMBr;
2689 int remaining_words = 0;
2690 int bytes_returned = 0;
2692 int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
2693 PNEGOTIATE_MESSAGE SecurityBlob;
2694 PCHALLENGE_MESSAGE SecurityBlob2;
2695 __u32 negotiate_flags, capabilities;
2698 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2701 domain = ses->domainName;
2702 *pNTLMv2_flag = false;
2703 smb_buffer = cifs_buf_get();
2704 if (smb_buffer == NULL) {
2707 smb_buffer_response = smb_buffer;
2708 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2709 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2711 /* send SMBsessionSetup here */
2712 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2713 NULL /* no tCon exists yet */ , 12 /* wct */ );
2715 smb_buffer->Mid = GetNextMid(ses->server);
2716 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2717 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2719 pSMB->req.AndXCommand = 0xFF;
2720 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2721 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2723 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2724 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2726 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2727 CAP_EXTENDED_SECURITY;
2728 if (ses->capabilities & CAP_UNICODE) {
2729 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2730 capabilities |= CAP_UNICODE;
2732 if (ses->capabilities & CAP_STATUS32) {
2733 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2734 capabilities |= CAP_STATUS32;
2736 if (ses->capabilities & CAP_DFS) {
2737 smb_buffer->Flags2 |= SMBFLG2_DFS;
2738 capabilities |= CAP_DFS;
2740 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2742 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2743 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2744 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2745 SecurityBlob->MessageType = NtLmNegotiate;
2747 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2748 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2749 NTLMSSP_NEGOTIATE_56 |
2750 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2752 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2753 /* if (ntlmv2_support)
2754 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2755 /* setup pointers to domain name and workstation name */
2756 bcc_ptr += SecurityBlobLength;
2758 SecurityBlob->WorkstationName.Buffer = 0;
2759 SecurityBlob->WorkstationName.Length = 0;
2760 SecurityBlob->WorkstationName.MaximumLength = 0;
2762 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2763 along with username on auth request (ie the response to challenge) */
2764 SecurityBlob->DomainName.Buffer = 0;
2765 SecurityBlob->DomainName.Length = 0;
2766 SecurityBlob->DomainName.MaximumLength = 0;
2767 if (ses->capabilities & CAP_UNICODE) {
2768 if ((long) bcc_ptr % 2) {
2774 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2776 bcc_ptr += 2 * bytes_returned;
2778 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2780 bcc_ptr += 2 * bytes_returned;
2781 bcc_ptr += 2; /* null terminate Linux version */
2783 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2785 bcc_ptr += 2 * bytes_returned;
2788 bcc_ptr += 2; /* null terminate network opsys string */
2791 bcc_ptr += 2; /* null domain */
2792 } else { /* ASCII */
2793 strcpy(bcc_ptr, "Linux version ");
2794 bcc_ptr += strlen("Linux version ");
2795 strcpy(bcc_ptr, utsname()->release);
2796 bcc_ptr += strlen(utsname()->release) + 1;
2797 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2798 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2799 bcc_ptr++; /* empty domain field */
2802 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2803 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2804 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2805 smb_buffer->smb_buf_length += count;
2806 pSMB->req.ByteCount = cpu_to_le16(count);
2808 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2809 &bytes_returned, CIFS_LONG_OP);
2811 if (smb_buffer_response->Status.CifsError ==
2812 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2816 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2817 } else if ((smb_buffer_response->WordCount == 3)
2818 || (smb_buffer_response->WordCount == 4)) {
2819 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2820 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2822 if (action & GUEST_LOGIN)
2823 cFYI(1, (" Guest login"));
2824 /* Do we want to set anything in SesInfo struct when guest login? */
2826 bcc_ptr = pByteArea(smb_buffer_response);
2827 /* response can have either 3 or 4 word count - Samba sends 3 */
2829 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2830 if (SecurityBlob2->MessageType != NtLmChallenge) {
2832 ("Unexpected NTLMSSP message type received %d",
2833 SecurityBlob2->MessageType));
2835 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2836 cFYI(1, ("UID = %d", ses->Suid));
2837 if ((pSMBr->resp.hdr.WordCount == 3)
2838 || ((pSMBr->resp.hdr.WordCount == 4)
2840 pSMBr->resp.ByteCount))) {
2842 if (pSMBr->resp.hdr.WordCount == 4) {
2843 bcc_ptr += blob_len;
2844 cFYI(1, ("Security Blob Length %d",
2848 cFYI(1, ("NTLMSSP Challenge rcvd"));
2850 memcpy(ses->server->cryptKey,
2851 SecurityBlob2->Challenge,
2852 CIFS_CRYPTO_KEY_SIZE);
2853 if (SecurityBlob2->NegotiateFlags &
2854 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2855 *pNTLMv2_flag = true;
2857 if ((SecurityBlob2->NegotiateFlags &
2858 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2859 || (sign_CIFS_PDUs > 1))
2860 ses->server->secMode |=
2861 SECMODE_SIGN_REQUIRED;
2862 if ((SecurityBlob2->NegotiateFlags &
2863 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2864 ses->server->secMode |=
2865 SECMODE_SIGN_ENABLED;
2867 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2868 if ((long) (bcc_ptr) % 2) {
2870 (BCC(smb_buffer_response)
2872 /* Must word align unicode strings */
2877 (smb_buffer_response) / 2;
2880 UniStrnlen((wchar_t *) bcc_ptr,
2881 remaining_words - 1);
2882 /* We look for obvious messed up bcc or strings in response so we do not go off
2883 the end since (at least) WIN2K and Windows XP have a major bug in not null
2884 terminating last Unicode string in response */
2886 kfree(ses->serverOS);
2888 kzalloc(2 * (len + 1), GFP_KERNEL);
2889 cifs_strfromUCS_le(ses->serverOS,
2893 bcc_ptr += 2 * (len + 1);
2894 remaining_words -= len + 1;
2895 ses->serverOS[2 * len] = 0;
2896 ses->serverOS[1 + (2 * len)] = 0;
2897 if (remaining_words > 0) {
2898 len = UniStrnlen((wchar_t *)
2902 kfree(ses->serverNOS);
2904 kzalloc(2 * (len + 1),
2906 cifs_strfromUCS_le(ses->
2912 bcc_ptr += 2 * (len + 1);
2913 ses->serverNOS[2 * len] = 0;
2916 remaining_words -= len + 1;
2917 if (remaining_words > 0) {
2918 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2919 /* last string not always null terminated
2920 (for e.g. for Windows XP & 2000) */
2921 kfree(ses->serverDomain);
2933 ses->serverDomain[2*len]
2938 } /* else no more room so create dummy domain string */
2940 kfree(ses->serverDomain);
2945 } else { /* no room so create dummy domain and NOS string */
2946 kfree(ses->serverDomain);
2948 kzalloc(2, GFP_KERNEL);
2949 kfree(ses->serverNOS);
2951 kzalloc(2, GFP_KERNEL);
2953 } else { /* ASCII */
2954 len = strnlen(bcc_ptr, 1024);
2955 if (((long) bcc_ptr + len) - (long)
2956 pByteArea(smb_buffer_response)
2957 <= BCC(smb_buffer_response)) {
2959 kfree(ses->serverOS);
2963 strncpy(ses->serverOS,
2967 bcc_ptr[0] = 0; /* null terminate string */
2970 len = strnlen(bcc_ptr, 1024);
2971 kfree(ses->serverNOS);
2975 strncpy(ses->serverNOS, bcc_ptr, len);
2980 len = strnlen(bcc_ptr, 1024);
2981 kfree(ses->serverDomain);
2985 strncpy(ses->serverDomain,
2992 ("field of length %d "
2993 "extends beyond end of smb",
2997 cERROR(1, ("Security Blob Length extends beyond"
3001 cERROR(1, ("No session structure passed in."));
3005 (" Invalid Word count %d:",
3006 smb_buffer_response->WordCount));
3010 cifs_buf_release(smb_buffer);
3015 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3016 char *ntlm_session_key, bool ntlmv2_flag,
3017 const struct nls_table *nls_codepage)
3019 struct smb_hdr *smb_buffer;
3020 struct smb_hdr *smb_buffer_response;
3021 SESSION_SETUP_ANDX *pSMB;
3022 SESSION_SETUP_ANDX *pSMBr;
3027 int remaining_words = 0;
3028 int bytes_returned = 0;
3030 int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
3031 PAUTHENTICATE_MESSAGE SecurityBlob;
3032 __u32 negotiate_flags, capabilities;
3035 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
3038 user = ses->userName;
3039 domain = ses->domainName;
3040 smb_buffer = cifs_buf_get();
3041 if (smb_buffer == NULL) {
3044 smb_buffer_response = smb_buffer;
3045 pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
3046 pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
3048 /* send SMBsessionSetup here */
3049 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
3050 NULL /* no tCon exists yet */ , 12 /* wct */ );
3052 smb_buffer->Mid = GetNextMid(ses->server);
3053 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
3054 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
3055 pSMB->req.AndXCommand = 0xFF;
3056 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
3057 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
3059 pSMB->req.hdr.Uid = ses->Suid;
3061 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3062 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3064 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
3065 CAP_EXTENDED_SECURITY;
3066 if (ses->capabilities & CAP_UNICODE) {
3067 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3068 capabilities |= CAP_UNICODE;
3070 if (ses->capabilities & CAP_STATUS32) {
3071 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3072 capabilities |= CAP_STATUS32;
3074 if (ses->capabilities & CAP_DFS) {
3075 smb_buffer->Flags2 |= SMBFLG2_DFS;
3076 capabilities |= CAP_DFS;
3078 pSMB->req.Capabilities = cpu_to_le32(capabilities);
3080 bcc_ptr = (char *)&pSMB->req.SecurityBlob;
3081 SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
3082 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
3083 SecurityBlob->MessageType = NtLmAuthenticate;
3084 bcc_ptr += SecurityBlobLength;
3085 negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
3086 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
3087 0x80000000 | NTLMSSP_NEGOTIATE_128;
3089 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
3091 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
3093 /* setup pointers to domain name and workstation name */
3095 SecurityBlob->WorkstationName.Buffer = 0;
3096 SecurityBlob->WorkstationName.Length = 0;
3097 SecurityBlob->WorkstationName.MaximumLength = 0;
3098 SecurityBlob->SessionKey.Length = 0;
3099 SecurityBlob->SessionKey.MaximumLength = 0;
3100 SecurityBlob->SessionKey.Buffer = 0;
3102 SecurityBlob->LmChallengeResponse.Length = 0;
3103 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
3104 SecurityBlob->LmChallengeResponse.Buffer = 0;
3106 SecurityBlob->NtChallengeResponse.Length =
3107 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3108 SecurityBlob->NtChallengeResponse.MaximumLength =
3109 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3110 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
3111 SecurityBlob->NtChallengeResponse.Buffer =
3112 cpu_to_le32(SecurityBlobLength);
3113 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
3114 bcc_ptr += CIFS_SESS_KEY_SIZE;
3116 if (ses->capabilities & CAP_UNICODE) {
3117 if (domain == NULL) {
3118 SecurityBlob->DomainName.Buffer = 0;
3119 SecurityBlob->DomainName.Length = 0;
3120 SecurityBlob->DomainName.MaximumLength = 0;
3122 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
3125 SecurityBlob->DomainName.MaximumLength =
3127 SecurityBlob->DomainName.Buffer =
3128 cpu_to_le32(SecurityBlobLength);
3130 SecurityBlobLength += ln;
3131 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3134 SecurityBlob->UserName.Buffer = 0;
3135 SecurityBlob->UserName.Length = 0;
3136 SecurityBlob->UserName.MaximumLength = 0;
3138 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
3141 SecurityBlob->UserName.MaximumLength =
3143 SecurityBlob->UserName.Buffer =
3144 cpu_to_le32(SecurityBlobLength);
3146 SecurityBlobLength += ln;
3147 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3150 /* SecurityBlob->WorkstationName.Length =
3151 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3152 SecurityBlob->WorkstationName.Length *= 2;
3153 SecurityBlob->WorkstationName.MaximumLength =
3154 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3155 SecurityBlob->WorkstationName.Buffer =
3156 cpu_to_le32(SecurityBlobLength);
3157 bcc_ptr += SecurityBlob->WorkstationName.Length;
3158 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3159 SecurityBlob->WorkstationName.Length =
3160 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3162 if ((long) bcc_ptr % 2) {
3167 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3169 bcc_ptr += 2 * bytes_returned;
3171 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3173 bcc_ptr += 2 * bytes_returned;
3174 bcc_ptr += 2; /* null term version string */
3176 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3178 bcc_ptr += 2 * bytes_returned;
3181 bcc_ptr += 2; /* null terminate network opsys string */
3184 bcc_ptr += 2; /* null domain */
3185 } else { /* ASCII */
3186 if (domain == NULL) {
3187 SecurityBlob->DomainName.Buffer = 0;
3188 SecurityBlob->DomainName.Length = 0;
3189 SecurityBlob->DomainName.MaximumLength = 0;
3192 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3193 strncpy(bcc_ptr, domain, 63);
3194 ln = strnlen(domain, 64);
3195 SecurityBlob->DomainName.MaximumLength =
3197 SecurityBlob->DomainName.Buffer =
3198 cpu_to_le32(SecurityBlobLength);
3200 SecurityBlobLength += ln;
3201 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3204 SecurityBlob->UserName.Buffer = 0;
3205 SecurityBlob->UserName.Length = 0;
3206 SecurityBlob->UserName.MaximumLength = 0;
3209 strncpy(bcc_ptr, user, 63);
3210 ln = strnlen(user, 64);
3211 SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
3212 SecurityBlob->UserName.Buffer =
3213 cpu_to_le32(SecurityBlobLength);
3215 SecurityBlobLength += ln;
3216 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3218 /* BB fill in our workstation name if known BB */
3220 strcpy(bcc_ptr, "Linux version ");
3221 bcc_ptr += strlen("Linux version ");
3222 strcpy(bcc_ptr, utsname()->release);
3223 bcc_ptr += strlen(utsname()->release) + 1;
3224 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3225 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3226 bcc_ptr++; /* null domain */
3229 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3230 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3231 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3232 smb_buffer->smb_buf_length += count;
3233 pSMB->req.ByteCount = cpu_to_le16(count);
3235 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3236 &bytes_returned, CIFS_LONG_OP);
3238 /* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3239 } else if ((smb_buffer_response->WordCount == 3) ||
3240 (smb_buffer_response->WordCount == 4)) {
3241 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3242 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3243 if (action & GUEST_LOGIN)
3244 cFYI(1, (" Guest login")); /* BB Should we set anything
3245 in SesInfo struct ? */
3246 /* if (SecurityBlob2->MessageType != NtLm??) {
3247 cFYI("Unexpected message type on auth response is %d"));
3252 ("Check challenge UID %d vs auth response UID %d",
3253 ses->Suid, smb_buffer_response->Uid));
3254 /* UID left in wire format */
3255 ses->Suid = smb_buffer_response->Uid;
3256 bcc_ptr = pByteArea(smb_buffer_response);
3257 /* response can have either 3 or 4 word count - Samba sends 3 */
3258 if ((pSMBr->resp.hdr.WordCount == 3)
3259 || ((pSMBr->resp.hdr.WordCount == 4)
3261 pSMBr->resp.ByteCount))) {
3262 if (pSMBr->resp.hdr.WordCount == 4) {
3266 ("Security Blob Length %d ",
3271 ("NTLMSSP response to Authenticate "));
3273 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3274 if ((long) (bcc_ptr) % 2) {
3276 (BCC(smb_buffer_response)
3278 bcc_ptr++; /* Unicode strings must be word aligned */
3280 remaining_words = BCC(smb_buffer_response) / 2;
3282 len = UniStrnlen((wchar_t *) bcc_ptr,
3283 remaining_words - 1);
3284 /* We look for obvious messed up bcc or strings in response so we do not go off
3285 the end since (at least) WIN2K and Windows XP have a major bug in not null
3286 terminating last Unicode string in response */
3288 kfree(ses->serverOS);
3290 kzalloc(2 * (len + 1), GFP_KERNEL);
3291 cifs_strfromUCS_le(ses->serverOS,
3295 bcc_ptr += 2 * (len + 1);
3296 remaining_words -= len + 1;
3297 ses->serverOS[2 * len] = 0;
3298 ses->serverOS[1 + (2 * len)] = 0;
3299 if (remaining_words > 0) {
3300 len = UniStrnlen((wchar_t *)
3304 kfree(ses->serverNOS);
3306 kzalloc(2 * (len + 1),
3308 cifs_strfromUCS_le(ses->
3314 bcc_ptr += 2 * (len + 1);
3315 ses->serverNOS[2 * len] = 0;
3316 ses->serverNOS[1+(2*len)] = 0;
3317 remaining_words -= len + 1;
3318 if (remaining_words > 0) {
3319 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3320 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3321 if (ses->serverDomain)
3322 kfree(ses->serverDomain);
3347 } /* else no more room so create dummy domain string */
3349 if (ses->serverDomain)
3350 kfree(ses->serverDomain);
3351 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3353 } else { /* no room so create dummy domain and NOS string */
3354 if (ses->serverDomain)
3355 kfree(ses->serverDomain);
3356 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3357 kfree(ses->serverNOS);
3358 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3360 } else { /* ASCII */
3361 len = strnlen(bcc_ptr, 1024);
3362 if (((long) bcc_ptr + len) -
3363 (long) pByteArea(smb_buffer_response)
3364 <= BCC(smb_buffer_response)) {
3366 kfree(ses->serverOS);
3367 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
3368 strncpy(ses->serverOS,bcc_ptr, len);
3371 bcc_ptr[0] = 0; /* null terminate the string */
3374 len = strnlen(bcc_ptr, 1024);
3375 kfree(ses->serverNOS);
3376 ses->serverNOS = kzalloc(len+1,
3378 strncpy(ses->serverNOS,
3384 len = strnlen(bcc_ptr, 1024);
3385 if (ses->serverDomain)
3386 kfree(ses->serverDomain);
3390 strncpy(ses->serverDomain,
3396 cFYI(1, ("field of length %d "
3397 "extends beyond end of smb ",
3401 cERROR(1, ("Security Blob extends beyond end "
3405 cERROR(1, ("No session structure passed in."));
3408 cERROR(1, ("Invalid Word count %d: ",
3409 smb_buffer_response->WordCount));
3413 cifs_buf_release(smb_buffer);
3419 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3420 const char *tree, struct cifsTconInfo *tcon,
3421 const struct nls_table *nls_codepage)
3423 struct smb_hdr *smb_buffer;
3424 struct smb_hdr *smb_buffer_response;
3427 unsigned char *bcc_ptr;
3435 smb_buffer = cifs_buf_get();
3436 if (smb_buffer == NULL) {
3439 smb_buffer_response = smb_buffer;
3441 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3442 NULL /*no tid */ , 4 /*wct */ );
3444 smb_buffer->Mid = GetNextMid(ses->server);
3445 smb_buffer->Uid = ses->Suid;
3446 pSMB = (TCONX_REQ *) smb_buffer;
3447 pSMBr = (TCONX_RSP *) smb_buffer_response;
3449 pSMB->AndXCommand = 0xFF;
3450 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3451 bcc_ptr = &pSMB->Password[0];
3452 if ((ses->server->secMode) & SECMODE_USER) {
3453 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3454 *bcc_ptr = 0; /* password is null byte */
3455 bcc_ptr++; /* skip password */
3456 /* already aligned so no need to do it below */
3458 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3459 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3460 specified as required (when that support is added to
3461 the vfs in the future) as only NTLM or the much
3462 weaker LANMAN (which we do not send by default) is accepted
3463 by Samba (not sure whether other servers allow
3464 NTLMv2 password here) */
3465 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3466 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3467 (ses->server->secType == LANMAN))
3468 calc_lanman_hash(ses, bcc_ptr);
3470 #endif /* CIFS_WEAK_PW_HASH */
3471 SMBNTencrypt(ses->password,
3472 ses->server->cryptKey,
3475 bcc_ptr += CIFS_SESS_KEY_SIZE;
3476 if (ses->capabilities & CAP_UNICODE) {
3477 /* must align unicode strings */
3478 *bcc_ptr = 0; /* null byte password */
3483 if (ses->server->secMode &
3484 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3485 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3487 if (ses->capabilities & CAP_STATUS32) {
3488 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3490 if (ses->capabilities & CAP_DFS) {
3491 smb_buffer->Flags2 |= SMBFLG2_DFS;
3493 if (ses->capabilities & CAP_UNICODE) {
3494 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3496 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3497 6 /* max utf8 char length in bytes */ *
3498 (/* server len*/ + 256 /* share len */), nls_codepage);
3499 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3500 bcc_ptr += 2; /* skip trailing null */
3501 } else { /* ASCII */
3502 strcpy(bcc_ptr, tree);
3503 bcc_ptr += strlen(tree) + 1;
3505 strcpy(bcc_ptr, "?????");
3506 bcc_ptr += strlen("?????");
3508 count = bcc_ptr - &pSMB->Password[0];
3509 pSMB->hdr.smb_buf_length += count;
3510 pSMB->ByteCount = cpu_to_le16(count);
3512 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3515 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3516 /* above now done in SendReceive */
3517 if ((rc == 0) && (tcon != NULL)) {
3518 tcon->tidStatus = CifsGood;
3519 tcon->need_reconnect = false;
3520 tcon->tid = smb_buffer_response->Tid;
3521 bcc_ptr = pByteArea(smb_buffer_response);
3522 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3523 /* skip service field (NB: this field is always ASCII) */
3525 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3526 (bcc_ptr[2] == 'C')) {
3527 cFYI(1, ("IPC connection"));
3530 } else if (length == 2) {
3531 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3532 /* the most common case */
3533 cFYI(1, ("disk share connection"));
3536 bcc_ptr += length + 1;
3537 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3538 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3539 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3540 if ((bcc_ptr + (2 * length)) -
3541 pByteArea(smb_buffer_response) <=
3542 BCC(smb_buffer_response)) {
3543 kfree(tcon->nativeFileSystem);
3544 tcon->nativeFileSystem =
3545 kzalloc(length + 2, GFP_KERNEL);
3546 if (tcon->nativeFileSystem)
3548 tcon->nativeFileSystem,
3550 length, nls_codepage);
3551 bcc_ptr += 2 * length;
3552 bcc_ptr[0] = 0; /* null terminate the string */
3556 /* else do not bother copying these information fields*/
3558 length = strnlen(bcc_ptr, 1024);
3559 if ((bcc_ptr + length) -
3560 pByteArea(smb_buffer_response) <=
3561 BCC(smb_buffer_response)) {
3562 kfree(tcon->nativeFileSystem);
3563 tcon->nativeFileSystem =
3564 kzalloc(length + 1, GFP_KERNEL);
3565 if (tcon->nativeFileSystem)
3566 strncpy(tcon->nativeFileSystem, bcc_ptr,
3569 /* else do not bother copying these information fields*/
3571 if ((smb_buffer_response->WordCount == 3) ||
3572 (smb_buffer_response->WordCount == 7))
3573 /* field is in same location */
3574 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3577 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3578 } else if ((rc == 0) && tcon == NULL) {
3579 /* all we need to save for IPC$ connection */
3580 ses->ipc_tid = smb_buffer_response->Tid;
3583 cifs_buf_release(smb_buffer);
3588 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3592 struct cifsSesInfo *ses = NULL;
3597 if (cifs_sb->tcon) {
3598 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3599 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3604 DeleteTconOplockQEntries(cifs_sb->tcon);
3605 tconInfoFree(cifs_sb->tcon);
3606 if ((ses) && (ses->server)) {
3607 /* save off task so we do not refer to ses later */
3608 cFYI(1, ("About to do SMBLogoff "));
3609 rc = CIFSSMBLogoff(xid, ses);
3613 } else if (rc == -ESHUTDOWN) {
3614 cFYI(1, ("Waking up socket by sending signal"));
3616 kill_cifsd(ses->server);
3618 } /* else - we have an smb session
3619 left on this socket do not kill cifsd */
3621 cFYI(1, ("No session or bad tcon"));
3624 cifs_sb->tcon = NULL;
3625 tmp = cifs_sb->prepath;
3626 cifs_sb->prepathlen = 0;
3627 cifs_sb->prepath = NULL;
3636 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3637 struct nls_table *nls_info)
3640 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3641 bool ntlmv2_flag = false;
3643 struct TCP_Server_Info *server = pSesInfo->server;
3645 /* what if server changes its buffer size after dropping the session? */
3646 if (server->maxBuf == 0) /* no need to send on reconnect */ {
3647 rc = CIFSSMBNegotiate(xid, pSesInfo);
3648 if (rc == -EAGAIN) {
3649 /* retry only once on 1st time connection */
3650 rc = CIFSSMBNegotiate(xid, pSesInfo);
3655 spin_lock(&GlobalMid_Lock);
3656 if (server->tcpStatus != CifsExiting)
3657 server->tcpStatus = CifsGood;
3660 spin_unlock(&GlobalMid_Lock);
3669 pSesInfo->flags = 0;
3670 pSesInfo->capabilities = server->capabilities;
3671 if (linuxExtEnabled == 0)
3672 pSesInfo->capabilities &= (~CAP_UNIX);
3673 /* pSesInfo->sequence_number = 0;*/
3674 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3675 server->secMode, server->capabilities, server->timeAdj));
3677 if (experimEnabled < 2)
3678 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
3679 else if (extended_security
3680 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3681 && (server->secType == NTLMSSP)) {
3683 } else if (extended_security
3684 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3685 && (server->secType == RawNTLMSSP)) {
3686 cFYI(1, ("NTLMSSP sesssetup"));
3687 rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag,
3692 cFYI(1, ("more secure NTLM ver2 hash"));
3693 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3698 v2_response = kmalloc(16 + 64 /* blob*/,
3701 CalcNTLMv2_response(pSesInfo,
3704 cifs_calculate_ntlmv2_mac_key */
3706 /* BB Put dummy sig in SessSetup PDU? */
3713 SMBNTencrypt(pSesInfo->password,
3718 cifs_calculate_mac_key(
3719 &server->mac_signing_key,
3721 pSesInfo->password);
3723 /* for better security the weaker lanman hash not sent
3724 in AuthSessSetup so we no longer calculate it */
3726 rc = CIFSNTLMSSPAuthSessSetup(xid, pSesInfo,
3731 } else { /* old style NTLM 0.12 session setup */
3732 SMBNTencrypt(pSesInfo->password, server->cryptKey,
3736 cifs_calculate_mac_key(&server->mac_signing_key,
3738 pSesInfo->password);
3740 rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info);
3743 cERROR(1, ("Send error in SessSetup = %d", rc));
3745 cFYI(1, ("CIFS Session Established successfully"));
3746 spin_lock(&GlobalMid_Lock);
3747 pSesInfo->status = CifsGood;
3748 pSesInfo->need_reconnect = false;
3749 spin_unlock(&GlobalMid_Lock);