4 * Copyright (C) International Business Machines Corp., 2002,2008
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <linux/net.h>
23 #include <linux/string.h>
24 #include <linux/list.h>
25 #include <linux/wait.h>
26 #include <linux/ipv6.h>
27 #include <linux/pagemap.h>
28 #include <linux/ctype.h>
29 #include <linux/utsname.h>
30 #include <linux/mempool.h>
31 #include <linux/delay.h>
32 #include <linux/completion.h>
33 #include <linux/kthread.h>
34 #include <linux/pagevec.h>
35 #include <linux/freezer.h>
36 #include <asm/uaccess.h>
37 #include <asm/processor.h>
40 #include "cifsproto.h"
41 #include "cifs_unicode.h"
42 #include "cifs_debug.h"
43 #include "cifs_fs_sb.h"
46 #include "rfc1002pdu.h"
50 #define RFC1001_PORT 139
52 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
55 extern mempool_t *cifs_req_poolp;
63 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
64 char *iocharset; /* local code page for mapping to and from Unicode */
65 char source_rfc1001_name[16]; /* netbios name of client */
66 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
80 bool no_psx_acl:1; /* set if posix acl support should be disabled */
82 bool no_xattr:1; /* set if xattr (EA) support should be disabled*/
83 bool server_ino:1; /* use inode numbers from server ie UniqueId */
85 bool remap:1; /* set to remap seven reserved chars in filenames */
86 bool posix_paths:1; /* unset to not ask for posix pathnames. */
89 bool nullauth:1; /* attempt to authenticate with null user */
90 bool nocase:1; /* request case insensitive filenames */
91 bool nobrl:1; /* disable sending byte range locks to srv */
92 bool seal:1; /* request transport encryption on share */
93 bool nodfs:1; /* Do not request DFS, even if available */
94 bool local_lease:1; /* check leases only on local system, not remote */
98 unsigned short int port;
102 static int ipv4_connect(struct sockaddr_in *psin_server,
103 struct socket **csocket,
105 char *server_netb_name);
106 static int ipv6_connect(struct sockaddr_in6 *psin_server,
107 struct socket **csocket);
111 * cifs tcp session reconnection
113 * mark tcp session as reconnecting so temporarily locked
114 * mark all smb sessions as reconnecting for tcp session
115 * reconnect tcp session
116 * wake up waiters on reconnection? - (not needed currently)
120 cifs_reconnect(struct TCP_Server_Info *server)
123 struct list_head *tmp;
124 struct cifsSesInfo *ses;
125 struct cifsTconInfo *tcon;
126 struct mid_q_entry *mid_entry;
128 spin_lock(&GlobalMid_Lock);
129 if (server->tcpStatus == CifsExiting) {
130 /* the demux thread will exit normally
131 next time through the loop */
132 spin_unlock(&GlobalMid_Lock);
135 server->tcpStatus = CifsNeedReconnect;
136 spin_unlock(&GlobalMid_Lock);
139 cFYI(1, ("Reconnecting tcp session"));
141 /* before reconnecting the tcp session, mark the smb session (uid)
142 and the tid bad so they are not used until reconnected */
143 read_lock(&GlobalSMBSeslock);
144 list_for_each(tmp, &GlobalSMBSessionList) {
145 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
147 if (ses->server == server) {
148 ses->status = CifsNeedReconnect;
152 /* else tcp and smb sessions need reconnection */
154 list_for_each(tmp, &GlobalTreeConnectionList) {
155 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
156 if ((tcon->ses) && (tcon->ses->server == server))
157 tcon->tidStatus = CifsNeedReconnect;
159 read_unlock(&GlobalSMBSeslock);
160 /* do not want to be sending data on a socket we are freeing */
161 down(&server->tcpSem);
162 if (server->ssocket) {
163 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
164 server->ssocket->flags));
165 kernel_sock_shutdown(server->ssocket, SHUT_WR);
166 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
167 server->ssocket->state,
168 server->ssocket->flags));
169 sock_release(server->ssocket);
170 server->ssocket = NULL;
173 spin_lock(&GlobalMid_Lock);
174 list_for_each(tmp, &server->pending_mid_q) {
175 mid_entry = list_entry(tmp, struct
178 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
179 /* Mark other intransit requests as needing
180 retry so we do not immediately mark the
181 session bad again (ie after we reconnect
182 below) as they timeout too */
183 mid_entry->midState = MID_RETRY_NEEDED;
186 spin_unlock(&GlobalMid_Lock);
189 while ((server->tcpStatus != CifsExiting) &&
190 (server->tcpStatus != CifsGood)) {
192 if (server->protocolType == IPV6) {
193 rc = ipv6_connect(&server->addr.sockAddr6,
196 rc = ipv4_connect(&server->addr.sockAddr,
198 server->workstation_RFC1001_name,
199 server->server_RFC1001_name);
202 cFYI(1, ("reconnect error %d", rc));
205 atomic_inc(&tcpSesReconnectCount);
206 spin_lock(&GlobalMid_Lock);
207 if (server->tcpStatus != CifsExiting)
208 server->tcpStatus = CifsGood;
209 server->sequence_number = 0;
210 spin_unlock(&GlobalMid_Lock);
211 /* atomic_set(&server->inFlight,0);*/
212 wake_up(&server->response_q);
220 0 not a transact2, or all data present
221 >0 transact2 with that much data missing
222 -EINVAL = invalid transact2
225 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
227 struct smb_t2_rsp *pSMBt;
229 int data_in_this_rsp;
232 if (pSMB->Command != SMB_COM_TRANSACTION2)
235 /* check for plausible wct, bcc and t2 data and parm sizes */
236 /* check for parm and data offset going beyond end of smb */
237 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
238 cFYI(1, ("invalid transact2 word count"));
242 pSMBt = (struct smb_t2_rsp *)pSMB;
244 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
245 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
247 remaining = total_data_size - data_in_this_rsp;
251 else if (remaining < 0) {
252 cFYI(1, ("total data %d smaller than data in frame %d",
253 total_data_size, data_in_this_rsp));
256 cFYI(1, ("missing %d bytes from transact2, check next response",
258 if (total_data_size > maxBufSize) {
259 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
260 total_data_size, maxBufSize));
267 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
269 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
270 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
275 char *data_area_of_target;
276 char *data_area_of_buf2;
279 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
281 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
282 cFYI(1, ("total data size of primary and secondary t2 differ"));
285 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
287 remaining = total_data_size - total_in_buf;
292 if (remaining == 0) /* nothing to do, ignore */
295 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
296 if (remaining < total_in_buf2) {
297 cFYI(1, ("transact2 2nd response contains too much data"));
300 /* find end of first SMB data area */
301 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
302 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
303 /* validate target area */
305 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
306 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
308 data_area_of_target += total_in_buf;
310 /* copy second buffer into end of first buffer */
311 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
312 total_in_buf += total_in_buf2;
313 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
314 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
315 byte_count += total_in_buf2;
316 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
318 byte_count = pTargetSMB->smb_buf_length;
319 byte_count += total_in_buf2;
321 /* BB also add check that we are not beyond maximum buffer size */
323 pTargetSMB->smb_buf_length = byte_count;
325 if (remaining == total_in_buf2) {
326 cFYI(1, ("found the last secondary response"));
327 return 0; /* we are done */
328 } else /* more responses to go */
334 cifs_demultiplex_thread(struct TCP_Server_Info *server)
337 unsigned int pdu_length, total_read;
338 struct smb_hdr *smb_buffer = NULL;
339 struct smb_hdr *bigbuf = NULL;
340 struct smb_hdr *smallbuf = NULL;
341 struct msghdr smb_msg;
343 struct socket *csocket = server->ssocket;
344 struct list_head *tmp;
345 struct cifsSesInfo *ses;
346 struct task_struct *task_to_wake = NULL;
347 struct mid_q_entry *mid_entry;
349 bool isLargeBuf = false;
353 current->flags |= PF_MEMALLOC;
354 cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
356 length = atomic_inc_return(&tcpSesAllocCount);
358 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
362 while (server->tcpStatus != CifsExiting) {
365 if (bigbuf == NULL) {
366 bigbuf = cifs_buf_get();
368 cERROR(1, ("No memory for large SMB response"));
370 /* retry will check if exiting */
373 } else if (isLargeBuf) {
374 /* we are reusing a dirty large buf, clear its start */
375 memset(bigbuf, 0, sizeof(struct smb_hdr));
378 if (smallbuf == NULL) {
379 smallbuf = cifs_small_buf_get();
381 cERROR(1, ("No memory for SMB response"));
383 /* retry will check if exiting */
386 /* beginning of smb buffer is cleared in our buf_get */
387 } else /* if existing small buf clear beginning */
388 memset(smallbuf, 0, sizeof(struct smb_hdr));
392 smb_buffer = smallbuf;
393 iov.iov_base = smb_buffer;
395 smb_msg.msg_control = NULL;
396 smb_msg.msg_controllen = 0;
397 pdu_length = 4; /* enough to get RFC1001 header */
400 kernel_recvmsg(csocket, &smb_msg,
401 &iov, 1, pdu_length, 0 /* BB other flags? */);
403 if (server->tcpStatus == CifsExiting) {
405 } else if (server->tcpStatus == CifsNeedReconnect) {
406 cFYI(1, ("Reconnect after server stopped responding"));
407 cifs_reconnect(server);
408 cFYI(1, ("call to reconnect done"));
409 csocket = server->ssocket;
411 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
412 msleep(1); /* minimum sleep to prevent looping
413 allowing socket to clear and app threads to set
414 tcpStatus CifsNeedReconnect if server hung */
419 } else if (length <= 0) {
420 if (server->tcpStatus == CifsNew) {
421 cFYI(1, ("tcp session abend after SMBnegprot"));
422 /* some servers kill the TCP session rather than
423 returning an SMB negprot error, in which
424 case reconnecting here is not going to help,
425 and so simply return error to mount */
428 if (!try_to_freeze() && (length == -EINTR)) {
429 cFYI(1, ("cifsd thread killed"));
432 cFYI(1, ("Reconnect after unexpected peek error %d",
434 cifs_reconnect(server);
435 csocket = server->ssocket;
436 wake_up(&server->response_q);
438 } else if (length < pdu_length) {
439 cFYI(1, ("requested %d bytes but only got %d bytes",
440 pdu_length, length));
441 pdu_length -= length;
446 /* The right amount was read from socket - 4 bytes */
447 /* so we can now interpret the length field */
449 /* the first byte big endian of the length field,
450 is actually not part of the length but the type
451 with the most common, zero, as regular data */
452 temp = *((char *) smb_buffer);
454 /* Note that FC 1001 length is big endian on the wire,
455 but we convert it here so it is always manipulated
456 as host byte order */
457 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
458 smb_buffer->smb_buf_length = pdu_length;
460 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
462 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
464 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
465 cFYI(1, ("Good RFC 1002 session rsp"));
467 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
468 /* we get this from Windows 98 instead of
469 an error on SMB negprot response */
470 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
472 if (server->tcpStatus == CifsNew) {
473 /* if nack on negprot (rather than
474 ret of smb negprot error) reconnecting
475 not going to help, ret error to mount */
478 /* give server a second to
479 clean up before reconnect attempt */
481 /* always try 445 first on reconnect
482 since we get NACK on some if we ever
483 connected to port 139 (the NACK is
484 since we do not begin with RFC1001
485 session initialize frame) */
486 server->addr.sockAddr.sin_port =
488 cifs_reconnect(server);
489 csocket = server->ssocket;
490 wake_up(&server->response_q);
493 } else if (temp != (char) 0) {
494 cERROR(1, ("Unknown RFC 1002 frame"));
495 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
497 cifs_reconnect(server);
498 csocket = server->ssocket;
502 /* else we have an SMB response */
503 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
504 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
505 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
506 length, pdu_length+4));
507 cifs_reconnect(server);
508 csocket = server->ssocket;
509 wake_up(&server->response_q);
516 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
518 memcpy(bigbuf, smallbuf, 4);
522 iov.iov_base = 4 + (char *)smb_buffer;
523 iov.iov_len = pdu_length;
524 for (total_read = 0; total_read < pdu_length;
525 total_read += length) {
526 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
527 pdu_length - total_read, 0);
528 if ((server->tcpStatus == CifsExiting) ||
529 (length == -EINTR)) {
533 } else if (server->tcpStatus == CifsNeedReconnect) {
534 cifs_reconnect(server);
535 csocket = server->ssocket;
536 /* Reconnect wakes up rspns q */
537 /* Now we will reread sock */
540 } else if ((length == -ERESTARTSYS) ||
541 (length == -EAGAIN)) {
542 msleep(1); /* minimum sleep to prevent looping,
543 allowing socket to clear and app
544 threads to set tcpStatus
545 CifsNeedReconnect if server hung*/
548 } else if (length <= 0) {
549 cERROR(1, ("Received no data, expecting %d",
550 pdu_length - total_read));
551 cifs_reconnect(server);
552 csocket = server->ssocket;
559 else if (reconnect == 1)
562 length += 4; /* account for rfc1002 hdr */
565 dump_smb(smb_buffer, length);
566 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
567 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
573 spin_lock(&GlobalMid_Lock);
574 list_for_each(tmp, &server->pending_mid_q) {
575 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
577 if ((mid_entry->mid == smb_buffer->Mid) &&
578 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
579 (mid_entry->command == smb_buffer->Command)) {
580 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
581 /* We have a multipart transact2 resp */
583 if (mid_entry->resp_buf) {
584 /* merge response - fix up 1st*/
585 if (coalesce_t2(smb_buffer,
586 mid_entry->resp_buf)) {
587 mid_entry->multiRsp =
591 /* all parts received */
592 mid_entry->multiEnd =
598 cERROR(1,("1st trans2 resp needs bigbuf"));
599 /* BB maybe we can fix this up, switch
600 to already allocated large buffer? */
602 /* Have first buffer */
603 mid_entry->resp_buf =
605 mid_entry->largeBuf =
612 mid_entry->resp_buf = smb_buffer;
613 mid_entry->largeBuf = isLargeBuf;
615 task_to_wake = mid_entry->tsk;
616 mid_entry->midState = MID_RESPONSE_RECEIVED;
617 #ifdef CONFIG_CIFS_STATS2
618 mid_entry->when_received = jiffies;
620 /* so we do not time out requests to server
621 which is still responding (since server could
622 be busy but not dead) */
623 server->lstrp = jiffies;
627 spin_unlock(&GlobalMid_Lock);
629 /* Was previous buf put in mpx struct for multi-rsp? */
631 /* smb buffer will be freed by user thread */
637 wake_up_process(task_to_wake);
638 } else if (!is_valid_oplock_break(smb_buffer, server) &&
640 cERROR(1, ("No task to wake, unknown frame received! "
641 "NumMids %d", midCount.counter));
642 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
643 sizeof(struct smb_hdr));
644 #ifdef CONFIG_CIFS_DEBUG2
645 cifs_dump_detail(smb_buffer);
646 cifs_dump_mids(server);
647 #endif /* CIFS_DEBUG2 */
650 } /* end while !EXITING */
652 spin_lock(&GlobalMid_Lock);
653 server->tcpStatus = CifsExiting;
654 spin_unlock(&GlobalMid_Lock);
655 wake_up_all(&server->response_q);
657 /* check if we have blocked requests that need to free */
658 /* Note that cifs_max_pending is normally 50, but
659 can be set at module install time to as little as two */
660 spin_lock(&GlobalMid_Lock);
661 if (atomic_read(&server->inFlight) >= cifs_max_pending)
662 atomic_set(&server->inFlight, cifs_max_pending - 1);
663 /* We do not want to set the max_pending too low or we
664 could end up with the counter going negative */
665 spin_unlock(&GlobalMid_Lock);
666 /* Although there should not be any requests blocked on
667 this queue it can not hurt to be paranoid and try to wake up requests
668 that may haven been blocked when more than 50 at time were on the wire
669 to the same server - they now will see the session is in exit state
670 and get out of SendReceive. */
671 wake_up_all(&server->request_q);
672 /* give those requests time to exit */
675 if (server->ssocket) {
676 sock_release(csocket);
677 server->ssocket = NULL;
679 /* buffer usuallly freed in free_mid - need to free it here on exit */
680 cifs_buf_release(bigbuf);
681 if (smallbuf) /* no sense logging a debug message if NULL */
682 cifs_small_buf_release(smallbuf);
684 read_lock(&GlobalSMBSeslock);
685 if (list_empty(&server->pending_mid_q)) {
686 /* loop through server session structures attached to this and
688 list_for_each(tmp, &GlobalSMBSessionList) {
690 list_entry(tmp, struct cifsSesInfo,
692 if (ses->server == server) {
693 ses->status = CifsExiting;
697 read_unlock(&GlobalSMBSeslock);
699 /* although we can not zero the server struct pointer yet,
700 since there are active requests which may depnd on them,
701 mark the corresponding SMB sessions as exiting too */
702 list_for_each(tmp, &GlobalSMBSessionList) {
703 ses = list_entry(tmp, struct cifsSesInfo,
705 if (ses->server == server)
706 ses->status = CifsExiting;
709 spin_lock(&GlobalMid_Lock);
710 list_for_each(tmp, &server->pending_mid_q) {
711 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
712 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
713 cFYI(1, ("Clearing Mid 0x%x - waking up ",
715 task_to_wake = mid_entry->tsk;
717 wake_up_process(task_to_wake);
720 spin_unlock(&GlobalMid_Lock);
721 read_unlock(&GlobalSMBSeslock);
722 /* 1/8th of sec is more than enough time for them to exit */
726 if (!list_empty(&server->pending_mid_q)) {
727 /* mpx threads have not exited yet give them
728 at least the smb send timeout time for long ops */
729 /* due to delays on oplock break requests, we need
730 to wait at least 45 seconds before giving up
731 on a request getting a response and going ahead
733 cFYI(1, ("Wait for exit from demultiplex thread"));
735 /* if threads still have not exited they are probably never
736 coming home not much else we can do but free the memory */
739 /* last chance to mark ses pointers invalid
740 if there are any pointing to this (e.g
741 if a crazy root user tried to kill cifsd
742 kernel thread explicitly this might happen) */
743 write_lock(&GlobalSMBSeslock);
744 list_for_each(tmp, &GlobalSMBSessionList) {
745 ses = list_entry(tmp, struct cifsSesInfo,
747 if (ses->server == server)
750 write_unlock(&GlobalSMBSeslock);
752 kfree(server->hostname);
755 length = atomic_dec_return(&tcpSesAllocCount);
757 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
763 /* extract the host portion of the UNC string */
765 extract_hostname(const char *unc)
771 /* skip double chars at beginning of string */
772 /* BB: check validity of these bytes? */
775 /* delimiter between hostname and sharename is always '\\' now */
776 delim = strchr(src, '\\');
778 return ERR_PTR(-EINVAL);
781 dst = kmalloc((len + 1), GFP_KERNEL);
783 return ERR_PTR(-ENOMEM);
785 memcpy(dst, src, len);
792 cifs_parse_mount_options(char *options, const char *devname,
797 unsigned int temp_len, i, j;
803 if (Local_System_Name[0] != 0)
804 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
806 char *nodename = utsname()->nodename;
807 int n = strnlen(nodename, 15);
808 memset(vol->source_rfc1001_name, 0x20, 15);
809 for (i = 0; i < n; i++) {
810 /* does not have to be perfect mapping since field is
811 informational, only used for servers that do not support
812 port 445 and it can be overridden at mount time */
813 vol->source_rfc1001_name[i] = toupper(nodename[i]);
816 vol->source_rfc1001_name[15] = 0;
817 /* null target name indicates to use *SMBSERVR default called name
818 if we end up sending RFC1001 session initialize */
819 vol->target_rfc1001_name[0] = 0;
820 vol->linux_uid = current->uid; /* current->euid instead? */
821 vol->linux_gid = current->gid;
822 vol->dir_mode = S_IRWXUGO;
823 /* 2767 perms indicate mandatory locking support */
824 vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
826 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
828 /* default is always to request posix paths. */
829 vol->posix_paths = 1;
834 if (strncmp(options, "sep=", 4) == 0) {
835 if (options[4] != 0) {
836 separator[0] = options[4];
839 cFYI(1, ("Null separator not allowed"));
843 while ((data = strsep(&options, separator)) != NULL) {
846 if ((value = strchr(data, '=')) != NULL)
849 /* Have to parse this before we parse for "user" */
850 if (strnicmp(data, "user_xattr", 10) == 0) {
852 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
854 } else if (strnicmp(data, "user", 4) == 0) {
857 "CIFS: invalid or missing username\n");
858 return 1; /* needs_arg; */
859 } else if (!*value) {
860 /* null user, ie anonymous, authentication */
863 if (strnlen(value, 200) < 200) {
864 vol->username = value;
866 printk(KERN_WARNING "CIFS: username too long\n");
869 } else if (strnicmp(data, "pass", 4) == 0) {
871 vol->password = NULL;
873 } else if (value[0] == 0) {
874 /* check if string begins with double comma
875 since that would mean the password really
876 does start with a comma, and would not
877 indicate an empty string */
878 if (value[1] != separator[0]) {
879 vol->password = NULL;
883 temp_len = strlen(value);
884 /* removed password length check, NTLM passwords
885 can be arbitrarily long */
887 /* if comma in password, the string will be
888 prematurely null terminated. Commas in password are
889 specified across the cifs mount interface by a double
890 comma ie ,, and a comma used as in other cases ie ','
891 as a parameter delimiter/separator is single and due
892 to the strsep above is temporarily zeroed. */
894 /* NB: password legally can have multiple commas and
895 the only illegal character in a password is null */
897 if ((value[temp_len] == 0) &&
898 (value[temp_len+1] == separator[0])) {
900 value[temp_len] = separator[0];
901 temp_len += 2; /* move after second comma */
902 while (value[temp_len] != 0) {
903 if (value[temp_len] == separator[0]) {
904 if (value[temp_len+1] ==
906 /* skip second comma */
909 /* single comma indicating start
916 if (value[temp_len] == 0) {
920 /* point option to start of next parm */
921 options = value + temp_len + 1;
923 /* go from value to value + temp_len condensing
924 double commas to singles. Note that this ends up
925 allocating a few bytes too many, which is ok */
926 vol->password = kzalloc(temp_len, GFP_KERNEL);
927 if (vol->password == NULL) {
928 printk(KERN_WARNING "CIFS: no memory "
932 for (i = 0, j = 0; i < temp_len; i++, j++) {
933 vol->password[j] = value[i];
934 if (value[i] == separator[0]
935 && value[i+1] == separator[0]) {
936 /* skip second comma */
940 vol->password[j] = 0;
942 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
943 if (vol->password == NULL) {
944 printk(KERN_WARNING "CIFS: no memory "
948 strcpy(vol->password, value);
950 } else if (strnicmp(data, "ip", 2) == 0) {
951 if (!value || !*value) {
953 } else if (strnlen(value, 35) < 35) {
956 printk(KERN_WARNING "CIFS: ip address "
960 } else if (strnicmp(data, "sec", 3) == 0) {
961 if (!value || !*value) {
962 cERROR(1, ("no security value specified"));
964 } else if (strnicmp(value, "krb5i", 5) == 0) {
965 vol->secFlg |= CIFSSEC_MAY_KRB5 |
967 } else if (strnicmp(value, "krb5p", 5) == 0) {
968 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
970 cERROR(1, ("Krb5 cifs privacy not supported"));
972 } else if (strnicmp(value, "krb5", 4) == 0) {
973 vol->secFlg |= CIFSSEC_MAY_KRB5;
974 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
975 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
977 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
978 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
979 } else if (strnicmp(value, "ntlmi", 5) == 0) {
980 vol->secFlg |= CIFSSEC_MAY_NTLM |
982 } else if (strnicmp(value, "ntlm", 4) == 0) {
983 /* ntlm is default so can be turned off too */
984 vol->secFlg |= CIFSSEC_MAY_NTLM;
985 } else if (strnicmp(value, "nontlm", 6) == 0) {
986 /* BB is there a better way to do this? */
987 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
988 #ifdef CONFIG_CIFS_WEAK_PW_HASH
989 } else if (strnicmp(value, "lanman", 6) == 0) {
990 vol->secFlg |= CIFSSEC_MAY_LANMAN;
992 } else if (strnicmp(value, "none", 4) == 0) {
995 cERROR(1, ("bad security option: %s", value));
998 } else if ((strnicmp(data, "unc", 3) == 0)
999 || (strnicmp(data, "target", 6) == 0)
1000 || (strnicmp(data, "path", 4) == 0)) {
1001 if (!value || !*value) {
1002 printk(KERN_WARNING "CIFS: invalid path to "
1003 "network resource\n");
1004 return 1; /* needs_arg; */
1006 if ((temp_len = strnlen(value, 300)) < 300) {
1007 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1008 if (vol->UNC == NULL)
1010 strcpy(vol->UNC, value);
1011 if (strncmp(vol->UNC, "//", 2) == 0) {
1014 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1016 "CIFS: UNC Path does not begin "
1017 "with // or \\\\ \n");
1021 printk(KERN_WARNING "CIFS: UNC name too long\n");
1024 } else if ((strnicmp(data, "domain", 3) == 0)
1025 || (strnicmp(data, "workgroup", 5) == 0)) {
1026 if (!value || !*value) {
1027 printk(KERN_WARNING "CIFS: invalid domain name\n");
1028 return 1; /* needs_arg; */
1030 /* BB are there cases in which a comma can be valid in
1031 a domain name and need special handling? */
1032 if (strnlen(value, 256) < 256) {
1033 vol->domainname = value;
1034 cFYI(1, ("Domain name set"));
1036 printk(KERN_WARNING "CIFS: domain name too "
1040 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1041 if (!value || !*value) {
1043 "CIFS: invalid path prefix\n");
1044 return 1; /* needs_argument */
1046 if ((temp_len = strnlen(value, 1024)) < 1024) {
1047 if (value[0] != '/')
1048 temp_len++; /* missing leading slash */
1049 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1050 if (vol->prepath == NULL)
1052 if (value[0] != '/') {
1053 vol->prepath[0] = '/';
1054 strcpy(vol->prepath+1, value);
1056 strcpy(vol->prepath, value);
1057 cFYI(1, ("prefix path %s", vol->prepath));
1059 printk(KERN_WARNING "CIFS: prefix too long\n");
1062 } else if (strnicmp(data, "iocharset", 9) == 0) {
1063 if (!value || !*value) {
1064 printk(KERN_WARNING "CIFS: invalid iocharset "
1066 return 1; /* needs_arg; */
1068 if (strnlen(value, 65) < 65) {
1069 if (strnicmp(value, "default", 7))
1070 vol->iocharset = value;
1071 /* if iocharset not set then load_nls_default
1072 is used by caller */
1073 cFYI(1, ("iocharset set to %s", value));
1075 printk(KERN_WARNING "CIFS: iocharset name "
1079 } else if (strnicmp(data, "uid", 3) == 0) {
1080 if (value && *value) {
1082 simple_strtoul(value, &value, 0);
1083 vol->override_uid = 1;
1085 } else if (strnicmp(data, "gid", 3) == 0) {
1086 if (value && *value) {
1088 simple_strtoul(value, &value, 0);
1089 vol->override_gid = 1;
1091 } else if (strnicmp(data, "file_mode", 4) == 0) {
1092 if (value && *value) {
1094 simple_strtoul(value, &value, 0);
1096 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1097 if (value && *value) {
1099 simple_strtoul(value, &value, 0);
1101 } else if (strnicmp(data, "dirmode", 4) == 0) {
1102 if (value && *value) {
1104 simple_strtoul(value, &value, 0);
1106 } else if (strnicmp(data, "port", 4) == 0) {
1107 if (value && *value) {
1109 simple_strtoul(value, &value, 0);
1111 } else if (strnicmp(data, "rsize", 5) == 0) {
1112 if (value && *value) {
1114 simple_strtoul(value, &value, 0);
1116 } else if (strnicmp(data, "wsize", 5) == 0) {
1117 if (value && *value) {
1119 simple_strtoul(value, &value, 0);
1121 } else if (strnicmp(data, "sockopt", 5) == 0) {
1122 if (value && *value) {
1124 simple_strtoul(value, &value, 0);
1126 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1127 if (!value || !*value || (*value == ' ')) {
1128 cFYI(1, ("invalid (empty) netbiosname"));
1130 memset(vol->source_rfc1001_name, 0x20, 15);
1131 for (i = 0; i < 15; i++) {
1132 /* BB are there cases in which a comma can be
1133 valid in this workstation netbios name (and need
1134 special handling)? */
1136 /* We do not uppercase netbiosname for user */
1140 vol->source_rfc1001_name[i] =
1143 /* The string has 16th byte zero still from
1144 set at top of the function */
1145 if ((i == 15) && (value[i] != 0))
1146 printk(KERN_WARNING "CIFS: netbiosname"
1147 " longer than 15 truncated.\n");
1149 } else if (strnicmp(data, "servern", 7) == 0) {
1150 /* servernetbiosname specified override *SMBSERVER */
1151 if (!value || !*value || (*value == ' ')) {
1152 cFYI(1, ("empty server netbiosname specified"));
1154 /* last byte, type, is 0x20 for servr type */
1155 memset(vol->target_rfc1001_name, 0x20, 16);
1157 for (i = 0; i < 15; i++) {
1158 /* BB are there cases in which a comma can be
1159 valid in this workstation netbios name
1160 (and need special handling)? */
1162 /* user or mount helper must uppercase
1167 vol->target_rfc1001_name[i] =
1170 /* The string has 16th byte zero still from
1171 set at top of the function */
1172 if ((i == 15) && (value[i] != 0))
1173 printk(KERN_WARNING "CIFS: server net"
1174 "biosname longer than 15 truncated.\n");
1176 } else if (strnicmp(data, "credentials", 4) == 0) {
1178 } else if (strnicmp(data, "version", 3) == 0) {
1180 } else if (strnicmp(data, "guest", 5) == 0) {
1182 } else if (strnicmp(data, "rw", 2) == 0) {
1184 } else if ((strnicmp(data, "suid", 4) == 0) ||
1185 (strnicmp(data, "nosuid", 6) == 0) ||
1186 (strnicmp(data, "exec", 4) == 0) ||
1187 (strnicmp(data, "noexec", 6) == 0) ||
1188 (strnicmp(data, "nodev", 5) == 0) ||
1189 (strnicmp(data, "noauto", 6) == 0) ||
1190 (strnicmp(data, "dev", 3) == 0)) {
1191 /* The mount tool or mount.cifs helper (if present)
1192 uses these opts to set flags, and the flags are read
1193 by the kernel vfs layer before we get here (ie
1194 before read super) so there is no point trying to
1195 parse these options again and set anything and it
1196 is ok to just ignore them */
1198 } else if (strnicmp(data, "ro", 2) == 0) {
1200 } else if (strnicmp(data, "hard", 4) == 0) {
1202 } else if (strnicmp(data, "soft", 4) == 0) {
1204 } else if (strnicmp(data, "perm", 4) == 0) {
1206 } else if (strnicmp(data, "noperm", 6) == 0) {
1208 } else if (strnicmp(data, "mapchars", 8) == 0) {
1210 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1212 } else if (strnicmp(data, "sfu", 3) == 0) {
1214 } else if (strnicmp(data, "nosfu", 5) == 0) {
1216 } else if (strnicmp(data, "nodfs", 5) == 0) {
1218 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1219 vol->posix_paths = 1;
1220 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1221 vol->posix_paths = 0;
1222 } else if (strnicmp(data, "nounix", 6) == 0) {
1223 vol->no_linux_ext = 1;
1224 } else if (strnicmp(data, "nolinux", 7) == 0) {
1225 vol->no_linux_ext = 1;
1226 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1227 (strnicmp(data, "ignorecase", 10) == 0)) {
1229 } else if (strnicmp(data, "brl", 3) == 0) {
1231 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1232 (strnicmp(data, "nolock", 6) == 0)) {
1234 /* turn off mandatory locking in mode
1235 if remote locking is turned off since the
1236 local vfs will do advisory */
1237 if (vol->file_mode ==
1238 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1239 vol->file_mode = S_IALLUGO;
1240 } else if (strnicmp(data, "setuids", 7) == 0) {
1242 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1244 } else if (strnicmp(data, "dynperm", 7) == 0) {
1245 vol->dynperm = true;
1246 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1247 vol->dynperm = false;
1248 } else if (strnicmp(data, "nohard", 6) == 0) {
1250 } else if (strnicmp(data, "nosoft", 6) == 0) {
1252 } else if (strnicmp(data, "nointr", 6) == 0) {
1254 } else if (strnicmp(data, "intr", 4) == 0) {
1256 } else if (strnicmp(data, "serverino", 7) == 0) {
1257 vol->server_ino = 1;
1258 } else if (strnicmp(data, "noserverino", 9) == 0) {
1259 vol->server_ino = 0;
1260 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1262 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1264 } else if (strnicmp(data, "acl", 3) == 0) {
1265 vol->no_psx_acl = 0;
1266 } else if (strnicmp(data, "noacl", 5) == 0) {
1267 vol->no_psx_acl = 1;
1268 #ifdef CONFIG_CIFS_EXPERIMENTAL
1269 } else if (strnicmp(data, "locallease", 6) == 0) {
1270 vol->local_lease = 1;
1272 } else if (strnicmp(data, "sign", 4) == 0) {
1273 vol->secFlg |= CIFSSEC_MUST_SIGN;
1274 } else if (strnicmp(data, "seal", 4) == 0) {
1275 /* we do not do the following in secFlags because seal
1276 is a per tree connection (mount) not a per socket
1277 or per-smb connection option in the protocol */
1278 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1280 } else if (strnicmp(data, "direct", 6) == 0) {
1282 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1284 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1285 if (!value || !*value) {
1286 vol->in6_addr = NULL;
1287 } else if (strnlen(value, 49) == 48) {
1288 vol->in6_addr = value;
1290 printk(KERN_WARNING "CIFS: ip v6 address not "
1291 "48 characters long\n");
1294 } else if (strnicmp(data, "noac", 4) == 0) {
1295 printk(KERN_WARNING "CIFS: Mount option noac not "
1296 "supported. Instead set "
1297 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1299 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1302 if (vol->UNC == NULL) {
1303 if (devname == NULL) {
1304 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1308 if ((temp_len = strnlen(devname, 300)) < 300) {
1309 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1310 if (vol->UNC == NULL)
1312 strcpy(vol->UNC, devname);
1313 if (strncmp(vol->UNC, "//", 2) == 0) {
1316 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1317 printk(KERN_WARNING "CIFS: UNC Path does not "
1318 "begin with // or \\\\ \n");
1321 value = strpbrk(vol->UNC+2, "/\\");
1325 printk(KERN_WARNING "CIFS: UNC name too long\n");
1329 if (vol->UNCip == NULL)
1330 vol->UNCip = &vol->UNC[2];
1335 static struct cifsSesInfo *
1336 cifs_find_tcp_session(struct in_addr *target_ip_addr,
1337 struct in6_addr *target_ip6_addr,
1338 char *userName, struct TCP_Server_Info **psrvTcp)
1340 struct list_head *tmp;
1341 struct cifsSesInfo *ses;
1345 read_lock(&GlobalSMBSeslock);
1346 list_for_each(tmp, &GlobalSMBSessionList) {
1347 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1351 if (target_ip_addr &&
1352 ses->server->addr.sockAddr.sin_addr.s_addr != target_ip_addr->s_addr)
1354 else if (target_ip6_addr &&
1355 memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1356 target_ip6_addr, sizeof(*target_ip6_addr)))
1358 /* BB lock server and tcp session; increment use count here?? */
1360 /* found a match on the TCP session */
1361 *psrvTcp = ses->server;
1363 /* BB check if reconnection needed */
1364 if (strncmp(ses->userName, userName, MAX_USERNAME_SIZE) == 0) {
1365 read_unlock(&GlobalSMBSeslock);
1366 /* Found exact match on both TCP and
1370 /* else tcp and smb sessions need reconnection */
1372 read_unlock(&GlobalSMBSeslock);
1377 static struct cifsTconInfo *
1378 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1380 struct list_head *tmp;
1381 struct cifsTconInfo *tcon;
1384 read_lock(&GlobalSMBSeslock);
1386 list_for_each(tmp, &GlobalTreeConnectionList) {
1387 cFYI(1, ("Next tcon"));
1388 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1389 if (!tcon->ses || !tcon->ses->server)
1392 old_ip = tcon->ses->server->addr.sockAddr.sin_addr.s_addr;
1393 cFYI(1, ("old ip addr: %x == new ip %x ?",
1394 old_ip, new_target_ip_addr));
1396 if (old_ip != new_target_ip_addr)
1399 /* BB lock tcon, server, tcp session and increment use count? */
1400 /* found a match on the TCP session */
1401 /* BB check if reconnection needed */
1402 cFYI(1, ("IP match, old UNC: %s new: %s",
1403 tcon->treeName, uncName));
1405 if (strncmp(tcon->treeName, uncName, MAX_TREE_SIZE))
1408 cFYI(1, ("and old usr: %s new: %s",
1409 tcon->treeName, uncName));
1411 if (strncmp(tcon->ses->userName, userName, MAX_USERNAME_SIZE))
1414 /* matched smb session (user name) */
1415 read_unlock(&GlobalSMBSeslock);
1419 read_unlock(&GlobalSMBSeslock);
1424 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1425 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1426 struct dfs_info3_param **preferrals, int remap)
1431 *pnum_referrals = 0;
1434 if (pSesInfo->ipc_tid == 0) {
1435 temp_unc = kmalloc(2 /* for slashes */ +
1436 strnlen(pSesInfo->serverName,
1437 SERVER_NAME_LEN_WITH_NULL * 2)
1438 + 1 + 4 /* slash IPC$ */ + 2,
1440 if (temp_unc == NULL)
1444 strcpy(temp_unc + 2, pSesInfo->serverName);
1445 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1446 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1448 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1452 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1453 pnum_referrals, nls_codepage, remap);
1454 /* BB map targetUNCs to dfs_info3 structures, here or
1455 in CIFSGetDFSRefer BB */
1460 #ifdef CONFIG_DEBUG_LOCK_ALLOC
1461 static struct lock_class_key cifs_key[2];
1462 static struct lock_class_key cifs_slock_key[2];
1465 cifs_reclassify_socket4(struct socket *sock)
1467 struct sock *sk = sock->sk;
1468 BUG_ON(sock_owned_by_user(sk));
1469 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
1470 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
1474 cifs_reclassify_socket6(struct socket *sock)
1476 struct sock *sk = sock->sk;
1477 BUG_ON(sock_owned_by_user(sk));
1478 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
1479 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
1483 cifs_reclassify_socket4(struct socket *sock)
1488 cifs_reclassify_socket6(struct socket *sock)
1493 /* See RFC1001 section 14 on representation of Netbios names */
1494 static void rfc1002mangle(char *target, char *source, unsigned int length)
1498 for (i = 0, j = 0; i < (length); i++) {
1499 /* mask a nibble at a time and encode */
1500 target[j] = 'A' + (0x0F & (source[i] >> 4));
1501 target[j+1] = 'A' + (0x0F & source[i]);
1509 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1510 char *netbios_name, char *target_name)
1514 __be16 orig_port = 0;
1516 if (*csocket == NULL) {
1517 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1518 IPPROTO_TCP, csocket);
1520 cERROR(1, ("Error %d creating socket", rc));
1524 /* BB other socket options to set KEEPALIVE, NODELAY? */
1525 cFYI(1, ("Socket created"));
1526 (*csocket)->sk->sk_allocation = GFP_NOFS;
1527 cifs_reclassify_socket4(*csocket);
1531 psin_server->sin_family = AF_INET;
1532 if (psin_server->sin_port) { /* user overrode default port */
1533 rc = (*csocket)->ops->connect(*csocket,
1534 (struct sockaddr *) psin_server,
1535 sizeof(struct sockaddr_in), 0);
1541 /* save original port so we can retry user specified port
1542 later if fall back ports fail this time */
1543 orig_port = psin_server->sin_port;
1545 /* do not retry on the same port we just failed on */
1546 if (psin_server->sin_port != htons(CIFS_PORT)) {
1547 psin_server->sin_port = htons(CIFS_PORT);
1549 rc = (*csocket)->ops->connect(*csocket,
1550 (struct sockaddr *) psin_server,
1551 sizeof(struct sockaddr_in), 0);
1557 psin_server->sin_port = htons(RFC1001_PORT);
1558 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1560 sizeof(struct sockaddr_in), 0);
1565 /* give up here - unless we want to retry on different
1566 protocol families some day */
1569 psin_server->sin_port = orig_port;
1570 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1571 sock_release(*csocket);
1575 /* Eventually check for other socket options to change from
1576 the default. sock_setsockopt not used because it expects
1577 user space buffer */
1578 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1579 (*csocket)->sk->sk_sndbuf,
1580 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1581 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1582 /* make the bufsizes depend on wsize/rsize and max requests */
1583 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1584 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1585 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1586 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1588 /* send RFC1001 sessinit */
1589 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1590 /* some servers require RFC1001 sessinit before sending
1591 negprot - BB check reconnection in case where second
1592 sessinit is sent but no second negprot */
1593 struct rfc1002_session_packet *ses_init_buf;
1594 struct smb_hdr *smb_buf;
1595 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1598 ses_init_buf->trailer.session_req.called_len = 32;
1599 if (target_name && (target_name[0] != 0)) {
1600 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1603 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1604 DEFAULT_CIFS_CALLED_NAME, 16);
1607 ses_init_buf->trailer.session_req.calling_len = 32;
1608 /* calling name ends in null (byte 16) from old smb
1610 if (netbios_name && (netbios_name[0] != 0)) {
1611 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1614 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1615 "LINUX_CIFS_CLNT", 16);
1617 ses_init_buf->trailer.session_req.scope1 = 0;
1618 ses_init_buf->trailer.session_req.scope2 = 0;
1619 smb_buf = (struct smb_hdr *)ses_init_buf;
1620 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1621 smb_buf->smb_buf_length = 0x81000044;
1622 rc = smb_send(*csocket, smb_buf, 0x44,
1623 (struct sockaddr *)psin_server);
1624 kfree(ses_init_buf);
1625 msleep(1); /* RFC1001 layer in at least one server
1626 requires very short break before negprot
1627 presumably because not expecting negprot
1628 to follow so fast. This is a simple
1629 solution that works without
1630 complicating the code and causes no
1631 significant slowing down on mount
1632 for everyone else */
1634 /* else the negprot may still work without this
1635 even though malloc failed */
1643 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1647 __be16 orig_port = 0;
1649 if (*csocket == NULL) {
1650 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1651 IPPROTO_TCP, csocket);
1653 cERROR(1, ("Error %d creating ipv6 socket", rc));
1657 /* BB other socket options to set KEEPALIVE, NODELAY? */
1658 cFYI(1, ("ipv6 Socket created"));
1659 (*csocket)->sk->sk_allocation = GFP_NOFS;
1660 cifs_reclassify_socket6(*csocket);
1664 psin_server->sin6_family = AF_INET6;
1666 if (psin_server->sin6_port) { /* user overrode default port */
1667 rc = (*csocket)->ops->connect(*csocket,
1668 (struct sockaddr *) psin_server,
1669 sizeof(struct sockaddr_in6), 0);
1675 /* save original port so we can retry user specified port
1676 later if fall back ports fail this time */
1678 orig_port = psin_server->sin6_port;
1679 /* do not retry on the same port we just failed on */
1680 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1681 psin_server->sin6_port = htons(CIFS_PORT);
1683 rc = (*csocket)->ops->connect(*csocket,
1684 (struct sockaddr *) psin_server,
1685 sizeof(struct sockaddr_in6), 0);
1691 psin_server->sin6_port = htons(RFC1001_PORT);
1692 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1693 psin_server, sizeof(struct sockaddr_in6), 0);
1698 /* give up here - unless we want to retry on different
1699 protocol families some day */
1702 psin_server->sin6_port = orig_port;
1703 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1704 sock_release(*csocket);
1708 /* Eventually check for other socket options to change from
1709 the default. sock_setsockopt not used because it expects
1710 user space buffer */
1711 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1716 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1717 struct super_block *sb, struct smb_vol *vol_info)
1719 /* if we are reconnecting then should we check to see if
1720 * any requested capabilities changed locally e.g. via
1721 * remount but we can not do much about it here
1722 * if they have (even if we could detect it by the following)
1723 * Perhaps we could add a backpointer to array of sb from tcon
1724 * or if we change to make all sb to same share the same
1725 * sb as NFS - then we only have one backpointer to sb.
1726 * What if we wanted to mount the server share twice once with
1727 * and once without posixacls or posix paths? */
1728 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1730 if (vol_info && vol_info->no_linux_ext) {
1731 tcon->fsUnixInfo.Capability = 0;
1732 tcon->unix_ext = 0; /* Unix Extensions disabled */
1733 cFYI(1, ("Linux protocol extensions disabled"));
1735 } else if (vol_info)
1736 tcon->unix_ext = 1; /* Unix Extensions supported */
1738 if (tcon->unix_ext == 0) {
1739 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1743 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1744 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1746 /* check for reconnect case in which we do not
1747 want to change the mount behavior if we can avoid it */
1748 if (vol_info == NULL) {
1749 /* turn off POSIX ACL and PATHNAMES if not set
1750 originally at mount time */
1751 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1752 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1753 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
1754 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1755 cERROR(1, ("POSIXPATH support change"));
1756 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1757 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
1758 cERROR(1, ("possible reconnect error"));
1760 ("server disabled POSIX path support"));
1764 cap &= CIFS_UNIX_CAP_MASK;
1765 if (vol_info && vol_info->no_psx_acl)
1766 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1767 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
1768 cFYI(1, ("negotiated posix acl support"));
1770 sb->s_flags |= MS_POSIXACL;
1773 if (vol_info && vol_info->posix_paths == 0)
1774 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1775 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1776 cFYI(1, ("negotiate posix pathnames"));
1778 CIFS_SB(sb)->mnt_cifs_flags |=
1779 CIFS_MOUNT_POSIX_PATHS;
1782 /* We might be setting the path sep back to a different
1783 form if we are reconnecting and the server switched its
1784 posix path capability for this share */
1785 if (sb && (CIFS_SB(sb)->prepathlen > 0))
1786 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1788 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
1789 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
1790 CIFS_SB(sb)->rsize = 127 * 1024;
1792 ("larger reads not supported by srv"));
1797 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
1798 #ifdef CONFIG_CIFS_DEBUG2
1799 if (cap & CIFS_UNIX_FCNTL_CAP)
1800 cFYI(1, ("FCNTL cap"));
1801 if (cap & CIFS_UNIX_EXTATTR_CAP)
1802 cFYI(1, ("EXTATTR cap"));
1803 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1804 cFYI(1, ("POSIX path cap"));
1805 if (cap & CIFS_UNIX_XATTR_CAP)
1806 cFYI(1, ("XATTR cap"));
1807 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
1808 cFYI(1, ("POSIX ACL cap"));
1809 if (cap & CIFS_UNIX_LARGE_READ_CAP)
1810 cFYI(1, ("very large read cap"));
1811 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
1812 cFYI(1, ("very large write cap"));
1813 #endif /* CIFS_DEBUG2 */
1814 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1815 if (vol_info == NULL) {
1816 cFYI(1, ("resetting capabilities failed"));
1818 cERROR(1, ("Negotiating Unix capabilities "
1819 "with the server failed. Consider "
1820 "mounting with the Unix Extensions\n"
1821 "disabled, if problems are found, "
1822 "by specifying the nounix mount "
1830 convert_delimiter(char *path, char delim)
1843 for (i = 0; path[i] != '\0'; i++) {
1844 if (path[i] == old_delim)
1850 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1851 char *mount_data, const char *devname)
1855 int address_type = AF_INET;
1856 struct socket *csocket = NULL;
1857 struct sockaddr_in sin_server;
1858 struct sockaddr_in6 sin_server6;
1859 struct smb_vol volume_info;
1860 struct cifsSesInfo *pSesInfo = NULL;
1861 struct cifsSesInfo *existingCifsSes = NULL;
1862 struct cifsTconInfo *tcon = NULL;
1863 struct TCP_Server_Info *srvTcp = NULL;
1867 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1869 memset(&volume_info, 0, sizeof(struct smb_vol));
1870 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1875 if (volume_info.nullauth) {
1876 cFYI(1, ("null user"));
1877 volume_info.username = "";
1878 } else if (volume_info.username) {
1879 /* BB fixme parse for domain name here */
1880 cFYI(1, ("Username: %s", volume_info.username));
1882 cifserror("No username specified");
1883 /* In userspace mount helper we can get user name from alternate
1884 locations such as env variables and files on disk */
1889 if (volume_info.UNCip && volume_info.UNC) {
1890 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
1891 &sin_server.sin_addr.s_addr);
1894 /* not ipv4 address, try ipv6 */
1895 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
1896 &sin_server6.sin6_addr.in6_u);
1898 address_type = AF_INET6;
1900 address_type = AF_INET;
1904 /* we failed translating address */
1909 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1912 } else if (volume_info.UNCip) {
1913 /* BB using ip addr as server name to connect to the
1915 cERROR(1, ("Connecting to DFS root not implemented yet"));
1918 } else /* which servers DFS root would we conect to */ {
1920 ("CIFS mount error: No UNC path (e.g. -o "
1921 "unc=//192.168.1.100/public) specified"));
1926 /* this is needed for ASCII cp to Unicode converts */
1927 if (volume_info.iocharset == NULL) {
1928 cifs_sb->local_nls = load_nls_default();
1929 /* load_nls_default can not return null */
1931 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1932 if (cifs_sb->local_nls == NULL) {
1933 cERROR(1, ("CIFS mount error: iocharset %s not found",
1934 volume_info.iocharset));
1940 if (address_type == AF_INET)
1941 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1942 NULL /* no ipv6 addr */,
1943 volume_info.username, &srvTcp);
1944 else if (address_type == AF_INET6) {
1945 cFYI(1, ("looking for ipv6 address"));
1946 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1947 &sin_server6.sin6_addr,
1948 volume_info.username, &srvTcp);
1955 cFYI(1, ("Existing tcp session with server found"));
1956 } else { /* create socket */
1957 if (volume_info.port)
1958 sin_server.sin_port = htons(volume_info.port);
1960 sin_server.sin_port = 0;
1961 if (address_type == AF_INET6) {
1962 cFYI(1, ("attempting ipv6 connect"));
1963 /* BB should we allow ipv6 on port 139? */
1964 /* other OS never observed in Wild doing 139 with v6 */
1965 rc = ipv6_connect(&sin_server6, &csocket);
1967 rc = ipv4_connect(&sin_server, &csocket,
1968 volume_info.source_rfc1001_name,
1969 volume_info.target_rfc1001_name);
1971 cERROR(1, ("Error connecting to IPv4 socket. "
1972 "Aborting operation"));
1973 if (csocket != NULL)
1974 sock_release(csocket);
1978 srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1981 sock_release(csocket);
1984 memcpy(&srvTcp->addr.sockAddr, &sin_server,
1985 sizeof(struct sockaddr_in));
1986 atomic_set(&srvTcp->inFlight, 0);
1987 /* BB Add code for ipv6 case too */
1988 srvTcp->ssocket = csocket;
1989 srvTcp->protocolType = IPV4;
1990 srvTcp->hostname = extract_hostname(volume_info.UNC);
1991 if (IS_ERR(srvTcp->hostname)) {
1992 rc = PTR_ERR(srvTcp->hostname);
1993 sock_release(csocket);
1996 init_waitqueue_head(&srvTcp->response_q);
1997 init_waitqueue_head(&srvTcp->request_q);
1998 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
1999 /* at this point we are the only ones with the pointer
2000 to the struct since the kernel thread not created yet
2001 so no need to spinlock this init of tcpStatus */
2002 srvTcp->tcpStatus = CifsNew;
2003 init_MUTEX(&srvTcp->tcpSem);
2004 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
2005 if (IS_ERR(srvTcp->tsk)) {
2006 rc = PTR_ERR(srvTcp->tsk);
2007 cERROR(1, ("error %d create cifsd thread", rc));
2009 sock_release(csocket);
2010 kfree(srvTcp->hostname);
2014 memcpy(srvTcp->workstation_RFC1001_name,
2015 volume_info.source_rfc1001_name, 16);
2016 memcpy(srvTcp->server_RFC1001_name,
2017 volume_info.target_rfc1001_name, 16);
2018 srvTcp->sequence_number = 0;
2022 if (existingCifsSes) {
2023 pSesInfo = existingCifsSes;
2024 cFYI(1, ("Existing smb sess found (status=%d)",
2026 down(&pSesInfo->sesSem);
2027 if (pSesInfo->status == CifsNeedReconnect) {
2028 cFYI(1, ("Session needs reconnect"));
2029 rc = cifs_setup_session(xid, pSesInfo,
2030 cifs_sb->local_nls);
2032 up(&pSesInfo->sesSem);
2034 cFYI(1, ("Existing smb sess not found"));
2035 pSesInfo = sesInfoAlloc();
2036 if (pSesInfo == NULL)
2039 pSesInfo->server = srvTcp;
2040 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
2041 NIPQUAD(sin_server.sin_addr.s_addr));
2045 /* volume_info.password freed at unmount */
2046 if (volume_info.password) {
2047 pSesInfo->password = volume_info.password;
2048 /* set to NULL to prevent freeing on exit */
2049 volume_info.password = NULL;
2051 if (volume_info.username)
2052 strncpy(pSesInfo->userName,
2053 volume_info.username,
2055 if (volume_info.domainname) {
2056 int len = strlen(volume_info.domainname);
2057 pSesInfo->domainName =
2058 kmalloc(len + 1, GFP_KERNEL);
2059 if (pSesInfo->domainName)
2060 strcpy(pSesInfo->domainName,
2061 volume_info.domainname);
2063 pSesInfo->linux_uid = volume_info.linux_uid;
2064 pSesInfo->overrideSecFlg = volume_info.secFlg;
2065 down(&pSesInfo->sesSem);
2066 /* BB FIXME need to pass vol->secFlgs BB */
2067 rc = cifs_setup_session(xid, pSesInfo,
2068 cifs_sb->local_nls);
2069 up(&pSesInfo->sesSem);
2071 atomic_inc(&srvTcp->socketUseCount);
2075 /* search for existing tcon to this server share */
2077 if (volume_info.rsize > CIFSMaxBufSize) {
2078 cERROR(1, ("rsize %d too large, using MaxBufSize",
2079 volume_info.rsize));
2080 cifs_sb->rsize = CIFSMaxBufSize;
2081 } else if ((volume_info.rsize) &&
2082 (volume_info.rsize <= CIFSMaxBufSize))
2083 cifs_sb->rsize = volume_info.rsize;
2085 cifs_sb->rsize = CIFSMaxBufSize;
2087 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2088 cERROR(1, ("wsize %d too large, using 4096 instead",
2089 volume_info.wsize));
2090 cifs_sb->wsize = 4096;
2091 } else if (volume_info.wsize)
2092 cifs_sb->wsize = volume_info.wsize;
2095 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2097 /* old default of CIFSMaxBufSize was too small now
2098 that SMB Write2 can send multiple pages in kvec.
2099 RFC1001 does not describe what happens when frame
2100 bigger than 128K is sent so use that as max in
2101 conjunction with 52K kvec constraint on arch with 4K
2104 if (cifs_sb->rsize < 2048) {
2105 cifs_sb->rsize = 2048;
2106 /* Windows ME may prefer this */
2107 cFYI(1, ("readsize set to minimum: 2048"));
2109 /* calculate prepath */
2110 cifs_sb->prepath = volume_info.prepath;
2111 if (cifs_sb->prepath) {
2112 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2113 /* we can not convert the / to \ in the path
2114 separators in the prefixpath yet because we do not
2115 know (until reset_cifs_unix_caps is called later)
2116 whether POSIX PATH CAP is available. We normalize
2117 the / to \ after reset_cifs_unix_caps is called */
2118 volume_info.prepath = NULL;
2120 cifs_sb->prepathlen = 0;
2121 cifs_sb->mnt_uid = volume_info.linux_uid;
2122 cifs_sb->mnt_gid = volume_info.linux_gid;
2123 cifs_sb->mnt_file_mode = volume_info.file_mode;
2124 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
2125 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2126 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2128 if (volume_info.noperm)
2129 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2130 if (volume_info.setuids)
2131 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2132 if (volume_info.server_ino)
2133 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2134 if (volume_info.remap)
2135 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2136 if (volume_info.no_xattr)
2137 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2138 if (volume_info.sfu_emul)
2139 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2140 if (volume_info.nobrl)
2141 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2142 if (volume_info.cifs_acl)
2143 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2144 if (volume_info.override_uid)
2145 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2146 if (volume_info.override_gid)
2147 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2148 if (volume_info.dynperm)
2149 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2150 if (volume_info.direct_io) {
2151 cFYI(1, ("mounting share using direct i/o"));
2152 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2155 if ((volume_info.cifs_acl) && (volume_info.dynperm))
2156 cERROR(1, ("mount option dynperm ignored if cifsacl "
2157 "mount option supported"));
2160 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
2161 volume_info.username);
2163 cFYI(1, ("Found match on UNC path"));
2164 /* we can have only one retry value for a connection
2165 to a share so for resources mounted more than once
2166 to the same server share the last value passed in
2167 for the retry flag is used */
2168 tcon->retry = volume_info.retry;
2169 tcon->nocase = volume_info.nocase;
2170 tcon->local_lease = volume_info.local_lease;
2171 if (tcon->seal != volume_info.seal)
2172 cERROR(1, ("transport encryption setting "
2173 "conflicts with existing tid"));
2175 tcon = tconInfoAlloc();
2179 /* check for null share name ie connecting to
2182 /* BB check if this works for exactly length
2184 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2185 && (strchr(volume_info.UNC + 3, '/') ==
2187 /* rc = connect_to_dfs_path(xid, pSesInfo,
2188 "", cifs_sb->local_nls,
2189 cifs_sb->mnt_cifs_flags &
2190 CIFS_MOUNT_MAP_SPECIAL_CHR);*/
2191 cFYI(1, ("DFS root not supported"));
2195 /* BB Do we need to wrap sesSem around
2196 * this TCon call and Unix SetFS as
2197 * we do on SessSetup and reconnect? */
2198 rc = CIFSTCon(xid, pSesInfo,
2200 tcon, cifs_sb->local_nls);
2201 cFYI(1, ("CIFS Tcon rc = %d", rc));
2202 if (volume_info.nodfs) {
2204 ~SMB_SHARE_IS_IN_DFS;
2205 cFYI(1, ("DFS disabled (%d)",
2210 atomic_inc(&pSesInfo->inUse);
2211 tcon->retry = volume_info.retry;
2212 tcon->nocase = volume_info.nocase;
2213 tcon->seal = volume_info.seal;
2219 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2220 sb->s_maxbytes = (u64) 1 << 63;
2222 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2225 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2226 sb->s_time_gran = 100;
2228 /* on error free sesinfo and tcon struct if needed */
2230 /* if session setup failed, use count is zero but
2231 we still need to free cifsd thread */
2232 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2233 spin_lock(&GlobalMid_Lock);
2234 srvTcp->tcpStatus = CifsExiting;
2235 spin_unlock(&GlobalMid_Lock);
2236 force_sig(SIGKILL, srvTcp->tsk);
2238 /* If find_unc succeeded then rc == 0 so we can not end */
2239 if (tcon) /* up accidently freeing someone elses tcon struct */
2241 if (existingCifsSes == NULL) {
2243 if ((pSesInfo->server) &&
2244 (pSesInfo->status == CifsGood)) {
2246 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2247 /* if the socketUseCount is now zero */
2248 if ((temp_rc == -ESHUTDOWN) &&
2249 (pSesInfo->server) &&
2250 (pSesInfo->server->tsk))
2252 pSesInfo->server->tsk);
2254 cFYI(1, ("No session or bad tcon"));
2255 if ((pSesInfo->server) &&
2256 (pSesInfo->server->tsk)) {
2257 spin_lock(&GlobalMid_Lock);
2258 srvTcp->tcpStatus = CifsExiting;
2259 spin_unlock(&GlobalMid_Lock);
2261 pSesInfo->server->tsk);
2264 sesInfoFree(pSesInfo);
2265 /* pSesInfo = NULL; */
2269 atomic_inc(&tcon->useCount);
2270 cifs_sb->tcon = tcon;
2271 tcon->ses = pSesInfo;
2273 /* do not care if following two calls succeed - informational */
2275 CIFSSMBQFSDeviceInfo(xid, tcon);
2276 CIFSSMBQFSAttributeInfo(xid, tcon);
2279 /* tell server which Unix caps we support */
2280 if (tcon->ses->capabilities & CAP_UNIX)
2281 /* reset of caps checks mount to see if unix extensions
2282 disabled for just this mount */
2283 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2285 tcon->unix_ext = 0; /* server does not support them */
2287 /* convert forward to back slashes in prepath here if needed */
2288 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2289 convert_delimiter(cifs_sb->prepath,
2290 CIFS_DIR_SEP(cifs_sb));
2292 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2293 cifs_sb->rsize = 1024 * 127;
2295 ("no very large read support, rsize now 127K"));
2297 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2298 cifs_sb->wsize = min(cifs_sb->wsize,
2299 (tcon->ses->server->maxBuf -
2300 MAX_CIFS_HDR_SIZE));
2301 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2302 cifs_sb->rsize = min(cifs_sb->rsize,
2303 (tcon->ses->server->maxBuf -
2304 MAX_CIFS_HDR_SIZE));
2307 /* volume_info.password is freed above when existing session found
2308 (in which case it is not needed anymore) but when new sesion is created
2309 the password ptr is put in the new session structure (in which case the
2310 password will be freed at unmount time) */
2312 /* zero out password before freeing */
2313 if (volume_info.password != NULL) {
2314 memset(volume_info.password, 0, strlen(volume_info.password));
2315 kfree(volume_info.password);
2317 kfree(volume_info.UNC);
2318 kfree(volume_info.prepath);
2324 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2325 char session_key[CIFS_SESS_KEY_SIZE],
2326 const struct nls_table *nls_codepage)
2328 struct smb_hdr *smb_buffer;
2329 struct smb_hdr *smb_buffer_response;
2330 SESSION_SETUP_ANDX *pSMB;
2331 SESSION_SETUP_ANDX *pSMBr;
2336 int remaining_words = 0;
2337 int bytes_returned = 0;
2342 cFYI(1, ("In sesssetup"));
2345 user = ses->userName;
2346 domain = ses->domainName;
2347 smb_buffer = cifs_buf_get();
2349 if (smb_buffer == NULL)
2352 smb_buffer_response = smb_buffer;
2353 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2355 /* send SMBsessionSetup here */
2356 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2357 NULL /* no tCon exists yet */ , 13 /* wct */ );
2359 smb_buffer->Mid = GetNextMid(ses->server);
2360 pSMB->req_no_secext.AndXCommand = 0xFF;
2361 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2362 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2364 if (ses->server->secMode &
2365 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2366 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2368 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2369 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2370 if (ses->capabilities & CAP_UNICODE) {
2371 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2372 capabilities |= CAP_UNICODE;
2374 if (ses->capabilities & CAP_STATUS32) {
2375 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2376 capabilities |= CAP_STATUS32;
2378 if (ses->capabilities & CAP_DFS) {
2379 smb_buffer->Flags2 |= SMBFLG2_DFS;
2380 capabilities |= CAP_DFS;
2382 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2384 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2385 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2387 pSMB->req_no_secext.CaseSensitivePasswordLength =
2388 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2389 bcc_ptr = pByteArea(smb_buffer);
2390 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2391 bcc_ptr += CIFS_SESS_KEY_SIZE;
2392 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2393 bcc_ptr += CIFS_SESS_KEY_SIZE;
2395 if (ses->capabilities & CAP_UNICODE) {
2396 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2401 bytes_returned = 0; /* skip null user */
2404 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2406 /* convert number of 16 bit words to bytes */
2407 bcc_ptr += 2 * bytes_returned;
2408 bcc_ptr += 2; /* trailing null */
2411 cifs_strtoUCS((__le16 *) bcc_ptr,
2412 "CIFS_LINUX_DOM", 32, nls_codepage);
2415 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2417 bcc_ptr += 2 * bytes_returned;
2420 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2422 bcc_ptr += 2 * bytes_returned;
2424 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2426 bcc_ptr += 2 * bytes_returned;
2429 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2431 bcc_ptr += 2 * bytes_returned;
2435 strncpy(bcc_ptr, user, 200);
2436 bcc_ptr += strnlen(user, 200);
2440 if (domain == NULL) {
2441 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2442 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2444 strncpy(bcc_ptr, domain, 64);
2445 bcc_ptr += strnlen(domain, 64);
2449 strcpy(bcc_ptr, "Linux version ");
2450 bcc_ptr += strlen("Linux version ");
2451 strcpy(bcc_ptr, utsname()->release);
2452 bcc_ptr += strlen(utsname()->release) + 1;
2453 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2454 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2456 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2457 smb_buffer->smb_buf_length += count;
2458 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2460 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2461 &bytes_returned, CIFS_LONG_OP);
2463 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2464 } else if ((smb_buffer_response->WordCount == 3)
2465 || (smb_buffer_response->WordCount == 4)) {
2466 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2467 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2468 if (action & GUEST_LOGIN)
2469 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2470 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2472 cFYI(1, ("UID = %d ", ses->Suid));
2473 /* response can have either 3 or 4 word count - Samba sends 3 */
2474 bcc_ptr = pByteArea(smb_buffer_response);
2475 if ((pSMBr->resp.hdr.WordCount == 3)
2476 || ((pSMBr->resp.hdr.WordCount == 4)
2477 && (blob_len < pSMBr->resp.ByteCount))) {
2478 if (pSMBr->resp.hdr.WordCount == 4)
2479 bcc_ptr += blob_len;
2481 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2482 if ((long) (bcc_ptr) % 2) {
2484 (BCC(smb_buffer_response) - 1) / 2;
2485 /* Unicode strings must be word
2490 BCC(smb_buffer_response) / 2;
2493 UniStrnlen((wchar_t *) bcc_ptr,
2494 remaining_words - 1);
2495 /* We look for obvious messed up bcc or strings in response so we do not go off
2496 the end since (at least) WIN2K and Windows XP have a major bug in not null
2497 terminating last Unicode string in response */
2499 kfree(ses->serverOS);
2500 ses->serverOS = kzalloc(2 * (len + 1),
2502 if (ses->serverOS == NULL)
2503 goto sesssetup_nomem;
2504 cifs_strfromUCS_le(ses->serverOS,
2507 bcc_ptr += 2 * (len + 1);
2508 remaining_words -= len + 1;
2509 ses->serverOS[2 * len] = 0;
2510 ses->serverOS[1 + (2 * len)] = 0;
2511 if (remaining_words > 0) {
2512 len = UniStrnlen((wchar_t *)bcc_ptr,
2514 kfree(ses->serverNOS);
2515 ses->serverNOS = kzalloc(2 * (len + 1),
2517 if (ses->serverNOS == NULL)
2518 goto sesssetup_nomem;
2519 cifs_strfromUCS_le(ses->serverNOS,
2522 bcc_ptr += 2 * (len + 1);
2523 ses->serverNOS[2 * len] = 0;
2524 ses->serverNOS[1 + (2 * len)] = 0;
2525 if (strncmp(ses->serverNOS,
2526 "NT LAN Manager 4", 16) == 0) {
2527 cFYI(1, ("NT4 server"));
2528 ses->flags |= CIFS_SES_NT4;
2530 remaining_words -= len + 1;
2531 if (remaining_words > 0) {
2532 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2533 /* last string is not always null terminated
2534 (for e.g. for Windows XP & 2000) */
2535 if (ses->serverDomain)
2536 kfree(ses->serverDomain);
2540 if (ses->serverDomain == NULL)
2541 goto sesssetup_nomem;
2542 cifs_strfromUCS_le(ses->serverDomain,
2545 bcc_ptr += 2 * (len + 1);
2546 ses->serverDomain[2*len] = 0;
2547 ses->serverDomain[1+(2*len)] = 0;
2548 } else { /* else no more room so create
2549 dummy domain string */
2550 if (ses->serverDomain)
2551 kfree(ses->serverDomain);
2553 kzalloc(2, GFP_KERNEL);
2555 } else { /* no room so create dummy domain
2558 /* if these kcallocs fail not much we
2559 can do, but better to not fail the
2561 kfree(ses->serverDomain);
2563 kzalloc(2, GFP_KERNEL);
2564 kfree(ses->serverNOS);
2566 kzalloc(2, GFP_KERNEL);
2568 } else { /* ASCII */
2569 len = strnlen(bcc_ptr, 1024);
2570 if (((long) bcc_ptr + len) - (long)
2571 pByteArea(smb_buffer_response)
2572 <= BCC(smb_buffer_response)) {
2573 kfree(ses->serverOS);
2574 ses->serverOS = kzalloc(len + 1,
2576 if (ses->serverOS == NULL)
2577 goto sesssetup_nomem;
2578 strncpy(ses->serverOS, bcc_ptr, len);
2581 /* null terminate the string */
2585 len = strnlen(bcc_ptr, 1024);
2586 kfree(ses->serverNOS);
2587 ses->serverNOS = kzalloc(len + 1,
2589 if (ses->serverNOS == NULL)
2590 goto sesssetup_nomem;
2591 strncpy(ses->serverNOS, bcc_ptr, len);
2596 len = strnlen(bcc_ptr, 1024);
2597 if (ses->serverDomain)
2598 kfree(ses->serverDomain);
2599 ses->serverDomain = kzalloc(len + 1,
2601 if (ses->serverDomain == NULL)
2602 goto sesssetup_nomem;
2603 strncpy(ses->serverDomain, bcc_ptr,
2610 ("Variable field of length %d "
2611 "extends beyond end of smb ",
2616 (" Security Blob Length extends beyond "
2621 (" Invalid Word count %d: ",
2622 smb_buffer_response->WordCount));
2625 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2626 since that could make reconnection harder, and
2627 reconnection might be needed to free memory */
2628 cifs_buf_release(smb_buffer);
2634 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2635 struct cifsSesInfo *ses, bool *pNTLMv2_flag,
2636 const struct nls_table *nls_codepage)
2638 struct smb_hdr *smb_buffer;
2639 struct smb_hdr *smb_buffer_response;
2640 SESSION_SETUP_ANDX *pSMB;
2641 SESSION_SETUP_ANDX *pSMBr;
2645 int remaining_words = 0;
2646 int bytes_returned = 0;
2648 int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
2649 PNEGOTIATE_MESSAGE SecurityBlob;
2650 PCHALLENGE_MESSAGE SecurityBlob2;
2651 __u32 negotiate_flags, capabilities;
2654 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2657 domain = ses->domainName;
2658 *pNTLMv2_flag = false;
2659 smb_buffer = cifs_buf_get();
2660 if (smb_buffer == NULL) {
2663 smb_buffer_response = smb_buffer;
2664 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2665 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2667 /* send SMBsessionSetup here */
2668 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2669 NULL /* no tCon exists yet */ , 12 /* wct */ );
2671 smb_buffer->Mid = GetNextMid(ses->server);
2672 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2673 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2675 pSMB->req.AndXCommand = 0xFF;
2676 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2677 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2679 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2680 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2682 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2683 CAP_EXTENDED_SECURITY;
2684 if (ses->capabilities & CAP_UNICODE) {
2685 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2686 capabilities |= CAP_UNICODE;
2688 if (ses->capabilities & CAP_STATUS32) {
2689 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2690 capabilities |= CAP_STATUS32;
2692 if (ses->capabilities & CAP_DFS) {
2693 smb_buffer->Flags2 |= SMBFLG2_DFS;
2694 capabilities |= CAP_DFS;
2696 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2698 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2699 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2700 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2701 SecurityBlob->MessageType = NtLmNegotiate;
2703 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2704 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2705 NTLMSSP_NEGOTIATE_56 |
2706 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2708 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2709 /* if (ntlmv2_support)
2710 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2711 /* setup pointers to domain name and workstation name */
2712 bcc_ptr += SecurityBlobLength;
2714 SecurityBlob->WorkstationName.Buffer = 0;
2715 SecurityBlob->WorkstationName.Length = 0;
2716 SecurityBlob->WorkstationName.MaximumLength = 0;
2718 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2719 along with username on auth request (ie the response to challenge) */
2720 SecurityBlob->DomainName.Buffer = 0;
2721 SecurityBlob->DomainName.Length = 0;
2722 SecurityBlob->DomainName.MaximumLength = 0;
2723 if (ses->capabilities & CAP_UNICODE) {
2724 if ((long) bcc_ptr % 2) {
2730 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2732 bcc_ptr += 2 * bytes_returned;
2734 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2736 bcc_ptr += 2 * bytes_returned;
2737 bcc_ptr += 2; /* null terminate Linux version */
2739 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2741 bcc_ptr += 2 * bytes_returned;
2744 bcc_ptr += 2; /* null terminate network opsys string */
2747 bcc_ptr += 2; /* null domain */
2748 } else { /* ASCII */
2749 strcpy(bcc_ptr, "Linux version ");
2750 bcc_ptr += strlen("Linux version ");
2751 strcpy(bcc_ptr, utsname()->release);
2752 bcc_ptr += strlen(utsname()->release) + 1;
2753 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2754 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2755 bcc_ptr++; /* empty domain field */
2758 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2759 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2760 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2761 smb_buffer->smb_buf_length += count;
2762 pSMB->req.ByteCount = cpu_to_le16(count);
2764 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2765 &bytes_returned, CIFS_LONG_OP);
2767 if (smb_buffer_response->Status.CifsError ==
2768 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2772 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2773 } else if ((smb_buffer_response->WordCount == 3)
2774 || (smb_buffer_response->WordCount == 4)) {
2775 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2776 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2778 if (action & GUEST_LOGIN)
2779 cFYI(1, (" Guest login"));
2780 /* Do we want to set anything in SesInfo struct when guest login? */
2782 bcc_ptr = pByteArea(smb_buffer_response);
2783 /* response can have either 3 or 4 word count - Samba sends 3 */
2785 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2786 if (SecurityBlob2->MessageType != NtLmChallenge) {
2788 ("Unexpected NTLMSSP message type received %d",
2789 SecurityBlob2->MessageType));
2791 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2792 cFYI(1, ("UID = %d", ses->Suid));
2793 if ((pSMBr->resp.hdr.WordCount == 3)
2794 || ((pSMBr->resp.hdr.WordCount == 4)
2796 pSMBr->resp.ByteCount))) {
2798 if (pSMBr->resp.hdr.WordCount == 4) {
2799 bcc_ptr += blob_len;
2800 cFYI(1, ("Security Blob Length %d",
2804 cFYI(1, ("NTLMSSP Challenge rcvd"));
2806 memcpy(ses->server->cryptKey,
2807 SecurityBlob2->Challenge,
2808 CIFS_CRYPTO_KEY_SIZE);
2809 if (SecurityBlob2->NegotiateFlags &
2810 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2811 *pNTLMv2_flag = true;
2813 if ((SecurityBlob2->NegotiateFlags &
2814 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2815 || (sign_CIFS_PDUs > 1))
2816 ses->server->secMode |=
2817 SECMODE_SIGN_REQUIRED;
2818 if ((SecurityBlob2->NegotiateFlags &
2819 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2820 ses->server->secMode |=
2821 SECMODE_SIGN_ENABLED;
2823 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2824 if ((long) (bcc_ptr) % 2) {
2826 (BCC(smb_buffer_response)
2828 /* Must word align unicode strings */
2833 (smb_buffer_response) / 2;
2836 UniStrnlen((wchar_t *) bcc_ptr,
2837 remaining_words - 1);
2838 /* We look for obvious messed up bcc or strings in response so we do not go off
2839 the end since (at least) WIN2K and Windows XP have a major bug in not null
2840 terminating last Unicode string in response */
2842 kfree(ses->serverOS);
2844 kzalloc(2 * (len + 1), GFP_KERNEL);
2845 cifs_strfromUCS_le(ses->serverOS,
2849 bcc_ptr += 2 * (len + 1);
2850 remaining_words -= len + 1;
2851 ses->serverOS[2 * len] = 0;
2852 ses->serverOS[1 + (2 * len)] = 0;
2853 if (remaining_words > 0) {
2854 len = UniStrnlen((wchar_t *)
2858 kfree(ses->serverNOS);
2860 kzalloc(2 * (len + 1),
2862 cifs_strfromUCS_le(ses->
2868 bcc_ptr += 2 * (len + 1);
2869 ses->serverNOS[2 * len] = 0;
2872 remaining_words -= len + 1;
2873 if (remaining_words > 0) {
2874 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2875 /* last string not always null terminated
2876 (for e.g. for Windows XP & 2000) */
2877 kfree(ses->serverDomain);
2889 ses->serverDomain[2*len]
2894 } /* else no more room so create dummy domain string */
2896 kfree(ses->serverDomain);
2901 } else { /* no room so create dummy domain and NOS string */
2902 kfree(ses->serverDomain);
2904 kzalloc(2, GFP_KERNEL);
2905 kfree(ses->serverNOS);
2907 kzalloc(2, GFP_KERNEL);
2909 } else { /* ASCII */
2910 len = strnlen(bcc_ptr, 1024);
2911 if (((long) bcc_ptr + len) - (long)
2912 pByteArea(smb_buffer_response)
2913 <= BCC(smb_buffer_response)) {
2915 kfree(ses->serverOS);
2919 strncpy(ses->serverOS,
2923 bcc_ptr[0] = 0; /* null terminate string */
2926 len = strnlen(bcc_ptr, 1024);
2927 kfree(ses->serverNOS);
2931 strncpy(ses->serverNOS, bcc_ptr, len);
2936 len = strnlen(bcc_ptr, 1024);
2937 kfree(ses->serverDomain);
2941 strncpy(ses->serverDomain,
2948 ("field of length %d "
2949 "extends beyond end of smb",
2953 cERROR(1, ("Security Blob Length extends beyond"
2957 cERROR(1, ("No session structure passed in."));
2961 (" Invalid Word count %d:",
2962 smb_buffer_response->WordCount));
2966 cifs_buf_release(smb_buffer);
2971 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2972 char *ntlm_session_key, bool ntlmv2_flag,
2973 const struct nls_table *nls_codepage)
2975 struct smb_hdr *smb_buffer;
2976 struct smb_hdr *smb_buffer_response;
2977 SESSION_SETUP_ANDX *pSMB;
2978 SESSION_SETUP_ANDX *pSMBr;
2983 int remaining_words = 0;
2984 int bytes_returned = 0;
2986 int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
2987 PAUTHENTICATE_MESSAGE SecurityBlob;
2988 __u32 negotiate_flags, capabilities;
2991 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2994 user = ses->userName;
2995 domain = ses->domainName;
2996 smb_buffer = cifs_buf_get();
2997 if (smb_buffer == NULL) {
3000 smb_buffer_response = smb_buffer;
3001 pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
3002 pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
3004 /* send SMBsessionSetup here */
3005 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
3006 NULL /* no tCon exists yet */ , 12 /* wct */ );
3008 smb_buffer->Mid = GetNextMid(ses->server);
3009 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
3010 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
3011 pSMB->req.AndXCommand = 0xFF;
3012 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
3013 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
3015 pSMB->req.hdr.Uid = ses->Suid;
3017 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3018 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3020 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
3021 CAP_EXTENDED_SECURITY;
3022 if (ses->capabilities & CAP_UNICODE) {
3023 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3024 capabilities |= CAP_UNICODE;
3026 if (ses->capabilities & CAP_STATUS32) {
3027 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3028 capabilities |= CAP_STATUS32;
3030 if (ses->capabilities & CAP_DFS) {
3031 smb_buffer->Flags2 |= SMBFLG2_DFS;
3032 capabilities |= CAP_DFS;
3034 pSMB->req.Capabilities = cpu_to_le32(capabilities);
3036 bcc_ptr = (char *)&pSMB->req.SecurityBlob;
3037 SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
3038 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
3039 SecurityBlob->MessageType = NtLmAuthenticate;
3040 bcc_ptr += SecurityBlobLength;
3041 negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
3042 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
3043 0x80000000 | NTLMSSP_NEGOTIATE_128;
3045 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
3047 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
3049 /* setup pointers to domain name and workstation name */
3051 SecurityBlob->WorkstationName.Buffer = 0;
3052 SecurityBlob->WorkstationName.Length = 0;
3053 SecurityBlob->WorkstationName.MaximumLength = 0;
3054 SecurityBlob->SessionKey.Length = 0;
3055 SecurityBlob->SessionKey.MaximumLength = 0;
3056 SecurityBlob->SessionKey.Buffer = 0;
3058 SecurityBlob->LmChallengeResponse.Length = 0;
3059 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
3060 SecurityBlob->LmChallengeResponse.Buffer = 0;
3062 SecurityBlob->NtChallengeResponse.Length =
3063 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3064 SecurityBlob->NtChallengeResponse.MaximumLength =
3065 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3066 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
3067 SecurityBlob->NtChallengeResponse.Buffer =
3068 cpu_to_le32(SecurityBlobLength);
3069 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
3070 bcc_ptr += CIFS_SESS_KEY_SIZE;
3072 if (ses->capabilities & CAP_UNICODE) {
3073 if (domain == NULL) {
3074 SecurityBlob->DomainName.Buffer = 0;
3075 SecurityBlob->DomainName.Length = 0;
3076 SecurityBlob->DomainName.MaximumLength = 0;
3078 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
3081 SecurityBlob->DomainName.MaximumLength =
3083 SecurityBlob->DomainName.Buffer =
3084 cpu_to_le32(SecurityBlobLength);
3086 SecurityBlobLength += ln;
3087 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3090 SecurityBlob->UserName.Buffer = 0;
3091 SecurityBlob->UserName.Length = 0;
3092 SecurityBlob->UserName.MaximumLength = 0;
3094 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
3097 SecurityBlob->UserName.MaximumLength =
3099 SecurityBlob->UserName.Buffer =
3100 cpu_to_le32(SecurityBlobLength);
3102 SecurityBlobLength += ln;
3103 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3106 /* SecurityBlob->WorkstationName.Length =
3107 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3108 SecurityBlob->WorkstationName.Length *= 2;
3109 SecurityBlob->WorkstationName.MaximumLength =
3110 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3111 SecurityBlob->WorkstationName.Buffer =
3112 cpu_to_le32(SecurityBlobLength);
3113 bcc_ptr += SecurityBlob->WorkstationName.Length;
3114 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3115 SecurityBlob->WorkstationName.Length =
3116 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3118 if ((long) bcc_ptr % 2) {
3123 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3125 bcc_ptr += 2 * bytes_returned;
3127 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3129 bcc_ptr += 2 * bytes_returned;
3130 bcc_ptr += 2; /* null term version string */
3132 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3134 bcc_ptr += 2 * bytes_returned;
3137 bcc_ptr += 2; /* null terminate network opsys string */
3140 bcc_ptr += 2; /* null domain */
3141 } else { /* ASCII */
3142 if (domain == NULL) {
3143 SecurityBlob->DomainName.Buffer = 0;
3144 SecurityBlob->DomainName.Length = 0;
3145 SecurityBlob->DomainName.MaximumLength = 0;
3148 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3149 strncpy(bcc_ptr, domain, 63);
3150 ln = strnlen(domain, 64);
3151 SecurityBlob->DomainName.MaximumLength =
3153 SecurityBlob->DomainName.Buffer =
3154 cpu_to_le32(SecurityBlobLength);
3156 SecurityBlobLength += ln;
3157 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3160 SecurityBlob->UserName.Buffer = 0;
3161 SecurityBlob->UserName.Length = 0;
3162 SecurityBlob->UserName.MaximumLength = 0;
3165 strncpy(bcc_ptr, user, 63);
3166 ln = strnlen(user, 64);
3167 SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
3168 SecurityBlob->UserName.Buffer =
3169 cpu_to_le32(SecurityBlobLength);
3171 SecurityBlobLength += ln;
3172 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3174 /* BB fill in our workstation name if known BB */
3176 strcpy(bcc_ptr, "Linux version ");
3177 bcc_ptr += strlen("Linux version ");
3178 strcpy(bcc_ptr, utsname()->release);
3179 bcc_ptr += strlen(utsname()->release) + 1;
3180 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3181 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3182 bcc_ptr++; /* null domain */
3185 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3186 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3187 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3188 smb_buffer->smb_buf_length += count;
3189 pSMB->req.ByteCount = cpu_to_le16(count);
3191 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3192 &bytes_returned, CIFS_LONG_OP);
3194 /* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3195 } else if ((smb_buffer_response->WordCount == 3) ||
3196 (smb_buffer_response->WordCount == 4)) {
3197 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3198 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3199 if (action & GUEST_LOGIN)
3200 cFYI(1, (" Guest login")); /* BB Should we set anything
3201 in SesInfo struct ? */
3202 /* if (SecurityBlob2->MessageType != NtLm??) {
3203 cFYI("Unexpected message type on auth response is %d"));
3208 ("Check challenge UID %d vs auth response UID %d",
3209 ses->Suid, smb_buffer_response->Uid));
3210 /* UID left in wire format */
3211 ses->Suid = smb_buffer_response->Uid;
3212 bcc_ptr = pByteArea(smb_buffer_response);
3213 /* response can have either 3 or 4 word count - Samba sends 3 */
3214 if ((pSMBr->resp.hdr.WordCount == 3)
3215 || ((pSMBr->resp.hdr.WordCount == 4)
3217 pSMBr->resp.ByteCount))) {
3218 if (pSMBr->resp.hdr.WordCount == 4) {
3222 ("Security Blob Length %d ",
3227 ("NTLMSSP response to Authenticate "));
3229 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3230 if ((long) (bcc_ptr) % 2) {
3232 (BCC(smb_buffer_response)
3234 bcc_ptr++; /* Unicode strings must be word aligned */
3236 remaining_words = BCC(smb_buffer_response) / 2;
3238 len = UniStrnlen((wchar_t *) bcc_ptr,
3239 remaining_words - 1);
3240 /* We look for obvious messed up bcc or strings in response so we do not go off
3241 the end since (at least) WIN2K and Windows XP have a major bug in not null
3242 terminating last Unicode string in response */
3244 kfree(ses->serverOS);
3246 kzalloc(2 * (len + 1), GFP_KERNEL);
3247 cifs_strfromUCS_le(ses->serverOS,
3251 bcc_ptr += 2 * (len + 1);
3252 remaining_words -= len + 1;
3253 ses->serverOS[2 * len] = 0;
3254 ses->serverOS[1 + (2 * len)] = 0;
3255 if (remaining_words > 0) {
3256 len = UniStrnlen((wchar_t *)
3260 kfree(ses->serverNOS);
3262 kzalloc(2 * (len + 1),
3264 cifs_strfromUCS_le(ses->
3270 bcc_ptr += 2 * (len + 1);
3271 ses->serverNOS[2 * len] = 0;
3272 ses->serverNOS[1+(2*len)] = 0;
3273 remaining_words -= len + 1;
3274 if (remaining_words > 0) {
3275 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3276 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3277 if (ses->serverDomain)
3278 kfree(ses->serverDomain);
3303 } /* else no more room so create dummy domain string */
3305 if (ses->serverDomain)
3306 kfree(ses->serverDomain);
3307 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3309 } else { /* no room so create dummy domain and NOS string */
3310 if (ses->serverDomain)
3311 kfree(ses->serverDomain);
3312 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3313 kfree(ses->serverNOS);
3314 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3316 } else { /* ASCII */
3317 len = strnlen(bcc_ptr, 1024);
3318 if (((long) bcc_ptr + len) -
3319 (long) pByteArea(smb_buffer_response)
3320 <= BCC(smb_buffer_response)) {
3322 kfree(ses->serverOS);
3323 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
3324 strncpy(ses->serverOS,bcc_ptr, len);
3327 bcc_ptr[0] = 0; /* null terminate the string */
3330 len = strnlen(bcc_ptr, 1024);
3331 kfree(ses->serverNOS);
3332 ses->serverNOS = kzalloc(len+1,
3334 strncpy(ses->serverNOS,
3340 len = strnlen(bcc_ptr, 1024);
3341 if (ses->serverDomain)
3342 kfree(ses->serverDomain);
3346 strncpy(ses->serverDomain,
3352 cFYI(1, ("field of length %d "
3353 "extends beyond end of smb ",
3357 cERROR(1, ("Security Blob extends beyond end "
3361 cERROR(1, ("No session structure passed in."));
3364 cERROR(1, ("Invalid Word count %d: ",
3365 smb_buffer_response->WordCount));
3369 cifs_buf_release(smb_buffer);
3375 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3376 const char *tree, struct cifsTconInfo *tcon,
3377 const struct nls_table *nls_codepage)
3379 struct smb_hdr *smb_buffer;
3380 struct smb_hdr *smb_buffer_response;
3383 unsigned char *bcc_ptr;
3391 smb_buffer = cifs_buf_get();
3392 if (smb_buffer == NULL) {
3395 smb_buffer_response = smb_buffer;
3397 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3398 NULL /*no tid */ , 4 /*wct */ );
3400 smb_buffer->Mid = GetNextMid(ses->server);
3401 smb_buffer->Uid = ses->Suid;
3402 pSMB = (TCONX_REQ *) smb_buffer;
3403 pSMBr = (TCONX_RSP *) smb_buffer_response;
3405 pSMB->AndXCommand = 0xFF;
3406 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3407 bcc_ptr = &pSMB->Password[0];
3408 if ((ses->server->secMode) & SECMODE_USER) {
3409 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3410 *bcc_ptr = 0; /* password is null byte */
3411 bcc_ptr++; /* skip password */
3412 /* already aligned so no need to do it below */
3414 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3415 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3416 specified as required (when that support is added to
3417 the vfs in the future) as only NTLM or the much
3418 weaker LANMAN (which we do not send by default) is accepted
3419 by Samba (not sure whether other servers allow
3420 NTLMv2 password here) */
3421 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3422 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3423 (ses->server->secType == LANMAN))
3424 calc_lanman_hash(ses, bcc_ptr);
3426 #endif /* CIFS_WEAK_PW_HASH */
3427 SMBNTencrypt(ses->password,
3428 ses->server->cryptKey,
3431 bcc_ptr += CIFS_SESS_KEY_SIZE;
3432 if (ses->capabilities & CAP_UNICODE) {
3433 /* must align unicode strings */
3434 *bcc_ptr = 0; /* null byte password */
3439 if (ses->server->secMode &
3440 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3441 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3443 if (ses->capabilities & CAP_STATUS32) {
3444 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3446 if (ses->capabilities & CAP_DFS) {
3447 smb_buffer->Flags2 |= SMBFLG2_DFS;
3449 if (ses->capabilities & CAP_UNICODE) {
3450 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3452 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3453 6 /* max utf8 char length in bytes */ *
3454 (/* server len*/ + 256 /* share len */), nls_codepage);
3455 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3456 bcc_ptr += 2; /* skip trailing null */
3457 } else { /* ASCII */
3458 strcpy(bcc_ptr, tree);
3459 bcc_ptr += strlen(tree) + 1;
3461 strcpy(bcc_ptr, "?????");
3462 bcc_ptr += strlen("?????");
3464 count = bcc_ptr - &pSMB->Password[0];
3465 pSMB->hdr.smb_buf_length += count;
3466 pSMB->ByteCount = cpu_to_le16(count);
3468 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3471 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3472 /* above now done in SendReceive */
3473 if ((rc == 0) && (tcon != NULL)) {
3474 tcon->tidStatus = CifsGood;
3475 tcon->tid = smb_buffer_response->Tid;
3476 bcc_ptr = pByteArea(smb_buffer_response);
3477 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3478 /* skip service field (NB: this field is always ASCII) */
3480 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3481 (bcc_ptr[2] == 'C')) {
3482 cFYI(1, ("IPC connection"));
3485 } else if (length == 2) {
3486 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3487 /* the most common case */
3488 cFYI(1, ("disk share connection"));
3491 bcc_ptr += length + 1;
3492 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3493 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3494 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3495 if ((bcc_ptr + (2 * length)) -
3496 pByteArea(smb_buffer_response) <=
3497 BCC(smb_buffer_response)) {
3498 kfree(tcon->nativeFileSystem);
3499 tcon->nativeFileSystem =
3500 kzalloc(length + 2, GFP_KERNEL);
3501 if (tcon->nativeFileSystem)
3503 tcon->nativeFileSystem,
3505 length, nls_codepage);
3506 bcc_ptr += 2 * length;
3507 bcc_ptr[0] = 0; /* null terminate the string */
3511 /* else do not bother copying these information fields*/
3513 length = strnlen(bcc_ptr, 1024);
3514 if ((bcc_ptr + length) -
3515 pByteArea(smb_buffer_response) <=
3516 BCC(smb_buffer_response)) {
3517 kfree(tcon->nativeFileSystem);
3518 tcon->nativeFileSystem =
3519 kzalloc(length + 1, GFP_KERNEL);
3520 if (tcon->nativeFileSystem)
3521 strncpy(tcon->nativeFileSystem, bcc_ptr,
3524 /* else do not bother copying these information fields*/
3526 if ((smb_buffer_response->WordCount == 3) ||
3527 (smb_buffer_response->WordCount == 7))
3528 /* field is in same location */
3529 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3532 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3533 } else if ((rc == 0) && tcon == NULL) {
3534 /* all we need to save for IPC$ connection */
3535 ses->ipc_tid = smb_buffer_response->Tid;
3538 cifs_buf_release(smb_buffer);
3543 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3547 struct cifsSesInfo *ses = NULL;
3548 struct task_struct *cifsd_task;
3553 if (cifs_sb->tcon) {
3554 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3555 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3560 DeleteTconOplockQEntries(cifs_sb->tcon);
3561 tconInfoFree(cifs_sb->tcon);
3562 if ((ses) && (ses->server)) {
3563 /* save off task so we do not refer to ses later */
3564 cifsd_task = ses->server->tsk;
3565 cFYI(1, ("About to do SMBLogoff "));
3566 rc = CIFSSMBLogoff(xid, ses);
3570 } else if (rc == -ESHUTDOWN) {
3571 cFYI(1, ("Waking up socket by sending signal"));
3573 force_sig(SIGKILL, cifsd_task);
3575 } /* else - we have an smb session
3576 left on this socket do not kill cifsd */
3578 cFYI(1, ("No session or bad tcon"));
3581 cifs_sb->tcon = NULL;
3582 tmp = cifs_sb->prepath;
3583 cifs_sb->prepathlen = 0;
3584 cifs_sb->prepath = NULL;
3593 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3594 struct nls_table *nls_info)
3597 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3598 bool ntlmv2_flag = false;
3600 struct TCP_Server_Info *server = pSesInfo->server;
3602 /* what if server changes its buffer size after dropping the session? */
3603 if (server->maxBuf == 0) /* no need to send on reconnect */ {
3604 rc = CIFSSMBNegotiate(xid, pSesInfo);
3605 if (rc == -EAGAIN) {
3606 /* retry only once on 1st time connection */
3607 rc = CIFSSMBNegotiate(xid, pSesInfo);
3612 spin_lock(&GlobalMid_Lock);
3613 if (server->tcpStatus != CifsExiting)
3614 server->tcpStatus = CifsGood;
3617 spin_unlock(&GlobalMid_Lock);
3626 pSesInfo->flags = 0;
3627 pSesInfo->capabilities = server->capabilities;
3628 if (linuxExtEnabled == 0)
3629 pSesInfo->capabilities &= (~CAP_UNIX);
3630 /* pSesInfo->sequence_number = 0;*/
3631 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3632 server->secMode, server->capabilities, server->timeAdj));
3634 if (experimEnabled < 2)
3635 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
3636 else if (extended_security
3637 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3638 && (server->secType == NTLMSSP)) {
3640 } else if (extended_security
3641 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3642 && (server->secType == RawNTLMSSP)) {
3643 cFYI(1, ("NTLMSSP sesssetup"));
3644 rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag,
3649 cFYI(1, ("more secure NTLM ver2 hash"));
3650 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3655 v2_response = kmalloc(16 + 64 /* blob*/,
3658 CalcNTLMv2_response(pSesInfo,
3661 cifs_calculate_ntlmv2_mac_key */
3663 /* BB Put dummy sig in SessSetup PDU? */
3670 SMBNTencrypt(pSesInfo->password,
3675 cifs_calculate_mac_key(
3676 &server->mac_signing_key,
3678 pSesInfo->password);
3680 /* for better security the weaker lanman hash not sent
3681 in AuthSessSetup so we no longer calculate it */
3683 rc = CIFSNTLMSSPAuthSessSetup(xid, pSesInfo,
3688 } else { /* old style NTLM 0.12 session setup */
3689 SMBNTencrypt(pSesInfo->password, server->cryptKey,
3693 cifs_calculate_mac_key(&server->mac_signing_key,
3695 pSesInfo->password);
3697 rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info);
3700 cERROR(1, ("Send error in SessSetup = %d", rc));
3702 cFYI(1, ("CIFS Session Established successfully"));
3703 spin_lock(&GlobalMid_Lock);
3704 pSesInfo->status = CifsGood;
3705 spin_unlock(&GlobalMid_Lock);