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 */
97 unsigned short int port;
101 static int ipv4_connect(struct sockaddr_in *psin_server,
102 struct socket **csocket,
104 char *server_netb_name);
105 static int ipv6_connect(struct sockaddr_in6 *psin_server,
106 struct socket **csocket);
110 * cifs tcp session reconnection
112 * mark tcp session as reconnecting so temporarily locked
113 * mark all smb sessions as reconnecting for tcp session
114 * reconnect tcp session
115 * wake up waiters on reconnection? - (not needed currently)
119 cifs_reconnect(struct TCP_Server_Info *server)
122 struct list_head *tmp;
123 struct cifsSesInfo *ses;
124 struct cifsTconInfo *tcon;
125 struct mid_q_entry *mid_entry;
127 spin_lock(&GlobalMid_Lock);
128 if (server->tcpStatus == CifsExiting) {
129 /* the demux thread will exit normally
130 next time through the loop */
131 spin_unlock(&GlobalMid_Lock);
134 server->tcpStatus = CifsNeedReconnect;
135 spin_unlock(&GlobalMid_Lock);
138 cFYI(1, ("Reconnecting tcp session"));
140 /* before reconnecting the tcp session, mark the smb session (uid)
141 and the tid bad so they are not used until reconnected */
142 read_lock(&GlobalSMBSeslock);
143 list_for_each(tmp, &GlobalSMBSessionList) {
144 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
146 if (ses->server == server) {
147 ses->status = CifsNeedReconnect;
151 /* else tcp and smb sessions need reconnection */
153 list_for_each(tmp, &GlobalTreeConnectionList) {
154 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
155 if ((tcon->ses) && (tcon->ses->server == server))
156 tcon->tidStatus = CifsNeedReconnect;
158 read_unlock(&GlobalSMBSeslock);
159 /* do not want to be sending data on a socket we are freeing */
160 down(&server->tcpSem);
161 if (server->ssocket) {
162 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
163 server->ssocket->flags));
164 kernel_sock_shutdown(server->ssocket, SHUT_WR);
165 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
166 server->ssocket->state,
167 server->ssocket->flags));
168 sock_release(server->ssocket);
169 server->ssocket = NULL;
172 spin_lock(&GlobalMid_Lock);
173 list_for_each(tmp, &server->pending_mid_q) {
174 mid_entry = list_entry(tmp, struct
177 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
178 /* Mark other intransit requests as needing
179 retry so we do not immediately mark the
180 session bad again (ie after we reconnect
181 below) as they timeout too */
182 mid_entry->midState = MID_RETRY_NEEDED;
185 spin_unlock(&GlobalMid_Lock);
188 while ((server->tcpStatus != CifsExiting) &&
189 (server->tcpStatus != CifsGood)) {
191 if (server->protocolType == IPV6) {
192 rc = ipv6_connect(&server->addr.sockAddr6,
195 rc = ipv4_connect(&server->addr.sockAddr,
197 server->workstation_RFC1001_name,
198 server->server_RFC1001_name);
201 cFYI(1, ("reconnect error %d", rc));
204 atomic_inc(&tcpSesReconnectCount);
205 spin_lock(&GlobalMid_Lock);
206 if (server->tcpStatus != CifsExiting)
207 server->tcpStatus = CifsGood;
208 server->sequence_number = 0;
209 spin_unlock(&GlobalMid_Lock);
210 /* atomic_set(&server->inFlight,0);*/
211 wake_up(&server->response_q);
219 0 not a transact2, or all data present
220 >0 transact2 with that much data missing
221 -EINVAL = invalid transact2
224 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
226 struct smb_t2_rsp *pSMBt;
228 int data_in_this_rsp;
231 if (pSMB->Command != SMB_COM_TRANSACTION2)
234 /* check for plausible wct, bcc and t2 data and parm sizes */
235 /* check for parm and data offset going beyond end of smb */
236 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
237 cFYI(1, ("invalid transact2 word count"));
241 pSMBt = (struct smb_t2_rsp *)pSMB;
243 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
244 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
246 remaining = total_data_size - data_in_this_rsp;
250 else if (remaining < 0) {
251 cFYI(1, ("total data %d smaller than data in frame %d",
252 total_data_size, data_in_this_rsp));
255 cFYI(1, ("missing %d bytes from transact2, check next response",
257 if (total_data_size > maxBufSize) {
258 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
259 total_data_size, maxBufSize));
266 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
268 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
269 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
274 char *data_area_of_target;
275 char *data_area_of_buf2;
278 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
280 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
281 cFYI(1, ("total data size of primary and secondary t2 differ"));
284 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
286 remaining = total_data_size - total_in_buf;
291 if (remaining == 0) /* nothing to do, ignore */
294 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
295 if (remaining < total_in_buf2) {
296 cFYI(1, ("transact2 2nd response contains too much data"));
299 /* find end of first SMB data area */
300 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
301 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
302 /* validate target area */
304 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
305 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
307 data_area_of_target += total_in_buf;
309 /* copy second buffer into end of first buffer */
310 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
311 total_in_buf += total_in_buf2;
312 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
313 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
314 byte_count += total_in_buf2;
315 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
317 byte_count = pTargetSMB->smb_buf_length;
318 byte_count += total_in_buf2;
320 /* BB also add check that we are not beyond maximum buffer size */
322 pTargetSMB->smb_buf_length = byte_count;
324 if (remaining == total_in_buf2) {
325 cFYI(1, ("found the last secondary response"));
326 return 0; /* we are done */
327 } else /* more responses to go */
333 cifs_demultiplex_thread(struct TCP_Server_Info *server)
336 unsigned int pdu_length, total_read;
337 struct smb_hdr *smb_buffer = NULL;
338 struct smb_hdr *bigbuf = NULL;
339 struct smb_hdr *smallbuf = NULL;
340 struct msghdr smb_msg;
342 struct socket *csocket = server->ssocket;
343 struct list_head *tmp;
344 struct cifsSesInfo *ses;
345 struct task_struct *task_to_wake = NULL;
346 struct mid_q_entry *mid_entry;
348 bool isLargeBuf = false;
352 current->flags |= PF_MEMALLOC;
353 cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
355 length = atomic_inc_return(&tcpSesAllocCount);
357 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
361 while (server->tcpStatus != CifsExiting) {
364 if (bigbuf == NULL) {
365 bigbuf = cifs_buf_get();
367 cERROR(1, ("No memory for large SMB response"));
369 /* retry will check if exiting */
372 } else if (isLargeBuf) {
373 /* we are reusing a dirty large buf, clear its start */
374 memset(bigbuf, 0, sizeof(struct smb_hdr));
377 if (smallbuf == NULL) {
378 smallbuf = cifs_small_buf_get();
380 cERROR(1, ("No memory for SMB response"));
382 /* retry will check if exiting */
385 /* beginning of smb buffer is cleared in our buf_get */
386 } else /* if existing small buf clear beginning */
387 memset(smallbuf, 0, sizeof(struct smb_hdr));
391 smb_buffer = smallbuf;
392 iov.iov_base = smb_buffer;
394 smb_msg.msg_control = NULL;
395 smb_msg.msg_controllen = 0;
396 pdu_length = 4; /* enough to get RFC1001 header */
399 kernel_recvmsg(csocket, &smb_msg,
400 &iov, 1, pdu_length, 0 /* BB other flags? */);
402 if (server->tcpStatus == CifsExiting) {
404 } else if (server->tcpStatus == CifsNeedReconnect) {
405 cFYI(1, ("Reconnect after server stopped responding"));
406 cifs_reconnect(server);
407 cFYI(1, ("call to reconnect done"));
408 csocket = server->ssocket;
410 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
411 msleep(1); /* minimum sleep to prevent looping
412 allowing socket to clear and app threads to set
413 tcpStatus CifsNeedReconnect if server hung */
418 } else if (length <= 0) {
419 if (server->tcpStatus == CifsNew) {
420 cFYI(1, ("tcp session abend after SMBnegprot"));
421 /* some servers kill the TCP session rather than
422 returning an SMB negprot error, in which
423 case reconnecting here is not going to help,
424 and so simply return error to mount */
427 if (!try_to_freeze() && (length == -EINTR)) {
428 cFYI(1, ("cifsd thread killed"));
431 cFYI(1, ("Reconnect after unexpected peek error %d",
433 cifs_reconnect(server);
434 csocket = server->ssocket;
435 wake_up(&server->response_q);
437 } else if (length < pdu_length) {
438 cFYI(1, ("requested %d bytes but only got %d bytes",
439 pdu_length, length));
440 pdu_length -= length;
445 /* The right amount was read from socket - 4 bytes */
446 /* so we can now interpret the length field */
448 /* the first byte big endian of the length field,
449 is actually not part of the length but the type
450 with the most common, zero, as regular data */
451 temp = *((char *) smb_buffer);
453 /* Note that FC 1001 length is big endian on the wire,
454 but we convert it here so it is always manipulated
455 as host byte order */
456 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
457 smb_buffer->smb_buf_length = pdu_length;
459 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
461 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
463 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
464 cFYI(1, ("Good RFC 1002 session rsp"));
466 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
467 /* we get this from Windows 98 instead of
468 an error on SMB negprot response */
469 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
471 if (server->tcpStatus == CifsNew) {
472 /* if nack on negprot (rather than
473 ret of smb negprot error) reconnecting
474 not going to help, ret error to mount */
477 /* give server a second to
478 clean up before reconnect attempt */
480 /* always try 445 first on reconnect
481 since we get NACK on some if we ever
482 connected to port 139 (the NACK is
483 since we do not begin with RFC1001
484 session initialize frame) */
485 server->addr.sockAddr.sin_port =
487 cifs_reconnect(server);
488 csocket = server->ssocket;
489 wake_up(&server->response_q);
492 } else if (temp != (char) 0) {
493 cERROR(1, ("Unknown RFC 1002 frame"));
494 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
496 cifs_reconnect(server);
497 csocket = server->ssocket;
501 /* else we have an SMB response */
502 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
503 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
504 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
505 length, pdu_length+4));
506 cifs_reconnect(server);
507 csocket = server->ssocket;
508 wake_up(&server->response_q);
515 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
517 memcpy(bigbuf, smallbuf, 4);
521 iov.iov_base = 4 + (char *)smb_buffer;
522 iov.iov_len = pdu_length;
523 for (total_read = 0; total_read < pdu_length;
524 total_read += length) {
525 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
526 pdu_length - total_read, 0);
527 if ((server->tcpStatus == CifsExiting) ||
528 (length == -EINTR)) {
532 } else if (server->tcpStatus == CifsNeedReconnect) {
533 cifs_reconnect(server);
534 csocket = server->ssocket;
535 /* Reconnect wakes up rspns q */
536 /* Now we will reread sock */
539 } else if ((length == -ERESTARTSYS) ||
540 (length == -EAGAIN)) {
541 msleep(1); /* minimum sleep to prevent looping,
542 allowing socket to clear and app
543 threads to set tcpStatus
544 CifsNeedReconnect if server hung*/
547 } else if (length <= 0) {
548 cERROR(1, ("Received no data, expecting %d",
549 pdu_length - total_read));
550 cifs_reconnect(server);
551 csocket = server->ssocket;
558 else if (reconnect == 1)
561 length += 4; /* account for rfc1002 hdr */
564 dump_smb(smb_buffer, length);
565 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
566 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
572 spin_lock(&GlobalMid_Lock);
573 list_for_each(tmp, &server->pending_mid_q) {
574 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
576 if ((mid_entry->mid == smb_buffer->Mid) &&
577 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
578 (mid_entry->command == smb_buffer->Command)) {
579 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
580 /* We have a multipart transact2 resp */
582 if (mid_entry->resp_buf) {
583 /* merge response - fix up 1st*/
584 if (coalesce_t2(smb_buffer,
585 mid_entry->resp_buf)) {
586 mid_entry->multiRsp =
590 /* all parts received */
591 mid_entry->multiEnd =
597 cERROR(1,("1st trans2 resp needs bigbuf"));
598 /* BB maybe we can fix this up, switch
599 to already allocated large buffer? */
601 /* Have first buffer */
602 mid_entry->resp_buf =
604 mid_entry->largeBuf =
611 mid_entry->resp_buf = smb_buffer;
612 mid_entry->largeBuf = isLargeBuf;
614 task_to_wake = mid_entry->tsk;
615 mid_entry->midState = MID_RESPONSE_RECEIVED;
616 #ifdef CONFIG_CIFS_STATS2
617 mid_entry->when_received = jiffies;
619 /* so we do not time out requests to server
620 which is still responding (since server could
621 be busy but not dead) */
622 server->lstrp = jiffies;
626 spin_unlock(&GlobalMid_Lock);
628 /* Was previous buf put in mpx struct for multi-rsp? */
630 /* smb buffer will be freed by user thread */
636 wake_up_process(task_to_wake);
637 } else if (!is_valid_oplock_break(smb_buffer, server) &&
639 cERROR(1, ("No task to wake, unknown frame received! "
640 "NumMids %d", midCount.counter));
641 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
642 sizeof(struct smb_hdr));
643 #ifdef CONFIG_CIFS_DEBUG2
644 cifs_dump_detail(smb_buffer);
645 cifs_dump_mids(server);
646 #endif /* CIFS_DEBUG2 */
649 } /* end while !EXITING */
651 spin_lock(&GlobalMid_Lock);
652 server->tcpStatus = CifsExiting;
653 spin_unlock(&GlobalMid_Lock);
654 wake_up_all(&server->response_q);
656 /* check if we have blocked requests that need to free */
657 /* Note that cifs_max_pending is normally 50, but
658 can be set at module install time to as little as two */
659 spin_lock(&GlobalMid_Lock);
660 if (atomic_read(&server->inFlight) >= cifs_max_pending)
661 atomic_set(&server->inFlight, cifs_max_pending - 1);
662 /* We do not want to set the max_pending too low or we
663 could end up with the counter going negative */
664 spin_unlock(&GlobalMid_Lock);
665 /* Although there should not be any requests blocked on
666 this queue it can not hurt to be paranoid and try to wake up requests
667 that may haven been blocked when more than 50 at time were on the wire
668 to the same server - they now will see the session is in exit state
669 and get out of SendReceive. */
670 wake_up_all(&server->request_q);
671 /* give those requests time to exit */
674 if (server->ssocket) {
675 sock_release(csocket);
676 server->ssocket = NULL;
678 /* buffer usuallly freed in free_mid - need to free it here on exit */
679 cifs_buf_release(bigbuf);
680 if (smallbuf) /* no sense logging a debug message if NULL */
681 cifs_small_buf_release(smallbuf);
683 read_lock(&GlobalSMBSeslock);
684 if (list_empty(&server->pending_mid_q)) {
685 /* loop through server session structures attached to this and
687 list_for_each(tmp, &GlobalSMBSessionList) {
689 list_entry(tmp, struct cifsSesInfo,
691 if (ses->server == server) {
692 ses->status = CifsExiting;
696 read_unlock(&GlobalSMBSeslock);
698 /* although we can not zero the server struct pointer yet,
699 since there are active requests which may depnd on them,
700 mark the corresponding SMB sessions as exiting too */
701 list_for_each(tmp, &GlobalSMBSessionList) {
702 ses = list_entry(tmp, struct cifsSesInfo,
704 if (ses->server == server)
705 ses->status = CifsExiting;
708 spin_lock(&GlobalMid_Lock);
709 list_for_each(tmp, &server->pending_mid_q) {
710 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
711 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
712 cFYI(1, ("Clearing Mid 0x%x - waking up ",
714 task_to_wake = mid_entry->tsk;
716 wake_up_process(task_to_wake);
719 spin_unlock(&GlobalMid_Lock);
720 read_unlock(&GlobalSMBSeslock);
721 /* 1/8th of sec is more than enough time for them to exit */
725 if (!list_empty(&server->pending_mid_q)) {
726 /* mpx threads have not exited yet give them
727 at least the smb send timeout time for long ops */
728 /* due to delays on oplock break requests, we need
729 to wait at least 45 seconds before giving up
730 on a request getting a response and going ahead
732 cFYI(1, ("Wait for exit from demultiplex thread"));
734 /* if threads still have not exited they are probably never
735 coming home not much else we can do but free the memory */
738 /* last chance to mark ses pointers invalid
739 if there are any pointing to this (e.g
740 if a crazy root user tried to kill cifsd
741 kernel thread explicitly this might happen) */
742 write_lock(&GlobalSMBSeslock);
743 list_for_each(tmp, &GlobalSMBSessionList) {
744 ses = list_entry(tmp, struct cifsSesInfo,
746 if (ses->server == server)
749 write_unlock(&GlobalSMBSeslock);
751 kfree(server->hostname);
754 length = atomic_dec_return(&tcpSesAllocCount);
756 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
762 /* extract the host portion of the UNC string */
764 extract_hostname(const char *unc)
770 /* skip double chars at beginning of string */
771 /* BB: check validity of these bytes? */
774 /* delimiter between hostname and sharename is always '\\' now */
775 delim = strchr(src, '\\');
777 return ERR_PTR(-EINVAL);
780 dst = kmalloc((len + 1), GFP_KERNEL);
782 return ERR_PTR(-ENOMEM);
784 memcpy(dst, src, len);
791 cifs_parse_mount_options(char *options, const char *devname,
796 unsigned int temp_len, i, j;
802 if (Local_System_Name[0] != 0)
803 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
805 char *nodename = utsname()->nodename;
806 int n = strnlen(nodename, 15);
807 memset(vol->source_rfc1001_name, 0x20, 15);
808 for (i = 0; i < n; i++) {
809 /* does not have to be perfect mapping since field is
810 informational, only used for servers that do not support
811 port 445 and it can be overridden at mount time */
812 vol->source_rfc1001_name[i] = toupper(nodename[i]);
815 vol->source_rfc1001_name[15] = 0;
816 /* null target name indicates to use *SMBSERVR default called name
817 if we end up sending RFC1001 session initialize */
818 vol->target_rfc1001_name[0] = 0;
819 vol->linux_uid = current->uid; /* current->euid instead? */
820 vol->linux_gid = current->gid;
821 vol->dir_mode = S_IRWXUGO;
822 /* 2767 perms indicate mandatory locking support */
823 vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
825 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
827 /* default is always to request posix paths. */
828 vol->posix_paths = 1;
833 if (strncmp(options, "sep=", 4) == 0) {
834 if (options[4] != 0) {
835 separator[0] = options[4];
838 cFYI(1, ("Null separator not allowed"));
842 while ((data = strsep(&options, separator)) != NULL) {
845 if ((value = strchr(data, '=')) != NULL)
848 /* Have to parse this before we parse for "user" */
849 if (strnicmp(data, "user_xattr", 10) == 0) {
851 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
853 } else if (strnicmp(data, "user", 4) == 0) {
856 "CIFS: invalid or missing username\n");
857 return 1; /* needs_arg; */
858 } else if (!*value) {
859 /* null user, ie anonymous, authentication */
862 if (strnlen(value, 200) < 200) {
863 vol->username = value;
865 printk(KERN_WARNING "CIFS: username too long\n");
868 } else if (strnicmp(data, "pass", 4) == 0) {
870 vol->password = NULL;
872 } else if (value[0] == 0) {
873 /* check if string begins with double comma
874 since that would mean the password really
875 does start with a comma, and would not
876 indicate an empty string */
877 if (value[1] != separator[0]) {
878 vol->password = NULL;
882 temp_len = strlen(value);
883 /* removed password length check, NTLM passwords
884 can be arbitrarily long */
886 /* if comma in password, the string will be
887 prematurely null terminated. Commas in password are
888 specified across the cifs mount interface by a double
889 comma ie ,, and a comma used as in other cases ie ','
890 as a parameter delimiter/separator is single and due
891 to the strsep above is temporarily zeroed. */
893 /* NB: password legally can have multiple commas and
894 the only illegal character in a password is null */
896 if ((value[temp_len] == 0) &&
897 (value[temp_len+1] == separator[0])) {
899 value[temp_len] = separator[0];
900 temp_len += 2; /* move after second comma */
901 while (value[temp_len] != 0) {
902 if (value[temp_len] == separator[0]) {
903 if (value[temp_len+1] ==
905 /* skip second comma */
908 /* single comma indicating start
915 if (value[temp_len] == 0) {
919 /* point option to start of next parm */
920 options = value + temp_len + 1;
922 /* go from value to value + temp_len condensing
923 double commas to singles. Note that this ends up
924 allocating a few bytes too many, which is ok */
925 vol->password = kzalloc(temp_len, GFP_KERNEL);
926 if (vol->password == NULL) {
927 printk(KERN_WARNING "CIFS: no memory "
931 for (i = 0, j = 0; i < temp_len; i++, j++) {
932 vol->password[j] = value[i];
933 if (value[i] == separator[0]
934 && value[i+1] == separator[0]) {
935 /* skip second comma */
939 vol->password[j] = 0;
941 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
942 if (vol->password == NULL) {
943 printk(KERN_WARNING "CIFS: no memory "
947 strcpy(vol->password, value);
949 } else if (strnicmp(data, "ip", 2) == 0) {
950 if (!value || !*value) {
952 } else if (strnlen(value, 35) < 35) {
955 printk(KERN_WARNING "CIFS: ip address "
959 } else if (strnicmp(data, "sec", 3) == 0) {
960 if (!value || !*value) {
961 cERROR(1, ("no security value specified"));
963 } else if (strnicmp(value, "krb5i", 5) == 0) {
964 vol->secFlg |= CIFSSEC_MAY_KRB5 |
966 } else if (strnicmp(value, "krb5p", 5) == 0) {
967 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
969 cERROR(1, ("Krb5 cifs privacy not supported"));
971 } else if (strnicmp(value, "krb5", 4) == 0) {
972 vol->secFlg |= CIFSSEC_MAY_KRB5;
973 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
974 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
976 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
977 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
978 } else if (strnicmp(value, "ntlmi", 5) == 0) {
979 vol->secFlg |= CIFSSEC_MAY_NTLM |
981 } else if (strnicmp(value, "ntlm", 4) == 0) {
982 /* ntlm is default so can be turned off too */
983 vol->secFlg |= CIFSSEC_MAY_NTLM;
984 } else if (strnicmp(value, "nontlm", 6) == 0) {
985 /* BB is there a better way to do this? */
986 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
987 #ifdef CONFIG_CIFS_WEAK_PW_HASH
988 } else if (strnicmp(value, "lanman", 6) == 0) {
989 vol->secFlg |= CIFSSEC_MAY_LANMAN;
991 } else if (strnicmp(value, "none", 4) == 0) {
994 cERROR(1, ("bad security option: %s", value));
997 } else if ((strnicmp(data, "unc", 3) == 0)
998 || (strnicmp(data, "target", 6) == 0)
999 || (strnicmp(data, "path", 4) == 0)) {
1000 if (!value || !*value) {
1001 printk(KERN_WARNING "CIFS: invalid path to "
1002 "network resource\n");
1003 return 1; /* needs_arg; */
1005 if ((temp_len = strnlen(value, 300)) < 300) {
1006 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1007 if (vol->UNC == NULL)
1009 strcpy(vol->UNC, value);
1010 if (strncmp(vol->UNC, "//", 2) == 0) {
1013 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1015 "CIFS: UNC Path does not begin "
1016 "with // or \\\\ \n");
1020 printk(KERN_WARNING "CIFS: UNC name too long\n");
1023 } else if ((strnicmp(data, "domain", 3) == 0)
1024 || (strnicmp(data, "workgroup", 5) == 0)) {
1025 if (!value || !*value) {
1026 printk(KERN_WARNING "CIFS: invalid domain name\n");
1027 return 1; /* needs_arg; */
1029 /* BB are there cases in which a comma can be valid in
1030 a domain name and need special handling? */
1031 if (strnlen(value, 256) < 256) {
1032 vol->domainname = value;
1033 cFYI(1, ("Domain name set"));
1035 printk(KERN_WARNING "CIFS: domain name too "
1039 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1040 if (!value || !*value) {
1042 "CIFS: invalid path prefix\n");
1043 return 1; /* needs_argument */
1045 if ((temp_len = strnlen(value, 1024)) < 1024) {
1046 if (value[0] != '/')
1047 temp_len++; /* missing leading slash */
1048 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1049 if (vol->prepath == NULL)
1051 if (value[0] != '/') {
1052 vol->prepath[0] = '/';
1053 strcpy(vol->prepath+1, value);
1055 strcpy(vol->prepath, value);
1056 cFYI(1, ("prefix path %s", vol->prepath));
1058 printk(KERN_WARNING "CIFS: prefix too long\n");
1061 } else if (strnicmp(data, "iocharset", 9) == 0) {
1062 if (!value || !*value) {
1063 printk(KERN_WARNING "CIFS: invalid iocharset "
1065 return 1; /* needs_arg; */
1067 if (strnlen(value, 65) < 65) {
1068 if (strnicmp(value, "default", 7))
1069 vol->iocharset = value;
1070 /* if iocharset not set then load_nls_default
1071 is used by caller */
1072 cFYI(1, ("iocharset set to %s", value));
1074 printk(KERN_WARNING "CIFS: iocharset name "
1078 } else if (strnicmp(data, "uid", 3) == 0) {
1079 if (value && *value) {
1081 simple_strtoul(value, &value, 0);
1082 vol->override_uid = 1;
1084 } else if (strnicmp(data, "gid", 3) == 0) {
1085 if (value && *value) {
1087 simple_strtoul(value, &value, 0);
1088 vol->override_gid = 1;
1090 } else if (strnicmp(data, "file_mode", 4) == 0) {
1091 if (value && *value) {
1093 simple_strtoul(value, &value, 0);
1095 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1096 if (value && *value) {
1098 simple_strtoul(value, &value, 0);
1100 } else if (strnicmp(data, "dirmode", 4) == 0) {
1101 if (value && *value) {
1103 simple_strtoul(value, &value, 0);
1105 } else if (strnicmp(data, "port", 4) == 0) {
1106 if (value && *value) {
1108 simple_strtoul(value, &value, 0);
1110 } else if (strnicmp(data, "rsize", 5) == 0) {
1111 if (value && *value) {
1113 simple_strtoul(value, &value, 0);
1115 } else if (strnicmp(data, "wsize", 5) == 0) {
1116 if (value && *value) {
1118 simple_strtoul(value, &value, 0);
1120 } else if (strnicmp(data, "sockopt", 5) == 0) {
1121 if (value && *value) {
1123 simple_strtoul(value, &value, 0);
1125 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1126 if (!value || !*value || (*value == ' ')) {
1127 cFYI(1, ("invalid (empty) netbiosname"));
1129 memset(vol->source_rfc1001_name, 0x20, 15);
1130 for (i = 0; i < 15; i++) {
1131 /* BB are there cases in which a comma can be
1132 valid in this workstation netbios name (and need
1133 special handling)? */
1135 /* We do not uppercase netbiosname for user */
1139 vol->source_rfc1001_name[i] =
1142 /* The string has 16th byte zero still from
1143 set at top of the function */
1144 if ((i == 15) && (value[i] != 0))
1145 printk(KERN_WARNING "CIFS: netbiosname"
1146 " longer than 15 truncated.\n");
1148 } else if (strnicmp(data, "servern", 7) == 0) {
1149 /* servernetbiosname specified override *SMBSERVER */
1150 if (!value || !*value || (*value == ' ')) {
1151 cFYI(1, ("empty server netbiosname specified"));
1153 /* last byte, type, is 0x20 for servr type */
1154 memset(vol->target_rfc1001_name, 0x20, 16);
1156 for (i = 0; i < 15; i++) {
1157 /* BB are there cases in which a comma can be
1158 valid in this workstation netbios name
1159 (and need special handling)? */
1161 /* user or mount helper must uppercase
1166 vol->target_rfc1001_name[i] =
1169 /* The string has 16th byte zero still from
1170 set at top of the function */
1171 if ((i == 15) && (value[i] != 0))
1172 printk(KERN_WARNING "CIFS: server net"
1173 "biosname longer than 15 truncated.\n");
1175 } else if (strnicmp(data, "credentials", 4) == 0) {
1177 } else if (strnicmp(data, "version", 3) == 0) {
1179 } else if (strnicmp(data, "guest", 5) == 0) {
1181 } else if (strnicmp(data, "rw", 2) == 0) {
1183 } else if ((strnicmp(data, "suid", 4) == 0) ||
1184 (strnicmp(data, "nosuid", 6) == 0) ||
1185 (strnicmp(data, "exec", 4) == 0) ||
1186 (strnicmp(data, "noexec", 6) == 0) ||
1187 (strnicmp(data, "nodev", 5) == 0) ||
1188 (strnicmp(data, "noauto", 6) == 0) ||
1189 (strnicmp(data, "dev", 3) == 0)) {
1190 /* The mount tool or mount.cifs helper (if present)
1191 uses these opts to set flags, and the flags are read
1192 by the kernel vfs layer before we get here (ie
1193 before read super) so there is no point trying to
1194 parse these options again and set anything and it
1195 is ok to just ignore them */
1197 } else if (strnicmp(data, "ro", 2) == 0) {
1199 } else if (strnicmp(data, "hard", 4) == 0) {
1201 } else if (strnicmp(data, "soft", 4) == 0) {
1203 } else if (strnicmp(data, "perm", 4) == 0) {
1205 } else if (strnicmp(data, "noperm", 6) == 0) {
1207 } else if (strnicmp(data, "mapchars", 8) == 0) {
1209 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1211 } else if (strnicmp(data, "sfu", 3) == 0) {
1213 } else if (strnicmp(data, "nosfu", 5) == 0) {
1215 } else if (strnicmp(data, "nodfs", 5) == 0) {
1217 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1218 vol->posix_paths = 1;
1219 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1220 vol->posix_paths = 0;
1221 } else if (strnicmp(data, "nounix", 6) == 0) {
1222 vol->no_linux_ext = 1;
1223 } else if (strnicmp(data, "nolinux", 7) == 0) {
1224 vol->no_linux_ext = 1;
1225 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1226 (strnicmp(data, "ignorecase", 10) == 0)) {
1228 } else if (strnicmp(data, "brl", 3) == 0) {
1230 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1231 (strnicmp(data, "nolock", 6) == 0)) {
1233 /* turn off mandatory locking in mode
1234 if remote locking is turned off since the
1235 local vfs will do advisory */
1236 if (vol->file_mode ==
1237 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1238 vol->file_mode = S_IALLUGO;
1239 } else if (strnicmp(data, "setuids", 7) == 0) {
1241 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1243 } else if (strnicmp(data, "dynperm", 7) == 0) {
1244 vol->dynperm = true;
1245 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1246 vol->dynperm = false;
1247 } else if (strnicmp(data, "nohard", 6) == 0) {
1249 } else if (strnicmp(data, "nosoft", 6) == 0) {
1251 } else if (strnicmp(data, "nointr", 6) == 0) {
1253 } else if (strnicmp(data, "intr", 4) == 0) {
1255 } else if (strnicmp(data, "serverino", 7) == 0) {
1256 vol->server_ino = 1;
1257 } else if (strnicmp(data, "noserverino", 9) == 0) {
1258 vol->server_ino = 0;
1259 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1261 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1263 } else if (strnicmp(data, "acl", 3) == 0) {
1264 vol->no_psx_acl = 0;
1265 } else if (strnicmp(data, "noacl", 5) == 0) {
1266 vol->no_psx_acl = 1;
1267 } else if (strnicmp(data, "sign", 4) == 0) {
1268 vol->secFlg |= CIFSSEC_MUST_SIGN;
1269 } else if (strnicmp(data, "seal", 4) == 0) {
1270 /* we do not do the following in secFlags because seal
1271 is a per tree connection (mount) not a per socket
1272 or per-smb connection option in the protocol */
1273 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1275 } else if (strnicmp(data, "direct", 6) == 0) {
1277 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1279 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1280 if (!value || !*value) {
1281 vol->in6_addr = NULL;
1282 } else if (strnlen(value, 49) == 48) {
1283 vol->in6_addr = value;
1285 printk(KERN_WARNING "CIFS: ip v6 address not "
1286 "48 characters long\n");
1289 } else if (strnicmp(data, "noac", 4) == 0) {
1290 printk(KERN_WARNING "CIFS: Mount option noac not "
1291 "supported. Instead set "
1292 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1294 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1297 if (vol->UNC == NULL) {
1298 if (devname == NULL) {
1299 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1303 if ((temp_len = strnlen(devname, 300)) < 300) {
1304 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1305 if (vol->UNC == NULL)
1307 strcpy(vol->UNC, devname);
1308 if (strncmp(vol->UNC, "//", 2) == 0) {
1311 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1312 printk(KERN_WARNING "CIFS: UNC Path does not "
1313 "begin with // or \\\\ \n");
1316 value = strpbrk(vol->UNC+2, "/\\");
1320 printk(KERN_WARNING "CIFS: UNC name too long\n");
1324 if (vol->UNCip == NULL)
1325 vol->UNCip = &vol->UNC[2];
1330 static struct cifsSesInfo *
1331 cifs_find_tcp_session(struct in_addr *target_ip_addr,
1332 struct in6_addr *target_ip6_addr,
1333 char *userName, struct TCP_Server_Info **psrvTcp)
1335 struct list_head *tmp;
1336 struct cifsSesInfo *ses;
1340 read_lock(&GlobalSMBSeslock);
1341 list_for_each(tmp, &GlobalSMBSessionList) {
1342 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1346 if (target_ip_addr &&
1347 ses->server->addr.sockAddr.sin_addr.s_addr != target_ip_addr->s_addr)
1349 else if (target_ip6_addr &&
1350 memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1351 target_ip6_addr, sizeof(*target_ip6_addr)))
1353 /* BB lock server and tcp session; increment use count here?? */
1355 /* found a match on the TCP session */
1356 *psrvTcp = ses->server;
1358 /* BB check if reconnection needed */
1359 if (strncmp(ses->userName, userName, MAX_USERNAME_SIZE) == 0) {
1360 read_unlock(&GlobalSMBSeslock);
1361 /* Found exact match on both TCP and
1365 /* else tcp and smb sessions need reconnection */
1367 read_unlock(&GlobalSMBSeslock);
1372 static struct cifsTconInfo *
1373 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1375 struct list_head *tmp;
1376 struct cifsTconInfo *tcon;
1379 read_lock(&GlobalSMBSeslock);
1381 list_for_each(tmp, &GlobalTreeConnectionList) {
1382 cFYI(1, ("Next tcon"));
1383 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1384 if (!tcon->ses || !tcon->ses->server)
1387 old_ip = tcon->ses->server->addr.sockAddr.sin_addr.s_addr;
1388 cFYI(1, ("old ip addr: %x == new ip %x ?",
1389 old_ip, new_target_ip_addr));
1391 if (old_ip != new_target_ip_addr)
1394 /* BB lock tcon, server, tcp session and increment use count? */
1395 /* found a match on the TCP session */
1396 /* BB check if reconnection needed */
1397 cFYI(1, ("IP match, old UNC: %s new: %s",
1398 tcon->treeName, uncName));
1400 if (strncmp(tcon->treeName, uncName, MAX_TREE_SIZE))
1403 cFYI(1, ("and old usr: %s new: %s",
1404 tcon->treeName, uncName));
1406 if (strncmp(tcon->ses->userName, userName, MAX_USERNAME_SIZE))
1409 /* matched smb session (user name) */
1410 read_unlock(&GlobalSMBSeslock);
1414 read_unlock(&GlobalSMBSeslock);
1419 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1420 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1421 struct dfs_info3_param **preferrals, int remap)
1426 *pnum_referrals = 0;
1429 if (pSesInfo->ipc_tid == 0) {
1430 temp_unc = kmalloc(2 /* for slashes */ +
1431 strnlen(pSesInfo->serverName,
1432 SERVER_NAME_LEN_WITH_NULL * 2)
1433 + 1 + 4 /* slash IPC$ */ + 2,
1435 if (temp_unc == NULL)
1439 strcpy(temp_unc + 2, pSesInfo->serverName);
1440 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1441 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1443 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1447 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1448 pnum_referrals, nls_codepage, remap);
1449 /* BB map targetUNCs to dfs_info3 structures, here or
1450 in CIFSGetDFSRefer BB */
1455 #ifdef CONFIG_DEBUG_LOCK_ALLOC
1456 static struct lock_class_key cifs_key[2];
1457 static struct lock_class_key cifs_slock_key[2];
1460 cifs_reclassify_socket4(struct socket *sock)
1462 struct sock *sk = sock->sk;
1463 BUG_ON(sock_owned_by_user(sk));
1464 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
1465 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
1469 cifs_reclassify_socket6(struct socket *sock)
1471 struct sock *sk = sock->sk;
1472 BUG_ON(sock_owned_by_user(sk));
1473 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
1474 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
1478 cifs_reclassify_socket4(struct socket *sock)
1483 cifs_reclassify_socket6(struct socket *sock)
1488 /* See RFC1001 section 14 on representation of Netbios names */
1489 static void rfc1002mangle(char *target, char *source, unsigned int length)
1493 for (i = 0, j = 0; i < (length); i++) {
1494 /* mask a nibble at a time and encode */
1495 target[j] = 'A' + (0x0F & (source[i] >> 4));
1496 target[j+1] = 'A' + (0x0F & source[i]);
1504 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1505 char *netbios_name, char *target_name)
1509 __be16 orig_port = 0;
1511 if (*csocket == NULL) {
1512 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1513 IPPROTO_TCP, csocket);
1515 cERROR(1, ("Error %d creating socket", rc));
1519 /* BB other socket options to set KEEPALIVE, NODELAY? */
1520 cFYI(1, ("Socket created"));
1521 (*csocket)->sk->sk_allocation = GFP_NOFS;
1522 cifs_reclassify_socket4(*csocket);
1526 psin_server->sin_family = AF_INET;
1527 if (psin_server->sin_port) { /* user overrode default port */
1528 rc = (*csocket)->ops->connect(*csocket,
1529 (struct sockaddr *) psin_server,
1530 sizeof(struct sockaddr_in), 0);
1536 /* save original port so we can retry user specified port
1537 later if fall back ports fail this time */
1538 orig_port = psin_server->sin_port;
1540 /* do not retry on the same port we just failed on */
1541 if (psin_server->sin_port != htons(CIFS_PORT)) {
1542 psin_server->sin_port = htons(CIFS_PORT);
1544 rc = (*csocket)->ops->connect(*csocket,
1545 (struct sockaddr *) psin_server,
1546 sizeof(struct sockaddr_in), 0);
1552 psin_server->sin_port = htons(RFC1001_PORT);
1553 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1555 sizeof(struct sockaddr_in), 0);
1560 /* give up here - unless we want to retry on different
1561 protocol families some day */
1564 psin_server->sin_port = orig_port;
1565 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1566 sock_release(*csocket);
1570 /* Eventually check for other socket options to change from
1571 the default. sock_setsockopt not used because it expects
1572 user space buffer */
1573 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1574 (*csocket)->sk->sk_sndbuf,
1575 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1576 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1577 /* make the bufsizes depend on wsize/rsize and max requests */
1578 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1579 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1580 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1581 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1583 /* send RFC1001 sessinit */
1584 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1585 /* some servers require RFC1001 sessinit before sending
1586 negprot - BB check reconnection in case where second
1587 sessinit is sent but no second negprot */
1588 struct rfc1002_session_packet *ses_init_buf;
1589 struct smb_hdr *smb_buf;
1590 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1593 ses_init_buf->trailer.session_req.called_len = 32;
1594 if (target_name && (target_name[0] != 0)) {
1595 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1598 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1599 DEFAULT_CIFS_CALLED_NAME, 16);
1602 ses_init_buf->trailer.session_req.calling_len = 32;
1603 /* calling name ends in null (byte 16) from old smb
1605 if (netbios_name && (netbios_name[0] != 0)) {
1606 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1609 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1610 "LINUX_CIFS_CLNT", 16);
1612 ses_init_buf->trailer.session_req.scope1 = 0;
1613 ses_init_buf->trailer.session_req.scope2 = 0;
1614 smb_buf = (struct smb_hdr *)ses_init_buf;
1615 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1616 smb_buf->smb_buf_length = 0x81000044;
1617 rc = smb_send(*csocket, smb_buf, 0x44,
1618 (struct sockaddr *)psin_server);
1619 kfree(ses_init_buf);
1620 msleep(1); /* RFC1001 layer in at least one server
1621 requires very short break before negprot
1622 presumably because not expecting negprot
1623 to follow so fast. This is a simple
1624 solution that works without
1625 complicating the code and causes no
1626 significant slowing down on mount
1627 for everyone else */
1629 /* else the negprot may still work without this
1630 even though malloc failed */
1638 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1642 __be16 orig_port = 0;
1644 if (*csocket == NULL) {
1645 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1646 IPPROTO_TCP, csocket);
1648 cERROR(1, ("Error %d creating ipv6 socket", rc));
1652 /* BB other socket options to set KEEPALIVE, NODELAY? */
1653 cFYI(1, ("ipv6 Socket created"));
1654 (*csocket)->sk->sk_allocation = GFP_NOFS;
1655 cifs_reclassify_socket6(*csocket);
1659 psin_server->sin6_family = AF_INET6;
1661 if (psin_server->sin6_port) { /* user overrode default port */
1662 rc = (*csocket)->ops->connect(*csocket,
1663 (struct sockaddr *) psin_server,
1664 sizeof(struct sockaddr_in6), 0);
1670 /* save original port so we can retry user specified port
1671 later if fall back ports fail this time */
1673 orig_port = psin_server->sin6_port;
1674 /* do not retry on the same port we just failed on */
1675 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1676 psin_server->sin6_port = htons(CIFS_PORT);
1678 rc = (*csocket)->ops->connect(*csocket,
1679 (struct sockaddr *) psin_server,
1680 sizeof(struct sockaddr_in6), 0);
1686 psin_server->sin6_port = htons(RFC1001_PORT);
1687 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1688 psin_server, sizeof(struct sockaddr_in6), 0);
1693 /* give up here - unless we want to retry on different
1694 protocol families some day */
1697 psin_server->sin6_port = orig_port;
1698 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1699 sock_release(*csocket);
1703 /* Eventually check for other socket options to change from
1704 the default. sock_setsockopt not used because it expects
1705 user space buffer */
1706 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1711 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1712 struct super_block *sb, struct smb_vol *vol_info)
1714 /* if we are reconnecting then should we check to see if
1715 * any requested capabilities changed locally e.g. via
1716 * remount but we can not do much about it here
1717 * if they have (even if we could detect it by the following)
1718 * Perhaps we could add a backpointer to array of sb from tcon
1719 * or if we change to make all sb to same share the same
1720 * sb as NFS - then we only have one backpointer to sb.
1721 * What if we wanted to mount the server share twice once with
1722 * and once without posixacls or posix paths? */
1723 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1725 if (vol_info && vol_info->no_linux_ext) {
1726 tcon->fsUnixInfo.Capability = 0;
1727 tcon->unix_ext = 0; /* Unix Extensions disabled */
1728 cFYI(1, ("Linux protocol extensions disabled"));
1730 } else if (vol_info)
1731 tcon->unix_ext = 1; /* Unix Extensions supported */
1733 if (tcon->unix_ext == 0) {
1734 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1738 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1739 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1741 /* check for reconnect case in which we do not
1742 want to change the mount behavior if we can avoid it */
1743 if (vol_info == NULL) {
1744 /* turn off POSIX ACL and PATHNAMES if not set
1745 originally at mount time */
1746 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1747 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1748 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
1749 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1750 cERROR(1, ("POSIXPATH support change"));
1751 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1752 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
1753 cERROR(1, ("possible reconnect error"));
1755 ("server disabled POSIX path support"));
1759 cap &= CIFS_UNIX_CAP_MASK;
1760 if (vol_info && vol_info->no_psx_acl)
1761 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1762 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
1763 cFYI(1, ("negotiated posix acl support"));
1765 sb->s_flags |= MS_POSIXACL;
1768 if (vol_info && vol_info->posix_paths == 0)
1769 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1770 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1771 cFYI(1, ("negotiate posix pathnames"));
1773 CIFS_SB(sb)->mnt_cifs_flags |=
1774 CIFS_MOUNT_POSIX_PATHS;
1777 /* We might be setting the path sep back to a different
1778 form if we are reconnecting and the server switched its
1779 posix path capability for this share */
1780 if (sb && (CIFS_SB(sb)->prepathlen > 0))
1781 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1783 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
1784 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
1785 CIFS_SB(sb)->rsize = 127 * 1024;
1787 ("larger reads not supported by srv"));
1792 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
1793 #ifdef CONFIG_CIFS_DEBUG2
1794 if (cap & CIFS_UNIX_FCNTL_CAP)
1795 cFYI(1, ("FCNTL cap"));
1796 if (cap & CIFS_UNIX_EXTATTR_CAP)
1797 cFYI(1, ("EXTATTR cap"));
1798 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1799 cFYI(1, ("POSIX path cap"));
1800 if (cap & CIFS_UNIX_XATTR_CAP)
1801 cFYI(1, ("XATTR cap"));
1802 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
1803 cFYI(1, ("POSIX ACL cap"));
1804 if (cap & CIFS_UNIX_LARGE_READ_CAP)
1805 cFYI(1, ("very large read cap"));
1806 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
1807 cFYI(1, ("very large write cap"));
1808 #endif /* CIFS_DEBUG2 */
1809 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1810 if (vol_info == NULL) {
1811 cFYI(1, ("resetting capabilities failed"));
1813 cERROR(1, ("Negotiating Unix capabilities "
1814 "with the server failed. Consider "
1815 "mounting with the Unix Extensions\n"
1816 "disabled, if problems are found, "
1817 "by specifying the nounix mount "
1825 convert_delimiter(char *path, char delim)
1838 for (i = 0; path[i] != '\0'; i++) {
1839 if (path[i] == old_delim)
1845 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1846 char *mount_data, const char *devname)
1850 int address_type = AF_INET;
1851 struct socket *csocket = NULL;
1852 struct sockaddr_in sin_server;
1853 struct sockaddr_in6 sin_server6;
1854 struct smb_vol volume_info;
1855 struct cifsSesInfo *pSesInfo = NULL;
1856 struct cifsSesInfo *existingCifsSes = NULL;
1857 struct cifsTconInfo *tcon = NULL;
1858 struct TCP_Server_Info *srvTcp = NULL;
1862 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1864 memset(&volume_info, 0, sizeof(struct smb_vol));
1865 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1870 if (volume_info.nullauth) {
1871 cFYI(1, ("null user"));
1872 volume_info.username = "";
1873 } else if (volume_info.username) {
1874 /* BB fixme parse for domain name here */
1875 cFYI(1, ("Username: %s", volume_info.username));
1877 cifserror("No username specified");
1878 /* In userspace mount helper we can get user name from alternate
1879 locations such as env variables and files on disk */
1884 if (volume_info.UNCip && volume_info.UNC) {
1885 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
1886 &sin_server.sin_addr.s_addr);
1889 /* not ipv4 address, try ipv6 */
1890 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
1891 &sin_server6.sin6_addr.in6_u);
1893 address_type = AF_INET6;
1895 address_type = AF_INET;
1899 /* we failed translating address */
1904 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1907 } else if (volume_info.UNCip) {
1908 /* BB using ip addr as server name to connect to the
1910 cERROR(1, ("Connecting to DFS root not implemented yet"));
1913 } else /* which servers DFS root would we conect to */ {
1915 ("CIFS mount error: No UNC path (e.g. -o "
1916 "unc=//192.168.1.100/public) specified"));
1921 /* this is needed for ASCII cp to Unicode converts */
1922 if (volume_info.iocharset == NULL) {
1923 cifs_sb->local_nls = load_nls_default();
1924 /* load_nls_default can not return null */
1926 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1927 if (cifs_sb->local_nls == NULL) {
1928 cERROR(1, ("CIFS mount error: iocharset %s not found",
1929 volume_info.iocharset));
1935 if (address_type == AF_INET)
1936 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1937 NULL /* no ipv6 addr */,
1938 volume_info.username, &srvTcp);
1939 else if (address_type == AF_INET6) {
1940 cFYI(1, ("looking for ipv6 address"));
1941 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1942 &sin_server6.sin6_addr,
1943 volume_info.username, &srvTcp);
1950 cFYI(1, ("Existing tcp session with server found"));
1951 } else { /* create socket */
1952 if (volume_info.port)
1953 sin_server.sin_port = htons(volume_info.port);
1955 sin_server.sin_port = 0;
1956 if (address_type == AF_INET6) {
1957 cFYI(1, ("attempting ipv6 connect"));
1958 /* BB should we allow ipv6 on port 139? */
1959 /* other OS never observed in Wild doing 139 with v6 */
1960 rc = ipv6_connect(&sin_server6, &csocket);
1962 rc = ipv4_connect(&sin_server, &csocket,
1963 volume_info.source_rfc1001_name,
1964 volume_info.target_rfc1001_name);
1966 cERROR(1, ("Error connecting to IPv4 socket. "
1967 "Aborting operation"));
1968 if (csocket != NULL)
1969 sock_release(csocket);
1973 srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1976 sock_release(csocket);
1979 memcpy(&srvTcp->addr.sockAddr, &sin_server,
1980 sizeof(struct sockaddr_in));
1981 atomic_set(&srvTcp->inFlight, 0);
1982 /* BB Add code for ipv6 case too */
1983 srvTcp->ssocket = csocket;
1984 srvTcp->protocolType = IPV4;
1985 srvTcp->hostname = extract_hostname(volume_info.UNC);
1986 if (IS_ERR(srvTcp->hostname)) {
1987 rc = PTR_ERR(srvTcp->hostname);
1988 sock_release(csocket);
1991 init_waitqueue_head(&srvTcp->response_q);
1992 init_waitqueue_head(&srvTcp->request_q);
1993 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
1994 /* at this point we are the only ones with the pointer
1995 to the struct since the kernel thread not created yet
1996 so no need to spinlock this init of tcpStatus */
1997 srvTcp->tcpStatus = CifsNew;
1998 init_MUTEX(&srvTcp->tcpSem);
1999 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
2000 if (IS_ERR(srvTcp->tsk)) {
2001 rc = PTR_ERR(srvTcp->tsk);
2002 cERROR(1, ("error %d create cifsd thread", rc));
2004 sock_release(csocket);
2005 kfree(srvTcp->hostname);
2009 memcpy(srvTcp->workstation_RFC1001_name,
2010 volume_info.source_rfc1001_name, 16);
2011 memcpy(srvTcp->server_RFC1001_name,
2012 volume_info.target_rfc1001_name, 16);
2013 srvTcp->sequence_number = 0;
2017 if (existingCifsSes) {
2018 pSesInfo = existingCifsSes;
2019 cFYI(1, ("Existing smb sess found (status=%d)",
2021 down(&pSesInfo->sesSem);
2022 if (pSesInfo->status == CifsNeedReconnect) {
2023 cFYI(1, ("Session needs reconnect"));
2024 rc = cifs_setup_session(xid, pSesInfo,
2025 cifs_sb->local_nls);
2027 up(&pSesInfo->sesSem);
2029 cFYI(1, ("Existing smb sess not found"));
2030 pSesInfo = sesInfoAlloc();
2031 if (pSesInfo == NULL)
2034 pSesInfo->server = srvTcp;
2035 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
2036 NIPQUAD(sin_server.sin_addr.s_addr));
2040 /* volume_info.password freed at unmount */
2041 if (volume_info.password) {
2042 pSesInfo->password = volume_info.password;
2043 /* set to NULL to prevent freeing on exit */
2044 volume_info.password = NULL;
2046 if (volume_info.username)
2047 strncpy(pSesInfo->userName,
2048 volume_info.username,
2050 if (volume_info.domainname) {
2051 int len = strlen(volume_info.domainname);
2052 pSesInfo->domainName =
2053 kmalloc(len + 1, GFP_KERNEL);
2054 if (pSesInfo->domainName)
2055 strcpy(pSesInfo->domainName,
2056 volume_info.domainname);
2058 pSesInfo->linux_uid = volume_info.linux_uid;
2059 pSesInfo->overrideSecFlg = volume_info.secFlg;
2060 down(&pSesInfo->sesSem);
2061 /* BB FIXME need to pass vol->secFlgs BB */
2062 rc = cifs_setup_session(xid, pSesInfo,
2063 cifs_sb->local_nls);
2064 up(&pSesInfo->sesSem);
2066 atomic_inc(&srvTcp->socketUseCount);
2070 /* search for existing tcon to this server share */
2072 if (volume_info.rsize > CIFSMaxBufSize) {
2073 cERROR(1, ("rsize %d too large, using MaxBufSize",
2074 volume_info.rsize));
2075 cifs_sb->rsize = CIFSMaxBufSize;
2076 } else if ((volume_info.rsize) &&
2077 (volume_info.rsize <= CIFSMaxBufSize))
2078 cifs_sb->rsize = volume_info.rsize;
2080 cifs_sb->rsize = CIFSMaxBufSize;
2082 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2083 cERROR(1, ("wsize %d too large, using 4096 instead",
2084 volume_info.wsize));
2085 cifs_sb->wsize = 4096;
2086 } else if (volume_info.wsize)
2087 cifs_sb->wsize = volume_info.wsize;
2090 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2092 /* old default of CIFSMaxBufSize was too small now
2093 that SMB Write2 can send multiple pages in kvec.
2094 RFC1001 does not describe what happens when frame
2095 bigger than 128K is sent so use that as max in
2096 conjunction with 52K kvec constraint on arch with 4K
2099 if (cifs_sb->rsize < 2048) {
2100 cifs_sb->rsize = 2048;
2101 /* Windows ME may prefer this */
2102 cFYI(1, ("readsize set to minimum: 2048"));
2104 /* calculate prepath */
2105 cifs_sb->prepath = volume_info.prepath;
2106 if (cifs_sb->prepath) {
2107 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2108 /* we can not convert the / to \ in the path
2109 separators in the prefixpath yet because we do not
2110 know (until reset_cifs_unix_caps is called later)
2111 whether POSIX PATH CAP is available. We normalize
2112 the / to \ after reset_cifs_unix_caps is called */
2113 volume_info.prepath = NULL;
2115 cifs_sb->prepathlen = 0;
2116 cifs_sb->mnt_uid = volume_info.linux_uid;
2117 cifs_sb->mnt_gid = volume_info.linux_gid;
2118 cifs_sb->mnt_file_mode = volume_info.file_mode;
2119 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
2120 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2121 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2123 if (volume_info.noperm)
2124 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2125 if (volume_info.setuids)
2126 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2127 if (volume_info.server_ino)
2128 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2129 if (volume_info.remap)
2130 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2131 if (volume_info.no_xattr)
2132 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2133 if (volume_info.sfu_emul)
2134 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2135 if (volume_info.nobrl)
2136 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2137 if (volume_info.cifs_acl)
2138 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2139 if (volume_info.override_uid)
2140 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2141 if (volume_info.override_gid)
2142 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2143 if (volume_info.dynperm)
2144 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2145 if (volume_info.direct_io) {
2146 cFYI(1, ("mounting share using direct i/o"));
2147 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2150 if ((volume_info.cifs_acl) && (volume_info.dynperm))
2151 cERROR(1, ("mount option dynperm ignored if cifsacl "
2152 "mount option supported"));
2155 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
2156 volume_info.username);
2158 cFYI(1, ("Found match on UNC path"));
2159 /* we can have only one retry value for a connection
2160 to a share so for resources mounted more than once
2161 to the same server share the last value passed in
2162 for the retry flag is used */
2163 tcon->retry = volume_info.retry;
2164 tcon->nocase = volume_info.nocase;
2165 if (tcon->seal != volume_info.seal)
2166 cERROR(1, ("transport encryption setting "
2167 "conflicts with existing tid"));
2169 tcon = tconInfoAlloc();
2173 /* check for null share name ie connecting to
2176 /* BB check if this works for exactly length
2178 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2179 && (strchr(volume_info.UNC + 3, '/') ==
2181 /* rc = connect_to_dfs_path(xid, pSesInfo,
2182 "", cifs_sb->local_nls,
2183 cifs_sb->mnt_cifs_flags &
2184 CIFS_MOUNT_MAP_SPECIAL_CHR);*/
2185 cFYI(1, ("DFS root not supported"));
2189 /* BB Do we need to wrap sesSem around
2190 * this TCon call and Unix SetFS as
2191 * we do on SessSetup and reconnect? */
2192 rc = CIFSTCon(xid, pSesInfo,
2194 tcon, cifs_sb->local_nls);
2195 cFYI(1, ("CIFS Tcon rc = %d", rc));
2196 if (volume_info.nodfs) {
2198 ~SMB_SHARE_IS_IN_DFS;
2199 cFYI(1, ("DFS disabled (%d)",
2204 atomic_inc(&pSesInfo->inUse);
2205 tcon->retry = volume_info.retry;
2206 tcon->nocase = volume_info.nocase;
2207 tcon->seal = volume_info.seal;
2213 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2214 sb->s_maxbytes = (u64) 1 << 63;
2216 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2219 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2220 sb->s_time_gran = 100;
2222 /* on error free sesinfo and tcon struct if needed */
2224 /* if session setup failed, use count is zero but
2225 we still need to free cifsd thread */
2226 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2227 spin_lock(&GlobalMid_Lock);
2228 srvTcp->tcpStatus = CifsExiting;
2229 spin_unlock(&GlobalMid_Lock);
2230 force_sig(SIGKILL, srvTcp->tsk);
2232 /* If find_unc succeeded then rc == 0 so we can not end */
2233 if (tcon) /* up accidently freeing someone elses tcon struct */
2235 if (existingCifsSes == NULL) {
2237 if ((pSesInfo->server) &&
2238 (pSesInfo->status == CifsGood)) {
2240 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2241 /* if the socketUseCount is now zero */
2242 if ((temp_rc == -ESHUTDOWN) &&
2243 (pSesInfo->server) &&
2244 (pSesInfo->server->tsk))
2246 pSesInfo->server->tsk);
2248 cFYI(1, ("No session or bad tcon"));
2249 if ((pSesInfo->server) &&
2250 (pSesInfo->server->tsk)) {
2251 spin_lock(&GlobalMid_Lock);
2252 srvTcp->tcpStatus = CifsExiting;
2253 spin_unlock(&GlobalMid_Lock);
2255 pSesInfo->server->tsk);
2258 sesInfoFree(pSesInfo);
2259 /* pSesInfo = NULL; */
2263 atomic_inc(&tcon->useCount);
2264 cifs_sb->tcon = tcon;
2265 tcon->ses = pSesInfo;
2267 /* do not care if following two calls succeed - informational */
2269 CIFSSMBQFSDeviceInfo(xid, tcon);
2270 CIFSSMBQFSAttributeInfo(xid, tcon);
2273 /* tell server which Unix caps we support */
2274 if (tcon->ses->capabilities & CAP_UNIX)
2275 /* reset of caps checks mount to see if unix extensions
2276 disabled for just this mount */
2277 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2279 tcon->unix_ext = 0; /* server does not support them */
2281 /* convert forward to back slashes in prepath here if needed */
2282 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2283 convert_delimiter(cifs_sb->prepath,
2284 CIFS_DIR_SEP(cifs_sb));
2286 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2287 cifs_sb->rsize = 1024 * 127;
2289 ("no very large read support, rsize now 127K"));
2291 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2292 cifs_sb->wsize = min(cifs_sb->wsize,
2293 (tcon->ses->server->maxBuf -
2294 MAX_CIFS_HDR_SIZE));
2295 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2296 cifs_sb->rsize = min(cifs_sb->rsize,
2297 (tcon->ses->server->maxBuf -
2298 MAX_CIFS_HDR_SIZE));
2301 /* volume_info.password is freed above when existing session found
2302 (in which case it is not needed anymore) but when new sesion is created
2303 the password ptr is put in the new session structure (in which case the
2304 password will be freed at unmount time) */
2306 /* zero out password before freeing */
2307 if (volume_info.password != NULL) {
2308 memset(volume_info.password, 0, strlen(volume_info.password));
2309 kfree(volume_info.password);
2311 kfree(volume_info.UNC);
2312 kfree(volume_info.prepath);
2318 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2319 char session_key[CIFS_SESS_KEY_SIZE],
2320 const struct nls_table *nls_codepage)
2322 struct smb_hdr *smb_buffer;
2323 struct smb_hdr *smb_buffer_response;
2324 SESSION_SETUP_ANDX *pSMB;
2325 SESSION_SETUP_ANDX *pSMBr;
2330 int remaining_words = 0;
2331 int bytes_returned = 0;
2336 cFYI(1, ("In sesssetup"));
2339 user = ses->userName;
2340 domain = ses->domainName;
2341 smb_buffer = cifs_buf_get();
2343 if (smb_buffer == NULL)
2346 smb_buffer_response = smb_buffer;
2347 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2349 /* send SMBsessionSetup here */
2350 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2351 NULL /* no tCon exists yet */ , 13 /* wct */ );
2353 smb_buffer->Mid = GetNextMid(ses->server);
2354 pSMB->req_no_secext.AndXCommand = 0xFF;
2355 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2356 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2358 if (ses->server->secMode &
2359 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2360 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2362 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2363 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2364 if (ses->capabilities & CAP_UNICODE) {
2365 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2366 capabilities |= CAP_UNICODE;
2368 if (ses->capabilities & CAP_STATUS32) {
2369 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2370 capabilities |= CAP_STATUS32;
2372 if (ses->capabilities & CAP_DFS) {
2373 smb_buffer->Flags2 |= SMBFLG2_DFS;
2374 capabilities |= CAP_DFS;
2376 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2378 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2379 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2381 pSMB->req_no_secext.CaseSensitivePasswordLength =
2382 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2383 bcc_ptr = pByteArea(smb_buffer);
2384 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2385 bcc_ptr += CIFS_SESS_KEY_SIZE;
2386 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2387 bcc_ptr += CIFS_SESS_KEY_SIZE;
2389 if (ses->capabilities & CAP_UNICODE) {
2390 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2395 bytes_returned = 0; /* skip null user */
2398 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2400 /* convert number of 16 bit words to bytes */
2401 bcc_ptr += 2 * bytes_returned;
2402 bcc_ptr += 2; /* trailing null */
2405 cifs_strtoUCS((__le16 *) bcc_ptr,
2406 "CIFS_LINUX_DOM", 32, nls_codepage);
2409 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2411 bcc_ptr += 2 * bytes_returned;
2414 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2416 bcc_ptr += 2 * bytes_returned;
2418 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2420 bcc_ptr += 2 * bytes_returned;
2423 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2425 bcc_ptr += 2 * bytes_returned;
2429 strncpy(bcc_ptr, user, 200);
2430 bcc_ptr += strnlen(user, 200);
2434 if (domain == NULL) {
2435 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2436 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2438 strncpy(bcc_ptr, domain, 64);
2439 bcc_ptr += strnlen(domain, 64);
2443 strcpy(bcc_ptr, "Linux version ");
2444 bcc_ptr += strlen("Linux version ");
2445 strcpy(bcc_ptr, utsname()->release);
2446 bcc_ptr += strlen(utsname()->release) + 1;
2447 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2448 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2450 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2451 smb_buffer->smb_buf_length += count;
2452 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2454 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2455 &bytes_returned, CIFS_LONG_OP);
2457 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2458 } else if ((smb_buffer_response->WordCount == 3)
2459 || (smb_buffer_response->WordCount == 4)) {
2460 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2461 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2462 if (action & GUEST_LOGIN)
2463 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2464 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2466 cFYI(1, ("UID = %d ", ses->Suid));
2467 /* response can have either 3 or 4 word count - Samba sends 3 */
2468 bcc_ptr = pByteArea(smb_buffer_response);
2469 if ((pSMBr->resp.hdr.WordCount == 3)
2470 || ((pSMBr->resp.hdr.WordCount == 4)
2471 && (blob_len < pSMBr->resp.ByteCount))) {
2472 if (pSMBr->resp.hdr.WordCount == 4)
2473 bcc_ptr += blob_len;
2475 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2476 if ((long) (bcc_ptr) % 2) {
2478 (BCC(smb_buffer_response) - 1) / 2;
2479 /* Unicode strings must be word
2484 BCC(smb_buffer_response) / 2;
2487 UniStrnlen((wchar_t *) bcc_ptr,
2488 remaining_words - 1);
2489 /* We look for obvious messed up bcc or strings in response so we do not go off
2490 the end since (at least) WIN2K and Windows XP have a major bug in not null
2491 terminating last Unicode string in response */
2493 kfree(ses->serverOS);
2494 ses->serverOS = kzalloc(2 * (len + 1),
2496 if (ses->serverOS == NULL)
2497 goto sesssetup_nomem;
2498 cifs_strfromUCS_le(ses->serverOS,
2501 bcc_ptr += 2 * (len + 1);
2502 remaining_words -= len + 1;
2503 ses->serverOS[2 * len] = 0;
2504 ses->serverOS[1 + (2 * len)] = 0;
2505 if (remaining_words > 0) {
2506 len = UniStrnlen((wchar_t *)bcc_ptr,
2508 kfree(ses->serverNOS);
2509 ses->serverNOS = kzalloc(2 * (len + 1),
2511 if (ses->serverNOS == NULL)
2512 goto sesssetup_nomem;
2513 cifs_strfromUCS_le(ses->serverNOS,
2516 bcc_ptr += 2 * (len + 1);
2517 ses->serverNOS[2 * len] = 0;
2518 ses->serverNOS[1 + (2 * len)] = 0;
2519 if (strncmp(ses->serverNOS,
2520 "NT LAN Manager 4", 16) == 0) {
2521 cFYI(1, ("NT4 server"));
2522 ses->flags |= CIFS_SES_NT4;
2524 remaining_words -= len + 1;
2525 if (remaining_words > 0) {
2526 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2527 /* last string is not always null terminated
2528 (for e.g. for Windows XP & 2000) */
2529 if (ses->serverDomain)
2530 kfree(ses->serverDomain);
2534 if (ses->serverDomain == NULL)
2535 goto sesssetup_nomem;
2536 cifs_strfromUCS_le(ses->serverDomain,
2539 bcc_ptr += 2 * (len + 1);
2540 ses->serverDomain[2*len] = 0;
2541 ses->serverDomain[1+(2*len)] = 0;
2542 } else { /* else no more room so create
2543 dummy domain string */
2544 if (ses->serverDomain)
2545 kfree(ses->serverDomain);
2547 kzalloc(2, GFP_KERNEL);
2549 } else { /* no room so create dummy domain
2552 /* if these kcallocs fail not much we
2553 can do, but better to not fail the
2555 kfree(ses->serverDomain);
2557 kzalloc(2, GFP_KERNEL);
2558 kfree(ses->serverNOS);
2560 kzalloc(2, GFP_KERNEL);
2562 } else { /* ASCII */
2563 len = strnlen(bcc_ptr, 1024);
2564 if (((long) bcc_ptr + len) - (long)
2565 pByteArea(smb_buffer_response)
2566 <= BCC(smb_buffer_response)) {
2567 kfree(ses->serverOS);
2568 ses->serverOS = kzalloc(len + 1,
2570 if (ses->serverOS == NULL)
2571 goto sesssetup_nomem;
2572 strncpy(ses->serverOS, bcc_ptr, len);
2575 /* null terminate the string */
2579 len = strnlen(bcc_ptr, 1024);
2580 kfree(ses->serverNOS);
2581 ses->serverNOS = kzalloc(len + 1,
2583 if (ses->serverNOS == NULL)
2584 goto sesssetup_nomem;
2585 strncpy(ses->serverNOS, bcc_ptr, len);
2590 len = strnlen(bcc_ptr, 1024);
2591 if (ses->serverDomain)
2592 kfree(ses->serverDomain);
2593 ses->serverDomain = kzalloc(len + 1,
2595 if (ses->serverDomain == NULL)
2596 goto sesssetup_nomem;
2597 strncpy(ses->serverDomain, bcc_ptr,
2604 ("Variable field of length %d "
2605 "extends beyond end of smb ",
2610 (" Security Blob Length extends beyond "
2615 (" Invalid Word count %d: ",
2616 smb_buffer_response->WordCount));
2619 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2620 since that could make reconnection harder, and
2621 reconnection might be needed to free memory */
2622 cifs_buf_release(smb_buffer);
2628 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2629 struct cifsSesInfo *ses, bool *pNTLMv2_flag,
2630 const struct nls_table *nls_codepage)
2632 struct smb_hdr *smb_buffer;
2633 struct smb_hdr *smb_buffer_response;
2634 SESSION_SETUP_ANDX *pSMB;
2635 SESSION_SETUP_ANDX *pSMBr;
2639 int remaining_words = 0;
2640 int bytes_returned = 0;
2642 int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
2643 PNEGOTIATE_MESSAGE SecurityBlob;
2644 PCHALLENGE_MESSAGE SecurityBlob2;
2645 __u32 negotiate_flags, capabilities;
2648 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2651 domain = ses->domainName;
2652 *pNTLMv2_flag = false;
2653 smb_buffer = cifs_buf_get();
2654 if (smb_buffer == NULL) {
2657 smb_buffer_response = smb_buffer;
2658 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2659 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2661 /* send SMBsessionSetup here */
2662 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2663 NULL /* no tCon exists yet */ , 12 /* wct */ );
2665 smb_buffer->Mid = GetNextMid(ses->server);
2666 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2667 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2669 pSMB->req.AndXCommand = 0xFF;
2670 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2671 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2673 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2674 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2676 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2677 CAP_EXTENDED_SECURITY;
2678 if (ses->capabilities & CAP_UNICODE) {
2679 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2680 capabilities |= CAP_UNICODE;
2682 if (ses->capabilities & CAP_STATUS32) {
2683 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2684 capabilities |= CAP_STATUS32;
2686 if (ses->capabilities & CAP_DFS) {
2687 smb_buffer->Flags2 |= SMBFLG2_DFS;
2688 capabilities |= CAP_DFS;
2690 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2692 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2693 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2694 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2695 SecurityBlob->MessageType = NtLmNegotiate;
2697 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2698 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2699 NTLMSSP_NEGOTIATE_56 |
2700 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2702 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2703 /* if (ntlmv2_support)
2704 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2705 /* setup pointers to domain name and workstation name */
2706 bcc_ptr += SecurityBlobLength;
2708 SecurityBlob->WorkstationName.Buffer = 0;
2709 SecurityBlob->WorkstationName.Length = 0;
2710 SecurityBlob->WorkstationName.MaximumLength = 0;
2712 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2713 along with username on auth request (ie the response to challenge) */
2714 SecurityBlob->DomainName.Buffer = 0;
2715 SecurityBlob->DomainName.Length = 0;
2716 SecurityBlob->DomainName.MaximumLength = 0;
2717 if (ses->capabilities & CAP_UNICODE) {
2718 if ((long) bcc_ptr % 2) {
2724 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2726 bcc_ptr += 2 * bytes_returned;
2728 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2730 bcc_ptr += 2 * bytes_returned;
2731 bcc_ptr += 2; /* null terminate Linux version */
2733 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2735 bcc_ptr += 2 * bytes_returned;
2738 bcc_ptr += 2; /* null terminate network opsys string */
2741 bcc_ptr += 2; /* null domain */
2742 } else { /* ASCII */
2743 strcpy(bcc_ptr, "Linux version ");
2744 bcc_ptr += strlen("Linux version ");
2745 strcpy(bcc_ptr, utsname()->release);
2746 bcc_ptr += strlen(utsname()->release) + 1;
2747 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2748 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2749 bcc_ptr++; /* empty domain field */
2752 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2753 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2754 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2755 smb_buffer->smb_buf_length += count;
2756 pSMB->req.ByteCount = cpu_to_le16(count);
2758 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2759 &bytes_returned, CIFS_LONG_OP);
2761 if (smb_buffer_response->Status.CifsError ==
2762 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2766 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2767 } else if ((smb_buffer_response->WordCount == 3)
2768 || (smb_buffer_response->WordCount == 4)) {
2769 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2770 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2772 if (action & GUEST_LOGIN)
2773 cFYI(1, (" Guest login"));
2774 /* Do we want to set anything in SesInfo struct when guest login? */
2776 bcc_ptr = pByteArea(smb_buffer_response);
2777 /* response can have either 3 or 4 word count - Samba sends 3 */
2779 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2780 if (SecurityBlob2->MessageType != NtLmChallenge) {
2782 ("Unexpected NTLMSSP message type received %d",
2783 SecurityBlob2->MessageType));
2785 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2786 cFYI(1, ("UID = %d", ses->Suid));
2787 if ((pSMBr->resp.hdr.WordCount == 3)
2788 || ((pSMBr->resp.hdr.WordCount == 4)
2790 pSMBr->resp.ByteCount))) {
2792 if (pSMBr->resp.hdr.WordCount == 4) {
2793 bcc_ptr += blob_len;
2794 cFYI(1, ("Security Blob Length %d",
2798 cFYI(1, ("NTLMSSP Challenge rcvd"));
2800 memcpy(ses->server->cryptKey,
2801 SecurityBlob2->Challenge,
2802 CIFS_CRYPTO_KEY_SIZE);
2803 if (SecurityBlob2->NegotiateFlags &
2804 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2805 *pNTLMv2_flag = true;
2807 if ((SecurityBlob2->NegotiateFlags &
2808 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2809 || (sign_CIFS_PDUs > 1))
2810 ses->server->secMode |=
2811 SECMODE_SIGN_REQUIRED;
2812 if ((SecurityBlob2->NegotiateFlags &
2813 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2814 ses->server->secMode |=
2815 SECMODE_SIGN_ENABLED;
2817 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2818 if ((long) (bcc_ptr) % 2) {
2820 (BCC(smb_buffer_response)
2822 /* Must word align unicode strings */
2827 (smb_buffer_response) / 2;
2830 UniStrnlen((wchar_t *) bcc_ptr,
2831 remaining_words - 1);
2832 /* We look for obvious messed up bcc or strings in response so we do not go off
2833 the end since (at least) WIN2K and Windows XP have a major bug in not null
2834 terminating last Unicode string in response */
2836 kfree(ses->serverOS);
2838 kzalloc(2 * (len + 1), GFP_KERNEL);
2839 cifs_strfromUCS_le(ses->serverOS,
2843 bcc_ptr += 2 * (len + 1);
2844 remaining_words -= len + 1;
2845 ses->serverOS[2 * len] = 0;
2846 ses->serverOS[1 + (2 * len)] = 0;
2847 if (remaining_words > 0) {
2848 len = UniStrnlen((wchar_t *)
2852 kfree(ses->serverNOS);
2854 kzalloc(2 * (len + 1),
2856 cifs_strfromUCS_le(ses->
2862 bcc_ptr += 2 * (len + 1);
2863 ses->serverNOS[2 * len] = 0;
2866 remaining_words -= len + 1;
2867 if (remaining_words > 0) {
2868 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2869 /* last string not always null terminated
2870 (for e.g. for Windows XP & 2000) */
2871 kfree(ses->serverDomain);
2883 ses->serverDomain[2*len]
2888 } /* else no more room so create dummy domain string */
2890 kfree(ses->serverDomain);
2895 } else { /* no room so create dummy domain and NOS string */
2896 kfree(ses->serverDomain);
2898 kzalloc(2, GFP_KERNEL);
2899 kfree(ses->serverNOS);
2901 kzalloc(2, GFP_KERNEL);
2903 } else { /* ASCII */
2904 len = strnlen(bcc_ptr, 1024);
2905 if (((long) bcc_ptr + len) - (long)
2906 pByteArea(smb_buffer_response)
2907 <= BCC(smb_buffer_response)) {
2909 kfree(ses->serverOS);
2913 strncpy(ses->serverOS,
2917 bcc_ptr[0] = 0; /* null terminate string */
2920 len = strnlen(bcc_ptr, 1024);
2921 kfree(ses->serverNOS);
2925 strncpy(ses->serverNOS, bcc_ptr, len);
2930 len = strnlen(bcc_ptr, 1024);
2931 kfree(ses->serverDomain);
2935 strncpy(ses->serverDomain,
2942 ("field of length %d "
2943 "extends beyond end of smb",
2947 cERROR(1, ("Security Blob Length extends beyond"
2951 cERROR(1, ("No session structure passed in."));
2955 (" Invalid Word count %d:",
2956 smb_buffer_response->WordCount));
2960 cifs_buf_release(smb_buffer);
2965 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2966 char *ntlm_session_key, bool ntlmv2_flag,
2967 const struct nls_table *nls_codepage)
2969 struct smb_hdr *smb_buffer;
2970 struct smb_hdr *smb_buffer_response;
2971 SESSION_SETUP_ANDX *pSMB;
2972 SESSION_SETUP_ANDX *pSMBr;
2977 int remaining_words = 0;
2978 int bytes_returned = 0;
2980 int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
2981 PAUTHENTICATE_MESSAGE SecurityBlob;
2982 __u32 negotiate_flags, capabilities;
2985 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2988 user = ses->userName;
2989 domain = ses->domainName;
2990 smb_buffer = cifs_buf_get();
2991 if (smb_buffer == NULL) {
2994 smb_buffer_response = smb_buffer;
2995 pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
2996 pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
2998 /* send SMBsessionSetup here */
2999 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
3000 NULL /* no tCon exists yet */ , 12 /* wct */ );
3002 smb_buffer->Mid = GetNextMid(ses->server);
3003 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
3004 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
3005 pSMB->req.AndXCommand = 0xFF;
3006 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
3007 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
3009 pSMB->req.hdr.Uid = ses->Suid;
3011 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3012 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3014 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
3015 CAP_EXTENDED_SECURITY;
3016 if (ses->capabilities & CAP_UNICODE) {
3017 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3018 capabilities |= CAP_UNICODE;
3020 if (ses->capabilities & CAP_STATUS32) {
3021 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3022 capabilities |= CAP_STATUS32;
3024 if (ses->capabilities & CAP_DFS) {
3025 smb_buffer->Flags2 |= SMBFLG2_DFS;
3026 capabilities |= CAP_DFS;
3028 pSMB->req.Capabilities = cpu_to_le32(capabilities);
3030 bcc_ptr = (char *)&pSMB->req.SecurityBlob;
3031 SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
3032 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
3033 SecurityBlob->MessageType = NtLmAuthenticate;
3034 bcc_ptr += SecurityBlobLength;
3035 negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
3036 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
3037 0x80000000 | NTLMSSP_NEGOTIATE_128;
3039 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
3041 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
3043 /* setup pointers to domain name and workstation name */
3045 SecurityBlob->WorkstationName.Buffer = 0;
3046 SecurityBlob->WorkstationName.Length = 0;
3047 SecurityBlob->WorkstationName.MaximumLength = 0;
3048 SecurityBlob->SessionKey.Length = 0;
3049 SecurityBlob->SessionKey.MaximumLength = 0;
3050 SecurityBlob->SessionKey.Buffer = 0;
3052 SecurityBlob->LmChallengeResponse.Length = 0;
3053 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
3054 SecurityBlob->LmChallengeResponse.Buffer = 0;
3056 SecurityBlob->NtChallengeResponse.Length =
3057 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3058 SecurityBlob->NtChallengeResponse.MaximumLength =
3059 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3060 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
3061 SecurityBlob->NtChallengeResponse.Buffer =
3062 cpu_to_le32(SecurityBlobLength);
3063 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
3064 bcc_ptr += CIFS_SESS_KEY_SIZE;
3066 if (ses->capabilities & CAP_UNICODE) {
3067 if (domain == NULL) {
3068 SecurityBlob->DomainName.Buffer = 0;
3069 SecurityBlob->DomainName.Length = 0;
3070 SecurityBlob->DomainName.MaximumLength = 0;
3072 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
3075 SecurityBlob->DomainName.MaximumLength =
3077 SecurityBlob->DomainName.Buffer =
3078 cpu_to_le32(SecurityBlobLength);
3080 SecurityBlobLength += ln;
3081 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3084 SecurityBlob->UserName.Buffer = 0;
3085 SecurityBlob->UserName.Length = 0;
3086 SecurityBlob->UserName.MaximumLength = 0;
3088 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
3091 SecurityBlob->UserName.MaximumLength =
3093 SecurityBlob->UserName.Buffer =
3094 cpu_to_le32(SecurityBlobLength);
3096 SecurityBlobLength += ln;
3097 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3100 /* SecurityBlob->WorkstationName.Length =
3101 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3102 SecurityBlob->WorkstationName.Length *= 2;
3103 SecurityBlob->WorkstationName.MaximumLength =
3104 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3105 SecurityBlob->WorkstationName.Buffer =
3106 cpu_to_le32(SecurityBlobLength);
3107 bcc_ptr += SecurityBlob->WorkstationName.Length;
3108 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3109 SecurityBlob->WorkstationName.Length =
3110 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3112 if ((long) bcc_ptr % 2) {
3117 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3119 bcc_ptr += 2 * bytes_returned;
3121 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3123 bcc_ptr += 2 * bytes_returned;
3124 bcc_ptr += 2; /* null term version string */
3126 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3128 bcc_ptr += 2 * bytes_returned;
3131 bcc_ptr += 2; /* null terminate network opsys string */
3134 bcc_ptr += 2; /* null domain */
3135 } else { /* ASCII */
3136 if (domain == NULL) {
3137 SecurityBlob->DomainName.Buffer = 0;
3138 SecurityBlob->DomainName.Length = 0;
3139 SecurityBlob->DomainName.MaximumLength = 0;
3142 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3143 strncpy(bcc_ptr, domain, 63);
3144 ln = strnlen(domain, 64);
3145 SecurityBlob->DomainName.MaximumLength =
3147 SecurityBlob->DomainName.Buffer =
3148 cpu_to_le32(SecurityBlobLength);
3150 SecurityBlobLength += ln;
3151 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3154 SecurityBlob->UserName.Buffer = 0;
3155 SecurityBlob->UserName.Length = 0;
3156 SecurityBlob->UserName.MaximumLength = 0;
3159 strncpy(bcc_ptr, user, 63);
3160 ln = strnlen(user, 64);
3161 SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
3162 SecurityBlob->UserName.Buffer =
3163 cpu_to_le32(SecurityBlobLength);
3165 SecurityBlobLength += ln;
3166 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3168 /* BB fill in our workstation name if known BB */
3170 strcpy(bcc_ptr, "Linux version ");
3171 bcc_ptr += strlen("Linux version ");
3172 strcpy(bcc_ptr, utsname()->release);
3173 bcc_ptr += strlen(utsname()->release) + 1;
3174 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3175 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3176 bcc_ptr++; /* null domain */
3179 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3180 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3181 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3182 smb_buffer->smb_buf_length += count;
3183 pSMB->req.ByteCount = cpu_to_le16(count);
3185 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3186 &bytes_returned, CIFS_LONG_OP);
3188 /* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3189 } else if ((smb_buffer_response->WordCount == 3) ||
3190 (smb_buffer_response->WordCount == 4)) {
3191 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3192 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3193 if (action & GUEST_LOGIN)
3194 cFYI(1, (" Guest login")); /* BB Should we set anything
3195 in SesInfo struct ? */
3196 /* if (SecurityBlob2->MessageType != NtLm??) {
3197 cFYI("Unexpected message type on auth response is %d"));
3202 ("Check challenge UID %d vs auth response UID %d",
3203 ses->Suid, smb_buffer_response->Uid));
3204 /* UID left in wire format */
3205 ses->Suid = smb_buffer_response->Uid;
3206 bcc_ptr = pByteArea(smb_buffer_response);
3207 /* response can have either 3 or 4 word count - Samba sends 3 */
3208 if ((pSMBr->resp.hdr.WordCount == 3)
3209 || ((pSMBr->resp.hdr.WordCount == 4)
3211 pSMBr->resp.ByteCount))) {
3212 if (pSMBr->resp.hdr.WordCount == 4) {
3216 ("Security Blob Length %d ",
3221 ("NTLMSSP response to Authenticate "));
3223 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3224 if ((long) (bcc_ptr) % 2) {
3226 (BCC(smb_buffer_response)
3228 bcc_ptr++; /* Unicode strings must be word aligned */
3230 remaining_words = BCC(smb_buffer_response) / 2;
3232 len = UniStrnlen((wchar_t *) bcc_ptr,
3233 remaining_words - 1);
3234 /* We look for obvious messed up bcc or strings in response so we do not go off
3235 the end since (at least) WIN2K and Windows XP have a major bug in not null
3236 terminating last Unicode string in response */
3238 kfree(ses->serverOS);
3240 kzalloc(2 * (len + 1), GFP_KERNEL);
3241 cifs_strfromUCS_le(ses->serverOS,
3245 bcc_ptr += 2 * (len + 1);
3246 remaining_words -= len + 1;
3247 ses->serverOS[2 * len] = 0;
3248 ses->serverOS[1 + (2 * len)] = 0;
3249 if (remaining_words > 0) {
3250 len = UniStrnlen((wchar_t *)
3254 kfree(ses->serverNOS);
3256 kzalloc(2 * (len + 1),
3258 cifs_strfromUCS_le(ses->
3264 bcc_ptr += 2 * (len + 1);
3265 ses->serverNOS[2 * len] = 0;
3266 ses->serverNOS[1+(2*len)] = 0;
3267 remaining_words -= len + 1;
3268 if (remaining_words > 0) {
3269 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3270 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3271 if (ses->serverDomain)
3272 kfree(ses->serverDomain);
3297 } /* else no more room so create dummy domain string */
3299 if (ses->serverDomain)
3300 kfree(ses->serverDomain);
3301 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3303 } else { /* no room so create dummy domain and NOS string */
3304 if (ses->serverDomain)
3305 kfree(ses->serverDomain);
3306 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3307 kfree(ses->serverNOS);
3308 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3310 } else { /* ASCII */
3311 len = strnlen(bcc_ptr, 1024);
3312 if (((long) bcc_ptr + len) -
3313 (long) pByteArea(smb_buffer_response)
3314 <= BCC(smb_buffer_response)) {
3316 kfree(ses->serverOS);
3317 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
3318 strncpy(ses->serverOS,bcc_ptr, len);
3321 bcc_ptr[0] = 0; /* null terminate the string */
3324 len = strnlen(bcc_ptr, 1024);
3325 kfree(ses->serverNOS);
3326 ses->serverNOS = kzalloc(len+1,
3328 strncpy(ses->serverNOS,
3334 len = strnlen(bcc_ptr, 1024);
3335 if (ses->serverDomain)
3336 kfree(ses->serverDomain);
3340 strncpy(ses->serverDomain,
3346 cFYI(1, ("field of length %d "
3347 "extends beyond end of smb ",
3351 cERROR(1, ("Security Blob extends beyond end "
3355 cERROR(1, ("No session structure passed in."));
3358 cERROR(1, ("Invalid Word count %d: ",
3359 smb_buffer_response->WordCount));
3363 cifs_buf_release(smb_buffer);
3369 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3370 const char *tree, struct cifsTconInfo *tcon,
3371 const struct nls_table *nls_codepage)
3373 struct smb_hdr *smb_buffer;
3374 struct smb_hdr *smb_buffer_response;
3377 unsigned char *bcc_ptr;
3385 smb_buffer = cifs_buf_get();
3386 if (smb_buffer == NULL) {
3389 smb_buffer_response = smb_buffer;
3391 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3392 NULL /*no tid */ , 4 /*wct */ );
3394 smb_buffer->Mid = GetNextMid(ses->server);
3395 smb_buffer->Uid = ses->Suid;
3396 pSMB = (TCONX_REQ *) smb_buffer;
3397 pSMBr = (TCONX_RSP *) smb_buffer_response;
3399 pSMB->AndXCommand = 0xFF;
3400 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3401 bcc_ptr = &pSMB->Password[0];
3402 if ((ses->server->secMode) & SECMODE_USER) {
3403 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3404 *bcc_ptr = 0; /* password is null byte */
3405 bcc_ptr++; /* skip password */
3406 /* already aligned so no need to do it below */
3408 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3409 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3410 specified as required (when that support is added to
3411 the vfs in the future) as only NTLM or the much
3412 weaker LANMAN (which we do not send by default) is accepted
3413 by Samba (not sure whether other servers allow
3414 NTLMv2 password here) */
3415 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3416 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3417 (ses->server->secType == LANMAN))
3418 calc_lanman_hash(ses, bcc_ptr);
3420 #endif /* CIFS_WEAK_PW_HASH */
3421 SMBNTencrypt(ses->password,
3422 ses->server->cryptKey,
3425 bcc_ptr += CIFS_SESS_KEY_SIZE;
3426 if (ses->capabilities & CAP_UNICODE) {
3427 /* must align unicode strings */
3428 *bcc_ptr = 0; /* null byte password */
3433 if (ses->server->secMode &
3434 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3435 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3437 if (ses->capabilities & CAP_STATUS32) {
3438 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3440 if (ses->capabilities & CAP_DFS) {
3441 smb_buffer->Flags2 |= SMBFLG2_DFS;
3443 if (ses->capabilities & CAP_UNICODE) {
3444 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3446 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3447 6 /* max utf8 char length in bytes */ *
3448 (/* server len*/ + 256 /* share len */), nls_codepage);
3449 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3450 bcc_ptr += 2; /* skip trailing null */
3451 } else { /* ASCII */
3452 strcpy(bcc_ptr, tree);
3453 bcc_ptr += strlen(tree) + 1;
3455 strcpy(bcc_ptr, "?????");
3456 bcc_ptr += strlen("?????");
3458 count = bcc_ptr - &pSMB->Password[0];
3459 pSMB->hdr.smb_buf_length += count;
3460 pSMB->ByteCount = cpu_to_le16(count);
3462 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3465 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3466 /* above now done in SendReceive */
3467 if ((rc == 0) && (tcon != NULL)) {
3468 tcon->tidStatus = CifsGood;
3469 tcon->tid = smb_buffer_response->Tid;
3470 bcc_ptr = pByteArea(smb_buffer_response);
3471 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3472 /* skip service field (NB: this field is always ASCII) */
3474 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3475 (bcc_ptr[2] == 'C')) {
3476 cFYI(1, ("IPC connection"));
3479 } else if (length == 2) {
3480 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3481 /* the most common case */
3482 cFYI(1, ("disk share connection"));
3485 bcc_ptr += length + 1;
3486 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3487 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3488 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3489 if ((bcc_ptr + (2 * length)) -
3490 pByteArea(smb_buffer_response) <=
3491 BCC(smb_buffer_response)) {
3492 kfree(tcon->nativeFileSystem);
3493 tcon->nativeFileSystem =
3494 kzalloc(length + 2, GFP_KERNEL);
3495 if (tcon->nativeFileSystem)
3497 tcon->nativeFileSystem,
3499 length, nls_codepage);
3500 bcc_ptr += 2 * length;
3501 bcc_ptr[0] = 0; /* null terminate the string */
3505 /* else do not bother copying these information fields*/
3507 length = strnlen(bcc_ptr, 1024);
3508 if ((bcc_ptr + length) -
3509 pByteArea(smb_buffer_response) <=
3510 BCC(smb_buffer_response)) {
3511 kfree(tcon->nativeFileSystem);
3512 tcon->nativeFileSystem =
3513 kzalloc(length + 1, GFP_KERNEL);
3514 if (tcon->nativeFileSystem)
3515 strncpy(tcon->nativeFileSystem, bcc_ptr,
3518 /* else do not bother copying these information fields*/
3520 if ((smb_buffer_response->WordCount == 3) ||
3521 (smb_buffer_response->WordCount == 7))
3522 /* field is in same location */
3523 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3526 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3527 } else if ((rc == 0) && tcon == NULL) {
3528 /* all we need to save for IPC$ connection */
3529 ses->ipc_tid = smb_buffer_response->Tid;
3532 cifs_buf_release(smb_buffer);
3537 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3541 struct cifsSesInfo *ses = NULL;
3542 struct task_struct *cifsd_task;
3547 if (cifs_sb->tcon) {
3548 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3549 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3554 DeleteTconOplockQEntries(cifs_sb->tcon);
3555 tconInfoFree(cifs_sb->tcon);
3556 if ((ses) && (ses->server)) {
3557 /* save off task so we do not refer to ses later */
3558 cifsd_task = ses->server->tsk;
3559 cFYI(1, ("About to do SMBLogoff "));
3560 rc = CIFSSMBLogoff(xid, ses);
3564 } else if (rc == -ESHUTDOWN) {
3565 cFYI(1, ("Waking up socket by sending signal"));
3567 force_sig(SIGKILL, cifsd_task);
3569 } /* else - we have an smb session
3570 left on this socket do not kill cifsd */
3572 cFYI(1, ("No session or bad tcon"));
3575 cifs_sb->tcon = NULL;
3576 tmp = cifs_sb->prepath;
3577 cifs_sb->prepathlen = 0;
3578 cifs_sb->prepath = NULL;
3587 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3588 struct nls_table *nls_info)
3591 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3592 bool ntlmv2_flag = false;
3594 struct TCP_Server_Info *server = pSesInfo->server;
3596 /* what if server changes its buffer size after dropping the session? */
3597 if (server->maxBuf == 0) /* no need to send on reconnect */ {
3598 rc = CIFSSMBNegotiate(xid, pSesInfo);
3599 if (rc == -EAGAIN) {
3600 /* retry only once on 1st time connection */
3601 rc = CIFSSMBNegotiate(xid, pSesInfo);
3606 spin_lock(&GlobalMid_Lock);
3607 if (server->tcpStatus != CifsExiting)
3608 server->tcpStatus = CifsGood;
3611 spin_unlock(&GlobalMid_Lock);
3620 pSesInfo->flags = 0;
3621 pSesInfo->capabilities = server->capabilities;
3622 if (linuxExtEnabled == 0)
3623 pSesInfo->capabilities &= (~CAP_UNIX);
3624 /* pSesInfo->sequence_number = 0;*/
3625 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3626 server->secMode, server->capabilities, server->timeAdj));
3628 if (experimEnabled < 2)
3629 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
3630 else if (extended_security
3631 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3632 && (server->secType == NTLMSSP)) {
3634 } else if (extended_security
3635 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3636 && (server->secType == RawNTLMSSP)) {
3637 cFYI(1, ("NTLMSSP sesssetup"));
3638 rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag,
3643 cFYI(1, ("more secure NTLM ver2 hash"));
3644 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3649 v2_response = kmalloc(16 + 64 /* blob*/,
3652 CalcNTLMv2_response(pSesInfo,
3655 cifs_calculate_ntlmv2_mac_key */
3657 /* BB Put dummy sig in SessSetup PDU? */
3664 SMBNTencrypt(pSesInfo->password,
3669 cifs_calculate_mac_key(
3670 &server->mac_signing_key,
3672 pSesInfo->password);
3674 /* for better security the weaker lanman hash not sent
3675 in AuthSessSetup so we no longer calculate it */
3677 rc = CIFSNTLMSSPAuthSessSetup(xid, pSesInfo,
3682 } else { /* old style NTLM 0.12 session setup */
3683 SMBNTencrypt(pSesInfo->password, server->cryptKey,
3687 cifs_calculate_mac_key(&server->mac_signing_key,
3689 pSesInfo->password);
3691 rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info);
3694 cERROR(1, ("Send error in SessSetup = %d", rc));
3696 cFYI(1, ("CIFS Session Established successfully"));
3697 spin_lock(&GlobalMid_Lock);
3698 pSesInfo->status = CifsGood;
3699 spin_unlock(&GlobalMid_Lock);