4 * Copyright (C) International Business Machines Corp., 2002,2005
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/pagevec.h>
34 #include <asm/uaccess.h>
35 #include <asm/processor.h>
38 #include "cifsproto.h"
39 #include "cifs_unicode.h"
40 #include "cifs_debug.h"
41 #include "cifs_fs_sb.h"
44 #include "rfc1002pdu.h"
48 #define RFC1001_PORT 139
50 static DECLARE_COMPLETION(cifsd_complete);
52 extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
54 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
57 extern mempool_t *cifs_req_poolp;
65 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
66 char *iocharset; /* local code page for mapping to and from Unicode */
67 char source_rfc1001_name[16]; /* netbios name of client */
68 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
78 unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
79 unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/
80 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
82 unsigned remap:1; /* set to remap seven reserved chars in filenames */
83 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
88 unsigned nullauth:1; /* attempt to authenticate with null user */
90 unsigned seal:1; /* encrypt */
91 unsigned nocase; /* request case insensitive filenames */
92 unsigned nobrl; /* disable sending byte range locks to srv */
96 unsigned short int port;
99 static int ipv4_connect(struct sockaddr_in *psin_server,
100 struct socket **csocket,
102 char * server_netb_name);
103 static int ipv6_connect(struct sockaddr_in6 *psin_server,
104 struct socket **csocket);
108 * cifs tcp session reconnection
110 * mark tcp session as reconnecting so temporarily locked
111 * mark all smb sessions as reconnecting for tcp session
112 * reconnect tcp session
113 * wake up waiters on reconnection? - (not needed currently)
117 cifs_reconnect(struct TCP_Server_Info *server)
120 struct list_head *tmp;
121 struct cifsSesInfo *ses;
122 struct cifsTconInfo *tcon;
123 struct mid_q_entry * mid_entry;
125 spin_lock(&GlobalMid_Lock);
126 if(server->tcpStatus == CifsExiting) {
127 /* the demux thread will exit normally
128 next time through the loop */
129 spin_unlock(&GlobalMid_Lock);
132 server->tcpStatus = CifsNeedReconnect;
133 spin_unlock(&GlobalMid_Lock);
136 cFYI(1, ("Reconnecting tcp session"));
138 /* before reconnecting the tcp session, mark the smb session (uid)
139 and the tid bad so they are not used until reconnected */
140 read_lock(&GlobalSMBSeslock);
141 list_for_each(tmp, &GlobalSMBSessionList) {
142 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
144 if (ses->server == server) {
145 ses->status = CifsNeedReconnect;
149 /* else tcp and smb sessions need reconnection */
151 list_for_each(tmp, &GlobalTreeConnectionList) {
152 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
153 if((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
154 tcon->tidStatus = CifsNeedReconnect;
157 read_unlock(&GlobalSMBSeslock);
158 /* do not want to be sending data on a socket we are freeing */
159 down(&server->tcpSem);
160 if(server->ssocket) {
161 cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state,
162 server->ssocket->flags));
163 server->ssocket->ops->shutdown(server->ssocket,SEND_SHUTDOWN);
164 cFYI(1,("Post shutdown state: 0x%x Flags: 0x%lx", server->ssocket->state,
165 server->ssocket->flags));
166 sock_release(server->ssocket);
167 server->ssocket = NULL;
170 spin_lock(&GlobalMid_Lock);
171 list_for_each(tmp, &server->pending_mid_q) {
172 mid_entry = list_entry(tmp, struct
176 if(mid_entry->midState == MID_REQUEST_SUBMITTED) {
177 /* Mark other intransit requests as needing
178 retry so we do not immediately mark the
179 session bad again (ie after we reconnect
180 below) as they timeout too */
181 mid_entry->midState = MID_RETRY_NEEDED;
185 spin_unlock(&GlobalMid_Lock);
188 while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
190 if(server->protocolType == IPV6) {
191 rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket);
193 rc = ipv4_connect(&server->addr.sockAddr,
195 server->workstation_RFC1001_name,
196 server->server_RFC1001_name);
199 cFYI(1,("reconnect error %d",rc));
202 atomic_inc(&tcpSesReconnectCount);
203 spin_lock(&GlobalMid_Lock);
204 if(server->tcpStatus != CifsExiting)
205 server->tcpStatus = CifsGood;
206 server->sequence_number = 0;
207 spin_unlock(&GlobalMid_Lock);
208 /* atomic_set(&server->inFlight,0);*/
209 wake_up(&server->response_q);
217 0 not a transact2, or all data present
218 >0 transact2 with that much data missing
219 -EINVAL = invalid transact2
222 static int check2ndT2(struct smb_hdr * pSMB, unsigned int maxBufSize)
224 struct smb_t2_rsp * pSMBt;
226 int data_in_this_rsp;
229 if(pSMB->Command != SMB_COM_TRANSACTION2)
232 /* check for plausible wct, bcc and t2 data and parm sizes */
233 /* check for parm and data offset going beyond end of smb */
234 if(pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
235 cFYI(1,("invalid transact2 word count"));
239 pSMBt = (struct smb_t2_rsp *)pSMB;
241 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
242 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
244 remaining = total_data_size - data_in_this_rsp;
248 else if(remaining < 0) {
249 cFYI(1,("total data %d smaller than data in frame %d",
250 total_data_size, data_in_this_rsp));
253 cFYI(1,("missing %d bytes from transact2, check next response",
255 if(total_data_size > maxBufSize) {
256 cERROR(1,("TotalDataSize %d is over maximum buffer %d",
257 total_data_size,maxBufSize));
264 static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB)
266 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
267 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
272 char * data_area_of_target;
273 char * data_area_of_buf2;
276 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
278 if(total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
279 cFYI(1,("total data sizes of primary and secondary t2 differ"));
282 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
284 remaining = total_data_size - total_in_buf;
289 if(remaining == 0) /* nothing to do, ignore */
292 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
293 if(remaining < total_in_buf2) {
294 cFYI(1,("transact2 2nd response contains too much data"));
297 /* find end of first SMB data area */
298 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
299 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
300 /* validate target area */
302 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
303 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
305 data_area_of_target += total_in_buf;
307 /* copy second buffer into end of first buffer */
308 memcpy(data_area_of_target,data_area_of_buf2,total_in_buf2);
309 total_in_buf += total_in_buf2;
310 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
311 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
312 byte_count += total_in_buf2;
313 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
315 byte_count = pTargetSMB->smb_buf_length;
316 byte_count += total_in_buf2;
318 /* BB also add check that we are not beyond maximum buffer size */
320 pTargetSMB->smb_buf_length = byte_count;
322 if(remaining == total_in_buf2) {
323 cFYI(1,("found the last secondary response"));
324 return 0; /* we are done */
325 } else /* more responses to go */
331 cifs_demultiplex_thread(struct TCP_Server_Info *server)
334 unsigned int pdu_length, total_read;
335 struct smb_hdr *smb_buffer = NULL;
336 struct smb_hdr *bigbuf = NULL;
337 struct smb_hdr *smallbuf = NULL;
338 struct msghdr smb_msg;
340 struct socket *csocket = server->ssocket;
341 struct list_head *tmp;
342 struct cifsSesInfo *ses;
343 struct task_struct *task_to_wake = NULL;
344 struct mid_q_entry *mid_entry;
346 int isLargeBuf = FALSE;
351 allow_signal(SIGKILL);
352 current->flags |= PF_MEMALLOC;
353 server->tsk = current; /* save process info to wake at shutdown */
354 cFYI(1, ("Demultiplex PID: %d", current->pid));
355 write_lock(&GlobalSMBSeslock);
356 atomic_inc(&tcpSesAllocCount);
357 length = tcpSesAllocCount.counter;
358 write_unlock(&GlobalSMBSeslock);
359 complete(&cifsd_complete);
361 mempool_resize(cifs_req_poolp,
362 length + cifs_min_rcv,
366 while (server->tcpStatus != CifsExiting) {
369 if (bigbuf == NULL) {
370 bigbuf = cifs_buf_get();
372 cERROR(1,("No memory for large SMB response"));
374 /* retry will check if exiting */
377 } else if(isLargeBuf) {
378 /* we are reusing a dirtry large buf, clear its start */
379 memset(bigbuf, 0, sizeof (struct smb_hdr));
382 if (smallbuf == NULL) {
383 smallbuf = cifs_small_buf_get();
384 if(smallbuf == NULL) {
385 cERROR(1,("No memory for SMB response"));
387 /* retry will check if exiting */
390 /* beginning of smb buffer is cleared in our buf_get */
391 } else /* if existing small buf clear beginning */
392 memset(smallbuf, 0, sizeof (struct smb_hdr));
396 smb_buffer = smallbuf;
397 iov.iov_base = smb_buffer;
399 smb_msg.msg_control = NULL;
400 smb_msg.msg_controllen = 0;
402 kernel_recvmsg(csocket, &smb_msg,
403 &iov, 1, 4, 0 /* BB see socket.h flags */);
405 if(server->tcpStatus == CifsExiting) {
407 } else if (server->tcpStatus == CifsNeedReconnect) {
408 cFYI(1,("Reconnect after server stopped responding"));
409 cifs_reconnect(server);
410 cFYI(1,("call to reconnect done"));
411 csocket = server->ssocket;
413 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
414 msleep(1); /* minimum sleep to prevent looping
415 allowing socket to clear and app threads to set
416 tcpStatus CifsNeedReconnect if server hung */
418 } else if (length <= 0) {
419 if(server->tcpStatus == CifsNew) {
420 cFYI(1,("tcp session abend after SMBnegprot"));
421 /* some servers kill the TCP session rather than
422 returning an SMB negprot error, in which
423 case reconnecting here is not going to help,
424 and so simply return error to mount */
427 if(length == -EINTR) {
428 cFYI(1,("cifsd thread killed"));
431 cFYI(1,("Reconnect after unexpected peek error %d",
433 cifs_reconnect(server);
434 csocket = server->ssocket;
435 wake_up(&server->response_q);
437 } else if (length < 4) {
439 ("Frame under four bytes received (%d bytes long)",
441 cifs_reconnect(server);
442 csocket = server->ssocket;
443 wake_up(&server->response_q);
447 /* The right amount was read from socket - 4 bytes */
448 /* so we can now interpret the length field */
450 /* the first byte big endian of the length field,
451 is actually not part of the length but the type
452 with the most common, zero, as regular data */
453 temp = *((char *) smb_buffer);
455 /* Note that FC 1001 length is big endian on the wire,
456 but we convert it here so it is always manipulated
457 as host byte order */
458 pdu_length = ntohl(smb_buffer->smb_buf_length);
459 smb_buffer->smb_buf_length = pdu_length;
461 cFYI(1,("rfc1002 length 0x%x)", pdu_length+4));
463 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
465 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
466 cFYI(1,("Good RFC 1002 session rsp"));
468 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
469 /* we get this from Windows 98 instead of
470 an error on SMB negprot response */
471 cFYI(1,("Negative RFC1002 Session Response Error 0x%x)",
473 if(server->tcpStatus == CifsNew) {
474 /* if nack on negprot (rather than
475 ret of smb negprot error) reconnecting
476 not going to help, ret error to mount */
479 /* give server a second to
480 clean up before reconnect attempt */
482 /* always try 445 first on reconnect
483 since we get NACK on some if we ever
484 connected to port 139 (the NACK is
485 since we do not begin with RFC1001
486 session initialize frame) */
487 server->addr.sockAddr.sin_port =
489 cifs_reconnect(server);
490 csocket = server->ssocket;
491 wake_up(&server->response_q);
494 } else if (temp != (char) 0) {
495 cERROR(1,("Unknown RFC 1002 frame"));
496 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
498 cifs_reconnect(server);
499 csocket = server->ssocket;
503 /* else we have an SMB response */
504 if((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
505 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
506 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
507 length, pdu_length+4));
508 cifs_reconnect(server);
509 csocket = server->ssocket;
510 wake_up(&server->response_q);
517 if(pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
519 memcpy(bigbuf, smallbuf, 4);
523 iov.iov_base = 4 + (char *)smb_buffer;
524 iov.iov_len = pdu_length;
525 for (total_read = 0; total_read < pdu_length;
526 total_read += length) {
527 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
528 pdu_length - total_read, 0);
529 if((server->tcpStatus == CifsExiting) ||
530 (length == -EINTR)) {
534 } else if (server->tcpStatus == CifsNeedReconnect) {
535 cifs_reconnect(server);
536 csocket = server->ssocket;
537 /* Reconnect wakes up rspns q */
538 /* Now we will reread sock */
541 } else if ((length == -ERESTARTSYS) ||
542 (length == -EAGAIN)) {
543 msleep(1); /* minimum sleep to prevent looping,
544 allowing socket to clear and app
545 threads to set tcpStatus
546 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)) {
589 /* all parts received */
594 cERROR(1,("1st trans2 resp needs bigbuf"));
595 /* BB maybe we can fix this up, switch
596 to already allocated large buffer? */
598 /* Have first buffer */
599 mid_entry->resp_buf =
601 mid_entry->largeBuf = 1;
607 mid_entry->resp_buf = smb_buffer;
609 mid_entry->largeBuf = 1;
611 mid_entry->largeBuf = 0;
613 task_to_wake = mid_entry->tsk;
614 mid_entry->midState = MID_RESPONSE_RECEIVED;
615 #ifdef CONFIG_CIFS_STATS2
616 mid_entry->when_received = jiffies;
621 spin_unlock(&GlobalMid_Lock);
623 /* Was previous buf put in mpx struct for multi-rsp? */
625 /* smb buffer will be freed by user thread */
631 wake_up_process(task_to_wake);
632 } else if ((is_valid_oplock_break(smb_buffer) == FALSE)
633 && (isMultiRsp == FALSE)) {
634 cERROR(1, ("No task to wake, unknown frame rcvd!"));
635 cifs_dump_mem("Received Data is: ",(char *)smb_buffer,
636 sizeof(struct smb_hdr));
638 } /* end while !EXITING */
640 spin_lock(&GlobalMid_Lock);
641 server->tcpStatus = CifsExiting;
643 /* check if we have blocked requests that need to free */
644 /* Note that cifs_max_pending is normally 50, but
645 can be set at module install time to as little as two */
646 if(atomic_read(&server->inFlight) >= cifs_max_pending)
647 atomic_set(&server->inFlight, cifs_max_pending - 1);
648 /* We do not want to set the max_pending too low or we
649 could end up with the counter going negative */
650 spin_unlock(&GlobalMid_Lock);
651 /* Although there should not be any requests blocked on
652 this queue it can not hurt to be paranoid and try to wake up requests
653 that may haven been blocked when more than 50 at time were on the wire
654 to the same server - they now will see the session is in exit state
655 and get out of SendReceive. */
656 wake_up_all(&server->request_q);
657 /* give those requests time to exit */
660 if(server->ssocket) {
661 sock_release(csocket);
662 server->ssocket = NULL;
664 /* buffer usuallly freed in free_mid - need to free it here on exit */
666 cifs_buf_release(bigbuf);
667 if (smallbuf != NULL)
668 cifs_small_buf_release(smallbuf);
670 read_lock(&GlobalSMBSeslock);
671 if (list_empty(&server->pending_mid_q)) {
672 /* loop through server session structures attached to this and
674 list_for_each(tmp, &GlobalSMBSessionList) {
676 list_entry(tmp, struct cifsSesInfo,
678 if (ses->server == server) {
679 ses->status = CifsExiting;
683 read_unlock(&GlobalSMBSeslock);
685 /* although we can not zero the server struct pointer yet,
686 since there are active requests which may depnd on them,
687 mark the corresponding SMB sessions as exiting too */
688 list_for_each(tmp, &GlobalSMBSessionList) {
689 ses = list_entry(tmp, struct cifsSesInfo,
691 if (ses->server == server) {
692 ses->status = CifsExiting;
696 spin_lock(&GlobalMid_Lock);
697 list_for_each(tmp, &server->pending_mid_q) {
698 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
699 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
701 ("Clearing Mid 0x%x - waking up ",mid_entry->mid));
702 task_to_wake = mid_entry->tsk;
704 wake_up_process(task_to_wake);
708 spin_unlock(&GlobalMid_Lock);
709 read_unlock(&GlobalSMBSeslock);
710 /* 1/8th of sec is more than enough time for them to exit */
714 if (!list_empty(&server->pending_mid_q)) {
715 /* mpx threads have not exited yet give them
716 at least the smb send timeout time for long ops */
717 /* due to delays on oplock break requests, we need
718 to wait at least 45 seconds before giving up
719 on a request getting a response and going ahead
721 cFYI(1, ("Wait for exit from demultiplex thread"));
723 /* if threads still have not exited they are probably never
724 coming home not much else we can do but free the memory */
727 write_lock(&GlobalSMBSeslock);
728 atomic_dec(&tcpSesAllocCount);
729 length = tcpSesAllocCount.counter;
731 /* last chance to mark ses pointers invalid
732 if there are any pointing to this (e.g
733 if a crazy root user tried to kill cifsd
734 kernel thread explicitly this might happen) */
735 list_for_each(tmp, &GlobalSMBSessionList) {
736 ses = list_entry(tmp, struct cifsSesInfo,
738 if (ses->server == server) {
742 write_unlock(&GlobalSMBSeslock);
746 mempool_resize(cifs_req_poolp,
747 length + cifs_min_rcv,
751 complete_and_exit(&cifsd_complete, 0);
756 cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
760 unsigned int temp_len, i, j;
766 memset(vol->source_rfc1001_name,0x20,15);
767 for(i=0;i < strnlen(system_utsname.nodename,15);i++) {
768 /* does not have to be a perfect mapping since the field is
769 informational, only used for servers that do not support
770 port 445 and it can be overridden at mount time */
771 vol->source_rfc1001_name[i] =
772 toupper(system_utsname.nodename[i]);
774 vol->source_rfc1001_name[15] = 0;
775 /* null target name indicates to use *SMBSERVR default called name
776 if we end up sending RFC1001 session initialize */
777 vol->target_rfc1001_name[0] = 0;
778 vol->linux_uid = current->uid; /* current->euid instead? */
779 vol->linux_gid = current->gid;
780 vol->dir_mode = S_IRWXUGO;
781 /* 2767 perms indicate mandatory locking support */
782 vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
784 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
787 /* default is always to request posix paths. */
788 vol->posix_paths = 1;
793 if(strncmp(options,"sep=",4) == 0) {
794 if(options[4] != 0) {
795 separator[0] = options[4];
798 cFYI(1,("Null separator not allowed"));
802 while ((data = strsep(&options, separator)) != NULL) {
805 if ((value = strchr(data, '=')) != NULL)
808 if (strnicmp(data, "user_xattr",10) == 0) {/*parse before user*/
810 } else if (strnicmp(data, "nouser_xattr",12) == 0) {
812 } else if (strnicmp(data, "user", 4) == 0) {
813 if (!value || !*value) {
815 "CIFS: invalid or missing username\n");
816 return 1; /* needs_arg; */
818 if (strnlen(value, 200) < 200) {
819 vol->username = value;
821 printk(KERN_WARNING "CIFS: username too long\n");
824 } else if (strnicmp(data, "pass", 4) == 0) {
826 vol->password = NULL;
828 } else if(value[0] == 0) {
829 /* check if string begins with double comma
830 since that would mean the password really
831 does start with a comma, and would not
832 indicate an empty string */
833 if(value[1] != separator[0]) {
834 vol->password = NULL;
838 temp_len = strlen(value);
839 /* removed password length check, NTLM passwords
840 can be arbitrarily long */
842 /* if comma in password, the string will be
843 prematurely null terminated. Commas in password are
844 specified across the cifs mount interface by a double
845 comma ie ,, and a comma used as in other cases ie ','
846 as a parameter delimiter/separator is single and due
847 to the strsep above is temporarily zeroed. */
849 /* NB: password legally can have multiple commas and
850 the only illegal character in a password is null */
852 if ((value[temp_len] == 0) &&
853 (value[temp_len+1] == separator[0])) {
855 value[temp_len] = separator[0];
856 temp_len+=2; /* move after the second comma */
857 while(value[temp_len] != 0) {
858 if (value[temp_len] == separator[0]) {
859 if (value[temp_len+1] ==
861 /* skip second comma */
864 /* single comma indicating start
871 if(value[temp_len] == 0) {
875 /* point option to start of next parm */
876 options = value + temp_len + 1;
878 /* go from value to value + temp_len condensing
879 double commas to singles. Note that this ends up
880 allocating a few bytes too many, which is ok */
881 vol->password = kzalloc(temp_len, GFP_KERNEL);
882 if(vol->password == NULL) {
883 printk("CIFS: no memory for pass\n");
886 for(i=0,j=0;i<temp_len;i++,j++) {
887 vol->password[j] = value[i];
888 if(value[i] == separator[0]
889 && value[i+1] == separator[0]) {
890 /* skip second comma */
894 vol->password[j] = 0;
896 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
897 if(vol->password == NULL) {
898 printk("CIFS: no memory for pass\n");
901 strcpy(vol->password, value);
903 } else if (strnicmp(data, "ip", 2) == 0) {
904 if (!value || !*value) {
906 } else if (strnlen(value, 35) < 35) {
909 printk(KERN_WARNING "CIFS: ip address too long\n");
912 } else if (strnicmp(data, "sec", 3) == 0) {
913 if (!value || !*value) {
914 cERROR(1,("no security value specified"));
916 } else if (strnicmp(value, "krb5i", 5) == 0) {
919 } else if (strnicmp(value, "krb5p", 5) == 0) {
922 cERROR(1,("Krb5 cifs privacy not supported"));
924 } else if (strnicmp(value, "krb5", 4) == 0) {
926 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
929 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
931 } else if (strnicmp(value, "ntlmi", 5) == 0) {
934 } else if (strnicmp(value, "ntlm", 4) == 0) {
935 /* ntlm is default so can be turned off too */
937 } else if (strnicmp(value, "nontlm", 6) == 0) {
939 } else if (strnicmp(value, "none", 4) == 0) {
942 cERROR(1,("bad security option: %s", value));
945 } else if ((strnicmp(data, "unc", 3) == 0)
946 || (strnicmp(data, "target", 6) == 0)
947 || (strnicmp(data, "path", 4) == 0)) {
948 if (!value || !*value) {
950 "CIFS: invalid path to network resource\n");
951 return 1; /* needs_arg; */
953 if ((temp_len = strnlen(value, 300)) < 300) {
954 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
957 strcpy(vol->UNC,value);
958 if (strncmp(vol->UNC, "//", 2) == 0) {
961 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
963 "CIFS: UNC Path does not begin with // or \\\\ \n");
967 printk(KERN_WARNING "CIFS: UNC name too long\n");
970 } else if ((strnicmp(data, "domain", 3) == 0)
971 || (strnicmp(data, "workgroup", 5) == 0)) {
972 if (!value || !*value) {
973 printk(KERN_WARNING "CIFS: invalid domain name\n");
974 return 1; /* needs_arg; */
976 /* BB are there cases in which a comma can be valid in
977 a domain name and need special handling? */
978 if (strnlen(value, 65) < 65) {
979 vol->domainname = value;
980 cFYI(1, ("Domain name set"));
982 printk(KERN_WARNING "CIFS: domain name too long\n");
985 } else if (strnicmp(data, "iocharset", 9) == 0) {
986 if (!value || !*value) {
987 printk(KERN_WARNING "CIFS: invalid iocharset specified\n");
988 return 1; /* needs_arg; */
990 if (strnlen(value, 65) < 65) {
991 if(strnicmp(value,"default",7))
992 vol->iocharset = value;
993 /* if iocharset not set load_nls_default used by caller */
994 cFYI(1, ("iocharset set to %s",value));
996 printk(KERN_WARNING "CIFS: iocharset name too long.\n");
999 } else if (strnicmp(data, "uid", 3) == 0) {
1000 if (value && *value) {
1002 simple_strtoul(value, &value, 0);
1004 } else if (strnicmp(data, "gid", 3) == 0) {
1005 if (value && *value) {
1007 simple_strtoul(value, &value, 0);
1009 } else if (strnicmp(data, "file_mode", 4) == 0) {
1010 if (value && *value) {
1012 simple_strtoul(value, &value, 0);
1014 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1015 if (value && *value) {
1017 simple_strtoul(value, &value, 0);
1019 } else if (strnicmp(data, "dirmode", 4) == 0) {
1020 if (value && *value) {
1022 simple_strtoul(value, &value, 0);
1024 } else if (strnicmp(data, "port", 4) == 0) {
1025 if (value && *value) {
1027 simple_strtoul(value, &value, 0);
1029 } else if (strnicmp(data, "rsize", 5) == 0) {
1030 if (value && *value) {
1032 simple_strtoul(value, &value, 0);
1034 } else if (strnicmp(data, "wsize", 5) == 0) {
1035 if (value && *value) {
1037 simple_strtoul(value, &value, 0);
1039 } else if (strnicmp(data, "sockopt", 5) == 0) {
1040 if (value && *value) {
1042 simple_strtoul(value, &value, 0);
1044 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1045 if (!value || !*value || (*value == ' ')) {
1046 cFYI(1,("invalid (empty) netbiosname specified"));
1048 memset(vol->source_rfc1001_name,0x20,15);
1050 /* BB are there cases in which a comma can be
1051 valid in this workstation netbios name (and need
1052 special handling)? */
1054 /* We do not uppercase netbiosname for user */
1058 vol->source_rfc1001_name[i] = value[i];
1060 /* The string has 16th byte zero still from
1061 set at top of the function */
1062 if((i==15) && (value[i] != 0))
1063 printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n");
1065 } else if (strnicmp(data, "servern", 7) == 0) {
1066 /* servernetbiosname specified override *SMBSERVER */
1067 if (!value || !*value || (*value == ' ')) {
1068 cFYI(1,("empty server netbiosname specified"));
1070 /* last byte, type, is 0x20 for servr type */
1071 memset(vol->target_rfc1001_name,0x20,16);
1074 /* BB are there cases in which a comma can be
1075 valid in this workstation netbios name (and need
1076 special handling)? */
1078 /* user or mount helper must uppercase netbiosname */
1082 vol->target_rfc1001_name[i] = value[i];
1084 /* The string has 16th byte zero still from
1085 set at top of the function */
1086 if((i==15) && (value[i] != 0))
1087 printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n");
1089 } else if (strnicmp(data, "credentials", 4) == 0) {
1091 } else if (strnicmp(data, "version", 3) == 0) {
1093 } else if (strnicmp(data, "guest",5) == 0) {
1095 } else if (strnicmp(data, "rw", 2) == 0) {
1097 } else if ((strnicmp(data, "suid", 4) == 0) ||
1098 (strnicmp(data, "nosuid", 6) == 0) ||
1099 (strnicmp(data, "exec", 4) == 0) ||
1100 (strnicmp(data, "noexec", 6) == 0) ||
1101 (strnicmp(data, "nodev", 5) == 0) ||
1102 (strnicmp(data, "noauto", 6) == 0) ||
1103 (strnicmp(data, "dev", 3) == 0)) {
1104 /* The mount tool or mount.cifs helper (if present)
1105 uses these opts to set flags, and the flags are read
1106 by the kernel vfs layer before we get here (ie
1107 before read super) so there is no point trying to
1108 parse these options again and set anything and it
1109 is ok to just ignore them */
1111 } else if (strnicmp(data, "ro", 2) == 0) {
1113 } else if (strnicmp(data, "hard", 4) == 0) {
1115 } else if (strnicmp(data, "soft", 4) == 0) {
1117 } else if (strnicmp(data, "perm", 4) == 0) {
1119 } else if (strnicmp(data, "noperm", 6) == 0) {
1121 } else if (strnicmp(data, "mapchars", 8) == 0) {
1123 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1125 } else if (strnicmp(data, "sfu", 3) == 0) {
1127 } else if (strnicmp(data, "nosfu", 5) == 0) {
1129 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1130 vol->posix_paths = 1;
1131 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1132 vol->posix_paths = 0;
1133 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1134 (strnicmp(data, "ignorecase", 10) == 0)) {
1136 } else if (strnicmp(data, "brl", 3) == 0) {
1138 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1139 (strnicmp(data, "nolock", 6) == 0)) {
1141 /* turn off mandatory locking in mode
1142 if remote locking is turned off since the
1143 local vfs will do advisory */
1144 if(vol->file_mode == (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1145 vol->file_mode = S_IALLUGO;
1146 } else if (strnicmp(data, "setuids", 7) == 0) {
1148 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1150 } else if (strnicmp(data, "nohard", 6) == 0) {
1152 } else if (strnicmp(data, "nosoft", 6) == 0) {
1154 } else if (strnicmp(data, "nointr", 6) == 0) {
1156 } else if (strnicmp(data, "intr", 4) == 0) {
1158 } else if (strnicmp(data, "serverino",7) == 0) {
1159 vol->server_ino = 1;
1160 } else if (strnicmp(data, "noserverino",9) == 0) {
1161 vol->server_ino = 0;
1162 } else if (strnicmp(data, "acl",3) == 0) {
1163 vol->no_psx_acl = 0;
1164 } else if (strnicmp(data, "noacl",5) == 0) {
1165 vol->no_psx_acl = 1;
1166 } else if (strnicmp(data, "direct",6) == 0) {
1168 } else if (strnicmp(data, "forcedirectio",13) == 0) {
1170 } else if (strnicmp(data, "in6_addr",8) == 0) {
1171 if (!value || !*value) {
1172 vol->in6_addr = NULL;
1173 } else if (strnlen(value, 49) == 48) {
1174 vol->in6_addr = value;
1176 printk(KERN_WARNING "CIFS: ip v6 address not 48 characters long\n");
1179 } else if (strnicmp(data, "noac", 4) == 0) {
1180 printk(KERN_WARNING "CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
1182 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);
1184 if (vol->UNC == NULL) {
1185 if(devname == NULL) {
1186 printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n");
1189 if ((temp_len = strnlen(devname, 300)) < 300) {
1190 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
1191 if(vol->UNC == NULL)
1193 strcpy(vol->UNC,devname);
1194 if (strncmp(vol->UNC, "//", 2) == 0) {
1197 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1198 printk(KERN_WARNING "CIFS: UNC Path does not begin with // or \\\\ \n");
1202 printk(KERN_WARNING "CIFS: UNC name too long\n");
1206 if(vol->UNCip == NULL)
1207 vol->UNCip = &vol->UNC[2];
1212 static struct cifsSesInfo *
1213 cifs_find_tcp_session(struct in_addr * target_ip_addr,
1214 struct in6_addr *target_ip6_addr,
1215 char *userName, struct TCP_Server_Info **psrvTcp)
1217 struct list_head *tmp;
1218 struct cifsSesInfo *ses;
1220 read_lock(&GlobalSMBSeslock);
1222 list_for_each(tmp, &GlobalSMBSessionList) {
1223 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1225 if((target_ip_addr &&
1226 (ses->server->addr.sockAddr.sin_addr.s_addr
1227 == target_ip_addr->s_addr)) || (target_ip6_addr
1228 && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1229 target_ip6_addr,sizeof(*target_ip6_addr)))){
1230 /* BB lock server and tcp session and increment use count here?? */
1231 *psrvTcp = ses->server; /* found a match on the TCP session */
1232 /* BB check if reconnection needed */
1234 (ses->userName, userName,
1235 MAX_USERNAME_SIZE) == 0){
1236 read_unlock(&GlobalSMBSeslock);
1237 return ses; /* found exact match on both tcp and SMB sessions */
1241 /* else tcp and smb sessions need reconnection */
1243 read_unlock(&GlobalSMBSeslock);
1247 static struct cifsTconInfo *
1248 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1250 struct list_head *tmp;
1251 struct cifsTconInfo *tcon;
1253 read_lock(&GlobalSMBSeslock);
1254 list_for_each(tmp, &GlobalTreeConnectionList) {
1255 cFYI(1, ("Next tcon - "));
1256 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1258 if (tcon->ses->server) {
1260 (" old ip addr: %x == new ip %x ?",
1261 tcon->ses->server->addr.sockAddr.sin_addr.
1262 s_addr, new_target_ip_addr));
1263 if (tcon->ses->server->addr.sockAddr.sin_addr.
1264 s_addr == new_target_ip_addr) {
1265 /* BB lock tcon and server and tcp session and increment use count here? */
1266 /* found a match on the TCP session */
1267 /* BB check if reconnection needed */
1268 cFYI(1,("Matched ip, old UNC: %s == new: %s ?",
1269 tcon->treeName, uncName));
1271 (tcon->treeName, uncName,
1272 MAX_TREE_SIZE) == 0) {
1274 ("Matched UNC, old user: %s == new: %s ?",
1275 tcon->treeName, uncName));
1277 (tcon->ses->userName,
1279 MAX_USERNAME_SIZE) == 0) {
1280 read_unlock(&GlobalSMBSeslock);
1281 return tcon;/* also matched user (smb session)*/
1288 read_unlock(&GlobalSMBSeslock);
1293 connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1294 const char *old_path, const struct nls_table *nls_codepage,
1297 unsigned char *referrals = NULL;
1298 unsigned int num_referrals;
1301 rc = get_dfs_path(xid, pSesInfo,old_path, nls_codepage,
1302 &num_referrals, &referrals, remap);
1304 /* BB Add in code to: if valid refrl, if not ip address contact
1305 the helper that resolves tcp names, mount to it, try to
1306 tcon to it unmount it if fail */
1314 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1315 const char *old_path, const struct nls_table *nls_codepage,
1316 unsigned int *pnum_referrals,
1317 unsigned char ** preferrals, int remap)
1322 *pnum_referrals = 0;
1324 if (pSesInfo->ipc_tid == 0) {
1325 temp_unc = kmalloc(2 /* for slashes */ +
1326 strnlen(pSesInfo->serverName,SERVER_NAME_LEN_WITH_NULL * 2)
1327 + 1 + 4 /* slash IPC$ */ + 2,
1329 if (temp_unc == NULL)
1333 strcpy(temp_unc + 2, pSesInfo->serverName);
1334 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1335 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1337 ("CIFS Tcon rc = %d ipc_tid = %d", rc,pSesInfo->ipc_tid));
1341 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1342 pnum_referrals, nls_codepage, remap);
1347 /* See RFC1001 section 14 on representation of Netbios names */
1348 static void rfc1002mangle(char * target,char * source, unsigned int length)
1352 for(i=0,j=0;i<(length);i++) {
1353 /* mask a nibble at a time and encode */
1354 target[j] = 'A' + (0x0F & (source[i] >> 4));
1355 target[j+1] = 'A' + (0x0F & source[i]);
1363 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1364 char * netbios_name, char * target_name)
1368 __be16 orig_port = 0;
1370 if(*csocket == NULL) {
1371 rc = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket);
1373 cERROR(1, ("Error %d creating socket",rc));
1377 /* BB other socket options to set KEEPALIVE, NODELAY? */
1378 cFYI(1,("Socket created"));
1379 (*csocket)->sk->sk_allocation = GFP_NOFS;
1383 psin_server->sin_family = AF_INET;
1384 if(psin_server->sin_port) { /* user overrode default port */
1385 rc = (*csocket)->ops->connect(*csocket,
1386 (struct sockaddr *) psin_server,
1387 sizeof (struct sockaddr_in),0);
1393 /* save original port so we can retry user specified port
1394 later if fall back ports fail this time */
1395 orig_port = psin_server->sin_port;
1397 /* do not retry on the same port we just failed on */
1398 if(psin_server->sin_port != htons(CIFS_PORT)) {
1399 psin_server->sin_port = htons(CIFS_PORT);
1401 rc = (*csocket)->ops->connect(*csocket,
1402 (struct sockaddr *) psin_server,
1403 sizeof (struct sockaddr_in),0);
1409 psin_server->sin_port = htons(RFC1001_PORT);
1410 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1411 psin_server, sizeof (struct sockaddr_in),0);
1416 /* give up here - unless we want to retry on different
1417 protocol families some day */
1420 psin_server->sin_port = orig_port;
1421 cFYI(1,("Error %d connecting to server via ipv4",rc));
1422 sock_release(*csocket);
1426 /* Eventually check for other socket options to change from
1427 the default. sock_setsockopt not used because it expects
1428 user space buffer */
1429 cFYI(1,("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",(*csocket)->sk->sk_sndbuf,
1430 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1431 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1432 /* make the bufsizes depend on wsize/rsize and max requests */
1433 if((*csocket)->sk->sk_sndbuf < (200 * 1024))
1434 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1435 if((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1436 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1438 /* send RFC1001 sessinit */
1439 if(psin_server->sin_port == htons(RFC1001_PORT)) {
1440 /* some servers require RFC1001 sessinit before sending
1441 negprot - BB check reconnection in case where second
1442 sessinit is sent but no second negprot */
1443 struct rfc1002_session_packet * ses_init_buf;
1444 struct smb_hdr * smb_buf;
1445 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL);
1447 ses_init_buf->trailer.session_req.called_len = 32;
1448 if(target_name && (target_name[0] != 0)) {
1449 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1452 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1453 DEFAULT_CIFS_CALLED_NAME,16);
1456 ses_init_buf->trailer.session_req.calling_len = 32;
1457 /* calling name ends in null (byte 16) from old smb
1459 if(netbios_name && (netbios_name[0] !=0)) {
1460 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1463 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1464 "LINUX_CIFS_CLNT",16);
1466 ses_init_buf->trailer.session_req.scope1 = 0;
1467 ses_init_buf->trailer.session_req.scope2 = 0;
1468 smb_buf = (struct smb_hdr *)ses_init_buf;
1469 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1470 smb_buf->smb_buf_length = 0x81000044;
1471 rc = smb_send(*csocket, smb_buf, 0x44,
1472 (struct sockaddr *)psin_server);
1473 kfree(ses_init_buf);
1475 /* else the negprot may still work without this
1476 even though malloc failed */
1484 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1488 __be16 orig_port = 0;
1490 if(*csocket == NULL) {
1491 rc = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, csocket);
1493 cERROR(1, ("Error %d creating ipv6 socket",rc));
1497 /* BB other socket options to set KEEPALIVE, NODELAY? */
1498 cFYI(1,("ipv6 Socket created"));
1499 (*csocket)->sk->sk_allocation = GFP_NOFS;
1503 psin_server->sin6_family = AF_INET6;
1505 if(psin_server->sin6_port) { /* user overrode default port */
1506 rc = (*csocket)->ops->connect(*csocket,
1507 (struct sockaddr *) psin_server,
1508 sizeof (struct sockaddr_in6),0);
1514 /* save original port so we can retry user specified port
1515 later if fall back ports fail this time */
1517 orig_port = psin_server->sin6_port;
1518 /* do not retry on the same port we just failed on */
1519 if(psin_server->sin6_port != htons(CIFS_PORT)) {
1520 psin_server->sin6_port = htons(CIFS_PORT);
1522 rc = (*csocket)->ops->connect(*csocket,
1523 (struct sockaddr *) psin_server,
1524 sizeof (struct sockaddr_in6),0);
1530 psin_server->sin6_port = htons(RFC1001_PORT);
1531 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1532 psin_server, sizeof (struct sockaddr_in6),0);
1537 /* give up here - unless we want to retry on different
1538 protocol families some day */
1541 psin_server->sin6_port = orig_port;
1542 cFYI(1,("Error %d connecting to server via ipv6",rc));
1543 sock_release(*csocket);
1547 /* Eventually check for other socket options to change from
1548 the default. sock_setsockopt not used because it expects
1549 user space buffer */
1550 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1556 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1557 char *mount_data, const char *devname)
1561 int address_type = AF_INET;
1562 struct socket *csocket = NULL;
1563 struct sockaddr_in sin_server;
1564 struct sockaddr_in6 sin_server6;
1565 struct smb_vol volume_info;
1566 struct cifsSesInfo *pSesInfo = NULL;
1567 struct cifsSesInfo *existingCifsSes = NULL;
1568 struct cifsTconInfo *tcon = NULL;
1569 struct TCP_Server_Info *srvTcp = NULL;
1573 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1575 memset(&volume_info,0,sizeof(struct smb_vol));
1576 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1577 kfree(volume_info.UNC);
1578 kfree(volume_info.password);
1583 if (volume_info.username) {
1584 /* BB fixme parse for domain name here */
1585 cFYI(1, ("Username: %s ", volume_info.username));
1588 cifserror("No username specified");
1589 /* In userspace mount helper we can get user name from alternate
1590 locations such as env variables and files on disk */
1591 kfree(volume_info.UNC);
1592 kfree(volume_info.password);
1597 if (volume_info.UNCip && volume_info.UNC) {
1598 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,&sin_server.sin_addr.s_addr);
1601 /* not ipv4 address, try ipv6 */
1602 rc = cifs_inet_pton(AF_INET6,volume_info.UNCip,&sin_server6.sin6_addr.in6_u);
1604 address_type = AF_INET6;
1606 address_type = AF_INET;
1610 /* we failed translating address */
1611 kfree(volume_info.UNC);
1612 kfree(volume_info.password);
1617 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1620 } else if (volume_info.UNCip){
1621 /* BB using ip addr as server name connect to the DFS root below */
1622 cERROR(1,("Connecting to DFS root not implemented yet"));
1623 kfree(volume_info.UNC);
1624 kfree(volume_info.password);
1627 } else /* which servers DFS root would we conect to */ {
1629 ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified"));
1630 kfree(volume_info.UNC);
1631 kfree(volume_info.password);
1636 /* this is needed for ASCII cp to Unicode converts */
1637 if(volume_info.iocharset == NULL) {
1638 cifs_sb->local_nls = load_nls_default();
1639 /* load_nls_default can not return null */
1641 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1642 if(cifs_sb->local_nls == NULL) {
1643 cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
1644 kfree(volume_info.UNC);
1645 kfree(volume_info.password);
1651 if(address_type == AF_INET)
1652 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1653 NULL /* no ipv6 addr */,
1654 volume_info.username, &srvTcp);
1655 else if(address_type == AF_INET6)
1656 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1657 &sin_server6.sin6_addr,
1658 volume_info.username, &srvTcp);
1660 kfree(volume_info.UNC);
1661 kfree(volume_info.password);
1668 cFYI(1, ("Existing tcp session with server found"));
1669 } else { /* create socket */
1670 if(volume_info.port)
1671 sin_server.sin_port = htons(volume_info.port);
1673 sin_server.sin_port = 0;
1674 rc = ipv4_connect(&sin_server,&csocket,
1675 volume_info.source_rfc1001_name,
1676 volume_info.target_rfc1001_name);
1679 ("Error connecting to IPv4 socket. Aborting operation"));
1681 sock_release(csocket);
1682 kfree(volume_info.UNC);
1683 kfree(volume_info.password);
1688 srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
1689 if (srvTcp == NULL) {
1691 sock_release(csocket);
1692 kfree(volume_info.UNC);
1693 kfree(volume_info.password);
1697 memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
1698 memcpy(&srvTcp->addr.sockAddr, &sin_server, sizeof (struct sockaddr_in));
1699 atomic_set(&srvTcp->inFlight,0);
1700 /* BB Add code for ipv6 case too */
1701 srvTcp->ssocket = csocket;
1702 srvTcp->protocolType = IPV4;
1703 init_waitqueue_head(&srvTcp->response_q);
1704 init_waitqueue_head(&srvTcp->request_q);
1705 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
1706 /* at this point we are the only ones with the pointer
1707 to the struct since the kernel thread not created yet
1708 so no need to spinlock this init of tcpStatus */
1709 srvTcp->tcpStatus = CifsNew;
1710 init_MUTEX(&srvTcp->tcpSem);
1711 rc = (int)kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
1712 CLONE_FS | CLONE_FILES | CLONE_VM);
1715 sock_release(csocket);
1716 kfree(volume_info.UNC);
1717 kfree(volume_info.password);
1721 wait_for_completion(&cifsd_complete);
1723 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
1724 memcpy(srvTcp->server_RFC1001_name, volume_info.target_rfc1001_name,16);
1725 srvTcp->sequence_number = 0;
1729 if (existingCifsSes) {
1730 pSesInfo = existingCifsSes;
1731 cFYI(1, ("Existing smb sess found"));
1732 kfree(volume_info.password);
1733 /* volume_info.UNC freed at end of function */
1735 cFYI(1, ("Existing smb sess not found"));
1736 pSesInfo = sesInfoAlloc();
1737 if (pSesInfo == NULL)
1740 pSesInfo->server = srvTcp;
1741 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
1742 NIPQUAD(sin_server.sin_addr.s_addr));
1746 /* volume_info.password freed at unmount */
1747 if (volume_info.password)
1748 pSesInfo->password = volume_info.password;
1749 if (volume_info.username)
1750 strncpy(pSesInfo->userName,
1751 volume_info.username,MAX_USERNAME_SIZE);
1752 if (volume_info.domainname)
1753 strncpy(pSesInfo->domainName,
1754 volume_info.domainname,MAX_USERNAME_SIZE);
1755 pSesInfo->linux_uid = volume_info.linux_uid;
1756 down(&pSesInfo->sesSem);
1757 rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls);
1758 up(&pSesInfo->sesSem);
1760 atomic_inc(&srvTcp->socketUseCount);
1762 kfree(volume_info.password);
1765 /* search for existing tcon to this server share */
1767 if(volume_info.rsize > CIFSMaxBufSize) {
1768 cERROR(1,("rsize %d too large, using MaxBufSize",
1769 volume_info.rsize));
1770 cifs_sb->rsize = CIFSMaxBufSize;
1771 } else if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize))
1772 cifs_sb->rsize = volume_info.rsize;
1774 cifs_sb->rsize = CIFSMaxBufSize;
1776 if(volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
1777 cERROR(1,("wsize %d too large using 4096 instead",
1778 volume_info.wsize));
1779 cifs_sb->wsize = 4096;
1780 } else if(volume_info.wsize)
1781 cifs_sb->wsize = volume_info.wsize;
1783 cifs_sb->wsize = CIFSMaxBufSize; /* default */
1784 if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
1785 cifs_sb->rsize = PAGE_CACHE_SIZE;
1786 /* Windows ME does this */
1787 cFYI(1,("Attempt to set readsize for mount to less than one page (4096)"));
1789 cifs_sb->mnt_uid = volume_info.linux_uid;
1790 cifs_sb->mnt_gid = volume_info.linux_gid;
1791 cifs_sb->mnt_file_mode = volume_info.file_mode;
1792 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
1793 cFYI(1,("file mode: 0x%x dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
1795 if(volume_info.noperm)
1796 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
1797 if(volume_info.setuids)
1798 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
1799 if(volume_info.server_ino)
1800 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
1801 if(volume_info.remap)
1802 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
1803 if(volume_info.no_xattr)
1804 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
1805 if(volume_info.sfu_emul)
1806 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
1807 if(volume_info.nobrl)
1808 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
1810 if(volume_info.direct_io) {
1811 cFYI(1,("mounting share using direct i/o"));
1812 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
1816 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
1817 volume_info.username);
1819 cFYI(1, ("Found match on UNC path"));
1820 /* we can have only one retry value for a connection
1821 to a share so for resources mounted more than once
1822 to the same server share the last value passed in
1823 for the retry flag is used */
1824 tcon->retry = volume_info.retry;
1825 tcon->nocase = volume_info.nocase;
1827 tcon = tconInfoAlloc();
1831 /* check for null share name ie connect to dfs root */
1833 /* BB check if this works for exactly length three strings */
1834 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
1835 && (strchr(volume_info.UNC + 3, '/') ==
1837 rc = connect_to_dfs_path(xid, pSesInfo,
1838 "", cifs_sb->local_nls,
1839 cifs_sb->mnt_cifs_flags &
1840 CIFS_MOUNT_MAP_SPECIAL_CHR);
1841 kfree(volume_info.UNC);
1845 rc = CIFSTCon(xid, pSesInfo,
1847 tcon, cifs_sb->local_nls);
1848 cFYI(1, ("CIFS Tcon rc = %d", rc));
1851 atomic_inc(&pSesInfo->inUse);
1852 tcon->retry = volume_info.retry;
1853 tcon->nocase = volume_info.nocase;
1859 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
1860 sb->s_maxbytes = (u64) 1 << 63;
1862 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
1865 sb->s_time_gran = 100;
1867 /* on error free sesinfo and tcon struct if needed */
1869 /* if session setup failed, use count is zero but
1870 we still need to free cifsd thread */
1871 if(atomic_read(&srvTcp->socketUseCount) == 0) {
1872 spin_lock(&GlobalMid_Lock);
1873 srvTcp->tcpStatus = CifsExiting;
1874 spin_unlock(&GlobalMid_Lock);
1876 send_sig(SIGKILL,srvTcp->tsk,1);
1877 wait_for_completion(&cifsd_complete);
1880 /* If find_unc succeeded then rc == 0 so we can not end */
1881 if (tcon) /* up accidently freeing someone elses tcon struct */
1883 if (existingCifsSes == NULL) {
1885 if ((pSesInfo->server) &&
1886 (pSesInfo->status == CifsGood)) {
1888 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
1889 /* if the socketUseCount is now zero */
1890 if((temp_rc == -ESHUTDOWN) &&
1891 (pSesInfo->server->tsk)) {
1892 send_sig(SIGKILL,pSesInfo->server->tsk,1);
1893 wait_for_completion(&cifsd_complete);
1896 cFYI(1, ("No session or bad tcon"));
1897 sesInfoFree(pSesInfo);
1898 /* pSesInfo = NULL; */
1902 atomic_inc(&tcon->useCount);
1903 cifs_sb->tcon = tcon;
1904 tcon->ses = pSesInfo;
1906 /* do not care if following two calls succeed - informational only */
1907 CIFSSMBQFSDeviceInfo(xid, tcon);
1908 CIFSSMBQFSAttributeInfo(xid, tcon);
1909 if (tcon->ses->capabilities & CAP_UNIX) {
1910 if(!CIFSSMBQFSUnixInfo(xid, tcon)) {
1911 if(!volume_info.no_psx_acl) {
1912 if(CIFS_UNIX_POSIX_ACL_CAP &
1913 le64_to_cpu(tcon->fsUnixInfo.Capability))
1914 cFYI(1,("server negotiated posix acl support"));
1915 sb->s_flags |= MS_POSIXACL;
1918 /* Try and negotiate POSIX pathnames if we can. */
1919 if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP &
1920 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1921 if (!CIFSSMBSetFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP)) {
1922 cFYI(1,("negotiated posix pathnames support"));
1923 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
1925 cFYI(1,("posix pathnames support requested but not supported"));
1930 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
1931 cifs_sb->wsize = min(cifs_sb->wsize,
1932 (tcon->ses->server->maxBuf -
1933 MAX_CIFS_HDR_SIZE));
1934 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
1935 cifs_sb->rsize = min(cifs_sb->rsize,
1936 (tcon->ses->server->maxBuf -
1937 MAX_CIFS_HDR_SIZE));
1940 /* volume_info.password is freed above when existing session found
1941 (in which case it is not needed anymore) but when new sesion is created
1942 the password ptr is put in the new session structure (in which case the
1943 password will be freed at unmount time) */
1944 kfree(volume_info.UNC);
1950 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
1951 char session_key[CIFS_SESSION_KEY_SIZE],
1952 const struct nls_table *nls_codepage)
1954 struct smb_hdr *smb_buffer;
1955 struct smb_hdr *smb_buffer_response;
1956 SESSION_SETUP_ANDX *pSMB;
1957 SESSION_SETUP_ANDX *pSMBr;
1962 int remaining_words = 0;
1963 int bytes_returned = 0;
1968 cFYI(1, ("In sesssetup "));
1971 user = ses->userName;
1972 domain = ses->domainName;
1973 smb_buffer = cifs_buf_get();
1974 if (smb_buffer == NULL) {
1977 smb_buffer_response = smb_buffer;
1978 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
1980 /* send SMBsessionSetup here */
1981 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
1982 NULL /* no tCon exists yet */ , 13 /* wct */ );
1984 smb_buffer->Mid = GetNextMid(ses->server);
1985 pSMB->req_no_secext.AndXCommand = 0xFF;
1986 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
1987 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
1989 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1990 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
1992 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
1993 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
1994 if (ses->capabilities & CAP_UNICODE) {
1995 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
1996 capabilities |= CAP_UNICODE;
1998 if (ses->capabilities & CAP_STATUS32) {
1999 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2000 capabilities |= CAP_STATUS32;
2002 if (ses->capabilities & CAP_DFS) {
2003 smb_buffer->Flags2 |= SMBFLG2_DFS;
2004 capabilities |= CAP_DFS;
2006 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2008 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2009 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
2011 pSMB->req_no_secext.CaseSensitivePasswordLength =
2012 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
2013 bcc_ptr = pByteArea(smb_buffer);
2014 memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
2015 bcc_ptr += CIFS_SESSION_KEY_SIZE;
2016 memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
2017 bcc_ptr += CIFS_SESSION_KEY_SIZE;
2019 if (ses->capabilities & CAP_UNICODE) {
2020 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2025 bytes_returned = 0; /* skill null user */
2028 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2030 /* convert number of 16 bit words to bytes */
2031 bcc_ptr += 2 * bytes_returned;
2032 bcc_ptr += 2; /* trailing null */
2035 cifs_strtoUCS((__le16 *) bcc_ptr,
2036 "CIFS_LINUX_DOM", 32, nls_codepage);
2039 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2041 bcc_ptr += 2 * bytes_returned;
2044 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2046 bcc_ptr += 2 * bytes_returned;
2048 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
2050 bcc_ptr += 2 * bytes_returned;
2053 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2055 bcc_ptr += 2 * bytes_returned;
2059 strncpy(bcc_ptr, user, 200);
2060 bcc_ptr += strnlen(user, 200);
2064 if (domain == NULL) {
2065 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2066 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2068 strncpy(bcc_ptr, domain, 64);
2069 bcc_ptr += strnlen(domain, 64);
2073 strcpy(bcc_ptr, "Linux version ");
2074 bcc_ptr += strlen("Linux version ");
2075 strcpy(bcc_ptr, system_utsname.release);
2076 bcc_ptr += strlen(system_utsname.release) + 1;
2077 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2078 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2080 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2081 smb_buffer->smb_buf_length += count;
2082 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2084 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2085 &bytes_returned, 1);
2087 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2088 } else if ((smb_buffer_response->WordCount == 3)
2089 || (smb_buffer_response->WordCount == 4)) {
2090 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2091 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2092 if (action & GUEST_LOGIN)
2093 cFYI(1, (" Guest login")); /* do we want to mark SesInfo struct ? */
2094 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
2095 cFYI(1, ("UID = %d ", ses->Suid));
2096 /* response can have either 3 or 4 word count - Samba sends 3 */
2097 bcc_ptr = pByteArea(smb_buffer_response);
2098 if ((pSMBr->resp.hdr.WordCount == 3)
2099 || ((pSMBr->resp.hdr.WordCount == 4)
2100 && (blob_len < pSMBr->resp.ByteCount))) {
2101 if (pSMBr->resp.hdr.WordCount == 4)
2102 bcc_ptr += blob_len;
2104 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2105 if ((long) (bcc_ptr) % 2) {
2107 (BCC(smb_buffer_response) - 1) /2;
2108 bcc_ptr++; /* Unicode strings must be word aligned */
2111 BCC(smb_buffer_response) / 2;
2114 UniStrnlen((wchar_t *) bcc_ptr,
2115 remaining_words - 1);
2116 /* We look for obvious messed up bcc or strings in response so we do not go off
2117 the end since (at least) WIN2K and Windows XP have a major bug in not null
2118 terminating last Unicode string in response */
2119 ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL);
2120 if(ses->serverOS == NULL)
2121 goto sesssetup_nomem;
2122 cifs_strfromUCS_le(ses->serverOS,
2123 (__le16 *)bcc_ptr, len,nls_codepage);
2124 bcc_ptr += 2 * (len + 1);
2125 remaining_words -= len + 1;
2126 ses->serverOS[2 * len] = 0;
2127 ses->serverOS[1 + (2 * len)] = 0;
2128 if (remaining_words > 0) {
2129 len = UniStrnlen((wchar_t *)bcc_ptr,
2131 ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL);
2132 if(ses->serverNOS == NULL)
2133 goto sesssetup_nomem;
2134 cifs_strfromUCS_le(ses->serverNOS,
2135 (__le16 *)bcc_ptr,len,nls_codepage);
2136 bcc_ptr += 2 * (len + 1);
2137 ses->serverNOS[2 * len] = 0;
2138 ses->serverNOS[1 + (2 * len)] = 0;
2139 if(strncmp(ses->serverNOS,
2140 "NT LAN Manager 4",16) == 0) {
2141 cFYI(1,("NT4 server"));
2142 ses->flags |= CIFS_SES_NT4;
2144 remaining_words -= len + 1;
2145 if (remaining_words > 0) {
2146 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2147 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2149 kzalloc(2*(len+1),GFP_KERNEL);
2150 if(ses->serverDomain == NULL)
2151 goto sesssetup_nomem;
2152 cifs_strfromUCS_le(ses->serverDomain,
2153 (__le16 *)bcc_ptr,len,nls_codepage);
2154 bcc_ptr += 2 * (len + 1);
2155 ses->serverDomain[2*len] = 0;
2156 ses->serverDomain[1+(2*len)] = 0;
2157 } /* else no more room so create dummy domain string */
2160 kzalloc(2, GFP_KERNEL);
2161 } else { /* no room so create dummy domain and NOS string */
2162 /* if these kcallocs fail not much we
2163 can do, but better to not fail the
2166 kzalloc(2, GFP_KERNEL);
2168 kzalloc(2, GFP_KERNEL);
2170 } else { /* ASCII */
2171 len = strnlen(bcc_ptr, 1024);
2172 if (((long) bcc_ptr + len) - (long)
2173 pByteArea(smb_buffer_response)
2174 <= BCC(smb_buffer_response)) {
2175 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
2176 if(ses->serverOS == NULL)
2177 goto sesssetup_nomem;
2178 strncpy(ses->serverOS,bcc_ptr, len);
2181 bcc_ptr[0] = 0; /* null terminate the string */
2184 len = strnlen(bcc_ptr, 1024);
2185 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL);
2186 if(ses->serverNOS == NULL)
2187 goto sesssetup_nomem;
2188 strncpy(ses->serverNOS, bcc_ptr, len);
2193 len = strnlen(bcc_ptr, 1024);
2194 ses->serverDomain = kzalloc(len + 1,GFP_KERNEL);
2195 if(ses->serverDomain == NULL)
2196 goto sesssetup_nomem;
2197 strncpy(ses->serverDomain, bcc_ptr, len);
2203 ("Variable field of length %d extends beyond end of smb ",
2208 (" Security Blob Length extends beyond end of SMB"));
2212 (" Invalid Word count %d: ",
2213 smb_buffer_response->WordCount));
2216 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2217 since that could make reconnection harder, and
2218 reconnection might be needed to free memory */
2220 cifs_buf_release(smb_buffer);
2226 CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2227 char *SecurityBlob,int SecurityBlobLength,
2228 const struct nls_table *nls_codepage)
2230 struct smb_hdr *smb_buffer;
2231 struct smb_hdr *smb_buffer_response;
2232 SESSION_SETUP_ANDX *pSMB;
2233 SESSION_SETUP_ANDX *pSMBr;
2238 int remaining_words = 0;
2239 int bytes_returned = 0;
2244 cFYI(1, ("In spnego sesssetup "));
2247 user = ses->userName;
2248 domain = ses->domainName;
2250 smb_buffer = cifs_buf_get();
2251 if (smb_buffer == NULL) {
2254 smb_buffer_response = smb_buffer;
2255 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2257 /* send SMBsessionSetup here */
2258 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2259 NULL /* no tCon exists yet */ , 12 /* wct */ );
2261 smb_buffer->Mid = GetNextMid(ses->server);
2262 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2263 pSMB->req.AndXCommand = 0xFF;
2264 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2265 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2267 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2268 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2270 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2271 CAP_EXTENDED_SECURITY;
2272 if (ses->capabilities & CAP_UNICODE) {
2273 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2274 capabilities |= CAP_UNICODE;
2276 if (ses->capabilities & CAP_STATUS32) {
2277 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2278 capabilities |= CAP_STATUS32;
2280 if (ses->capabilities & CAP_DFS) {
2281 smb_buffer->Flags2 |= SMBFLG2_DFS;
2282 capabilities |= CAP_DFS;
2284 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2286 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2287 bcc_ptr = pByteArea(smb_buffer);
2288 memcpy(bcc_ptr, SecurityBlob, SecurityBlobLength);
2289 bcc_ptr += SecurityBlobLength;
2291 if (ses->capabilities & CAP_UNICODE) {
2292 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode strings */
2297 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, nls_codepage);
2298 bcc_ptr += 2 * bytes_returned; /* convert num of 16 bit words to bytes */
2299 bcc_ptr += 2; /* trailing null */
2302 cifs_strtoUCS((__le16 *) bcc_ptr,
2303 "CIFS_LINUX_DOM", 32, nls_codepage);
2306 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2308 bcc_ptr += 2 * bytes_returned;
2311 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2313 bcc_ptr += 2 * bytes_returned;
2315 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
2317 bcc_ptr += 2 * bytes_returned;
2320 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2322 bcc_ptr += 2 * bytes_returned;
2325 strncpy(bcc_ptr, user, 200);
2326 bcc_ptr += strnlen(user, 200);
2329 if (domain == NULL) {
2330 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2331 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2333 strncpy(bcc_ptr, domain, 64);
2334 bcc_ptr += strnlen(domain, 64);
2338 strcpy(bcc_ptr, "Linux version ");
2339 bcc_ptr += strlen("Linux version ");
2340 strcpy(bcc_ptr, system_utsname.release);
2341 bcc_ptr += strlen(system_utsname.release) + 1;
2342 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2343 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2345 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2346 smb_buffer->smb_buf_length += count;
2347 pSMB->req.ByteCount = cpu_to_le16(count);
2349 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2350 &bytes_returned, 1);
2352 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2353 } else if ((smb_buffer_response->WordCount == 3)
2354 || (smb_buffer_response->WordCount == 4)) {
2355 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2357 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2358 if (action & GUEST_LOGIN)
2359 cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */
2361 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
2362 cFYI(1, ("UID = %d ", ses->Suid));
2363 bcc_ptr = pByteArea(smb_buffer_response); /* response can have either 3 or 4 word count - Samba sends 3 */
2365 /* BB Fix below to make endian neutral !! */
2367 if ((pSMBr->resp.hdr.WordCount == 3)
2368 || ((pSMBr->resp.hdr.WordCount == 4)
2370 pSMBr->resp.ByteCount))) {
2371 if (pSMBr->resp.hdr.WordCount == 4) {
2375 ("Security Blob Length %d ",
2379 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2380 if ((long) (bcc_ptr) % 2) {
2382 (BCC(smb_buffer_response)
2384 bcc_ptr++; /* Unicode strings must be word aligned */
2388 (smb_buffer_response) / 2;
2391 UniStrnlen((wchar_t *) bcc_ptr,
2392 remaining_words - 1);
2393 /* We look for obvious messed up bcc or strings in response so we do not go off
2394 the end since (at least) WIN2K and Windows XP have a major bug in not null
2395 terminating last Unicode string in response */
2397 kzalloc(2 * (len + 1), GFP_KERNEL);
2398 cifs_strfromUCS_le(ses->serverOS,
2402 bcc_ptr += 2 * (len + 1);
2403 remaining_words -= len + 1;
2404 ses->serverOS[2 * len] = 0;
2405 ses->serverOS[1 + (2 * len)] = 0;
2406 if (remaining_words > 0) {
2407 len = UniStrnlen((wchar_t *)bcc_ptr,
2411 kzalloc(2 * (len + 1),
2413 cifs_strfromUCS_le(ses->serverNOS,
2417 bcc_ptr += 2 * (len + 1);
2418 ses->serverNOS[2 * len] = 0;
2419 ses->serverNOS[1 + (2 * len)] = 0;
2420 remaining_words -= len + 1;
2421 if (remaining_words > 0) {
2422 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2423 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2424 ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL);
2425 cifs_strfromUCS_le(ses->serverDomain,
2428 bcc_ptr += 2*(len+1);
2429 ses->serverDomain[2*len] = 0;
2430 ses->serverDomain[1+(2*len)] = 0;
2431 } /* else no more room so create dummy domain string */
2434 kzalloc(2,GFP_KERNEL);
2435 } else { /* no room so create dummy domain and NOS string */
2436 ses->serverDomain = kzalloc(2, GFP_KERNEL);
2437 ses->serverNOS = kzalloc(2, GFP_KERNEL);
2439 } else { /* ASCII */
2441 len = strnlen(bcc_ptr, 1024);
2442 if (((long) bcc_ptr + len) - (long)
2443 pByteArea(smb_buffer_response)
2444 <= BCC(smb_buffer_response)) {
2445 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
2446 strncpy(ses->serverOS, bcc_ptr, len);
2449 bcc_ptr[0] = 0; /* null terminate the string */
2452 len = strnlen(bcc_ptr, 1024);
2453 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL);
2454 strncpy(ses->serverNOS, bcc_ptr, len);
2459 len = strnlen(bcc_ptr, 1024);
2460 ses->serverDomain = kzalloc(len + 1, GFP_KERNEL);
2461 strncpy(ses->serverDomain, bcc_ptr, len);
2467 ("Variable field of length %d extends beyond end of smb ",
2472 (" Security Blob Length extends beyond end of SMB"));
2475 cERROR(1, ("No session structure passed in."));
2479 (" Invalid Word count %d: ",
2480 smb_buffer_response->WordCount));
2485 cifs_buf_release(smb_buffer);
2491 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2492 struct cifsSesInfo *ses, int * pNTLMv2_flag,
2493 const struct nls_table *nls_codepage)
2495 struct smb_hdr *smb_buffer;
2496 struct smb_hdr *smb_buffer_response;
2497 SESSION_SETUP_ANDX *pSMB;
2498 SESSION_SETUP_ANDX *pSMBr;
2502 int remaining_words = 0;
2503 int bytes_returned = 0;
2505 int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
2506 PNEGOTIATE_MESSAGE SecurityBlob;
2507 PCHALLENGE_MESSAGE SecurityBlob2;
2508 __u32 negotiate_flags, capabilities;
2511 cFYI(1, ("In NTLMSSP sesssetup (negotiate) "));
2514 domain = ses->domainName;
2515 *pNTLMv2_flag = FALSE;
2516 smb_buffer = cifs_buf_get();
2517 if (smb_buffer == NULL) {
2520 smb_buffer_response = smb_buffer;
2521 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2522 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2524 /* send SMBsessionSetup here */
2525 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2526 NULL /* no tCon exists yet */ , 12 /* wct */ );
2528 smb_buffer->Mid = GetNextMid(ses->server);
2529 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2530 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2532 pSMB->req.AndXCommand = 0xFF;
2533 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2534 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2536 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2537 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2539 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2540 CAP_EXTENDED_SECURITY;
2541 if (ses->capabilities & CAP_UNICODE) {
2542 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2543 capabilities |= CAP_UNICODE;
2545 if (ses->capabilities & CAP_STATUS32) {
2546 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2547 capabilities |= CAP_STATUS32;
2549 if (ses->capabilities & CAP_DFS) {
2550 smb_buffer->Flags2 |= SMBFLG2_DFS;
2551 capabilities |= CAP_DFS;
2553 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2555 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2556 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2557 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2558 SecurityBlob->MessageType = NtLmNegotiate;
2560 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2561 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 |
2562 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2564 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2566 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2567 /* setup pointers to domain name and workstation name */
2568 bcc_ptr += SecurityBlobLength;
2570 SecurityBlob->WorkstationName.Buffer = 0;
2571 SecurityBlob->WorkstationName.Length = 0;
2572 SecurityBlob->WorkstationName.MaximumLength = 0;
2574 if (domain == NULL) {
2575 SecurityBlob->DomainName.Buffer = 0;
2576 SecurityBlob->DomainName.Length = 0;
2577 SecurityBlob->DomainName.MaximumLength = 0;
2580 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
2581 strncpy(bcc_ptr, domain, 63);
2582 len = strnlen(domain, 64);
2583 SecurityBlob->DomainName.MaximumLength =
2585 SecurityBlob->DomainName.Buffer =
2586 cpu_to_le32((long) &SecurityBlob->
2588 (long) &SecurityBlob->Signature);
2590 SecurityBlobLength += len;
2591 SecurityBlob->DomainName.Length =
2594 if (ses->capabilities & CAP_UNICODE) {
2595 if ((long) bcc_ptr % 2) {
2601 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2603 bcc_ptr += 2 * bytes_returned;
2605 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
2607 bcc_ptr += 2 * bytes_returned;
2608 bcc_ptr += 2; /* null terminate Linux version */
2610 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2612 bcc_ptr += 2 * bytes_returned;
2615 bcc_ptr += 2; /* null terminate network opsys string */
2618 bcc_ptr += 2; /* null domain */
2619 } else { /* ASCII */
2620 strcpy(bcc_ptr, "Linux version ");
2621 bcc_ptr += strlen("Linux version ");
2622 strcpy(bcc_ptr, system_utsname.release);
2623 bcc_ptr += strlen(system_utsname.release) + 1;
2624 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2625 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2626 bcc_ptr++; /* empty domain field */
2629 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2630 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2631 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2632 smb_buffer->smb_buf_length += count;
2633 pSMB->req.ByteCount = cpu_to_le16(count);
2635 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2636 &bytes_returned, 1);
2638 if (smb_buffer_response->Status.CifsError ==
2639 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2643 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2644 } else if ((smb_buffer_response->WordCount == 3)
2645 || (smb_buffer_response->WordCount == 4)) {
2646 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2647 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2649 if (action & GUEST_LOGIN)
2650 cFYI(1, (" Guest login"));
2651 /* Do we want to set anything in SesInfo struct when guest login? */
2653 bcc_ptr = pByteArea(smb_buffer_response);
2654 /* response can have either 3 or 4 word count - Samba sends 3 */
2656 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2657 if (SecurityBlob2->MessageType != NtLmChallenge) {
2659 ("Unexpected NTLMSSP message type received %d",
2660 SecurityBlob2->MessageType));
2662 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2663 cFYI(1, ("UID = %d ", ses->Suid));
2664 if ((pSMBr->resp.hdr.WordCount == 3)
2665 || ((pSMBr->resp.hdr.WordCount == 4)
2667 pSMBr->resp.ByteCount))) {
2669 if (pSMBr->resp.hdr.WordCount == 4) {
2670 bcc_ptr += blob_len;
2672 ("Security Blob Length %d ",
2676 cFYI(1, ("NTLMSSP Challenge rcvd "));
2678 memcpy(ses->server->cryptKey,
2679 SecurityBlob2->Challenge,
2680 CIFS_CRYPTO_KEY_SIZE);
2681 if(SecurityBlob2->NegotiateFlags & cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2682 *pNTLMv2_flag = TRUE;
2684 if((SecurityBlob2->NegotiateFlags &
2685 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2686 || (sign_CIFS_PDUs > 1))
2687 ses->server->secMode |=
2688 SECMODE_SIGN_REQUIRED;
2689 if ((SecurityBlob2->NegotiateFlags &
2690 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2691 ses->server->secMode |=
2692 SECMODE_SIGN_ENABLED;
2694 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2695 if ((long) (bcc_ptr) % 2) {
2697 (BCC(smb_buffer_response)
2699 bcc_ptr++; /* Unicode strings must be word aligned */
2703 (smb_buffer_response) / 2;
2706 UniStrnlen((wchar_t *) bcc_ptr,
2707 remaining_words - 1);
2708 /* We look for obvious messed up bcc or strings in response so we do not go off
2709 the end since (at least) WIN2K and Windows XP have a major bug in not null
2710 terminating last Unicode string in response */
2712 kzalloc(2 * (len + 1), GFP_KERNEL);
2713 cifs_strfromUCS_le(ses->serverOS,
2717 bcc_ptr += 2 * (len + 1);
2718 remaining_words -= len + 1;
2719 ses->serverOS[2 * len] = 0;
2720 ses->serverOS[1 + (2 * len)] = 0;
2721 if (remaining_words > 0) {
2722 len = UniStrnlen((wchar_t *)
2727 kzalloc(2 * (len + 1),
2729 cifs_strfromUCS_le(ses->
2735 bcc_ptr += 2 * (len + 1);
2736 ses->serverNOS[2 * len] = 0;
2739 remaining_words -= len + 1;
2740 if (remaining_words > 0) {
2741 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2742 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2754 ses->serverDomain[2*len]
2759 } /* else no more room so create dummy domain string */
2764 } else { /* no room so create dummy domain and NOS string */
2766 kzalloc(2, GFP_KERNEL);
2768 kzalloc(2, GFP_KERNEL);
2770 } else { /* ASCII */
2771 len = strnlen(bcc_ptr, 1024);
2772 if (((long) bcc_ptr + len) - (long)
2773 pByteArea(smb_buffer_response)
2774 <= BCC(smb_buffer_response)) {
2778 strncpy(ses->serverOS,
2782 bcc_ptr[0] = 0; /* null terminate string */
2785 len = strnlen(bcc_ptr, 1024);
2789 strncpy(ses->serverNOS, bcc_ptr, len);
2794 len = strnlen(bcc_ptr, 1024);
2798 strncpy(ses->serverDomain, bcc_ptr, len);
2804 ("Variable field of length %d extends beyond end of smb ",
2809 (" Security Blob Length extends beyond end of SMB"));
2812 cERROR(1, ("No session structure passed in."));
2816 (" Invalid Word count %d: ",
2817 smb_buffer_response->WordCount));
2822 cifs_buf_release(smb_buffer);
2827 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2828 char *ntlm_session_key, int ntlmv2_flag,
2829 const struct nls_table *nls_codepage)
2831 struct smb_hdr *smb_buffer;
2832 struct smb_hdr *smb_buffer_response;
2833 SESSION_SETUP_ANDX *pSMB;
2834 SESSION_SETUP_ANDX *pSMBr;
2839 int remaining_words = 0;
2840 int bytes_returned = 0;
2842 int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
2843 PAUTHENTICATE_MESSAGE SecurityBlob;
2844 __u32 negotiate_flags, capabilities;
2847 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2850 user = ses->userName;
2851 domain = ses->domainName;
2852 smb_buffer = cifs_buf_get();
2853 if (smb_buffer == NULL) {
2856 smb_buffer_response = smb_buffer;
2857 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2858 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2860 /* send SMBsessionSetup here */
2861 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2862 NULL /* no tCon exists yet */ , 12 /* wct */ );
2864 smb_buffer->Mid = GetNextMid(ses->server);
2865 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2866 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2867 pSMB->req.AndXCommand = 0xFF;
2868 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2869 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2871 pSMB->req.hdr.Uid = ses->Suid;
2873 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2874 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2876 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2877 CAP_EXTENDED_SECURITY;
2878 if (ses->capabilities & CAP_UNICODE) {
2879 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2880 capabilities |= CAP_UNICODE;
2882 if (ses->capabilities & CAP_STATUS32) {
2883 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2884 capabilities |= CAP_STATUS32;
2886 if (ses->capabilities & CAP_DFS) {
2887 smb_buffer->Flags2 |= SMBFLG2_DFS;
2888 capabilities |= CAP_DFS;
2890 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2892 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2893 SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
2894 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2895 SecurityBlob->MessageType = NtLmAuthenticate;
2896 bcc_ptr += SecurityBlobLength;
2898 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
2899 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
2900 0x80000000 | NTLMSSP_NEGOTIATE_128;
2902 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
2904 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2906 /* setup pointers to domain name and workstation name */
2908 SecurityBlob->WorkstationName.Buffer = 0;
2909 SecurityBlob->WorkstationName.Length = 0;
2910 SecurityBlob->WorkstationName.MaximumLength = 0;
2911 SecurityBlob->SessionKey.Length = 0;
2912 SecurityBlob->SessionKey.MaximumLength = 0;
2913 SecurityBlob->SessionKey.Buffer = 0;
2915 SecurityBlob->LmChallengeResponse.Length = 0;
2916 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
2917 SecurityBlob->LmChallengeResponse.Buffer = 0;
2919 SecurityBlob->NtChallengeResponse.Length =
2920 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
2921 SecurityBlob->NtChallengeResponse.MaximumLength =
2922 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
2923 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESSION_KEY_SIZE);
2924 SecurityBlob->NtChallengeResponse.Buffer =
2925 cpu_to_le32(SecurityBlobLength);
2926 SecurityBlobLength += CIFS_SESSION_KEY_SIZE;
2927 bcc_ptr += CIFS_SESSION_KEY_SIZE;
2929 if (ses->capabilities & CAP_UNICODE) {
2930 if (domain == NULL) {
2931 SecurityBlob->DomainName.Buffer = 0;
2932 SecurityBlob->DomainName.Length = 0;
2933 SecurityBlob->DomainName.MaximumLength = 0;
2936 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2939 SecurityBlob->DomainName.MaximumLength =
2941 SecurityBlob->DomainName.Buffer =
2942 cpu_to_le32(SecurityBlobLength);
2944 SecurityBlobLength += len;
2945 SecurityBlob->DomainName.Length =
2949 SecurityBlob->UserName.Buffer = 0;
2950 SecurityBlob->UserName.Length = 0;
2951 SecurityBlob->UserName.MaximumLength = 0;
2954 cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
2957 SecurityBlob->UserName.MaximumLength =
2959 SecurityBlob->UserName.Buffer =
2960 cpu_to_le32(SecurityBlobLength);
2962 SecurityBlobLength += len;
2963 SecurityBlob->UserName.Length =
2967 /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
2968 SecurityBlob->WorkstationName.Length *= 2;
2969 SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length);
2970 SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength);
2971 bcc_ptr += SecurityBlob->WorkstationName.Length;
2972 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
2973 SecurityBlob->WorkstationName.Length = cpu_to_le16(SecurityBlob->WorkstationName.Length); */
2975 if ((long) bcc_ptr % 2) {
2980 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2982 bcc_ptr += 2 * bytes_returned;
2984 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
2986 bcc_ptr += 2 * bytes_returned;
2987 bcc_ptr += 2; /* null term version string */
2989 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2991 bcc_ptr += 2 * bytes_returned;
2994 bcc_ptr += 2; /* null terminate network opsys string */
2997 bcc_ptr += 2; /* null domain */
2998 } else { /* ASCII */
2999 if (domain == NULL) {
3000 SecurityBlob->DomainName.Buffer = 0;
3001 SecurityBlob->DomainName.Length = 0;
3002 SecurityBlob->DomainName.MaximumLength = 0;
3005 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3006 strncpy(bcc_ptr, domain, 63);
3007 len = strnlen(domain, 64);
3008 SecurityBlob->DomainName.MaximumLength =
3010 SecurityBlob->DomainName.Buffer =
3011 cpu_to_le32(SecurityBlobLength);
3013 SecurityBlobLength += len;
3014 SecurityBlob->DomainName.Length = cpu_to_le16(len);
3017 SecurityBlob->UserName.Buffer = 0;
3018 SecurityBlob->UserName.Length = 0;
3019 SecurityBlob->UserName.MaximumLength = 0;
3022 strncpy(bcc_ptr, user, 63);
3023 len = strnlen(user, 64);
3024 SecurityBlob->UserName.MaximumLength =
3026 SecurityBlob->UserName.Buffer =
3027 cpu_to_le32(SecurityBlobLength);
3029 SecurityBlobLength += len;
3030 SecurityBlob->UserName.Length = cpu_to_le16(len);
3032 /* BB fill in our workstation name if known BB */
3034 strcpy(bcc_ptr, "Linux version ");
3035 bcc_ptr += strlen("Linux version ");
3036 strcpy(bcc_ptr, system_utsname.release);
3037 bcc_ptr += strlen(system_utsname.release) + 1;
3038 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3039 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3040 bcc_ptr++; /* null domain */
3043 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3044 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3045 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3046 smb_buffer->smb_buf_length += count;
3047 pSMB->req.ByteCount = cpu_to_le16(count);
3049 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3050 &bytes_returned, 1);
3052 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
3053 } else if ((smb_buffer_response->WordCount == 3)
3054 || (smb_buffer_response->WordCount == 4)) {
3055 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3057 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3058 if (action & GUEST_LOGIN)
3059 cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */
3060 /* if(SecurityBlob2->MessageType != NtLm??){
3061 cFYI("Unexpected message type on auth response is %d "));
3065 ("Does UID on challenge %d match auth response UID %d ",
3066 ses->Suid, smb_buffer_response->Uid));
3067 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format */
3068 bcc_ptr = pByteArea(smb_buffer_response);
3069 /* response can have either 3 or 4 word count - Samba sends 3 */
3070 if ((pSMBr->resp.hdr.WordCount == 3)
3071 || ((pSMBr->resp.hdr.WordCount == 4)
3073 pSMBr->resp.ByteCount))) {
3074 if (pSMBr->resp.hdr.WordCount == 4) {
3078 ("Security Blob Length %d ",
3083 ("NTLMSSP response to Authenticate "));
3085 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3086 if ((long) (bcc_ptr) % 2) {
3088 (BCC(smb_buffer_response)
3090 bcc_ptr++; /* Unicode strings must be word aligned */
3092 remaining_words = BCC(smb_buffer_response) / 2;
3095 UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
3096 /* We look for obvious messed up bcc or strings in response so we do not go off
3097 the end since (at least) WIN2K and Windows XP have a major bug in not null
3098 terminating last Unicode string in response */
3100 kzalloc(2 * (len + 1), GFP_KERNEL);
3101 cifs_strfromUCS_le(ses->serverOS,
3105 bcc_ptr += 2 * (len + 1);
3106 remaining_words -= len + 1;
3107 ses->serverOS[2 * len] = 0;
3108 ses->serverOS[1 + (2 * len)] = 0;
3109 if (remaining_words > 0) {
3110 len = UniStrnlen((wchar_t *)
3115 kzalloc(2 * (len + 1),
3117 cifs_strfromUCS_le(ses->
3123 bcc_ptr += 2 * (len + 1);
3124 ses->serverNOS[2 * len] = 0;
3125 ses->serverNOS[1+(2*len)] = 0;
3126 remaining_words -= len + 1;
3127 if (remaining_words > 0) {
3128 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3129 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3154 } /* else no more room so create dummy domain string */
3156 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3157 } else { /* no room so create dummy domain and NOS string */
3158 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3159 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3161 } else { /* ASCII */
3162 len = strnlen(bcc_ptr, 1024);
3163 if (((long) bcc_ptr + len) -
3164 (long) pByteArea(smb_buffer_response)
3165 <= BCC(smb_buffer_response)) {
3166 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
3167 strncpy(ses->serverOS,bcc_ptr, len);
3170 bcc_ptr[0] = 0; /* null terminate the string */
3173 len = strnlen(bcc_ptr, 1024);
3174 ses->serverNOS = kzalloc(len+1,GFP_KERNEL);
3175 strncpy(ses->serverNOS, bcc_ptr, len);
3180 len = strnlen(bcc_ptr, 1024);
3181 ses->serverDomain = kzalloc(len+1,GFP_KERNEL);
3182 strncpy(ses->serverDomain, bcc_ptr, len);
3188 ("Variable field of length %d extends beyond end of smb ",
3193 (" Security Blob Length extends beyond end of SMB"));
3196 cERROR(1, ("No session structure passed in."));
3200 (" Invalid Word count %d: ",
3201 smb_buffer_response->WordCount));
3206 cifs_buf_release(smb_buffer);
3212 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3213 const char *tree, struct cifsTconInfo *tcon,
3214 const struct nls_table *nls_codepage)
3216 struct smb_hdr *smb_buffer;
3217 struct smb_hdr *smb_buffer_response;
3220 unsigned char *bcc_ptr;
3228 smb_buffer = cifs_buf_get();
3229 if (smb_buffer == NULL) {
3232 smb_buffer_response = smb_buffer;
3234 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3235 NULL /*no tid */ , 4 /*wct */ );
3237 smb_buffer->Mid = GetNextMid(ses->server);
3238 smb_buffer->Uid = ses->Suid;
3239 pSMB = (TCONX_REQ *) smb_buffer;
3240 pSMBr = (TCONX_RSP *) smb_buffer_response;
3242 pSMB->AndXCommand = 0xFF;
3243 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3244 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3245 bcc_ptr = &pSMB->Password[0];
3246 bcc_ptr++; /* skip password */
3248 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3249 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3251 if (ses->capabilities & CAP_STATUS32) {
3252 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3254 if (ses->capabilities & CAP_DFS) {
3255 smb_buffer->Flags2 |= SMBFLG2_DFS;
3257 if (ses->capabilities & CAP_UNICODE) {
3258 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3260 cifs_strtoUCS((__le16 *) bcc_ptr, tree, 100, nls_codepage);
3261 bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */
3262 bcc_ptr += 2; /* skip trailing null */
3263 } else { /* ASCII */
3265 strcpy(bcc_ptr, tree);
3266 bcc_ptr += strlen(tree) + 1;
3268 strcpy(bcc_ptr, "?????");
3269 bcc_ptr += strlen("?????");
3271 count = bcc_ptr - &pSMB->Password[0];
3272 pSMB->hdr.smb_buf_length += count;
3273 pSMB->ByteCount = cpu_to_le16(count);
3275 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
3277 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3278 /* above now done in SendReceive */
3279 if ((rc == 0) && (tcon != NULL)) {
3280 tcon->tidStatus = CifsGood;
3281 tcon->tid = smb_buffer_response->Tid;
3282 bcc_ptr = pByteArea(smb_buffer_response);
3283 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3284 /* skip service field (NB: this field is always ASCII) */
3285 bcc_ptr += length + 1;
3286 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3287 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3288 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3289 if ((bcc_ptr + (2 * length)) -
3290 pByteArea(smb_buffer_response) <=
3291 BCC(smb_buffer_response)) {
3292 kfree(tcon->nativeFileSystem);
3293 tcon->nativeFileSystem =
3294 kzalloc(length + 2, GFP_KERNEL);
3295 cifs_strfromUCS_le(tcon->nativeFileSystem,
3297 length, nls_codepage);
3298 bcc_ptr += 2 * length;
3299 bcc_ptr[0] = 0; /* null terminate the string */
3303 /* else do not bother copying these informational fields */
3305 length = strnlen(bcc_ptr, 1024);
3306 if ((bcc_ptr + length) -
3307 pByteArea(smb_buffer_response) <=
3308 BCC(smb_buffer_response)) {
3309 kfree(tcon->nativeFileSystem);
3310 tcon->nativeFileSystem =
3311 kzalloc(length + 1, GFP_KERNEL);
3312 strncpy(tcon->nativeFileSystem, bcc_ptr,
3315 /* else do not bother copying these informational fields */
3317 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3318 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3319 } else if ((rc == 0) && tcon == NULL) {
3320 /* all we need to save for IPC$ connection */
3321 ses->ipc_tid = smb_buffer_response->Tid;
3325 cifs_buf_release(smb_buffer);
3330 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3334 struct cifsSesInfo *ses = NULL;
3335 struct task_struct *cifsd_task;
3339 if (cifs_sb->tcon) {
3340 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3341 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3346 tconInfoFree(cifs_sb->tcon);
3347 if ((ses) && (ses->server)) {
3348 /* save off task so we do not refer to ses later */
3349 cifsd_task = ses->server->tsk;
3350 cFYI(1, ("About to do SMBLogoff "));
3351 rc = CIFSSMBLogoff(xid, ses);
3355 } else if (rc == -ESHUTDOWN) {
3356 cFYI(1,("Waking up socket by sending it signal"));
3358 send_sig(SIGKILL,cifsd_task,1);
3359 wait_for_completion(&cifsd_complete);
3362 } /* else - we have an smb session
3363 left on this socket do not kill cifsd */
3365 cFYI(1, ("No session or bad tcon"));
3368 cifs_sb->tcon = NULL;
3370 schedule_timeout_interruptible(msecs_to_jiffies(500));
3375 return rc; /* BB check if we should always return zero here */
3378 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3379 struct nls_table * nls_info)
3382 char ntlm_session_key[CIFS_SESSION_KEY_SIZE];
3383 int ntlmv2_flag = FALSE;
3386 /* what if server changes its buffer size after dropping the session? */
3387 if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
3388 rc = CIFSSMBNegotiate(xid, pSesInfo);
3389 if(rc == -EAGAIN) /* retry only once on 1st time connection */ {
3390 rc = CIFSSMBNegotiate(xid, pSesInfo);
3395 spin_lock(&GlobalMid_Lock);
3396 if(pSesInfo->server->tcpStatus != CifsExiting)
3397 pSesInfo->server->tcpStatus = CifsGood;
3400 spin_unlock(&GlobalMid_Lock);
3406 pSesInfo->capabilities = pSesInfo->server->capabilities;
3407 if(linuxExtEnabled == 0)
3408 pSesInfo->capabilities &= (~CAP_UNIX);
3409 /* pSesInfo->sequence_number = 0;*/
3410 cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d",
3411 pSesInfo->server->secMode,
3412 pSesInfo->server->capabilities,
3413 pSesInfo->server->timeZone));
3414 if (extended_security
3415 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3416 && (pSesInfo->server->secType == NTLMSSP)) {
3417 cFYI(1, ("New style sesssetup "));
3418 rc = CIFSSpnegoSessSetup(xid, pSesInfo,
3419 NULL /* security blob */,
3420 0 /* blob length */,
3422 } else if (extended_security
3423 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3424 && (pSesInfo->server->secType == RawNTLMSSP)) {
3425 cFYI(1, ("NTLMSSP sesssetup "));
3426 rc = CIFSNTLMSSPNegotiateSessSetup(xid,
3433 cFYI(1,("Can use more secure NTLM version 2 password hash"));
3434 if(CalcNTLMv2_partial_mac_key(pSesInfo,
3439 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
3441 CalcNTLMv2_response(pSesInfo,v2_response);
3443 cifs_calculate_ntlmv2_mac_key(
3444 pSesInfo->server->mac_signing_key,
3445 response, ntlm_session_key, */
3447 /* BB Put dummy sig in SessSetup PDU? */
3454 SMBNTencrypt(pSesInfo->password,
3455 pSesInfo->server->cryptKey,
3459 cifs_calculate_mac_key(
3460 pSesInfo->server->mac_signing_key,
3462 pSesInfo->password);
3464 /* for better security the weaker lanman hash not sent
3465 in AuthSessSetup so we no longer calculate it */
3467 rc = CIFSNTLMSSPAuthSessSetup(xid,
3473 } else { /* old style NTLM 0.12 session setup */
3474 SMBNTencrypt(pSesInfo->password,
3475 pSesInfo->server->cryptKey,
3479 cifs_calculate_mac_key(
3480 pSesInfo->server->mac_signing_key,
3481 ntlm_session_key, pSesInfo->password);
3483 rc = CIFSSessSetup(xid, pSesInfo,
3484 ntlm_session_key, nls_info);
3487 cERROR(1,("Send error in SessSetup = %d",rc));
3489 cFYI(1,("CIFS Session Established successfully"));
3490 pSesInfo->status = CifsGood;