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 */
98 unsigned short int port;
102 static int ipv4_connect(struct sockaddr_in *psin_server,
103 struct socket **csocket,
105 char *server_netb_name);
106 static int ipv6_connect(struct sockaddr_in6 *psin_server,
107 struct socket **csocket);
111 * cifs tcp session reconnection
113 * mark tcp session as reconnecting so temporarily locked
114 * mark all smb sessions as reconnecting for tcp session
115 * reconnect tcp session
116 * wake up waiters on reconnection? - (not needed currently)
120 cifs_reconnect(struct TCP_Server_Info *server)
123 struct list_head *tmp;
124 struct cifsSesInfo *ses;
125 struct cifsTconInfo *tcon;
126 struct mid_q_entry *mid_entry;
128 spin_lock(&GlobalMid_Lock);
129 if (server->tcpStatus == CifsExiting) {
130 /* the demux thread will exit normally
131 next time through the loop */
132 spin_unlock(&GlobalMid_Lock);
135 server->tcpStatus = CifsNeedReconnect;
136 spin_unlock(&GlobalMid_Lock);
139 cFYI(1, ("Reconnecting tcp session"));
141 /* before reconnecting the tcp session, mark the smb session (uid)
142 and the tid bad so they are not used until reconnected */
143 read_lock(&GlobalSMBSeslock);
144 list_for_each(tmp, &GlobalSMBSessionList) {
145 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
147 if (ses->server == server) {
148 ses->status = CifsNeedReconnect;
152 /* else tcp and smb sessions need reconnection */
154 list_for_each(tmp, &GlobalTreeConnectionList) {
155 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
156 if ((tcon->ses) && (tcon->ses->server == server))
157 tcon->tidStatus = CifsNeedReconnect;
159 read_unlock(&GlobalSMBSeslock);
160 /* do not want to be sending data on a socket we are freeing */
161 down(&server->tcpSem);
162 if (server->ssocket) {
163 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
164 server->ssocket->flags));
165 kernel_sock_shutdown(server->ssocket, SHUT_WR);
166 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
167 server->ssocket->state,
168 server->ssocket->flags));
169 sock_release(server->ssocket);
170 server->ssocket = NULL;
173 spin_lock(&GlobalMid_Lock);
174 list_for_each(tmp, &server->pending_mid_q) {
175 mid_entry = list_entry(tmp, struct
178 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
179 /* Mark other intransit requests as needing
180 retry so we do not immediately mark the
181 session bad again (ie after we reconnect
182 below) as they timeout too */
183 mid_entry->midState = MID_RETRY_NEEDED;
186 spin_unlock(&GlobalMid_Lock);
189 while ((server->tcpStatus != CifsExiting) &&
190 (server->tcpStatus != CifsGood)) {
192 if (server->protocolType == IPV6) {
193 rc = ipv6_connect(&server->addr.sockAddr6,
196 rc = ipv4_connect(&server->addr.sockAddr,
198 server->workstation_RFC1001_name,
199 server->server_RFC1001_name);
202 cFYI(1, ("reconnect error %d", rc));
205 atomic_inc(&tcpSesReconnectCount);
206 spin_lock(&GlobalMid_Lock);
207 if (server->tcpStatus != CifsExiting)
208 server->tcpStatus = CifsGood;
209 server->sequence_number = 0;
210 spin_unlock(&GlobalMid_Lock);
211 /* atomic_set(&server->inFlight,0);*/
212 wake_up(&server->response_q);
220 0 not a transact2, or all data present
221 >0 transact2 with that much data missing
222 -EINVAL = invalid transact2
225 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
227 struct smb_t2_rsp *pSMBt;
229 int data_in_this_rsp;
232 if (pSMB->Command != SMB_COM_TRANSACTION2)
235 /* check for plausible wct, bcc and t2 data and parm sizes */
236 /* check for parm and data offset going beyond end of smb */
237 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
238 cFYI(1, ("invalid transact2 word count"));
242 pSMBt = (struct smb_t2_rsp *)pSMB;
244 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
245 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
247 remaining = total_data_size - data_in_this_rsp;
251 else if (remaining < 0) {
252 cFYI(1, ("total data %d smaller than data in frame %d",
253 total_data_size, data_in_this_rsp));
256 cFYI(1, ("missing %d bytes from transact2, check next response",
258 if (total_data_size > maxBufSize) {
259 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
260 total_data_size, maxBufSize));
267 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
269 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
270 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
275 char *data_area_of_target;
276 char *data_area_of_buf2;
279 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
281 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
282 cFYI(1, ("total data size of primary and secondary t2 differ"));
285 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
287 remaining = total_data_size - total_in_buf;
292 if (remaining == 0) /* nothing to do, ignore */
295 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
296 if (remaining < total_in_buf2) {
297 cFYI(1, ("transact2 2nd response contains too much data"));
300 /* find end of first SMB data area */
301 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
302 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
303 /* validate target area */
305 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
306 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
308 data_area_of_target += total_in_buf;
310 /* copy second buffer into end of first buffer */
311 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
312 total_in_buf += total_in_buf2;
313 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
314 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
315 byte_count += total_in_buf2;
316 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
318 byte_count = pTargetSMB->smb_buf_length;
319 byte_count += total_in_buf2;
321 /* BB also add check that we are not beyond maximum buffer size */
323 pTargetSMB->smb_buf_length = byte_count;
325 if (remaining == total_in_buf2) {
326 cFYI(1, ("found the last secondary response"));
327 return 0; /* we are done */
328 } else /* more responses to go */
334 cifs_demultiplex_thread(struct TCP_Server_Info *server)
337 unsigned int pdu_length, total_read;
338 struct smb_hdr *smb_buffer = NULL;
339 struct smb_hdr *bigbuf = NULL;
340 struct smb_hdr *smallbuf = NULL;
341 struct msghdr smb_msg;
343 struct socket *csocket = server->ssocket;
344 struct list_head *tmp;
345 struct cifsSesInfo *ses;
346 struct task_struct *task_to_wake = NULL;
347 struct mid_q_entry *mid_entry;
349 bool isLargeBuf = false;
353 current->flags |= PF_MEMALLOC;
354 cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
356 length = atomic_inc_return(&tcpSesAllocCount);
358 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
362 while (server->tcpStatus != CifsExiting) {
365 if (bigbuf == NULL) {
366 bigbuf = cifs_buf_get();
368 cERROR(1, ("No memory for large SMB response"));
370 /* retry will check if exiting */
373 } else if (isLargeBuf) {
374 /* we are reusing a dirty large buf, clear its start */
375 memset(bigbuf, 0, sizeof(struct smb_hdr));
378 if (smallbuf == NULL) {
379 smallbuf = cifs_small_buf_get();
381 cERROR(1, ("No memory for SMB response"));
383 /* retry will check if exiting */
386 /* beginning of smb buffer is cleared in our buf_get */
387 } else /* if existing small buf clear beginning */
388 memset(smallbuf, 0, sizeof(struct smb_hdr));
392 smb_buffer = smallbuf;
393 iov.iov_base = smb_buffer;
395 smb_msg.msg_control = NULL;
396 smb_msg.msg_controllen = 0;
397 pdu_length = 4; /* enough to get RFC1001 header */
400 kernel_recvmsg(csocket, &smb_msg,
401 &iov, 1, pdu_length, 0 /* BB other flags? */);
403 if (server->tcpStatus == CifsExiting) {
405 } else if (server->tcpStatus == CifsNeedReconnect) {
406 cFYI(1, ("Reconnect after server stopped responding"));
407 cifs_reconnect(server);
408 cFYI(1, ("call to reconnect done"));
409 csocket = server->ssocket;
411 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
412 msleep(1); /* minimum sleep to prevent looping
413 allowing socket to clear and app threads to set
414 tcpStatus CifsNeedReconnect if server hung */
419 } else if (length <= 0) {
420 if (server->tcpStatus == CifsNew) {
421 cFYI(1, ("tcp session abend after SMBnegprot"));
422 /* some servers kill the TCP session rather than
423 returning an SMB negprot error, in which
424 case reconnecting here is not going to help,
425 and so simply return error to mount */
428 if (!try_to_freeze() && (length == -EINTR)) {
429 cFYI(1, ("cifsd thread killed"));
432 cFYI(1, ("Reconnect after unexpected peek error %d",
434 cifs_reconnect(server);
435 csocket = server->ssocket;
436 wake_up(&server->response_q);
438 } else if (length < pdu_length) {
439 cFYI(1, ("requested %d bytes but only got %d bytes",
440 pdu_length, length));
441 pdu_length -= length;
446 /* The right amount was read from socket - 4 bytes */
447 /* so we can now interpret the length field */
449 /* the first byte big endian of the length field,
450 is actually not part of the length but the type
451 with the most common, zero, as regular data */
452 temp = *((char *) smb_buffer);
454 /* Note that FC 1001 length is big endian on the wire,
455 but we convert it here so it is always manipulated
456 as host byte order */
457 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
458 smb_buffer->smb_buf_length = pdu_length;
460 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
462 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
464 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
465 cFYI(1, ("Good RFC 1002 session rsp"));
467 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
468 /* we get this from Windows 98 instead of
469 an error on SMB negprot response */
470 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
472 if (server->tcpStatus == CifsNew) {
473 /* if nack on negprot (rather than
474 ret of smb negprot error) reconnecting
475 not going to help, ret error to mount */
478 /* give server a second to
479 clean up before reconnect attempt */
481 /* always try 445 first on reconnect
482 since we get NACK on some if we ever
483 connected to port 139 (the NACK is
484 since we do not begin with RFC1001
485 session initialize frame) */
486 server->addr.sockAddr.sin_port =
488 cifs_reconnect(server);
489 csocket = server->ssocket;
490 wake_up(&server->response_q);
493 } else if (temp != (char) 0) {
494 cERROR(1, ("Unknown RFC 1002 frame"));
495 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
497 cifs_reconnect(server);
498 csocket = server->ssocket;
502 /* else we have an SMB response */
503 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
504 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
505 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
506 length, pdu_length+4));
507 cifs_reconnect(server);
508 csocket = server->ssocket;
509 wake_up(&server->response_q);
516 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
518 memcpy(bigbuf, smallbuf, 4);
522 iov.iov_base = 4 + (char *)smb_buffer;
523 iov.iov_len = pdu_length;
524 for (total_read = 0; total_read < pdu_length;
525 total_read += length) {
526 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
527 pdu_length - total_read, 0);
528 if ((server->tcpStatus == CifsExiting) ||
529 (length == -EINTR)) {
533 } else if (server->tcpStatus == CifsNeedReconnect) {
534 cifs_reconnect(server);
535 csocket = server->ssocket;
536 /* Reconnect wakes up rspns q */
537 /* Now we will reread sock */
540 } else if ((length == -ERESTARTSYS) ||
541 (length == -EAGAIN)) {
542 msleep(1); /* minimum sleep to prevent looping,
543 allowing socket to clear and app
544 threads to set tcpStatus
545 CifsNeedReconnect if server hung*/
548 } else if (length <= 0) {
549 cERROR(1, ("Received no data, expecting %d",
550 pdu_length - total_read));
551 cifs_reconnect(server);
552 csocket = server->ssocket;
559 else if (reconnect == 1)
562 length += 4; /* account for rfc1002 hdr */
565 dump_smb(smb_buffer, length);
566 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
567 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
573 spin_lock(&GlobalMid_Lock);
574 list_for_each(tmp, &server->pending_mid_q) {
575 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
577 if ((mid_entry->mid == smb_buffer->Mid) &&
578 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
579 (mid_entry->command == smb_buffer->Command)) {
580 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
581 /* We have a multipart transact2 resp */
583 if (mid_entry->resp_buf) {
584 /* merge response - fix up 1st*/
585 if (coalesce_t2(smb_buffer,
586 mid_entry->resp_buf)) {
587 mid_entry->multiRsp =
591 /* all parts received */
592 mid_entry->multiEnd =
598 cERROR(1,("1st trans2 resp needs bigbuf"));
599 /* BB maybe we can fix this up, switch
600 to already allocated large buffer? */
602 /* Have first buffer */
603 mid_entry->resp_buf =
605 mid_entry->largeBuf =
612 mid_entry->resp_buf = smb_buffer;
613 mid_entry->largeBuf = isLargeBuf;
615 task_to_wake = mid_entry->tsk;
616 mid_entry->midState = MID_RESPONSE_RECEIVED;
617 #ifdef CONFIG_CIFS_STATS2
618 mid_entry->when_received = jiffies;
620 /* so we do not time out requests to server
621 which is still responding (since server could
622 be busy but not dead) */
623 server->lstrp = jiffies;
627 spin_unlock(&GlobalMid_Lock);
629 /* Was previous buf put in mpx struct for multi-rsp? */
631 /* smb buffer will be freed by user thread */
637 wake_up_process(task_to_wake);
638 } else if (!is_valid_oplock_break(smb_buffer, server) &&
640 cERROR(1, ("No task to wake, unknown frame received! "
641 "NumMids %d", midCount.counter));
642 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
643 sizeof(struct smb_hdr));
644 #ifdef CONFIG_CIFS_DEBUG2
645 cifs_dump_detail(smb_buffer);
646 cifs_dump_mids(server);
647 #endif /* CIFS_DEBUG2 */
650 } /* end while !EXITING */
652 spin_lock(&GlobalMid_Lock);
653 server->tcpStatus = CifsExiting;
654 spin_unlock(&GlobalMid_Lock);
655 wake_up_all(&server->response_q);
657 /* check if we have blocked requests that need to free */
658 /* Note that cifs_max_pending is normally 50, but
659 can be set at module install time to as little as two */
660 spin_lock(&GlobalMid_Lock);
661 if (atomic_read(&server->inFlight) >= cifs_max_pending)
662 atomic_set(&server->inFlight, cifs_max_pending - 1);
663 /* We do not want to set the max_pending too low or we
664 could end up with the counter going negative */
665 spin_unlock(&GlobalMid_Lock);
666 /* Although there should not be any requests blocked on
667 this queue it can not hurt to be paranoid and try to wake up requests
668 that may haven been blocked when more than 50 at time were on the wire
669 to the same server - they now will see the session is in exit state
670 and get out of SendReceive. */
671 wake_up_all(&server->request_q);
672 /* give those requests time to exit */
675 if (server->ssocket) {
676 sock_release(csocket);
677 server->ssocket = NULL;
679 /* buffer usuallly freed in free_mid - need to free it here on exit */
680 cifs_buf_release(bigbuf);
681 if (smallbuf) /* no sense logging a debug message if NULL */
682 cifs_small_buf_release(smallbuf);
684 read_lock(&GlobalSMBSeslock);
685 if (list_empty(&server->pending_mid_q)) {
686 /* loop through server session structures attached to this and
688 list_for_each(tmp, &GlobalSMBSessionList) {
690 list_entry(tmp, struct cifsSesInfo,
692 if (ses->server == server) {
693 ses->status = CifsExiting;
697 read_unlock(&GlobalSMBSeslock);
699 /* although we can not zero the server struct pointer yet,
700 since there are active requests which may depnd on them,
701 mark the corresponding SMB sessions as exiting too */
702 list_for_each(tmp, &GlobalSMBSessionList) {
703 ses = list_entry(tmp, struct cifsSesInfo,
705 if (ses->server == server)
706 ses->status = CifsExiting;
709 spin_lock(&GlobalMid_Lock);
710 list_for_each(tmp, &server->pending_mid_q) {
711 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
712 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
713 cFYI(1, ("Clearing Mid 0x%x - waking up ",
715 task_to_wake = mid_entry->tsk;
717 wake_up_process(task_to_wake);
720 spin_unlock(&GlobalMid_Lock);
721 read_unlock(&GlobalSMBSeslock);
722 /* 1/8th of sec is more than enough time for them to exit */
726 if (!list_empty(&server->pending_mid_q)) {
727 /* mpx threads have not exited yet give them
728 at least the smb send timeout time for long ops */
729 /* due to delays on oplock break requests, we need
730 to wait at least 45 seconds before giving up
731 on a request getting a response and going ahead
733 cFYI(1, ("Wait for exit from demultiplex thread"));
735 /* if threads still have not exited they are probably never
736 coming home not much else we can do but free the memory */
739 /* last chance to mark ses pointers invalid
740 if there are any pointing to this (e.g
741 if a crazy root user tried to kill cifsd
742 kernel thread explicitly this might happen) */
743 write_lock(&GlobalSMBSeslock);
744 list_for_each(tmp, &GlobalSMBSessionList) {
745 ses = list_entry(tmp, struct cifsSesInfo,
747 if (ses->server == server)
750 write_unlock(&GlobalSMBSeslock);
752 kfree(server->hostname);
753 task_to_wake = xchg(&server->tsk, NULL);
756 length = atomic_dec_return(&tcpSesAllocCount);
758 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
761 /* if server->tsk was NULL then wait for a signal before exiting */
763 set_current_state(TASK_INTERRUPTIBLE);
764 while (!signal_pending(current)) {
766 set_current_state(TASK_INTERRUPTIBLE);
768 set_current_state(TASK_RUNNING);
774 /* extract the host portion of the UNC string */
776 extract_hostname(const char *unc)
782 /* skip double chars at beginning of string */
783 /* BB: check validity of these bytes? */
786 /* delimiter between hostname and sharename is always '\\' now */
787 delim = strchr(src, '\\');
789 return ERR_PTR(-EINVAL);
792 dst = kmalloc((len + 1), GFP_KERNEL);
794 return ERR_PTR(-ENOMEM);
796 memcpy(dst, src, len);
803 cifs_parse_mount_options(char *options, const char *devname,
808 unsigned int temp_len, i, j;
814 if (Local_System_Name[0] != 0)
815 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
817 char *nodename = utsname()->nodename;
818 int n = strnlen(nodename, 15);
819 memset(vol->source_rfc1001_name, 0x20, 15);
820 for (i = 0; i < n; i++) {
821 /* does not have to be perfect mapping since field is
822 informational, only used for servers that do not support
823 port 445 and it can be overridden at mount time */
824 vol->source_rfc1001_name[i] = toupper(nodename[i]);
827 vol->source_rfc1001_name[15] = 0;
828 /* null target name indicates to use *SMBSERVR default called name
829 if we end up sending RFC1001 session initialize */
830 vol->target_rfc1001_name[0] = 0;
831 vol->linux_uid = current->uid; /* current->euid instead? */
832 vol->linux_gid = current->gid;
833 vol->dir_mode = S_IRWXUGO;
834 /* 2767 perms indicate mandatory locking support */
835 vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
837 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
839 /* default is always to request posix paths. */
840 vol->posix_paths = 1;
845 if (strncmp(options, "sep=", 4) == 0) {
846 if (options[4] != 0) {
847 separator[0] = options[4];
850 cFYI(1, ("Null separator not allowed"));
854 while ((data = strsep(&options, separator)) != NULL) {
857 if ((value = strchr(data, '=')) != NULL)
860 /* Have to parse this before we parse for "user" */
861 if (strnicmp(data, "user_xattr", 10) == 0) {
863 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
865 } else if (strnicmp(data, "user", 4) == 0) {
868 "CIFS: invalid or missing username\n");
869 return 1; /* needs_arg; */
870 } else if (!*value) {
871 /* null user, ie anonymous, authentication */
874 if (strnlen(value, 200) < 200) {
875 vol->username = value;
877 printk(KERN_WARNING "CIFS: username too long\n");
880 } else if (strnicmp(data, "pass", 4) == 0) {
882 vol->password = NULL;
884 } else if (value[0] == 0) {
885 /* check if string begins with double comma
886 since that would mean the password really
887 does start with a comma, and would not
888 indicate an empty string */
889 if (value[1] != separator[0]) {
890 vol->password = NULL;
894 temp_len = strlen(value);
895 /* removed password length check, NTLM passwords
896 can be arbitrarily long */
898 /* if comma in password, the string will be
899 prematurely null terminated. Commas in password are
900 specified across the cifs mount interface by a double
901 comma ie ,, and a comma used as in other cases ie ','
902 as a parameter delimiter/separator is single and due
903 to the strsep above is temporarily zeroed. */
905 /* NB: password legally can have multiple commas and
906 the only illegal character in a password is null */
908 if ((value[temp_len] == 0) &&
909 (value[temp_len+1] == separator[0])) {
911 value[temp_len] = separator[0];
912 temp_len += 2; /* move after second comma */
913 while (value[temp_len] != 0) {
914 if (value[temp_len] == separator[0]) {
915 if (value[temp_len+1] ==
917 /* skip second comma */
920 /* single comma indicating start
927 if (value[temp_len] == 0) {
931 /* point option to start of next parm */
932 options = value + temp_len + 1;
934 /* go from value to value + temp_len condensing
935 double commas to singles. Note that this ends up
936 allocating a few bytes too many, which is ok */
937 vol->password = kzalloc(temp_len, GFP_KERNEL);
938 if (vol->password == NULL) {
939 printk(KERN_WARNING "CIFS: no memory "
943 for (i = 0, j = 0; i < temp_len; i++, j++) {
944 vol->password[j] = value[i];
945 if (value[i] == separator[0]
946 && value[i+1] == separator[0]) {
947 /* skip second comma */
951 vol->password[j] = 0;
953 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
954 if (vol->password == NULL) {
955 printk(KERN_WARNING "CIFS: no memory "
959 strcpy(vol->password, value);
961 } else if (strnicmp(data, "ip", 2) == 0) {
962 if (!value || !*value) {
964 } else if (strnlen(value, 35) < 35) {
967 printk(KERN_WARNING "CIFS: ip address "
971 } else if (strnicmp(data, "sec", 3) == 0) {
972 if (!value || !*value) {
973 cERROR(1, ("no security value specified"));
975 } else if (strnicmp(value, "krb5i", 5) == 0) {
976 vol->secFlg |= CIFSSEC_MAY_KRB5 |
978 } else if (strnicmp(value, "krb5p", 5) == 0) {
979 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
981 cERROR(1, ("Krb5 cifs privacy not supported"));
983 } else if (strnicmp(value, "krb5", 4) == 0) {
984 vol->secFlg |= CIFSSEC_MAY_KRB5;
985 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
986 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
988 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
989 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
990 } else if (strnicmp(value, "ntlmi", 5) == 0) {
991 vol->secFlg |= CIFSSEC_MAY_NTLM |
993 } else if (strnicmp(value, "ntlm", 4) == 0) {
994 /* ntlm is default so can be turned off too */
995 vol->secFlg |= CIFSSEC_MAY_NTLM;
996 } else if (strnicmp(value, "nontlm", 6) == 0) {
997 /* BB is there a better way to do this? */
998 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
999 #ifdef CONFIG_CIFS_WEAK_PW_HASH
1000 } else if (strnicmp(value, "lanman", 6) == 0) {
1001 vol->secFlg |= CIFSSEC_MAY_LANMAN;
1003 } else if (strnicmp(value, "none", 4) == 0) {
1006 cERROR(1, ("bad security option: %s", value));
1009 } else if ((strnicmp(data, "unc", 3) == 0)
1010 || (strnicmp(data, "target", 6) == 0)
1011 || (strnicmp(data, "path", 4) == 0)) {
1012 if (!value || !*value) {
1013 printk(KERN_WARNING "CIFS: invalid path to "
1014 "network resource\n");
1015 return 1; /* needs_arg; */
1017 if ((temp_len = strnlen(value, 300)) < 300) {
1018 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1019 if (vol->UNC == NULL)
1021 strcpy(vol->UNC, value);
1022 if (strncmp(vol->UNC, "//", 2) == 0) {
1025 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1027 "CIFS: UNC Path does not begin "
1028 "with // or \\\\ \n");
1032 printk(KERN_WARNING "CIFS: UNC name too long\n");
1035 } else if ((strnicmp(data, "domain", 3) == 0)
1036 || (strnicmp(data, "workgroup", 5) == 0)) {
1037 if (!value || !*value) {
1038 printk(KERN_WARNING "CIFS: invalid domain name\n");
1039 return 1; /* needs_arg; */
1041 /* BB are there cases in which a comma can be valid in
1042 a domain name and need special handling? */
1043 if (strnlen(value, 256) < 256) {
1044 vol->domainname = value;
1045 cFYI(1, ("Domain name set"));
1047 printk(KERN_WARNING "CIFS: domain name too "
1051 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1052 if (!value || !*value) {
1054 "CIFS: invalid path prefix\n");
1055 return 1; /* needs_argument */
1057 if ((temp_len = strnlen(value, 1024)) < 1024) {
1058 if (value[0] != '/')
1059 temp_len++; /* missing leading slash */
1060 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1061 if (vol->prepath == NULL)
1063 if (value[0] != '/') {
1064 vol->prepath[0] = '/';
1065 strcpy(vol->prepath+1, value);
1067 strcpy(vol->prepath, value);
1068 cFYI(1, ("prefix path %s", vol->prepath));
1070 printk(KERN_WARNING "CIFS: prefix too long\n");
1073 } else if (strnicmp(data, "iocharset", 9) == 0) {
1074 if (!value || !*value) {
1075 printk(KERN_WARNING "CIFS: invalid iocharset "
1077 return 1; /* needs_arg; */
1079 if (strnlen(value, 65) < 65) {
1080 if (strnicmp(value, "default", 7))
1081 vol->iocharset = value;
1082 /* if iocharset not set then load_nls_default
1083 is used by caller */
1084 cFYI(1, ("iocharset set to %s", value));
1086 printk(KERN_WARNING "CIFS: iocharset name "
1090 } else if (strnicmp(data, "uid", 3) == 0) {
1091 if (value && *value) {
1093 simple_strtoul(value, &value, 0);
1094 vol->override_uid = 1;
1096 } else if (strnicmp(data, "gid", 3) == 0) {
1097 if (value && *value) {
1099 simple_strtoul(value, &value, 0);
1100 vol->override_gid = 1;
1102 } else if (strnicmp(data, "file_mode", 4) == 0) {
1103 if (value && *value) {
1105 simple_strtoul(value, &value, 0);
1107 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1108 if (value && *value) {
1110 simple_strtoul(value, &value, 0);
1112 } else if (strnicmp(data, "dirmode", 4) == 0) {
1113 if (value && *value) {
1115 simple_strtoul(value, &value, 0);
1117 } else if (strnicmp(data, "port", 4) == 0) {
1118 if (value && *value) {
1120 simple_strtoul(value, &value, 0);
1122 } else if (strnicmp(data, "rsize", 5) == 0) {
1123 if (value && *value) {
1125 simple_strtoul(value, &value, 0);
1127 } else if (strnicmp(data, "wsize", 5) == 0) {
1128 if (value && *value) {
1130 simple_strtoul(value, &value, 0);
1132 } else if (strnicmp(data, "sockopt", 5) == 0) {
1133 if (value && *value) {
1135 simple_strtoul(value, &value, 0);
1137 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1138 if (!value || !*value || (*value == ' ')) {
1139 cFYI(1, ("invalid (empty) netbiosname"));
1141 memset(vol->source_rfc1001_name, 0x20, 15);
1142 for (i = 0; i < 15; i++) {
1143 /* BB are there cases in which a comma can be
1144 valid in this workstation netbios name (and need
1145 special handling)? */
1147 /* We do not uppercase netbiosname for user */
1151 vol->source_rfc1001_name[i] =
1154 /* The string has 16th byte zero still from
1155 set at top of the function */
1156 if ((i == 15) && (value[i] != 0))
1157 printk(KERN_WARNING "CIFS: netbiosname"
1158 " longer than 15 truncated.\n");
1160 } else if (strnicmp(data, "servern", 7) == 0) {
1161 /* servernetbiosname specified override *SMBSERVER */
1162 if (!value || !*value || (*value == ' ')) {
1163 cFYI(1, ("empty server netbiosname specified"));
1165 /* last byte, type, is 0x20 for servr type */
1166 memset(vol->target_rfc1001_name, 0x20, 16);
1168 for (i = 0; i < 15; i++) {
1169 /* BB are there cases in which a comma can be
1170 valid in this workstation netbios name
1171 (and need special handling)? */
1173 /* user or mount helper must uppercase
1178 vol->target_rfc1001_name[i] =
1181 /* The string has 16th byte zero still from
1182 set at top of the function */
1183 if ((i == 15) && (value[i] != 0))
1184 printk(KERN_WARNING "CIFS: server net"
1185 "biosname longer than 15 truncated.\n");
1187 } else if (strnicmp(data, "credentials", 4) == 0) {
1189 } else if (strnicmp(data, "version", 3) == 0) {
1191 } else if (strnicmp(data, "guest", 5) == 0) {
1193 } else if (strnicmp(data, "rw", 2) == 0) {
1195 } else if ((strnicmp(data, "suid", 4) == 0) ||
1196 (strnicmp(data, "nosuid", 6) == 0) ||
1197 (strnicmp(data, "exec", 4) == 0) ||
1198 (strnicmp(data, "noexec", 6) == 0) ||
1199 (strnicmp(data, "nodev", 5) == 0) ||
1200 (strnicmp(data, "noauto", 6) == 0) ||
1201 (strnicmp(data, "dev", 3) == 0)) {
1202 /* The mount tool or mount.cifs helper (if present)
1203 uses these opts to set flags, and the flags are read
1204 by the kernel vfs layer before we get here (ie
1205 before read super) so there is no point trying to
1206 parse these options again and set anything and it
1207 is ok to just ignore them */
1209 } else if (strnicmp(data, "ro", 2) == 0) {
1211 } else if (strnicmp(data, "hard", 4) == 0) {
1213 } else if (strnicmp(data, "soft", 4) == 0) {
1215 } else if (strnicmp(data, "perm", 4) == 0) {
1217 } else if (strnicmp(data, "noperm", 6) == 0) {
1219 } else if (strnicmp(data, "mapchars", 8) == 0) {
1221 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1223 } else if (strnicmp(data, "sfu", 3) == 0) {
1225 } else if (strnicmp(data, "nosfu", 5) == 0) {
1227 } else if (strnicmp(data, "nodfs", 5) == 0) {
1229 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1230 vol->posix_paths = 1;
1231 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1232 vol->posix_paths = 0;
1233 } else if (strnicmp(data, "nounix", 6) == 0) {
1234 vol->no_linux_ext = 1;
1235 } else if (strnicmp(data, "nolinux", 7) == 0) {
1236 vol->no_linux_ext = 1;
1237 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1238 (strnicmp(data, "ignorecase", 10) == 0)) {
1240 } else if (strnicmp(data, "brl", 3) == 0) {
1242 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1243 (strnicmp(data, "nolock", 6) == 0)) {
1245 /* turn off mandatory locking in mode
1246 if remote locking is turned off since the
1247 local vfs will do advisory */
1248 if (vol->file_mode ==
1249 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1250 vol->file_mode = S_IALLUGO;
1251 } else if (strnicmp(data, "setuids", 7) == 0) {
1253 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1255 } else if (strnicmp(data, "dynperm", 7) == 0) {
1256 vol->dynperm = true;
1257 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1258 vol->dynperm = false;
1259 } else if (strnicmp(data, "nohard", 6) == 0) {
1261 } else if (strnicmp(data, "nosoft", 6) == 0) {
1263 } else if (strnicmp(data, "nointr", 6) == 0) {
1265 } else if (strnicmp(data, "intr", 4) == 0) {
1267 } else if (strnicmp(data, "serverino", 7) == 0) {
1268 vol->server_ino = 1;
1269 } else if (strnicmp(data, "noserverino", 9) == 0) {
1270 vol->server_ino = 0;
1271 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1273 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1275 } else if (strnicmp(data, "acl", 3) == 0) {
1276 vol->no_psx_acl = 0;
1277 } else if (strnicmp(data, "noacl", 5) == 0) {
1278 vol->no_psx_acl = 1;
1279 #ifdef CONFIG_CIFS_EXPERIMENTAL
1280 } else if (strnicmp(data, "locallease", 6) == 0) {
1281 vol->local_lease = 1;
1283 } else if (strnicmp(data, "sign", 4) == 0) {
1284 vol->secFlg |= CIFSSEC_MUST_SIGN;
1285 } else if (strnicmp(data, "seal", 4) == 0) {
1286 /* we do not do the following in secFlags because seal
1287 is a per tree connection (mount) not a per socket
1288 or per-smb connection option in the protocol */
1289 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1291 } else if (strnicmp(data, "direct", 6) == 0) {
1293 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1295 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1296 if (!value || !*value) {
1297 vol->in6_addr = NULL;
1298 } else if (strnlen(value, 49) == 48) {
1299 vol->in6_addr = value;
1301 printk(KERN_WARNING "CIFS: ip v6 address not "
1302 "48 characters long\n");
1305 } else if (strnicmp(data, "noac", 4) == 0) {
1306 printk(KERN_WARNING "CIFS: Mount option noac not "
1307 "supported. Instead set "
1308 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1310 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1313 if (vol->UNC == NULL) {
1314 if (devname == NULL) {
1315 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1319 if ((temp_len = strnlen(devname, 300)) < 300) {
1320 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1321 if (vol->UNC == NULL)
1323 strcpy(vol->UNC, devname);
1324 if (strncmp(vol->UNC, "//", 2) == 0) {
1327 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1328 printk(KERN_WARNING "CIFS: UNC Path does not "
1329 "begin with // or \\\\ \n");
1332 value = strpbrk(vol->UNC+2, "/\\");
1336 printk(KERN_WARNING "CIFS: UNC name too long\n");
1340 if (vol->UNCip == NULL)
1341 vol->UNCip = &vol->UNC[2];
1346 static struct cifsSesInfo *
1347 cifs_find_tcp_session(struct in_addr *target_ip_addr,
1348 struct in6_addr *target_ip6_addr,
1349 char *userName, struct TCP_Server_Info **psrvTcp)
1351 struct list_head *tmp;
1352 struct cifsSesInfo *ses;
1356 read_lock(&GlobalSMBSeslock);
1357 list_for_each(tmp, &GlobalSMBSessionList) {
1358 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1362 if (target_ip_addr &&
1363 ses->server->addr.sockAddr.sin_addr.s_addr != target_ip_addr->s_addr)
1365 else if (target_ip6_addr &&
1366 memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1367 target_ip6_addr, sizeof(*target_ip6_addr)))
1369 /* BB lock server and tcp session; increment use count here?? */
1371 /* found a match on the TCP session */
1372 *psrvTcp = ses->server;
1374 /* BB check if reconnection needed */
1375 if (strncmp(ses->userName, userName, MAX_USERNAME_SIZE) == 0) {
1376 read_unlock(&GlobalSMBSeslock);
1377 /* Found exact match on both TCP and
1381 /* else tcp and smb sessions need reconnection */
1383 read_unlock(&GlobalSMBSeslock);
1388 static struct cifsTconInfo *
1389 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1391 struct list_head *tmp;
1392 struct cifsTconInfo *tcon;
1395 read_lock(&GlobalSMBSeslock);
1397 list_for_each(tmp, &GlobalTreeConnectionList) {
1398 cFYI(1, ("Next tcon"));
1399 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1400 if (!tcon->ses || !tcon->ses->server)
1403 old_ip = tcon->ses->server->addr.sockAddr.sin_addr.s_addr;
1404 cFYI(1, ("old ip addr: %x == new ip %x ?",
1405 old_ip, new_target_ip_addr));
1407 if (old_ip != new_target_ip_addr)
1410 /* BB lock tcon, server, tcp session and increment use count? */
1411 /* found a match on the TCP session */
1412 /* BB check if reconnection needed */
1413 cFYI(1, ("IP match, old UNC: %s new: %s",
1414 tcon->treeName, uncName));
1416 if (strncmp(tcon->treeName, uncName, MAX_TREE_SIZE))
1419 cFYI(1, ("and old usr: %s new: %s",
1420 tcon->treeName, uncName));
1422 if (strncmp(tcon->ses->userName, userName, MAX_USERNAME_SIZE))
1425 /* matched smb session (user name) */
1426 read_unlock(&GlobalSMBSeslock);
1430 read_unlock(&GlobalSMBSeslock);
1435 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1436 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1437 struct dfs_info3_param **preferrals, int remap)
1442 *pnum_referrals = 0;
1445 if (pSesInfo->ipc_tid == 0) {
1446 temp_unc = kmalloc(2 /* for slashes */ +
1447 strnlen(pSesInfo->serverName,
1448 SERVER_NAME_LEN_WITH_NULL * 2)
1449 + 1 + 4 /* slash IPC$ */ + 2,
1451 if (temp_unc == NULL)
1455 strcpy(temp_unc + 2, pSesInfo->serverName);
1456 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1457 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1459 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1463 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1464 pnum_referrals, nls_codepage, remap);
1465 /* BB map targetUNCs to dfs_info3 structures, here or
1466 in CIFSGetDFSRefer BB */
1471 #ifdef CONFIG_DEBUG_LOCK_ALLOC
1472 static struct lock_class_key cifs_key[2];
1473 static struct lock_class_key cifs_slock_key[2];
1476 cifs_reclassify_socket4(struct socket *sock)
1478 struct sock *sk = sock->sk;
1479 BUG_ON(sock_owned_by_user(sk));
1480 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
1481 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
1485 cifs_reclassify_socket6(struct socket *sock)
1487 struct sock *sk = sock->sk;
1488 BUG_ON(sock_owned_by_user(sk));
1489 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
1490 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
1494 cifs_reclassify_socket4(struct socket *sock)
1499 cifs_reclassify_socket6(struct socket *sock)
1504 /* See RFC1001 section 14 on representation of Netbios names */
1505 static void rfc1002mangle(char *target, char *source, unsigned int length)
1509 for (i = 0, j = 0; i < (length); i++) {
1510 /* mask a nibble at a time and encode */
1511 target[j] = 'A' + (0x0F & (source[i] >> 4));
1512 target[j+1] = 'A' + (0x0F & source[i]);
1520 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1521 char *netbios_name, char *target_name)
1525 __be16 orig_port = 0;
1527 if (*csocket == NULL) {
1528 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1529 IPPROTO_TCP, csocket);
1531 cERROR(1, ("Error %d creating socket", rc));
1535 /* BB other socket options to set KEEPALIVE, NODELAY? */
1536 cFYI(1, ("Socket created"));
1537 (*csocket)->sk->sk_allocation = GFP_NOFS;
1538 cifs_reclassify_socket4(*csocket);
1542 psin_server->sin_family = AF_INET;
1543 if (psin_server->sin_port) { /* user overrode default port */
1544 rc = (*csocket)->ops->connect(*csocket,
1545 (struct sockaddr *) psin_server,
1546 sizeof(struct sockaddr_in), 0);
1552 /* save original port so we can retry user specified port
1553 later if fall back ports fail this time */
1554 orig_port = psin_server->sin_port;
1556 /* do not retry on the same port we just failed on */
1557 if (psin_server->sin_port != htons(CIFS_PORT)) {
1558 psin_server->sin_port = htons(CIFS_PORT);
1560 rc = (*csocket)->ops->connect(*csocket,
1561 (struct sockaddr *) psin_server,
1562 sizeof(struct sockaddr_in), 0);
1568 psin_server->sin_port = htons(RFC1001_PORT);
1569 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1571 sizeof(struct sockaddr_in), 0);
1576 /* give up here - unless we want to retry on different
1577 protocol families some day */
1580 psin_server->sin_port = orig_port;
1581 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1582 sock_release(*csocket);
1586 /* Eventually check for other socket options to change from
1587 the default. sock_setsockopt not used because it expects
1588 user space buffer */
1589 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1590 (*csocket)->sk->sk_sndbuf,
1591 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1592 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1593 /* make the bufsizes depend on wsize/rsize and max requests */
1594 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1595 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1596 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1597 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1599 /* send RFC1001 sessinit */
1600 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1601 /* some servers require RFC1001 sessinit before sending
1602 negprot - BB check reconnection in case where second
1603 sessinit is sent but no second negprot */
1604 struct rfc1002_session_packet *ses_init_buf;
1605 struct smb_hdr *smb_buf;
1606 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1609 ses_init_buf->trailer.session_req.called_len = 32;
1610 if (target_name && (target_name[0] != 0)) {
1611 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1614 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1615 DEFAULT_CIFS_CALLED_NAME, 16);
1618 ses_init_buf->trailer.session_req.calling_len = 32;
1619 /* calling name ends in null (byte 16) from old smb
1621 if (netbios_name && (netbios_name[0] != 0)) {
1622 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1625 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1626 "LINUX_CIFS_CLNT", 16);
1628 ses_init_buf->trailer.session_req.scope1 = 0;
1629 ses_init_buf->trailer.session_req.scope2 = 0;
1630 smb_buf = (struct smb_hdr *)ses_init_buf;
1631 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1632 smb_buf->smb_buf_length = 0x81000044;
1633 rc = smb_send(*csocket, smb_buf, 0x44,
1634 (struct sockaddr *)psin_server);
1635 kfree(ses_init_buf);
1636 msleep(1); /* RFC1001 layer in at least one server
1637 requires very short break before negprot
1638 presumably because not expecting negprot
1639 to follow so fast. This is a simple
1640 solution that works without
1641 complicating the code and causes no
1642 significant slowing down on mount
1643 for everyone else */
1645 /* else the negprot may still work without this
1646 even though malloc failed */
1654 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1658 __be16 orig_port = 0;
1660 if (*csocket == NULL) {
1661 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1662 IPPROTO_TCP, csocket);
1664 cERROR(1, ("Error %d creating ipv6 socket", rc));
1668 /* BB other socket options to set KEEPALIVE, NODELAY? */
1669 cFYI(1, ("ipv6 Socket created"));
1670 (*csocket)->sk->sk_allocation = GFP_NOFS;
1671 cifs_reclassify_socket6(*csocket);
1675 psin_server->sin6_family = AF_INET6;
1677 if (psin_server->sin6_port) { /* user overrode default port */
1678 rc = (*csocket)->ops->connect(*csocket,
1679 (struct sockaddr *) psin_server,
1680 sizeof(struct sockaddr_in6), 0);
1686 /* save original port so we can retry user specified port
1687 later if fall back ports fail this time */
1689 orig_port = psin_server->sin6_port;
1690 /* do not retry on the same port we just failed on */
1691 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1692 psin_server->sin6_port = htons(CIFS_PORT);
1694 rc = (*csocket)->ops->connect(*csocket,
1695 (struct sockaddr *) psin_server,
1696 sizeof(struct sockaddr_in6), 0);
1702 psin_server->sin6_port = htons(RFC1001_PORT);
1703 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1704 psin_server, sizeof(struct sockaddr_in6), 0);
1709 /* give up here - unless we want to retry on different
1710 protocol families some day */
1713 psin_server->sin6_port = orig_port;
1714 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1715 sock_release(*csocket);
1719 /* Eventually check for other socket options to change from
1720 the default. sock_setsockopt not used because it expects
1721 user space buffer */
1722 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1727 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1728 struct super_block *sb, struct smb_vol *vol_info)
1730 /* if we are reconnecting then should we check to see if
1731 * any requested capabilities changed locally e.g. via
1732 * remount but we can not do much about it here
1733 * if they have (even if we could detect it by the following)
1734 * Perhaps we could add a backpointer to array of sb from tcon
1735 * or if we change to make all sb to same share the same
1736 * sb as NFS - then we only have one backpointer to sb.
1737 * What if we wanted to mount the server share twice once with
1738 * and once without posixacls or posix paths? */
1739 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1741 if (vol_info && vol_info->no_linux_ext) {
1742 tcon->fsUnixInfo.Capability = 0;
1743 tcon->unix_ext = 0; /* Unix Extensions disabled */
1744 cFYI(1, ("Linux protocol extensions disabled"));
1746 } else if (vol_info)
1747 tcon->unix_ext = 1; /* Unix Extensions supported */
1749 if (tcon->unix_ext == 0) {
1750 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1754 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1755 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1757 /* check for reconnect case in which we do not
1758 want to change the mount behavior if we can avoid it */
1759 if (vol_info == NULL) {
1760 /* turn off POSIX ACL and PATHNAMES if not set
1761 originally at mount time */
1762 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1763 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1764 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
1765 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1766 cERROR(1, ("POSIXPATH support change"));
1767 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1768 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
1769 cERROR(1, ("possible reconnect error"));
1771 ("server disabled POSIX path support"));
1775 cap &= CIFS_UNIX_CAP_MASK;
1776 if (vol_info && vol_info->no_psx_acl)
1777 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1778 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
1779 cFYI(1, ("negotiated posix acl support"));
1781 sb->s_flags |= MS_POSIXACL;
1784 if (vol_info && vol_info->posix_paths == 0)
1785 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1786 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1787 cFYI(1, ("negotiate posix pathnames"));
1789 CIFS_SB(sb)->mnt_cifs_flags |=
1790 CIFS_MOUNT_POSIX_PATHS;
1793 /* We might be setting the path sep back to a different
1794 form if we are reconnecting and the server switched its
1795 posix path capability for this share */
1796 if (sb && (CIFS_SB(sb)->prepathlen > 0))
1797 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1799 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
1800 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
1801 CIFS_SB(sb)->rsize = 127 * 1024;
1803 ("larger reads not supported by srv"));
1808 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
1809 #ifdef CONFIG_CIFS_DEBUG2
1810 if (cap & CIFS_UNIX_FCNTL_CAP)
1811 cFYI(1, ("FCNTL cap"));
1812 if (cap & CIFS_UNIX_EXTATTR_CAP)
1813 cFYI(1, ("EXTATTR cap"));
1814 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1815 cFYI(1, ("POSIX path cap"));
1816 if (cap & CIFS_UNIX_XATTR_CAP)
1817 cFYI(1, ("XATTR cap"));
1818 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
1819 cFYI(1, ("POSIX ACL cap"));
1820 if (cap & CIFS_UNIX_LARGE_READ_CAP)
1821 cFYI(1, ("very large read cap"));
1822 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
1823 cFYI(1, ("very large write cap"));
1824 #endif /* CIFS_DEBUG2 */
1825 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1826 if (vol_info == NULL) {
1827 cFYI(1, ("resetting capabilities failed"));
1829 cERROR(1, ("Negotiating Unix capabilities "
1830 "with the server failed. Consider "
1831 "mounting with the Unix Extensions\n"
1832 "disabled, if problems are found, "
1833 "by specifying the nounix mount "
1841 convert_delimiter(char *path, char delim)
1854 for (i = 0; path[i] != '\0'; i++) {
1855 if (path[i] == old_delim)
1861 kill_cifsd(struct TCP_Server_Info *server)
1863 struct task_struct *task;
1865 task = xchg(&server->tsk, NULL);
1867 force_sig(SIGKILL, task);
1871 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1872 char *mount_data, const char *devname)
1876 int address_type = AF_INET;
1877 struct socket *csocket = NULL;
1878 struct sockaddr_in sin_server;
1879 struct sockaddr_in6 sin_server6;
1880 struct smb_vol volume_info;
1881 struct cifsSesInfo *pSesInfo = NULL;
1882 struct cifsSesInfo *existingCifsSes = NULL;
1883 struct cifsTconInfo *tcon = NULL;
1884 struct TCP_Server_Info *srvTcp = NULL;
1888 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1890 memset(&volume_info, 0, sizeof(struct smb_vol));
1891 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1896 if (volume_info.nullauth) {
1897 cFYI(1, ("null user"));
1898 volume_info.username = "";
1899 } else if (volume_info.username) {
1900 /* BB fixme parse for domain name here */
1901 cFYI(1, ("Username: %s", volume_info.username));
1903 cifserror("No username specified");
1904 /* In userspace mount helper we can get user name from alternate
1905 locations such as env variables and files on disk */
1910 if (volume_info.UNCip && volume_info.UNC) {
1911 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
1912 &sin_server.sin_addr.s_addr);
1915 /* not ipv4 address, try ipv6 */
1916 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
1917 &sin_server6.sin6_addr.in6_u);
1919 address_type = AF_INET6;
1921 address_type = AF_INET;
1925 /* we failed translating address */
1930 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1933 } else if (volume_info.UNCip) {
1934 /* BB using ip addr as server name to connect to the
1936 cERROR(1, ("Connecting to DFS root not implemented yet"));
1939 } else /* which servers DFS root would we conect to */ {
1941 ("CIFS mount error: No UNC path (e.g. -o "
1942 "unc=//192.168.1.100/public) specified"));
1947 /* this is needed for ASCII cp to Unicode converts */
1948 if (volume_info.iocharset == NULL) {
1949 cifs_sb->local_nls = load_nls_default();
1950 /* load_nls_default can not return null */
1952 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1953 if (cifs_sb->local_nls == NULL) {
1954 cERROR(1, ("CIFS mount error: iocharset %s not found",
1955 volume_info.iocharset));
1961 if (address_type == AF_INET)
1962 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1963 NULL /* no ipv6 addr */,
1964 volume_info.username, &srvTcp);
1965 else if (address_type == AF_INET6) {
1966 cFYI(1, ("looking for ipv6 address"));
1967 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1968 &sin_server6.sin6_addr,
1969 volume_info.username, &srvTcp);
1976 cFYI(1, ("Existing tcp session with server found"));
1977 } else { /* create socket */
1978 if (volume_info.port)
1979 sin_server.sin_port = htons(volume_info.port);
1981 sin_server.sin_port = 0;
1982 if (address_type == AF_INET6) {
1983 cFYI(1, ("attempting ipv6 connect"));
1984 /* BB should we allow ipv6 on port 139? */
1985 /* other OS never observed in Wild doing 139 with v6 */
1986 rc = ipv6_connect(&sin_server6, &csocket);
1988 rc = ipv4_connect(&sin_server, &csocket,
1989 volume_info.source_rfc1001_name,
1990 volume_info.target_rfc1001_name);
1992 cERROR(1, ("Error connecting to IPv4 socket. "
1993 "Aborting operation"));
1994 if (csocket != NULL)
1995 sock_release(csocket);
1999 srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
2002 sock_release(csocket);
2005 memcpy(&srvTcp->addr.sockAddr, &sin_server,
2006 sizeof(struct sockaddr_in));
2007 atomic_set(&srvTcp->inFlight, 0);
2008 /* BB Add code for ipv6 case too */
2009 srvTcp->ssocket = csocket;
2010 srvTcp->protocolType = IPV4;
2011 srvTcp->hostname = extract_hostname(volume_info.UNC);
2012 if (IS_ERR(srvTcp->hostname)) {
2013 rc = PTR_ERR(srvTcp->hostname);
2014 sock_release(csocket);
2017 init_waitqueue_head(&srvTcp->response_q);
2018 init_waitqueue_head(&srvTcp->request_q);
2019 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
2020 /* at this point we are the only ones with the pointer
2021 to the struct since the kernel thread not created yet
2022 so no need to spinlock this init of tcpStatus */
2023 srvTcp->tcpStatus = CifsNew;
2024 init_MUTEX(&srvTcp->tcpSem);
2025 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
2026 if (IS_ERR(srvTcp->tsk)) {
2027 rc = PTR_ERR(srvTcp->tsk);
2028 cERROR(1, ("error %d create cifsd thread", rc));
2030 sock_release(csocket);
2031 kfree(srvTcp->hostname);
2035 memcpy(srvTcp->workstation_RFC1001_name,
2036 volume_info.source_rfc1001_name, 16);
2037 memcpy(srvTcp->server_RFC1001_name,
2038 volume_info.target_rfc1001_name, 16);
2039 srvTcp->sequence_number = 0;
2043 if (existingCifsSes) {
2044 pSesInfo = existingCifsSes;
2045 cFYI(1, ("Existing smb sess found (status=%d)",
2047 down(&pSesInfo->sesSem);
2048 if (pSesInfo->status == CifsNeedReconnect) {
2049 cFYI(1, ("Session needs reconnect"));
2050 rc = cifs_setup_session(xid, pSesInfo,
2051 cifs_sb->local_nls);
2053 up(&pSesInfo->sesSem);
2055 cFYI(1, ("Existing smb sess not found"));
2056 pSesInfo = sesInfoAlloc();
2057 if (pSesInfo == NULL)
2060 pSesInfo->server = srvTcp;
2061 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
2062 NIPQUAD(sin_server.sin_addr.s_addr));
2066 /* volume_info.password freed at unmount */
2067 if (volume_info.password) {
2068 pSesInfo->password = volume_info.password;
2069 /* set to NULL to prevent freeing on exit */
2070 volume_info.password = NULL;
2072 if (volume_info.username)
2073 strncpy(pSesInfo->userName,
2074 volume_info.username,
2076 if (volume_info.domainname) {
2077 int len = strlen(volume_info.domainname);
2078 pSesInfo->domainName =
2079 kmalloc(len + 1, GFP_KERNEL);
2080 if (pSesInfo->domainName)
2081 strcpy(pSesInfo->domainName,
2082 volume_info.domainname);
2084 pSesInfo->linux_uid = volume_info.linux_uid;
2085 pSesInfo->overrideSecFlg = volume_info.secFlg;
2086 down(&pSesInfo->sesSem);
2087 /* BB FIXME need to pass vol->secFlgs BB */
2088 rc = cifs_setup_session(xid, pSesInfo,
2089 cifs_sb->local_nls);
2090 up(&pSesInfo->sesSem);
2092 atomic_inc(&srvTcp->socketUseCount);
2096 /* search for existing tcon to this server share */
2098 if (volume_info.rsize > CIFSMaxBufSize) {
2099 cERROR(1, ("rsize %d too large, using MaxBufSize",
2100 volume_info.rsize));
2101 cifs_sb->rsize = CIFSMaxBufSize;
2102 } else if ((volume_info.rsize) &&
2103 (volume_info.rsize <= CIFSMaxBufSize))
2104 cifs_sb->rsize = volume_info.rsize;
2106 cifs_sb->rsize = CIFSMaxBufSize;
2108 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2109 cERROR(1, ("wsize %d too large, using 4096 instead",
2110 volume_info.wsize));
2111 cifs_sb->wsize = 4096;
2112 } else if (volume_info.wsize)
2113 cifs_sb->wsize = volume_info.wsize;
2116 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2118 /* old default of CIFSMaxBufSize was too small now
2119 that SMB Write2 can send multiple pages in kvec.
2120 RFC1001 does not describe what happens when frame
2121 bigger than 128K is sent so use that as max in
2122 conjunction with 52K kvec constraint on arch with 4K
2125 if (cifs_sb->rsize < 2048) {
2126 cifs_sb->rsize = 2048;
2127 /* Windows ME may prefer this */
2128 cFYI(1, ("readsize set to minimum: 2048"));
2130 /* calculate prepath */
2131 cifs_sb->prepath = volume_info.prepath;
2132 if (cifs_sb->prepath) {
2133 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2134 /* we can not convert the / to \ in the path
2135 separators in the prefixpath yet because we do not
2136 know (until reset_cifs_unix_caps is called later)
2137 whether POSIX PATH CAP is available. We normalize
2138 the / to \ after reset_cifs_unix_caps is called */
2139 volume_info.prepath = NULL;
2141 cifs_sb->prepathlen = 0;
2142 cifs_sb->mnt_uid = volume_info.linux_uid;
2143 cifs_sb->mnt_gid = volume_info.linux_gid;
2144 cifs_sb->mnt_file_mode = volume_info.file_mode;
2145 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
2146 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2147 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2149 if (volume_info.noperm)
2150 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2151 if (volume_info.setuids)
2152 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2153 if (volume_info.server_ino)
2154 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2155 if (volume_info.remap)
2156 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2157 if (volume_info.no_xattr)
2158 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2159 if (volume_info.sfu_emul)
2160 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2161 if (volume_info.nobrl)
2162 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2163 if (volume_info.cifs_acl)
2164 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2165 if (volume_info.override_uid)
2166 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2167 if (volume_info.override_gid)
2168 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2169 if (volume_info.dynperm)
2170 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2171 if (volume_info.direct_io) {
2172 cFYI(1, ("mounting share using direct i/o"));
2173 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2176 if ((volume_info.cifs_acl) && (volume_info.dynperm))
2177 cERROR(1, ("mount option dynperm ignored if cifsacl "
2178 "mount option supported"));
2181 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
2182 volume_info.username);
2184 cFYI(1, ("Found match on UNC path"));
2185 /* we can have only one retry value for a connection
2186 to a share so for resources mounted more than once
2187 to the same server share the last value passed in
2188 for the retry flag is used */
2189 tcon->retry = volume_info.retry;
2190 tcon->nocase = volume_info.nocase;
2191 tcon->local_lease = volume_info.local_lease;
2192 if (tcon->seal != volume_info.seal)
2193 cERROR(1, ("transport encryption setting "
2194 "conflicts with existing tid"));
2196 tcon = tconInfoAlloc();
2200 /* check for null share name ie connecting to
2203 /* BB check if this works for exactly length
2205 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2206 && (strchr(volume_info.UNC + 3, '/') ==
2208 /* rc = connect_to_dfs_path(xid, pSesInfo,
2209 "", cifs_sb->local_nls,
2210 cifs_sb->mnt_cifs_flags &
2211 CIFS_MOUNT_MAP_SPECIAL_CHR);*/
2212 cFYI(1, ("DFS root not supported"));
2216 /* BB Do we need to wrap sesSem around
2217 * this TCon call and Unix SetFS as
2218 * we do on SessSetup and reconnect? */
2219 rc = CIFSTCon(xid, pSesInfo,
2221 tcon, cifs_sb->local_nls);
2222 cFYI(1, ("CIFS Tcon rc = %d", rc));
2223 if (volume_info.nodfs) {
2225 ~SMB_SHARE_IS_IN_DFS;
2226 cFYI(1, ("DFS disabled (%d)",
2231 atomic_inc(&pSesInfo->inUse);
2232 tcon->retry = volume_info.retry;
2233 tcon->nocase = volume_info.nocase;
2234 tcon->seal = volume_info.seal;
2240 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2241 sb->s_maxbytes = (u64) 1 << 63;
2243 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2246 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2247 sb->s_time_gran = 100;
2249 /* on error free sesinfo and tcon struct if needed */
2251 /* if session setup failed, use count is zero but
2252 we still need to free cifsd thread */
2253 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2254 spin_lock(&GlobalMid_Lock);
2255 srvTcp->tcpStatus = CifsExiting;
2256 spin_unlock(&GlobalMid_Lock);
2259 /* If find_unc succeeded then rc == 0 so we can not end */
2260 if (tcon) /* up accidently freeing someone elses tcon struct */
2262 if (existingCifsSes == NULL) {
2264 if ((pSesInfo->server) &&
2265 (pSesInfo->status == CifsGood)) {
2267 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2268 /* if the socketUseCount is now zero */
2269 if ((temp_rc == -ESHUTDOWN) &&
2271 kill_cifsd(pSesInfo->server);
2273 cFYI(1, ("No session or bad tcon"));
2274 if (pSesInfo->server) {
2275 spin_lock(&GlobalMid_Lock);
2276 srvTcp->tcpStatus = CifsExiting;
2277 spin_unlock(&GlobalMid_Lock);
2278 kill_cifsd(pSesInfo->server);
2281 sesInfoFree(pSesInfo);
2282 /* pSesInfo = NULL; */
2286 atomic_inc(&tcon->useCount);
2287 cifs_sb->tcon = tcon;
2288 tcon->ses = pSesInfo;
2290 /* do not care if following two calls succeed - informational */
2292 CIFSSMBQFSDeviceInfo(xid, tcon);
2293 CIFSSMBQFSAttributeInfo(xid, tcon);
2296 /* tell server which Unix caps we support */
2297 if (tcon->ses->capabilities & CAP_UNIX)
2298 /* reset of caps checks mount to see if unix extensions
2299 disabled for just this mount */
2300 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2302 tcon->unix_ext = 0; /* server does not support them */
2304 /* convert forward to back slashes in prepath here if needed */
2305 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2306 convert_delimiter(cifs_sb->prepath,
2307 CIFS_DIR_SEP(cifs_sb));
2309 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2310 cifs_sb->rsize = 1024 * 127;
2312 ("no very large read support, rsize now 127K"));
2314 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2315 cifs_sb->wsize = min(cifs_sb->wsize,
2316 (tcon->ses->server->maxBuf -
2317 MAX_CIFS_HDR_SIZE));
2318 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2319 cifs_sb->rsize = min(cifs_sb->rsize,
2320 (tcon->ses->server->maxBuf -
2321 MAX_CIFS_HDR_SIZE));
2324 /* volume_info.password is freed above when existing session found
2325 (in which case it is not needed anymore) but when new sesion is created
2326 the password ptr is put in the new session structure (in which case the
2327 password will be freed at unmount time) */
2329 /* zero out password before freeing */
2330 if (volume_info.password != NULL) {
2331 memset(volume_info.password, 0, strlen(volume_info.password));
2332 kfree(volume_info.password);
2334 kfree(volume_info.UNC);
2335 kfree(volume_info.prepath);
2341 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2342 char session_key[CIFS_SESS_KEY_SIZE],
2343 const struct nls_table *nls_codepage)
2345 struct smb_hdr *smb_buffer;
2346 struct smb_hdr *smb_buffer_response;
2347 SESSION_SETUP_ANDX *pSMB;
2348 SESSION_SETUP_ANDX *pSMBr;
2353 int remaining_words = 0;
2354 int bytes_returned = 0;
2359 cFYI(1, ("In sesssetup"));
2362 user = ses->userName;
2363 domain = ses->domainName;
2364 smb_buffer = cifs_buf_get();
2366 if (smb_buffer == NULL)
2369 smb_buffer_response = smb_buffer;
2370 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2372 /* send SMBsessionSetup here */
2373 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2374 NULL /* no tCon exists yet */ , 13 /* wct */ );
2376 smb_buffer->Mid = GetNextMid(ses->server);
2377 pSMB->req_no_secext.AndXCommand = 0xFF;
2378 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2379 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2381 if (ses->server->secMode &
2382 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2383 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2385 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2386 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2387 if (ses->capabilities & CAP_UNICODE) {
2388 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2389 capabilities |= CAP_UNICODE;
2391 if (ses->capabilities & CAP_STATUS32) {
2392 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2393 capabilities |= CAP_STATUS32;
2395 if (ses->capabilities & CAP_DFS) {
2396 smb_buffer->Flags2 |= SMBFLG2_DFS;
2397 capabilities |= CAP_DFS;
2399 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2401 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2402 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2404 pSMB->req_no_secext.CaseSensitivePasswordLength =
2405 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2406 bcc_ptr = pByteArea(smb_buffer);
2407 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2408 bcc_ptr += CIFS_SESS_KEY_SIZE;
2409 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2410 bcc_ptr += CIFS_SESS_KEY_SIZE;
2412 if (ses->capabilities & CAP_UNICODE) {
2413 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2418 bytes_returned = 0; /* skip null user */
2421 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2423 /* convert number of 16 bit words to bytes */
2424 bcc_ptr += 2 * bytes_returned;
2425 bcc_ptr += 2; /* trailing null */
2428 cifs_strtoUCS((__le16 *) bcc_ptr,
2429 "CIFS_LINUX_DOM", 32, nls_codepage);
2432 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2434 bcc_ptr += 2 * bytes_returned;
2437 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2439 bcc_ptr += 2 * bytes_returned;
2441 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2443 bcc_ptr += 2 * bytes_returned;
2446 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2448 bcc_ptr += 2 * bytes_returned;
2452 strncpy(bcc_ptr, user, 200);
2453 bcc_ptr += strnlen(user, 200);
2457 if (domain == NULL) {
2458 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2459 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2461 strncpy(bcc_ptr, domain, 64);
2462 bcc_ptr += strnlen(domain, 64);
2466 strcpy(bcc_ptr, "Linux version ");
2467 bcc_ptr += strlen("Linux version ");
2468 strcpy(bcc_ptr, utsname()->release);
2469 bcc_ptr += strlen(utsname()->release) + 1;
2470 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2471 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2473 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2474 smb_buffer->smb_buf_length += count;
2475 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2477 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2478 &bytes_returned, CIFS_LONG_OP);
2480 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2481 } else if ((smb_buffer_response->WordCount == 3)
2482 || (smb_buffer_response->WordCount == 4)) {
2483 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2484 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2485 if (action & GUEST_LOGIN)
2486 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2487 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2489 cFYI(1, ("UID = %d ", ses->Suid));
2490 /* response can have either 3 or 4 word count - Samba sends 3 */
2491 bcc_ptr = pByteArea(smb_buffer_response);
2492 if ((pSMBr->resp.hdr.WordCount == 3)
2493 || ((pSMBr->resp.hdr.WordCount == 4)
2494 && (blob_len < pSMBr->resp.ByteCount))) {
2495 if (pSMBr->resp.hdr.WordCount == 4)
2496 bcc_ptr += blob_len;
2498 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2499 if ((long) (bcc_ptr) % 2) {
2501 (BCC(smb_buffer_response) - 1) / 2;
2502 /* Unicode strings must be word
2507 BCC(smb_buffer_response) / 2;
2510 UniStrnlen((wchar_t *) bcc_ptr,
2511 remaining_words - 1);
2512 /* We look for obvious messed up bcc or strings in response so we do not go off
2513 the end since (at least) WIN2K and Windows XP have a major bug in not null
2514 terminating last Unicode string in response */
2516 kfree(ses->serverOS);
2517 ses->serverOS = kzalloc(2 * (len + 1),
2519 if (ses->serverOS == NULL)
2520 goto sesssetup_nomem;
2521 cifs_strfromUCS_le(ses->serverOS,
2524 bcc_ptr += 2 * (len + 1);
2525 remaining_words -= len + 1;
2526 ses->serverOS[2 * len] = 0;
2527 ses->serverOS[1 + (2 * len)] = 0;
2528 if (remaining_words > 0) {
2529 len = UniStrnlen((wchar_t *)bcc_ptr,
2531 kfree(ses->serverNOS);
2532 ses->serverNOS = kzalloc(2 * (len + 1),
2534 if (ses->serverNOS == NULL)
2535 goto sesssetup_nomem;
2536 cifs_strfromUCS_le(ses->serverNOS,
2539 bcc_ptr += 2 * (len + 1);
2540 ses->serverNOS[2 * len] = 0;
2541 ses->serverNOS[1 + (2 * len)] = 0;
2542 if (strncmp(ses->serverNOS,
2543 "NT LAN Manager 4", 16) == 0) {
2544 cFYI(1, ("NT4 server"));
2545 ses->flags |= CIFS_SES_NT4;
2547 remaining_words -= len + 1;
2548 if (remaining_words > 0) {
2549 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2550 /* last string is not always null terminated
2551 (for e.g. for Windows XP & 2000) */
2552 if (ses->serverDomain)
2553 kfree(ses->serverDomain);
2557 if (ses->serverDomain == NULL)
2558 goto sesssetup_nomem;
2559 cifs_strfromUCS_le(ses->serverDomain,
2562 bcc_ptr += 2 * (len + 1);
2563 ses->serverDomain[2*len] = 0;
2564 ses->serverDomain[1+(2*len)] = 0;
2565 } else { /* else no more room so create
2566 dummy domain string */
2567 if (ses->serverDomain)
2568 kfree(ses->serverDomain);
2570 kzalloc(2, GFP_KERNEL);
2572 } else { /* no room so create dummy domain
2575 /* if these kcallocs fail not much we
2576 can do, but better to not fail the
2578 kfree(ses->serverDomain);
2580 kzalloc(2, GFP_KERNEL);
2581 kfree(ses->serverNOS);
2583 kzalloc(2, GFP_KERNEL);
2585 } else { /* ASCII */
2586 len = strnlen(bcc_ptr, 1024);
2587 if (((long) bcc_ptr + len) - (long)
2588 pByteArea(smb_buffer_response)
2589 <= BCC(smb_buffer_response)) {
2590 kfree(ses->serverOS);
2591 ses->serverOS = kzalloc(len + 1,
2593 if (ses->serverOS == NULL)
2594 goto sesssetup_nomem;
2595 strncpy(ses->serverOS, bcc_ptr, len);
2598 /* null terminate the string */
2602 len = strnlen(bcc_ptr, 1024);
2603 kfree(ses->serverNOS);
2604 ses->serverNOS = kzalloc(len + 1,
2606 if (ses->serverNOS == NULL)
2607 goto sesssetup_nomem;
2608 strncpy(ses->serverNOS, bcc_ptr, len);
2613 len = strnlen(bcc_ptr, 1024);
2614 if (ses->serverDomain)
2615 kfree(ses->serverDomain);
2616 ses->serverDomain = kzalloc(len + 1,
2618 if (ses->serverDomain == NULL)
2619 goto sesssetup_nomem;
2620 strncpy(ses->serverDomain, bcc_ptr,
2627 ("Variable field of length %d "
2628 "extends beyond end of smb ",
2633 (" Security Blob Length extends beyond "
2638 (" Invalid Word count %d: ",
2639 smb_buffer_response->WordCount));
2642 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2643 since that could make reconnection harder, and
2644 reconnection might be needed to free memory */
2645 cifs_buf_release(smb_buffer);
2651 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2652 struct cifsSesInfo *ses, bool *pNTLMv2_flag,
2653 const struct nls_table *nls_codepage)
2655 struct smb_hdr *smb_buffer;
2656 struct smb_hdr *smb_buffer_response;
2657 SESSION_SETUP_ANDX *pSMB;
2658 SESSION_SETUP_ANDX *pSMBr;
2662 int remaining_words = 0;
2663 int bytes_returned = 0;
2665 int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
2666 PNEGOTIATE_MESSAGE SecurityBlob;
2667 PCHALLENGE_MESSAGE SecurityBlob2;
2668 __u32 negotiate_flags, capabilities;
2671 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2674 domain = ses->domainName;
2675 *pNTLMv2_flag = false;
2676 smb_buffer = cifs_buf_get();
2677 if (smb_buffer == NULL) {
2680 smb_buffer_response = smb_buffer;
2681 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2682 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2684 /* send SMBsessionSetup here */
2685 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2686 NULL /* no tCon exists yet */ , 12 /* wct */ );
2688 smb_buffer->Mid = GetNextMid(ses->server);
2689 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2690 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2692 pSMB->req.AndXCommand = 0xFF;
2693 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2694 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2696 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2697 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2699 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2700 CAP_EXTENDED_SECURITY;
2701 if (ses->capabilities & CAP_UNICODE) {
2702 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2703 capabilities |= CAP_UNICODE;
2705 if (ses->capabilities & CAP_STATUS32) {
2706 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2707 capabilities |= CAP_STATUS32;
2709 if (ses->capabilities & CAP_DFS) {
2710 smb_buffer->Flags2 |= SMBFLG2_DFS;
2711 capabilities |= CAP_DFS;
2713 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2715 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2716 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2717 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2718 SecurityBlob->MessageType = NtLmNegotiate;
2720 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2721 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2722 NTLMSSP_NEGOTIATE_56 |
2723 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2725 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2726 /* if (ntlmv2_support)
2727 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2728 /* setup pointers to domain name and workstation name */
2729 bcc_ptr += SecurityBlobLength;
2731 SecurityBlob->WorkstationName.Buffer = 0;
2732 SecurityBlob->WorkstationName.Length = 0;
2733 SecurityBlob->WorkstationName.MaximumLength = 0;
2735 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2736 along with username on auth request (ie the response to challenge) */
2737 SecurityBlob->DomainName.Buffer = 0;
2738 SecurityBlob->DomainName.Length = 0;
2739 SecurityBlob->DomainName.MaximumLength = 0;
2740 if (ses->capabilities & CAP_UNICODE) {
2741 if ((long) bcc_ptr % 2) {
2747 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2749 bcc_ptr += 2 * bytes_returned;
2751 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2753 bcc_ptr += 2 * bytes_returned;
2754 bcc_ptr += 2; /* null terminate Linux version */
2756 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2758 bcc_ptr += 2 * bytes_returned;
2761 bcc_ptr += 2; /* null terminate network opsys string */
2764 bcc_ptr += 2; /* null domain */
2765 } else { /* ASCII */
2766 strcpy(bcc_ptr, "Linux version ");
2767 bcc_ptr += strlen("Linux version ");
2768 strcpy(bcc_ptr, utsname()->release);
2769 bcc_ptr += strlen(utsname()->release) + 1;
2770 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2771 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2772 bcc_ptr++; /* empty domain field */
2775 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2776 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2777 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2778 smb_buffer->smb_buf_length += count;
2779 pSMB->req.ByteCount = cpu_to_le16(count);
2781 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2782 &bytes_returned, CIFS_LONG_OP);
2784 if (smb_buffer_response->Status.CifsError ==
2785 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2789 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2790 } else if ((smb_buffer_response->WordCount == 3)
2791 || (smb_buffer_response->WordCount == 4)) {
2792 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2793 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2795 if (action & GUEST_LOGIN)
2796 cFYI(1, (" Guest login"));
2797 /* Do we want to set anything in SesInfo struct when guest login? */
2799 bcc_ptr = pByteArea(smb_buffer_response);
2800 /* response can have either 3 or 4 word count - Samba sends 3 */
2802 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2803 if (SecurityBlob2->MessageType != NtLmChallenge) {
2805 ("Unexpected NTLMSSP message type received %d",
2806 SecurityBlob2->MessageType));
2808 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2809 cFYI(1, ("UID = %d", ses->Suid));
2810 if ((pSMBr->resp.hdr.WordCount == 3)
2811 || ((pSMBr->resp.hdr.WordCount == 4)
2813 pSMBr->resp.ByteCount))) {
2815 if (pSMBr->resp.hdr.WordCount == 4) {
2816 bcc_ptr += blob_len;
2817 cFYI(1, ("Security Blob Length %d",
2821 cFYI(1, ("NTLMSSP Challenge rcvd"));
2823 memcpy(ses->server->cryptKey,
2824 SecurityBlob2->Challenge,
2825 CIFS_CRYPTO_KEY_SIZE);
2826 if (SecurityBlob2->NegotiateFlags &
2827 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2828 *pNTLMv2_flag = true;
2830 if ((SecurityBlob2->NegotiateFlags &
2831 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2832 || (sign_CIFS_PDUs > 1))
2833 ses->server->secMode |=
2834 SECMODE_SIGN_REQUIRED;
2835 if ((SecurityBlob2->NegotiateFlags &
2836 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2837 ses->server->secMode |=
2838 SECMODE_SIGN_ENABLED;
2840 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2841 if ((long) (bcc_ptr) % 2) {
2843 (BCC(smb_buffer_response)
2845 /* Must word align unicode strings */
2850 (smb_buffer_response) / 2;
2853 UniStrnlen((wchar_t *) bcc_ptr,
2854 remaining_words - 1);
2855 /* We look for obvious messed up bcc or strings in response so we do not go off
2856 the end since (at least) WIN2K and Windows XP have a major bug in not null
2857 terminating last Unicode string in response */
2859 kfree(ses->serverOS);
2861 kzalloc(2 * (len + 1), GFP_KERNEL);
2862 cifs_strfromUCS_le(ses->serverOS,
2866 bcc_ptr += 2 * (len + 1);
2867 remaining_words -= len + 1;
2868 ses->serverOS[2 * len] = 0;
2869 ses->serverOS[1 + (2 * len)] = 0;
2870 if (remaining_words > 0) {
2871 len = UniStrnlen((wchar_t *)
2875 kfree(ses->serverNOS);
2877 kzalloc(2 * (len + 1),
2879 cifs_strfromUCS_le(ses->
2885 bcc_ptr += 2 * (len + 1);
2886 ses->serverNOS[2 * len] = 0;
2889 remaining_words -= len + 1;
2890 if (remaining_words > 0) {
2891 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2892 /* last string not always null terminated
2893 (for e.g. for Windows XP & 2000) */
2894 kfree(ses->serverDomain);
2906 ses->serverDomain[2*len]
2911 } /* else no more room so create dummy domain string */
2913 kfree(ses->serverDomain);
2918 } else { /* no room so create dummy domain and NOS string */
2919 kfree(ses->serverDomain);
2921 kzalloc(2, GFP_KERNEL);
2922 kfree(ses->serverNOS);
2924 kzalloc(2, GFP_KERNEL);
2926 } else { /* ASCII */
2927 len = strnlen(bcc_ptr, 1024);
2928 if (((long) bcc_ptr + len) - (long)
2929 pByteArea(smb_buffer_response)
2930 <= BCC(smb_buffer_response)) {
2932 kfree(ses->serverOS);
2936 strncpy(ses->serverOS,
2940 bcc_ptr[0] = 0; /* null terminate string */
2943 len = strnlen(bcc_ptr, 1024);
2944 kfree(ses->serverNOS);
2948 strncpy(ses->serverNOS, bcc_ptr, len);
2953 len = strnlen(bcc_ptr, 1024);
2954 kfree(ses->serverDomain);
2958 strncpy(ses->serverDomain,
2965 ("field of length %d "
2966 "extends beyond end of smb",
2970 cERROR(1, ("Security Blob Length extends beyond"
2974 cERROR(1, ("No session structure passed in."));
2978 (" Invalid Word count %d:",
2979 smb_buffer_response->WordCount));
2983 cifs_buf_release(smb_buffer);
2988 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2989 char *ntlm_session_key, bool ntlmv2_flag,
2990 const struct nls_table *nls_codepage)
2992 struct smb_hdr *smb_buffer;
2993 struct smb_hdr *smb_buffer_response;
2994 SESSION_SETUP_ANDX *pSMB;
2995 SESSION_SETUP_ANDX *pSMBr;
3000 int remaining_words = 0;
3001 int bytes_returned = 0;
3003 int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
3004 PAUTHENTICATE_MESSAGE SecurityBlob;
3005 __u32 negotiate_flags, capabilities;
3008 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
3011 user = ses->userName;
3012 domain = ses->domainName;
3013 smb_buffer = cifs_buf_get();
3014 if (smb_buffer == NULL) {
3017 smb_buffer_response = smb_buffer;
3018 pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
3019 pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
3021 /* send SMBsessionSetup here */
3022 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
3023 NULL /* no tCon exists yet */ , 12 /* wct */ );
3025 smb_buffer->Mid = GetNextMid(ses->server);
3026 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
3027 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
3028 pSMB->req.AndXCommand = 0xFF;
3029 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
3030 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
3032 pSMB->req.hdr.Uid = ses->Suid;
3034 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3035 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3037 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
3038 CAP_EXTENDED_SECURITY;
3039 if (ses->capabilities & CAP_UNICODE) {
3040 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3041 capabilities |= CAP_UNICODE;
3043 if (ses->capabilities & CAP_STATUS32) {
3044 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3045 capabilities |= CAP_STATUS32;
3047 if (ses->capabilities & CAP_DFS) {
3048 smb_buffer->Flags2 |= SMBFLG2_DFS;
3049 capabilities |= CAP_DFS;
3051 pSMB->req.Capabilities = cpu_to_le32(capabilities);
3053 bcc_ptr = (char *)&pSMB->req.SecurityBlob;
3054 SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
3055 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
3056 SecurityBlob->MessageType = NtLmAuthenticate;
3057 bcc_ptr += SecurityBlobLength;
3058 negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
3059 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
3060 0x80000000 | NTLMSSP_NEGOTIATE_128;
3062 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
3064 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
3066 /* setup pointers to domain name and workstation name */
3068 SecurityBlob->WorkstationName.Buffer = 0;
3069 SecurityBlob->WorkstationName.Length = 0;
3070 SecurityBlob->WorkstationName.MaximumLength = 0;
3071 SecurityBlob->SessionKey.Length = 0;
3072 SecurityBlob->SessionKey.MaximumLength = 0;
3073 SecurityBlob->SessionKey.Buffer = 0;
3075 SecurityBlob->LmChallengeResponse.Length = 0;
3076 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
3077 SecurityBlob->LmChallengeResponse.Buffer = 0;
3079 SecurityBlob->NtChallengeResponse.Length =
3080 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3081 SecurityBlob->NtChallengeResponse.MaximumLength =
3082 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3083 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
3084 SecurityBlob->NtChallengeResponse.Buffer =
3085 cpu_to_le32(SecurityBlobLength);
3086 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
3087 bcc_ptr += CIFS_SESS_KEY_SIZE;
3089 if (ses->capabilities & CAP_UNICODE) {
3090 if (domain == NULL) {
3091 SecurityBlob->DomainName.Buffer = 0;
3092 SecurityBlob->DomainName.Length = 0;
3093 SecurityBlob->DomainName.MaximumLength = 0;
3095 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
3098 SecurityBlob->DomainName.MaximumLength =
3100 SecurityBlob->DomainName.Buffer =
3101 cpu_to_le32(SecurityBlobLength);
3103 SecurityBlobLength += ln;
3104 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3107 SecurityBlob->UserName.Buffer = 0;
3108 SecurityBlob->UserName.Length = 0;
3109 SecurityBlob->UserName.MaximumLength = 0;
3111 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
3114 SecurityBlob->UserName.MaximumLength =
3116 SecurityBlob->UserName.Buffer =
3117 cpu_to_le32(SecurityBlobLength);
3119 SecurityBlobLength += ln;
3120 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3123 /* SecurityBlob->WorkstationName.Length =
3124 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3125 SecurityBlob->WorkstationName.Length *= 2;
3126 SecurityBlob->WorkstationName.MaximumLength =
3127 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3128 SecurityBlob->WorkstationName.Buffer =
3129 cpu_to_le32(SecurityBlobLength);
3130 bcc_ptr += SecurityBlob->WorkstationName.Length;
3131 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3132 SecurityBlob->WorkstationName.Length =
3133 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3135 if ((long) bcc_ptr % 2) {
3140 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3142 bcc_ptr += 2 * bytes_returned;
3144 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3146 bcc_ptr += 2 * bytes_returned;
3147 bcc_ptr += 2; /* null term version string */
3149 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3151 bcc_ptr += 2 * bytes_returned;
3154 bcc_ptr += 2; /* null terminate network opsys string */
3157 bcc_ptr += 2; /* null domain */
3158 } else { /* ASCII */
3159 if (domain == NULL) {
3160 SecurityBlob->DomainName.Buffer = 0;
3161 SecurityBlob->DomainName.Length = 0;
3162 SecurityBlob->DomainName.MaximumLength = 0;
3165 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3166 strncpy(bcc_ptr, domain, 63);
3167 ln = strnlen(domain, 64);
3168 SecurityBlob->DomainName.MaximumLength =
3170 SecurityBlob->DomainName.Buffer =
3171 cpu_to_le32(SecurityBlobLength);
3173 SecurityBlobLength += ln;
3174 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3177 SecurityBlob->UserName.Buffer = 0;
3178 SecurityBlob->UserName.Length = 0;
3179 SecurityBlob->UserName.MaximumLength = 0;
3182 strncpy(bcc_ptr, user, 63);
3183 ln = strnlen(user, 64);
3184 SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
3185 SecurityBlob->UserName.Buffer =
3186 cpu_to_le32(SecurityBlobLength);
3188 SecurityBlobLength += ln;
3189 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3191 /* BB fill in our workstation name if known BB */
3193 strcpy(bcc_ptr, "Linux version ");
3194 bcc_ptr += strlen("Linux version ");
3195 strcpy(bcc_ptr, utsname()->release);
3196 bcc_ptr += strlen(utsname()->release) + 1;
3197 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3198 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3199 bcc_ptr++; /* null domain */
3202 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3203 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3204 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3205 smb_buffer->smb_buf_length += count;
3206 pSMB->req.ByteCount = cpu_to_le16(count);
3208 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3209 &bytes_returned, CIFS_LONG_OP);
3211 /* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3212 } else if ((smb_buffer_response->WordCount == 3) ||
3213 (smb_buffer_response->WordCount == 4)) {
3214 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3215 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3216 if (action & GUEST_LOGIN)
3217 cFYI(1, (" Guest login")); /* BB Should we set anything
3218 in SesInfo struct ? */
3219 /* if (SecurityBlob2->MessageType != NtLm??) {
3220 cFYI("Unexpected message type on auth response is %d"));
3225 ("Check challenge UID %d vs auth response UID %d",
3226 ses->Suid, smb_buffer_response->Uid));
3227 /* UID left in wire format */
3228 ses->Suid = smb_buffer_response->Uid;
3229 bcc_ptr = pByteArea(smb_buffer_response);
3230 /* response can have either 3 or 4 word count - Samba sends 3 */
3231 if ((pSMBr->resp.hdr.WordCount == 3)
3232 || ((pSMBr->resp.hdr.WordCount == 4)
3234 pSMBr->resp.ByteCount))) {
3235 if (pSMBr->resp.hdr.WordCount == 4) {
3239 ("Security Blob Length %d ",
3244 ("NTLMSSP response to Authenticate "));
3246 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3247 if ((long) (bcc_ptr) % 2) {
3249 (BCC(smb_buffer_response)
3251 bcc_ptr++; /* Unicode strings must be word aligned */
3253 remaining_words = BCC(smb_buffer_response) / 2;
3255 len = UniStrnlen((wchar_t *) bcc_ptr,
3256 remaining_words - 1);
3257 /* We look for obvious messed up bcc or strings in response so we do not go off
3258 the end since (at least) WIN2K and Windows XP have a major bug in not null
3259 terminating last Unicode string in response */
3261 kfree(ses->serverOS);
3263 kzalloc(2 * (len + 1), GFP_KERNEL);
3264 cifs_strfromUCS_le(ses->serverOS,
3268 bcc_ptr += 2 * (len + 1);
3269 remaining_words -= len + 1;
3270 ses->serverOS[2 * len] = 0;
3271 ses->serverOS[1 + (2 * len)] = 0;
3272 if (remaining_words > 0) {
3273 len = UniStrnlen((wchar_t *)
3277 kfree(ses->serverNOS);
3279 kzalloc(2 * (len + 1),
3281 cifs_strfromUCS_le(ses->
3287 bcc_ptr += 2 * (len + 1);
3288 ses->serverNOS[2 * len] = 0;
3289 ses->serverNOS[1+(2*len)] = 0;
3290 remaining_words -= len + 1;
3291 if (remaining_words > 0) {
3292 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3293 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3294 if (ses->serverDomain)
3295 kfree(ses->serverDomain);
3320 } /* else no more room so create dummy domain string */
3322 if (ses->serverDomain)
3323 kfree(ses->serverDomain);
3324 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3326 } else { /* no room so create dummy domain and NOS string */
3327 if (ses->serverDomain)
3328 kfree(ses->serverDomain);
3329 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3330 kfree(ses->serverNOS);
3331 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3333 } else { /* ASCII */
3334 len = strnlen(bcc_ptr, 1024);
3335 if (((long) bcc_ptr + len) -
3336 (long) pByteArea(smb_buffer_response)
3337 <= BCC(smb_buffer_response)) {
3339 kfree(ses->serverOS);
3340 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
3341 strncpy(ses->serverOS,bcc_ptr, len);
3344 bcc_ptr[0] = 0; /* null terminate the string */
3347 len = strnlen(bcc_ptr, 1024);
3348 kfree(ses->serverNOS);
3349 ses->serverNOS = kzalloc(len+1,
3351 strncpy(ses->serverNOS,
3357 len = strnlen(bcc_ptr, 1024);
3358 if (ses->serverDomain)
3359 kfree(ses->serverDomain);
3363 strncpy(ses->serverDomain,
3369 cFYI(1, ("field of length %d "
3370 "extends beyond end of smb ",
3374 cERROR(1, ("Security Blob extends beyond end "
3378 cERROR(1, ("No session structure passed in."));
3381 cERROR(1, ("Invalid Word count %d: ",
3382 smb_buffer_response->WordCount));
3386 cifs_buf_release(smb_buffer);
3392 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3393 const char *tree, struct cifsTconInfo *tcon,
3394 const struct nls_table *nls_codepage)
3396 struct smb_hdr *smb_buffer;
3397 struct smb_hdr *smb_buffer_response;
3400 unsigned char *bcc_ptr;
3408 smb_buffer = cifs_buf_get();
3409 if (smb_buffer == NULL) {
3412 smb_buffer_response = smb_buffer;
3414 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3415 NULL /*no tid */ , 4 /*wct */ );
3417 smb_buffer->Mid = GetNextMid(ses->server);
3418 smb_buffer->Uid = ses->Suid;
3419 pSMB = (TCONX_REQ *) smb_buffer;
3420 pSMBr = (TCONX_RSP *) smb_buffer_response;
3422 pSMB->AndXCommand = 0xFF;
3423 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3424 bcc_ptr = &pSMB->Password[0];
3425 if ((ses->server->secMode) & SECMODE_USER) {
3426 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3427 *bcc_ptr = 0; /* password is null byte */
3428 bcc_ptr++; /* skip password */
3429 /* already aligned so no need to do it below */
3431 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3432 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3433 specified as required (when that support is added to
3434 the vfs in the future) as only NTLM or the much
3435 weaker LANMAN (which we do not send by default) is accepted
3436 by Samba (not sure whether other servers allow
3437 NTLMv2 password here) */
3438 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3439 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3440 (ses->server->secType == LANMAN))
3441 calc_lanman_hash(ses, bcc_ptr);
3443 #endif /* CIFS_WEAK_PW_HASH */
3444 SMBNTencrypt(ses->password,
3445 ses->server->cryptKey,
3448 bcc_ptr += CIFS_SESS_KEY_SIZE;
3449 if (ses->capabilities & CAP_UNICODE) {
3450 /* must align unicode strings */
3451 *bcc_ptr = 0; /* null byte password */
3456 if (ses->server->secMode &
3457 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3458 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3460 if (ses->capabilities & CAP_STATUS32) {
3461 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3463 if (ses->capabilities & CAP_DFS) {
3464 smb_buffer->Flags2 |= SMBFLG2_DFS;
3466 if (ses->capabilities & CAP_UNICODE) {
3467 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3469 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3470 6 /* max utf8 char length in bytes */ *
3471 (/* server len*/ + 256 /* share len */), nls_codepage);
3472 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3473 bcc_ptr += 2; /* skip trailing null */
3474 } else { /* ASCII */
3475 strcpy(bcc_ptr, tree);
3476 bcc_ptr += strlen(tree) + 1;
3478 strcpy(bcc_ptr, "?????");
3479 bcc_ptr += strlen("?????");
3481 count = bcc_ptr - &pSMB->Password[0];
3482 pSMB->hdr.smb_buf_length += count;
3483 pSMB->ByteCount = cpu_to_le16(count);
3485 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3488 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3489 /* above now done in SendReceive */
3490 if ((rc == 0) && (tcon != NULL)) {
3491 tcon->tidStatus = CifsGood;
3492 tcon->tid = smb_buffer_response->Tid;
3493 bcc_ptr = pByteArea(smb_buffer_response);
3494 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3495 /* skip service field (NB: this field is always ASCII) */
3497 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3498 (bcc_ptr[2] == 'C')) {
3499 cFYI(1, ("IPC connection"));
3502 } else if (length == 2) {
3503 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3504 /* the most common case */
3505 cFYI(1, ("disk share connection"));
3508 bcc_ptr += length + 1;
3509 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3510 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3511 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3512 if ((bcc_ptr + (2 * length)) -
3513 pByteArea(smb_buffer_response) <=
3514 BCC(smb_buffer_response)) {
3515 kfree(tcon->nativeFileSystem);
3516 tcon->nativeFileSystem =
3517 kzalloc(length + 2, GFP_KERNEL);
3518 if (tcon->nativeFileSystem)
3520 tcon->nativeFileSystem,
3522 length, nls_codepage);
3523 bcc_ptr += 2 * length;
3524 bcc_ptr[0] = 0; /* null terminate the string */
3528 /* else do not bother copying these information fields*/
3530 length = strnlen(bcc_ptr, 1024);
3531 if ((bcc_ptr + length) -
3532 pByteArea(smb_buffer_response) <=
3533 BCC(smb_buffer_response)) {
3534 kfree(tcon->nativeFileSystem);
3535 tcon->nativeFileSystem =
3536 kzalloc(length + 1, GFP_KERNEL);
3537 if (tcon->nativeFileSystem)
3538 strncpy(tcon->nativeFileSystem, bcc_ptr,
3541 /* else do not bother copying these information fields*/
3543 if ((smb_buffer_response->WordCount == 3) ||
3544 (smb_buffer_response->WordCount == 7))
3545 /* field is in same location */
3546 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3549 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3550 } else if ((rc == 0) && tcon == NULL) {
3551 /* all we need to save for IPC$ connection */
3552 ses->ipc_tid = smb_buffer_response->Tid;
3555 cifs_buf_release(smb_buffer);
3560 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3564 struct cifsSesInfo *ses = NULL;
3569 if (cifs_sb->tcon) {
3570 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3571 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3576 DeleteTconOplockQEntries(cifs_sb->tcon);
3577 tconInfoFree(cifs_sb->tcon);
3578 if ((ses) && (ses->server)) {
3579 /* save off task so we do not refer to ses later */
3580 cFYI(1, ("About to do SMBLogoff "));
3581 rc = CIFSSMBLogoff(xid, ses);
3585 } else if (rc == -ESHUTDOWN) {
3586 cFYI(1, ("Waking up socket by sending signal"));
3588 kill_cifsd(ses->server);
3590 } /* else - we have an smb session
3591 left on this socket do not kill cifsd */
3593 cFYI(1, ("No session or bad tcon"));
3596 cifs_sb->tcon = NULL;
3597 tmp = cifs_sb->prepath;
3598 cifs_sb->prepathlen = 0;
3599 cifs_sb->prepath = NULL;
3608 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3609 struct nls_table *nls_info)
3612 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3613 bool ntlmv2_flag = false;
3615 struct TCP_Server_Info *server = pSesInfo->server;
3617 /* what if server changes its buffer size after dropping the session? */
3618 if (server->maxBuf == 0) /* no need to send on reconnect */ {
3619 rc = CIFSSMBNegotiate(xid, pSesInfo);
3620 if (rc == -EAGAIN) {
3621 /* retry only once on 1st time connection */
3622 rc = CIFSSMBNegotiate(xid, pSesInfo);
3627 spin_lock(&GlobalMid_Lock);
3628 if (server->tcpStatus != CifsExiting)
3629 server->tcpStatus = CifsGood;
3632 spin_unlock(&GlobalMid_Lock);
3641 pSesInfo->flags = 0;
3642 pSesInfo->capabilities = server->capabilities;
3643 if (linuxExtEnabled == 0)
3644 pSesInfo->capabilities &= (~CAP_UNIX);
3645 /* pSesInfo->sequence_number = 0;*/
3646 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3647 server->secMode, server->capabilities, server->timeAdj));
3649 if (experimEnabled < 2)
3650 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
3651 else if (extended_security
3652 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3653 && (server->secType == NTLMSSP)) {
3655 } else if (extended_security
3656 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3657 && (server->secType == RawNTLMSSP)) {
3658 cFYI(1, ("NTLMSSP sesssetup"));
3659 rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag,
3664 cFYI(1, ("more secure NTLM ver2 hash"));
3665 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3670 v2_response = kmalloc(16 + 64 /* blob*/,
3673 CalcNTLMv2_response(pSesInfo,
3676 cifs_calculate_ntlmv2_mac_key */
3678 /* BB Put dummy sig in SessSetup PDU? */
3685 SMBNTencrypt(pSesInfo->password,
3690 cifs_calculate_mac_key(
3691 &server->mac_signing_key,
3693 pSesInfo->password);
3695 /* for better security the weaker lanman hash not sent
3696 in AuthSessSetup so we no longer calculate it */
3698 rc = CIFSNTLMSSPAuthSessSetup(xid, pSesInfo,
3703 } else { /* old style NTLM 0.12 session setup */
3704 SMBNTencrypt(pSesInfo->password, server->cryptKey,
3708 cifs_calculate_mac_key(&server->mac_signing_key,
3710 pSesInfo->password);
3712 rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info);
3715 cERROR(1, ("Send error in SessSetup = %d", rc));
3717 cFYI(1, ("CIFS Session Established successfully"));
3718 spin_lock(&GlobalMid_Lock);
3719 pSesInfo->status = CifsGood;
3720 spin_unlock(&GlobalMid_Lock);