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 */
80 unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/
81 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
83 unsigned remap:1; /* set to remap seven reserved chars in filenames */
84 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
89 unsigned nullauth:1; /* attempt to authenticate with null user */
91 unsigned seal:1; /* encrypt */
92 unsigned nocase; /* request case insensitive filenames */
93 unsigned nobrl; /* disable sending byte range locks to srv */
97 unsigned short int port;
100 static int ipv4_connect(struct sockaddr_in *psin_server,
101 struct socket **csocket,
103 char * server_netb_name);
104 static int ipv6_connect(struct sockaddr_in6 *psin_server,
105 struct socket **csocket);
109 * cifs tcp session reconnection
111 * mark tcp session as reconnecting so temporarily locked
112 * mark all smb sessions as reconnecting for tcp session
113 * reconnect tcp session
114 * wake up waiters on reconnection? - (not needed currently)
118 cifs_reconnect(struct TCP_Server_Info *server)
121 struct list_head *tmp;
122 struct cifsSesInfo *ses;
123 struct cifsTconInfo *tcon;
124 struct mid_q_entry * mid_entry;
126 spin_lock(&GlobalMid_Lock);
127 if(server->tcpStatus == CifsExiting) {
128 /* the demux thread will exit normally
129 next time through the loop */
130 spin_unlock(&GlobalMid_Lock);
133 server->tcpStatus = CifsNeedReconnect;
134 spin_unlock(&GlobalMid_Lock);
137 cFYI(1, ("Reconnecting tcp session"));
139 /* before reconnecting the tcp session, mark the smb session (uid)
140 and the tid bad so they are not used until reconnected */
141 read_lock(&GlobalSMBSeslock);
142 list_for_each(tmp, &GlobalSMBSessionList) {
143 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
145 if (ses->server == server) {
146 ses->status = CifsNeedReconnect;
150 /* else tcp and smb sessions need reconnection */
152 list_for_each(tmp, &GlobalTreeConnectionList) {
153 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
154 if((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
155 tcon->tidStatus = CifsNeedReconnect;
158 read_unlock(&GlobalSMBSeslock);
159 /* do not want to be sending data on a socket we are freeing */
160 down(&server->tcpSem);
161 if(server->ssocket) {
162 cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state,
163 server->ssocket->flags));
164 server->ssocket->ops->shutdown(server->ssocket,SEND_SHUTDOWN);
165 cFYI(1,("Post shutdown state: 0x%x Flags: 0x%lx", server->ssocket->state,
166 server->ssocket->flags));
167 sock_release(server->ssocket);
168 server->ssocket = NULL;
171 spin_lock(&GlobalMid_Lock);
172 list_for_each(tmp, &server->pending_mid_q) {
173 mid_entry = list_entry(tmp, struct
177 if(mid_entry->midState == MID_REQUEST_SUBMITTED) {
178 /* Mark other intransit requests as needing
179 retry so we do not immediately mark the
180 session bad again (ie after we reconnect
181 below) as they timeout too */
182 mid_entry->midState = MID_RETRY_NEEDED;
186 spin_unlock(&GlobalMid_Lock);
189 while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
192 if(server->protocolType == IPV6) {
193 rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket);
195 rc = ipv4_connect(&server->addr.sockAddr,
197 server->workstation_RFC1001_name,
198 server->server_RFC1001_name);
201 cFYI(1,("reconnect error %d",rc));
204 atomic_inc(&tcpSesReconnectCount);
205 spin_lock(&GlobalMid_Lock);
206 if(server->tcpStatus != CifsExiting)
207 server->tcpStatus = CifsGood;
208 server->sequence_number = 0;
209 spin_unlock(&GlobalMid_Lock);
210 /* atomic_set(&server->inFlight,0);*/
211 wake_up(&server->response_q);
219 0 not a transact2, or all data present
220 >0 transact2 with that much data missing
221 -EINVAL = invalid transact2
224 static int check2ndT2(struct smb_hdr * pSMB, unsigned int maxBufSize)
226 struct smb_t2_rsp * pSMBt;
228 int data_in_this_rsp;
231 if(pSMB->Command != SMB_COM_TRANSACTION2)
234 /* check for plausible wct, bcc and t2 data and parm sizes */
235 /* check for parm and data offset going beyond end of smb */
236 if(pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
237 cFYI(1,("invalid transact2 word count"));
241 pSMBt = (struct smb_t2_rsp *)pSMB;
243 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
244 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
246 remaining = total_data_size - data_in_this_rsp;
250 else if(remaining < 0) {
251 cFYI(1,("total data %d smaller than data in frame %d",
252 total_data_size, data_in_this_rsp));
255 cFYI(1,("missing %d bytes from transact2, check next response",
257 if(total_data_size > maxBufSize) {
258 cERROR(1,("TotalDataSize %d is over maximum buffer %d",
259 total_data_size,maxBufSize));
266 static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB)
268 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
269 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
274 char * data_area_of_target;
275 char * data_area_of_buf2;
278 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
280 if(total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
281 cFYI(1,("total data sizes of primary and secondary t2 differ"));
284 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
286 remaining = total_data_size - total_in_buf;
291 if(remaining == 0) /* nothing to do, ignore */
294 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
295 if(remaining < total_in_buf2) {
296 cFYI(1,("transact2 2nd response contains too much data"));
299 /* find end of first SMB data area */
300 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
301 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
302 /* validate target area */
304 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
305 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
307 data_area_of_target += total_in_buf;
309 /* copy second buffer into end of first buffer */
310 memcpy(data_area_of_target,data_area_of_buf2,total_in_buf2);
311 total_in_buf += total_in_buf2;
312 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
313 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
314 byte_count += total_in_buf2;
315 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
317 byte_count = pTargetSMB->smb_buf_length;
318 byte_count += total_in_buf2;
320 /* BB also add check that we are not beyond maximum buffer size */
322 pTargetSMB->smb_buf_length = byte_count;
324 if(remaining == total_in_buf2) {
325 cFYI(1,("found the last secondary response"));
326 return 0; /* we are done */
327 } else /* more responses to go */
333 cifs_demultiplex_thread(struct TCP_Server_Info *server)
336 unsigned int pdu_length, total_read;
337 struct smb_hdr *smb_buffer = NULL;
338 struct smb_hdr *bigbuf = NULL;
339 struct smb_hdr *smallbuf = NULL;
340 struct msghdr smb_msg;
342 struct socket *csocket = server->ssocket;
343 struct list_head *tmp;
344 struct cifsSesInfo *ses;
345 struct task_struct *task_to_wake = NULL;
346 struct mid_q_entry *mid_entry;
348 int isLargeBuf = FALSE;
353 allow_signal(SIGKILL);
354 current->flags |= PF_MEMALLOC;
355 server->tsk = current; /* save process info to wake at shutdown */
356 cFYI(1, ("Demultiplex PID: %d", current->pid));
357 write_lock(&GlobalSMBSeslock);
358 atomic_inc(&tcpSesAllocCount);
359 length = tcpSesAllocCount.counter;
360 write_unlock(&GlobalSMBSeslock);
361 complete(&cifsd_complete);
363 mempool_resize(cifs_req_poolp,
364 length + cifs_min_rcv,
368 while (server->tcpStatus != CifsExiting) {
371 if (bigbuf == NULL) {
372 bigbuf = cifs_buf_get();
374 cERROR(1,("No memory for large SMB response"));
376 /* retry will check if exiting */
379 } else if(isLargeBuf) {
380 /* we are reusing a dirtry large buf, clear its start */
381 memset(bigbuf, 0, sizeof (struct smb_hdr));
384 if (smallbuf == NULL) {
385 smallbuf = cifs_small_buf_get();
386 if(smallbuf == NULL) {
387 cERROR(1,("No memory for SMB response"));
389 /* retry will check if exiting */
392 /* beginning of smb buffer is cleared in our buf_get */
393 } else /* if existing small buf clear beginning */
394 memset(smallbuf, 0, sizeof (struct smb_hdr));
398 smb_buffer = smallbuf;
399 iov.iov_base = smb_buffer;
401 smb_msg.msg_control = NULL;
402 smb_msg.msg_controllen = 0;
404 kernel_recvmsg(csocket, &smb_msg,
405 &iov, 1, 4, 0 /* BB see socket.h flags */);
407 if(server->tcpStatus == CifsExiting) {
409 } else if (server->tcpStatus == CifsNeedReconnect) {
410 cFYI(1,("Reconnect after server stopped responding"));
411 cifs_reconnect(server);
412 cFYI(1,("call to reconnect done"));
413 csocket = server->ssocket;
415 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
416 msleep(1); /* minimum sleep to prevent looping
417 allowing socket to clear and app threads to set
418 tcpStatus CifsNeedReconnect if server hung */
420 } else if (length <= 0) {
421 if(server->tcpStatus == CifsNew) {
422 cFYI(1,("tcp session abend after SMBnegprot"));
423 /* some servers kill the TCP session rather than
424 returning an SMB negprot error, in which
425 case reconnecting here is not going to help,
426 and so simply return error to mount */
429 if(length == -EINTR) {
430 cFYI(1,("cifsd thread killed"));
433 cFYI(1,("Reconnect after unexpected peek error %d",
435 cifs_reconnect(server);
436 csocket = server->ssocket;
437 wake_up(&server->response_q);
439 } else if (length < 4) {
441 ("Frame under four bytes received (%d bytes long)",
443 cifs_reconnect(server);
444 csocket = server->ssocket;
445 wake_up(&server->response_q);
449 /* The right amount was read from socket - 4 bytes */
450 /* so we can now interpret the length field */
452 /* the first byte big endian of the length field,
453 is actually not part of the length but the type
454 with the most common, zero, as regular data */
455 temp = *((char *) smb_buffer);
457 /* Note that FC 1001 length is big endian on the wire,
458 but we convert it here so it is always manipulated
459 as host byte order */
460 pdu_length = ntohl(smb_buffer->smb_buf_length);
461 smb_buffer->smb_buf_length = pdu_length;
463 cFYI(1,("rfc1002 length 0x%x)", pdu_length+4));
465 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
467 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
468 cFYI(1,("Good RFC 1002 session rsp"));
470 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
471 /* we get this from Windows 98 instead of
472 an error on SMB negprot response */
473 cFYI(1,("Negative RFC1002 Session Response Error 0x%x)",
475 if(server->tcpStatus == CifsNew) {
476 /* if nack on negprot (rather than
477 ret of smb negprot error) reconnecting
478 not going to help, ret error to mount */
481 /* give server a second to
482 clean up before reconnect attempt */
484 /* always try 445 first on reconnect
485 since we get NACK on some if we ever
486 connected to port 139 (the NACK is
487 since we do not begin with RFC1001
488 session initialize frame) */
489 server->addr.sockAddr.sin_port =
491 cifs_reconnect(server);
492 csocket = server->ssocket;
493 wake_up(&server->response_q);
496 } else if (temp != (char) 0) {
497 cERROR(1,("Unknown RFC 1002 frame"));
498 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
500 cifs_reconnect(server);
501 csocket = server->ssocket;
505 /* else we have an SMB response */
506 if((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
507 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
508 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
509 length, pdu_length+4));
510 cifs_reconnect(server);
511 csocket = server->ssocket;
512 wake_up(&server->response_q);
519 if(pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
521 memcpy(bigbuf, smallbuf, 4);
525 iov.iov_base = 4 + (char *)smb_buffer;
526 iov.iov_len = pdu_length;
527 for (total_read = 0; total_read < pdu_length;
528 total_read += length) {
529 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
530 pdu_length - total_read, 0);
531 if((server->tcpStatus == CifsExiting) ||
532 (length == -EINTR)) {
536 } else if (server->tcpStatus == CifsNeedReconnect) {
537 cifs_reconnect(server);
538 csocket = server->ssocket;
539 /* Reconnect wakes up rspns q */
540 /* Now we will reread sock */
543 } else if ((length == -ERESTARTSYS) ||
544 (length == -EAGAIN)) {
545 msleep(1); /* minimum sleep to prevent looping,
546 allowing socket to clear and app
547 threads to set tcpStatus
548 CifsNeedReconnect if server hung*/
550 } else if (length <= 0) {
551 cERROR(1,("Received no data, expecting %d",
552 pdu_length - total_read));
553 cifs_reconnect(server);
554 csocket = server->ssocket;
561 else if(reconnect == 1)
564 length += 4; /* account for rfc1002 hdr */
567 dump_smb(smb_buffer, length);
568 if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) {
569 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
575 spin_lock(&GlobalMid_Lock);
576 list_for_each(tmp, &server->pending_mid_q) {
577 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
579 if ((mid_entry->mid == smb_buffer->Mid) &&
580 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
581 (mid_entry->command == smb_buffer->Command)) {
582 if(check2ndT2(smb_buffer,server->maxBuf) > 0) {
583 /* We have a multipart transact2 resp */
585 if(mid_entry->resp_buf) {
586 /* merge response - fix up 1st*/
587 if(coalesce_t2(smb_buffer,
588 mid_entry->resp_buf)) {
591 /* all parts received */
596 cERROR(1,("1st trans2 resp needs bigbuf"));
597 /* BB maybe we can fix this up, switch
598 to already allocated large buffer? */
600 /* Have first buffer */
601 mid_entry->resp_buf =
603 mid_entry->largeBuf = 1;
609 mid_entry->resp_buf = smb_buffer;
611 mid_entry->largeBuf = 1;
613 mid_entry->largeBuf = 0;
615 task_to_wake = mid_entry->tsk;
616 mid_entry->midState = MID_RESPONSE_RECEIVED;
617 #ifdef CONFIG_CIFS_STATS2
618 mid_entry->when_received = jiffies;
623 spin_unlock(&GlobalMid_Lock);
625 /* Was previous buf put in mpx struct for multi-rsp? */
627 /* smb buffer will be freed by user thread */
633 wake_up_process(task_to_wake);
634 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE)
635 && (isMultiRsp == FALSE)) {
636 cERROR(1, ("No task to wake, unknown frame rcvd!"));
637 cifs_dump_mem("Received Data is: ",(char *)smb_buffer,
638 sizeof(struct smb_hdr));
640 } /* end while !EXITING */
642 spin_lock(&GlobalMid_Lock);
643 server->tcpStatus = CifsExiting;
645 /* check if we have blocked requests that need to free */
646 /* Note that cifs_max_pending is normally 50, but
647 can be set at module install time to as little as two */
648 if(atomic_read(&server->inFlight) >= cifs_max_pending)
649 atomic_set(&server->inFlight, cifs_max_pending - 1);
650 /* We do not want to set the max_pending too low or we
651 could end up with the counter going negative */
652 spin_unlock(&GlobalMid_Lock);
653 /* Although there should not be any requests blocked on
654 this queue it can not hurt to be paranoid and try to wake up requests
655 that may haven been blocked when more than 50 at time were on the wire
656 to the same server - they now will see the session is in exit state
657 and get out of SendReceive. */
658 wake_up_all(&server->request_q);
659 /* give those requests time to exit */
662 if(server->ssocket) {
663 sock_release(csocket);
664 server->ssocket = NULL;
666 /* buffer usuallly freed in free_mid - need to free it here on exit */
668 cifs_buf_release(bigbuf);
669 if (smallbuf != NULL)
670 cifs_small_buf_release(smallbuf);
672 read_lock(&GlobalSMBSeslock);
673 if (list_empty(&server->pending_mid_q)) {
674 /* loop through server session structures attached to this and
676 list_for_each(tmp, &GlobalSMBSessionList) {
678 list_entry(tmp, struct cifsSesInfo,
680 if (ses->server == server) {
681 ses->status = CifsExiting;
685 read_unlock(&GlobalSMBSeslock);
687 /* although we can not zero the server struct pointer yet,
688 since there are active requests which may depnd on them,
689 mark the corresponding SMB sessions as exiting too */
690 list_for_each(tmp, &GlobalSMBSessionList) {
691 ses = list_entry(tmp, struct cifsSesInfo,
693 if (ses->server == server) {
694 ses->status = CifsExiting;
698 spin_lock(&GlobalMid_Lock);
699 list_for_each(tmp, &server->pending_mid_q) {
700 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
701 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
703 ("Clearing Mid 0x%x - waking up ",mid_entry->mid));
704 task_to_wake = mid_entry->tsk;
706 wake_up_process(task_to_wake);
710 spin_unlock(&GlobalMid_Lock);
711 read_unlock(&GlobalSMBSeslock);
712 /* 1/8th of sec is more than enough time for them to exit */
716 if (!list_empty(&server->pending_mid_q)) {
717 /* mpx threads have not exited yet give them
718 at least the smb send timeout time for long ops */
719 /* due to delays on oplock break requests, we need
720 to wait at least 45 seconds before giving up
721 on a request getting a response and going ahead
723 cFYI(1, ("Wait for exit from demultiplex thread"));
725 /* if threads still have not exited they are probably never
726 coming home not much else we can do but free the memory */
729 write_lock(&GlobalSMBSeslock);
730 atomic_dec(&tcpSesAllocCount);
731 length = tcpSesAllocCount.counter;
733 /* last chance to mark ses pointers invalid
734 if there are any pointing to this (e.g
735 if a crazy root user tried to kill cifsd
736 kernel thread explicitly this might happen) */
737 list_for_each(tmp, &GlobalSMBSessionList) {
738 ses = list_entry(tmp, struct cifsSesInfo,
740 if (ses->server == server) {
744 write_unlock(&GlobalSMBSeslock);
748 mempool_resize(cifs_req_poolp,
749 length + cifs_min_rcv,
753 complete_and_exit(&cifsd_complete, 0);
758 cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
762 unsigned int temp_len, i, j;
768 memset(vol->source_rfc1001_name,0x20,15);
769 for(i=0;i < strnlen(system_utsname.nodename,15);i++) {
770 /* does not have to be a perfect mapping since the field is
771 informational, only used for servers that do not support
772 port 445 and it can be overridden at mount time */
773 vol->source_rfc1001_name[i] =
774 toupper(system_utsname.nodename[i]);
776 vol->source_rfc1001_name[15] = 0;
777 /* null target name indicates to use *SMBSERVR default called name
778 if we end up sending RFC1001 session initialize */
779 vol->target_rfc1001_name[0] = 0;
780 vol->linux_uid = current->uid; /* current->euid instead? */
781 vol->linux_gid = current->gid;
782 vol->dir_mode = S_IRWXUGO;
783 /* 2767 perms indicate mandatory locking support */
784 vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
786 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
789 /* default is always to request posix paths. */
790 vol->posix_paths = 1;
795 if(strncmp(options,"sep=",4) == 0) {
796 if(options[4] != 0) {
797 separator[0] = options[4];
800 cFYI(1,("Null separator not allowed"));
804 while ((data = strsep(&options, separator)) != NULL) {
807 if ((value = strchr(data, '=')) != NULL)
810 if (strnicmp(data, "user_xattr",10) == 0) {/*parse before user*/
812 } else if (strnicmp(data, "nouser_xattr",12) == 0) {
814 } else if (strnicmp(data, "user", 4) == 0) {
815 if (!value || !*value) {
817 "CIFS: invalid or missing username\n");
818 return 1; /* needs_arg; */
820 if (strnlen(value, 200) < 200) {
821 vol->username = value;
823 printk(KERN_WARNING "CIFS: username too long\n");
826 } else if (strnicmp(data, "pass", 4) == 0) {
828 vol->password = NULL;
830 } else if(value[0] == 0) {
831 /* check if string begins with double comma
832 since that would mean the password really
833 does start with a comma, and would not
834 indicate an empty string */
835 if(value[1] != separator[0]) {
836 vol->password = NULL;
840 temp_len = strlen(value);
841 /* removed password length check, NTLM passwords
842 can be arbitrarily long */
844 /* if comma in password, the string will be
845 prematurely null terminated. Commas in password are
846 specified across the cifs mount interface by a double
847 comma ie ,, and a comma used as in other cases ie ','
848 as a parameter delimiter/separator is single and due
849 to the strsep above is temporarily zeroed. */
851 /* NB: password legally can have multiple commas and
852 the only illegal character in a password is null */
854 if ((value[temp_len] == 0) &&
855 (value[temp_len+1] == separator[0])) {
857 value[temp_len] = separator[0];
858 temp_len+=2; /* move after the second comma */
859 while(value[temp_len] != 0) {
860 if (value[temp_len] == separator[0]) {
861 if (value[temp_len+1] ==
863 /* skip second comma */
866 /* single comma indicating start
873 if(value[temp_len] == 0) {
877 /* point option to start of next parm */
878 options = value + temp_len + 1;
880 /* go from value to value + temp_len condensing
881 double commas to singles. Note that this ends up
882 allocating a few bytes too many, which is ok */
883 vol->password = kzalloc(temp_len, GFP_KERNEL);
884 if(vol->password == NULL) {
885 printk("CIFS: no memory for pass\n");
888 for(i=0,j=0;i<temp_len;i++,j++) {
889 vol->password[j] = value[i];
890 if(value[i] == separator[0]
891 && value[i+1] == separator[0]) {
892 /* skip second comma */
896 vol->password[j] = 0;
898 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
899 if(vol->password == NULL) {
900 printk("CIFS: no memory for pass\n");
903 strcpy(vol->password, value);
905 } else if (strnicmp(data, "ip", 2) == 0) {
906 if (!value || !*value) {
908 } else if (strnlen(value, 35) < 35) {
911 printk(KERN_WARNING "CIFS: ip address too long\n");
914 } else if (strnicmp(data, "sec", 3) == 0) {
915 if (!value || !*value) {
916 cERROR(1,("no security value specified"));
918 } else if (strnicmp(value, "krb5i", 5) == 0) {
921 } else if (strnicmp(value, "krb5p", 5) == 0) {
924 cERROR(1,("Krb5 cifs privacy not supported"));
926 } else if (strnicmp(value, "krb5", 4) == 0) {
928 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
931 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
933 } else if (strnicmp(value, "ntlmi", 5) == 0) {
936 } else if (strnicmp(value, "ntlm", 4) == 0) {
937 /* ntlm is default so can be turned off too */
939 } else if (strnicmp(value, "nontlm", 6) == 0) {
941 } else if (strnicmp(value, "none", 4) == 0) {
944 cERROR(1,("bad security option: %s", value));
947 } else if ((strnicmp(data, "unc", 3) == 0)
948 || (strnicmp(data, "target", 6) == 0)
949 || (strnicmp(data, "path", 4) == 0)) {
950 if (!value || !*value) {
952 "CIFS: invalid path to network resource\n");
953 return 1; /* needs_arg; */
955 if ((temp_len = strnlen(value, 300)) < 300) {
956 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
959 strcpy(vol->UNC,value);
960 if (strncmp(vol->UNC, "//", 2) == 0) {
963 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
965 "CIFS: UNC Path does not begin with // or \\\\ \n");
969 printk(KERN_WARNING "CIFS: UNC name too long\n");
972 } else if ((strnicmp(data, "domain", 3) == 0)
973 || (strnicmp(data, "workgroup", 5) == 0)) {
974 if (!value || !*value) {
975 printk(KERN_WARNING "CIFS: invalid domain name\n");
976 return 1; /* needs_arg; */
978 /* BB are there cases in which a comma can be valid in
979 a domain name and need special handling? */
980 if (strnlen(value, 65) < 65) {
981 vol->domainname = value;
982 cFYI(1, ("Domain name set"));
984 printk(KERN_WARNING "CIFS: domain name too long\n");
987 } else if (strnicmp(data, "iocharset", 9) == 0) {
988 if (!value || !*value) {
989 printk(KERN_WARNING "CIFS: invalid iocharset specified\n");
990 return 1; /* needs_arg; */
992 if (strnlen(value, 65) < 65) {
993 if(strnicmp(value,"default",7))
994 vol->iocharset = value;
995 /* if iocharset not set load_nls_default used by caller */
996 cFYI(1, ("iocharset set to %s",value));
998 printk(KERN_WARNING "CIFS: iocharset name too long.\n");
1001 } else if (strnicmp(data, "uid", 3) == 0) {
1002 if (value && *value) {
1004 simple_strtoul(value, &value, 0);
1006 } else if (strnicmp(data, "gid", 3) == 0) {
1007 if (value && *value) {
1009 simple_strtoul(value, &value, 0);
1011 } else if (strnicmp(data, "file_mode", 4) == 0) {
1012 if (value && *value) {
1014 simple_strtoul(value, &value, 0);
1016 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1017 if (value && *value) {
1019 simple_strtoul(value, &value, 0);
1021 } else if (strnicmp(data, "dirmode", 4) == 0) {
1022 if (value && *value) {
1024 simple_strtoul(value, &value, 0);
1026 } else if (strnicmp(data, "port", 4) == 0) {
1027 if (value && *value) {
1029 simple_strtoul(value, &value, 0);
1031 } else if (strnicmp(data, "rsize", 5) == 0) {
1032 if (value && *value) {
1034 simple_strtoul(value, &value, 0);
1036 } else if (strnicmp(data, "wsize", 5) == 0) {
1037 if (value && *value) {
1039 simple_strtoul(value, &value, 0);
1041 } else if (strnicmp(data, "sockopt", 5) == 0) {
1042 if (value && *value) {
1044 simple_strtoul(value, &value, 0);
1046 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1047 if (!value || !*value || (*value == ' ')) {
1048 cFYI(1,("invalid (empty) netbiosname specified"));
1050 memset(vol->source_rfc1001_name,0x20,15);
1052 /* BB are there cases in which a comma can be
1053 valid in this workstation netbios name (and need
1054 special handling)? */
1056 /* We do not uppercase netbiosname for user */
1060 vol->source_rfc1001_name[i] = value[i];
1062 /* The string has 16th byte zero still from
1063 set at top of the function */
1064 if((i==15) && (value[i] != 0))
1065 printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n");
1067 } else if (strnicmp(data, "servern", 7) == 0) {
1068 /* servernetbiosname specified override *SMBSERVER */
1069 if (!value || !*value || (*value == ' ')) {
1070 cFYI(1,("empty server netbiosname specified"));
1072 /* last byte, type, is 0x20 for servr type */
1073 memset(vol->target_rfc1001_name,0x20,16);
1076 /* BB are there cases in which a comma can be
1077 valid in this workstation netbios name (and need
1078 special handling)? */
1080 /* user or mount helper must uppercase netbiosname */
1084 vol->target_rfc1001_name[i] = value[i];
1086 /* The string has 16th byte zero still from
1087 set at top of the function */
1088 if((i==15) && (value[i] != 0))
1089 printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n");
1091 } else if (strnicmp(data, "credentials", 4) == 0) {
1093 } else if (strnicmp(data, "version", 3) == 0) {
1095 } else if (strnicmp(data, "guest",5) == 0) {
1097 } else if (strnicmp(data, "rw", 2) == 0) {
1099 } else if ((strnicmp(data, "suid", 4) == 0) ||
1100 (strnicmp(data, "nosuid", 6) == 0) ||
1101 (strnicmp(data, "exec", 4) == 0) ||
1102 (strnicmp(data, "noexec", 6) == 0) ||
1103 (strnicmp(data, "nodev", 5) == 0) ||
1104 (strnicmp(data, "noauto", 6) == 0) ||
1105 (strnicmp(data, "dev", 3) == 0)) {
1106 /* The mount tool or mount.cifs helper (if present)
1107 uses these opts to set flags, and the flags are read
1108 by the kernel vfs layer before we get here (ie
1109 before read super) so there is no point trying to
1110 parse these options again and set anything and it
1111 is ok to just ignore them */
1113 } else if (strnicmp(data, "ro", 2) == 0) {
1115 } else if (strnicmp(data, "hard", 4) == 0) {
1117 } else if (strnicmp(data, "soft", 4) == 0) {
1119 } else if (strnicmp(data, "perm", 4) == 0) {
1121 } else if (strnicmp(data, "noperm", 6) == 0) {
1123 } else if (strnicmp(data, "mapchars", 8) == 0) {
1125 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1127 } else if (strnicmp(data, "sfu", 3) == 0) {
1129 } else if (strnicmp(data, "nosfu", 5) == 0) {
1131 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1132 vol->posix_paths = 1;
1133 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1134 vol->posix_paths = 0;
1135 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1136 (strnicmp(data, "ignorecase", 10) == 0)) {
1138 } else if (strnicmp(data, "brl", 3) == 0) {
1140 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1141 (strnicmp(data, "nolock", 6) == 0)) {
1143 /* turn off mandatory locking in mode
1144 if remote locking is turned off since the
1145 local vfs will do advisory */
1146 if(vol->file_mode == (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1147 vol->file_mode = S_IALLUGO;
1148 } else if (strnicmp(data, "setuids", 7) == 0) {
1150 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1152 } else if (strnicmp(data, "nohard", 6) == 0) {
1154 } else if (strnicmp(data, "nosoft", 6) == 0) {
1156 } else if (strnicmp(data, "nointr", 6) == 0) {
1158 } else if (strnicmp(data, "intr", 4) == 0) {
1160 } else if (strnicmp(data, "serverino",7) == 0) {
1161 vol->server_ino = 1;
1162 } else if (strnicmp(data, "noserverino",9) == 0) {
1163 vol->server_ino = 0;
1164 } else if (strnicmp(data, "cifsacl",7) == 0) {
1166 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1168 } else if (strnicmp(data, "acl",3) == 0) {
1169 vol->no_psx_acl = 0;
1170 } else if (strnicmp(data, "noacl",5) == 0) {
1171 vol->no_psx_acl = 1;
1172 } else if (strnicmp(data, "direct",6) == 0) {
1174 } else if (strnicmp(data, "forcedirectio",13) == 0) {
1176 } else if (strnicmp(data, "in6_addr",8) == 0) {
1177 if (!value || !*value) {
1178 vol->in6_addr = NULL;
1179 } else if (strnlen(value, 49) == 48) {
1180 vol->in6_addr = value;
1182 printk(KERN_WARNING "CIFS: ip v6 address not 48 characters long\n");
1185 } else if (strnicmp(data, "noac", 4) == 0) {
1186 printk(KERN_WARNING "CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
1188 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);
1190 if (vol->UNC == NULL) {
1191 if(devname == NULL) {
1192 printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n");
1195 if ((temp_len = strnlen(devname, 300)) < 300) {
1196 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
1197 if(vol->UNC == NULL)
1199 strcpy(vol->UNC,devname);
1200 if (strncmp(vol->UNC, "//", 2) == 0) {
1203 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1204 printk(KERN_WARNING "CIFS: UNC Path does not begin with // or \\\\ \n");
1208 printk(KERN_WARNING "CIFS: UNC name too long\n");
1212 if(vol->UNCip == NULL)
1213 vol->UNCip = &vol->UNC[2];
1218 static struct cifsSesInfo *
1219 cifs_find_tcp_session(struct in_addr * target_ip_addr,
1220 struct in6_addr *target_ip6_addr,
1221 char *userName, struct TCP_Server_Info **psrvTcp)
1223 struct list_head *tmp;
1224 struct cifsSesInfo *ses;
1226 read_lock(&GlobalSMBSeslock);
1228 list_for_each(tmp, &GlobalSMBSessionList) {
1229 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1231 if((target_ip_addr &&
1232 (ses->server->addr.sockAddr.sin_addr.s_addr
1233 == target_ip_addr->s_addr)) || (target_ip6_addr
1234 && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1235 target_ip6_addr,sizeof(*target_ip6_addr)))){
1236 /* BB lock server and tcp session and increment use count here?? */
1237 *psrvTcp = ses->server; /* found a match on the TCP session */
1238 /* BB check if reconnection needed */
1240 (ses->userName, userName,
1241 MAX_USERNAME_SIZE) == 0){
1242 read_unlock(&GlobalSMBSeslock);
1243 return ses; /* found exact match on both tcp and SMB sessions */
1247 /* else tcp and smb sessions need reconnection */
1249 read_unlock(&GlobalSMBSeslock);
1253 static struct cifsTconInfo *
1254 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1256 struct list_head *tmp;
1257 struct cifsTconInfo *tcon;
1259 read_lock(&GlobalSMBSeslock);
1260 list_for_each(tmp, &GlobalTreeConnectionList) {
1261 cFYI(1, ("Next tcon - "));
1262 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1264 if (tcon->ses->server) {
1266 (" old ip addr: %x == new ip %x ?",
1267 tcon->ses->server->addr.sockAddr.sin_addr.
1268 s_addr, new_target_ip_addr));
1269 if (tcon->ses->server->addr.sockAddr.sin_addr.
1270 s_addr == new_target_ip_addr) {
1271 /* BB lock tcon and server and tcp session and increment use count here? */
1272 /* found a match on the TCP session */
1273 /* BB check if reconnection needed */
1274 cFYI(1,("Matched ip, old UNC: %s == new: %s ?",
1275 tcon->treeName, uncName));
1277 (tcon->treeName, uncName,
1278 MAX_TREE_SIZE) == 0) {
1280 ("Matched UNC, old user: %s == new: %s ?",
1281 tcon->treeName, uncName));
1283 (tcon->ses->userName,
1285 MAX_USERNAME_SIZE) == 0) {
1286 read_unlock(&GlobalSMBSeslock);
1287 return tcon;/* also matched user (smb session)*/
1294 read_unlock(&GlobalSMBSeslock);
1299 connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1300 const char *old_path, const struct nls_table *nls_codepage,
1303 unsigned char *referrals = NULL;
1304 unsigned int num_referrals;
1307 rc = get_dfs_path(xid, pSesInfo,old_path, nls_codepage,
1308 &num_referrals, &referrals, remap);
1310 /* BB Add in code to: if valid refrl, if not ip address contact
1311 the helper that resolves tcp names, mount to it, try to
1312 tcon to it unmount it if fail */
1320 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1321 const char *old_path, const struct nls_table *nls_codepage,
1322 unsigned int *pnum_referrals,
1323 unsigned char ** preferrals, int remap)
1328 *pnum_referrals = 0;
1330 if (pSesInfo->ipc_tid == 0) {
1331 temp_unc = kmalloc(2 /* for slashes */ +
1332 strnlen(pSesInfo->serverName,SERVER_NAME_LEN_WITH_NULL * 2)
1333 + 1 + 4 /* slash IPC$ */ + 2,
1335 if (temp_unc == NULL)
1339 strcpy(temp_unc + 2, pSesInfo->serverName);
1340 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1341 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1343 ("CIFS Tcon rc = %d ipc_tid = %d", rc,pSesInfo->ipc_tid));
1347 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1348 pnum_referrals, nls_codepage, remap);
1353 /* See RFC1001 section 14 on representation of Netbios names */
1354 static void rfc1002mangle(char * target,char * source, unsigned int length)
1358 for(i=0,j=0;i<(length);i++) {
1359 /* mask a nibble at a time and encode */
1360 target[j] = 'A' + (0x0F & (source[i] >> 4));
1361 target[j+1] = 'A' + (0x0F & source[i]);
1369 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1370 char * netbios_name, char * target_name)
1374 __be16 orig_port = 0;
1376 if(*csocket == NULL) {
1377 rc = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket);
1379 cERROR(1, ("Error %d creating socket",rc));
1383 /* BB other socket options to set KEEPALIVE, NODELAY? */
1384 cFYI(1,("Socket created"));
1385 (*csocket)->sk->sk_allocation = GFP_NOFS;
1389 psin_server->sin_family = AF_INET;
1390 if(psin_server->sin_port) { /* user overrode default port */
1391 rc = (*csocket)->ops->connect(*csocket,
1392 (struct sockaddr *) psin_server,
1393 sizeof (struct sockaddr_in),0);
1399 /* save original port so we can retry user specified port
1400 later if fall back ports fail this time */
1401 orig_port = psin_server->sin_port;
1403 /* do not retry on the same port we just failed on */
1404 if(psin_server->sin_port != htons(CIFS_PORT)) {
1405 psin_server->sin_port = htons(CIFS_PORT);
1407 rc = (*csocket)->ops->connect(*csocket,
1408 (struct sockaddr *) psin_server,
1409 sizeof (struct sockaddr_in),0);
1415 psin_server->sin_port = htons(RFC1001_PORT);
1416 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1417 psin_server, sizeof (struct sockaddr_in),0);
1422 /* give up here - unless we want to retry on different
1423 protocol families some day */
1426 psin_server->sin_port = orig_port;
1427 cFYI(1,("Error %d connecting to server via ipv4",rc));
1428 sock_release(*csocket);
1432 /* Eventually check for other socket options to change from
1433 the default. sock_setsockopt not used because it expects
1434 user space buffer */
1435 cFYI(1,("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",(*csocket)->sk->sk_sndbuf,
1436 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1437 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1438 /* make the bufsizes depend on wsize/rsize and max requests */
1439 if((*csocket)->sk->sk_sndbuf < (200 * 1024))
1440 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1441 if((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1442 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1444 /* send RFC1001 sessinit */
1445 if(psin_server->sin_port == htons(RFC1001_PORT)) {
1446 /* some servers require RFC1001 sessinit before sending
1447 negprot - BB check reconnection in case where second
1448 sessinit is sent but no second negprot */
1449 struct rfc1002_session_packet * ses_init_buf;
1450 struct smb_hdr * smb_buf;
1451 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL);
1453 ses_init_buf->trailer.session_req.called_len = 32;
1454 if(target_name && (target_name[0] != 0)) {
1455 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1458 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1459 DEFAULT_CIFS_CALLED_NAME,16);
1462 ses_init_buf->trailer.session_req.calling_len = 32;
1463 /* calling name ends in null (byte 16) from old smb
1465 if(netbios_name && (netbios_name[0] !=0)) {
1466 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1469 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1470 "LINUX_CIFS_CLNT",16);
1472 ses_init_buf->trailer.session_req.scope1 = 0;
1473 ses_init_buf->trailer.session_req.scope2 = 0;
1474 smb_buf = (struct smb_hdr *)ses_init_buf;
1475 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1476 smb_buf->smb_buf_length = 0x81000044;
1477 rc = smb_send(*csocket, smb_buf, 0x44,
1478 (struct sockaddr *)psin_server);
1479 kfree(ses_init_buf);
1481 /* else the negprot may still work without this
1482 even though malloc failed */
1490 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1494 __be16 orig_port = 0;
1496 if(*csocket == NULL) {
1497 rc = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, csocket);
1499 cERROR(1, ("Error %d creating ipv6 socket",rc));
1503 /* BB other socket options to set KEEPALIVE, NODELAY? */
1504 cFYI(1,("ipv6 Socket created"));
1505 (*csocket)->sk->sk_allocation = GFP_NOFS;
1509 psin_server->sin6_family = AF_INET6;
1511 if(psin_server->sin6_port) { /* user overrode default port */
1512 rc = (*csocket)->ops->connect(*csocket,
1513 (struct sockaddr *) psin_server,
1514 sizeof (struct sockaddr_in6),0);
1520 /* save original port so we can retry user specified port
1521 later if fall back ports fail this time */
1523 orig_port = psin_server->sin6_port;
1524 /* do not retry on the same port we just failed on */
1525 if(psin_server->sin6_port != htons(CIFS_PORT)) {
1526 psin_server->sin6_port = htons(CIFS_PORT);
1528 rc = (*csocket)->ops->connect(*csocket,
1529 (struct sockaddr *) psin_server,
1530 sizeof (struct sockaddr_in6),0);
1536 psin_server->sin6_port = htons(RFC1001_PORT);
1537 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1538 psin_server, sizeof (struct sockaddr_in6),0);
1543 /* give up here - unless we want to retry on different
1544 protocol families some day */
1547 psin_server->sin6_port = orig_port;
1548 cFYI(1,("Error %d connecting to server via ipv6",rc));
1549 sock_release(*csocket);
1553 /* Eventually check for other socket options to change from
1554 the default. sock_setsockopt not used because it expects
1555 user space buffer */
1556 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1562 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1563 char *mount_data, const char *devname)
1567 int address_type = AF_INET;
1568 struct socket *csocket = NULL;
1569 struct sockaddr_in sin_server;
1570 struct sockaddr_in6 sin_server6;
1571 struct smb_vol volume_info;
1572 struct cifsSesInfo *pSesInfo = NULL;
1573 struct cifsSesInfo *existingCifsSes = NULL;
1574 struct cifsTconInfo *tcon = NULL;
1575 struct TCP_Server_Info *srvTcp = NULL;
1579 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1581 memset(&volume_info,0,sizeof(struct smb_vol));
1582 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1583 kfree(volume_info.UNC);
1584 kfree(volume_info.password);
1589 if (volume_info.username) {
1590 /* BB fixme parse for domain name here */
1591 cFYI(1, ("Username: %s ", volume_info.username));
1594 cifserror("No username specified");
1595 /* In userspace mount helper we can get user name from alternate
1596 locations such as env variables and files on disk */
1597 kfree(volume_info.UNC);
1598 kfree(volume_info.password);
1603 if (volume_info.UNCip && volume_info.UNC) {
1604 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,&sin_server.sin_addr.s_addr);
1607 /* not ipv4 address, try ipv6 */
1608 rc = cifs_inet_pton(AF_INET6,volume_info.UNCip,&sin_server6.sin6_addr.in6_u);
1610 address_type = AF_INET6;
1612 address_type = AF_INET;
1616 /* we failed translating address */
1617 kfree(volume_info.UNC);
1618 kfree(volume_info.password);
1623 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1626 } else if (volume_info.UNCip){
1627 /* BB using ip addr as server name connect to the DFS root below */
1628 cERROR(1,("Connecting to DFS root not implemented yet"));
1629 kfree(volume_info.UNC);
1630 kfree(volume_info.password);
1633 } else /* which servers DFS root would we conect to */ {
1635 ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified"));
1636 kfree(volume_info.UNC);
1637 kfree(volume_info.password);
1642 /* this is needed for ASCII cp to Unicode converts */
1643 if(volume_info.iocharset == NULL) {
1644 cifs_sb->local_nls = load_nls_default();
1645 /* load_nls_default can not return null */
1647 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1648 if(cifs_sb->local_nls == NULL) {
1649 cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
1650 kfree(volume_info.UNC);
1651 kfree(volume_info.password);
1657 if(address_type == AF_INET)
1658 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1659 NULL /* no ipv6 addr */,
1660 volume_info.username, &srvTcp);
1661 else if(address_type == AF_INET6)
1662 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1663 &sin_server6.sin6_addr,
1664 volume_info.username, &srvTcp);
1666 kfree(volume_info.UNC);
1667 kfree(volume_info.password);
1674 cFYI(1, ("Existing tcp session with server found"));
1675 } else { /* create socket */
1676 if(volume_info.port)
1677 sin_server.sin_port = htons(volume_info.port);
1679 sin_server.sin_port = 0;
1680 rc = ipv4_connect(&sin_server,&csocket,
1681 volume_info.source_rfc1001_name,
1682 volume_info.target_rfc1001_name);
1685 ("Error connecting to IPv4 socket. Aborting operation"));
1687 sock_release(csocket);
1688 kfree(volume_info.UNC);
1689 kfree(volume_info.password);
1694 srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
1695 if (srvTcp == NULL) {
1697 sock_release(csocket);
1698 kfree(volume_info.UNC);
1699 kfree(volume_info.password);
1703 memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
1704 memcpy(&srvTcp->addr.sockAddr, &sin_server, sizeof (struct sockaddr_in));
1705 atomic_set(&srvTcp->inFlight,0);
1706 /* BB Add code for ipv6 case too */
1707 srvTcp->ssocket = csocket;
1708 srvTcp->protocolType = IPV4;
1709 init_waitqueue_head(&srvTcp->response_q);
1710 init_waitqueue_head(&srvTcp->request_q);
1711 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
1712 /* at this point we are the only ones with the pointer
1713 to the struct since the kernel thread not created yet
1714 so no need to spinlock this init of tcpStatus */
1715 srvTcp->tcpStatus = CifsNew;
1716 init_MUTEX(&srvTcp->tcpSem);
1717 rc = (int)kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
1718 CLONE_FS | CLONE_FILES | CLONE_VM);
1721 sock_release(csocket);
1722 kfree(volume_info.UNC);
1723 kfree(volume_info.password);
1727 wait_for_completion(&cifsd_complete);
1729 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
1730 memcpy(srvTcp->server_RFC1001_name, volume_info.target_rfc1001_name,16);
1731 srvTcp->sequence_number = 0;
1735 if (existingCifsSes) {
1736 pSesInfo = existingCifsSes;
1737 cFYI(1, ("Existing smb sess found"));
1738 kfree(volume_info.password);
1739 /* volume_info.UNC freed at end of function */
1741 cFYI(1, ("Existing smb sess not found"));
1742 pSesInfo = sesInfoAlloc();
1743 if (pSesInfo == NULL)
1746 pSesInfo->server = srvTcp;
1747 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
1748 NIPQUAD(sin_server.sin_addr.s_addr));
1752 /* volume_info.password freed at unmount */
1753 if (volume_info.password)
1754 pSesInfo->password = volume_info.password;
1755 if (volume_info.username)
1756 strncpy(pSesInfo->userName,
1757 volume_info.username,MAX_USERNAME_SIZE);
1758 if (volume_info.domainname)
1759 strncpy(pSesInfo->domainName,
1760 volume_info.domainname,MAX_USERNAME_SIZE);
1761 pSesInfo->linux_uid = volume_info.linux_uid;
1762 down(&pSesInfo->sesSem);
1763 rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls);
1764 up(&pSesInfo->sesSem);
1766 atomic_inc(&srvTcp->socketUseCount);
1768 kfree(volume_info.password);
1771 /* search for existing tcon to this server share */
1773 if(volume_info.rsize > CIFSMaxBufSize) {
1774 cERROR(1,("rsize %d too large, using MaxBufSize",
1775 volume_info.rsize));
1776 cifs_sb->rsize = CIFSMaxBufSize;
1777 } else if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize))
1778 cifs_sb->rsize = volume_info.rsize;
1780 cifs_sb->rsize = CIFSMaxBufSize;
1782 if(volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
1783 cERROR(1,("wsize %d too large using 4096 instead",
1784 volume_info.wsize));
1785 cifs_sb->wsize = 4096;
1786 } else if(volume_info.wsize)
1787 cifs_sb->wsize = volume_info.wsize;
1790 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
1792 /* old default of CIFSMaxBufSize was too small now
1793 that SMB Write2 can send multiple pages in kvec.
1794 RFC1001 does not describe what happens when frame
1795 bigger than 128K is sent so use that as max in
1796 conjunction with 52K kvec constraint on arch with 4K
1799 if(cifs_sb->rsize < 2048) {
1800 cifs_sb->rsize = 2048;
1801 /* Windows ME may prefer this */
1802 cFYI(1,("readsize set to minimum 2048"));
1804 cifs_sb->mnt_uid = volume_info.linux_uid;
1805 cifs_sb->mnt_gid = volume_info.linux_gid;
1806 cifs_sb->mnt_file_mode = volume_info.file_mode;
1807 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
1808 cFYI(1,("file mode: 0x%x dir mode: 0x%x",
1809 cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
1811 if(volume_info.noperm)
1812 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
1813 if(volume_info.setuids)
1814 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
1815 if(volume_info.server_ino)
1816 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
1817 if(volume_info.remap)
1818 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
1819 if(volume_info.no_xattr)
1820 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
1821 if(volume_info.sfu_emul)
1822 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
1823 if(volume_info.nobrl)
1824 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
1825 if(volume_info.cifs_acl)
1826 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
1828 if(volume_info.direct_io) {
1829 cFYI(1,("mounting share using direct i/o"));
1830 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
1834 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
1835 volume_info.username);
1837 cFYI(1, ("Found match on UNC path"));
1838 /* we can have only one retry value for a connection
1839 to a share so for resources mounted more than once
1840 to the same server share the last value passed in
1841 for the retry flag is used */
1842 tcon->retry = volume_info.retry;
1843 tcon->nocase = volume_info.nocase;
1845 tcon = tconInfoAlloc();
1849 /* check for null share name ie connect to dfs root */
1851 /* BB check if this works for exactly length three strings */
1852 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
1853 && (strchr(volume_info.UNC + 3, '/') ==
1855 rc = connect_to_dfs_path(xid, pSesInfo,
1856 "", cifs_sb->local_nls,
1857 cifs_sb->mnt_cifs_flags &
1858 CIFS_MOUNT_MAP_SPECIAL_CHR);
1859 kfree(volume_info.UNC);
1863 rc = CIFSTCon(xid, pSesInfo,
1865 tcon, cifs_sb->local_nls);
1866 cFYI(1, ("CIFS Tcon rc = %d", rc));
1869 atomic_inc(&pSesInfo->inUse);
1870 tcon->retry = volume_info.retry;
1871 tcon->nocase = volume_info.nocase;
1877 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
1878 sb->s_maxbytes = (u64) 1 << 63;
1880 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
1883 sb->s_time_gran = 100;
1885 /* on error free sesinfo and tcon struct if needed */
1887 /* if session setup failed, use count is zero but
1888 we still need to free cifsd thread */
1889 if(atomic_read(&srvTcp->socketUseCount) == 0) {
1890 spin_lock(&GlobalMid_Lock);
1891 srvTcp->tcpStatus = CifsExiting;
1892 spin_unlock(&GlobalMid_Lock);
1894 send_sig(SIGKILL,srvTcp->tsk,1);
1895 wait_for_completion(&cifsd_complete);
1898 /* If find_unc succeeded then rc == 0 so we can not end */
1899 if (tcon) /* up accidently freeing someone elses tcon struct */
1901 if (existingCifsSes == NULL) {
1903 if ((pSesInfo->server) &&
1904 (pSesInfo->status == CifsGood)) {
1906 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
1907 /* if the socketUseCount is now zero */
1908 if((temp_rc == -ESHUTDOWN) &&
1909 (pSesInfo->server->tsk)) {
1910 send_sig(SIGKILL,pSesInfo->server->tsk,1);
1911 wait_for_completion(&cifsd_complete);
1914 cFYI(1, ("No session or bad tcon"));
1915 sesInfoFree(pSesInfo);
1916 /* pSesInfo = NULL; */
1920 atomic_inc(&tcon->useCount);
1921 cifs_sb->tcon = tcon;
1922 tcon->ses = pSesInfo;
1924 /* do not care if following two calls succeed - informational only */
1925 CIFSSMBQFSDeviceInfo(xid, tcon);
1926 CIFSSMBQFSAttributeInfo(xid, tcon);
1927 if (tcon->ses->capabilities & CAP_UNIX) {
1928 if(!CIFSSMBQFSUnixInfo(xid, tcon)) {
1929 if(!volume_info.no_psx_acl) {
1930 if(CIFS_UNIX_POSIX_ACL_CAP &
1931 le64_to_cpu(tcon->fsUnixInfo.Capability))
1932 cFYI(1,("server negotiated posix acl support"));
1933 sb->s_flags |= MS_POSIXACL;
1936 /* Try and negotiate POSIX pathnames if we can. */
1937 if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP &
1938 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1939 if (!CIFSSMBSetFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP)) {
1940 cFYI(1,("negotiated posix pathnames support"));
1941 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
1943 cFYI(1,("posix pathnames support requested but not supported"));
1948 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
1949 cifs_sb->wsize = min(cifs_sb->wsize,
1950 (tcon->ses->server->maxBuf -
1951 MAX_CIFS_HDR_SIZE));
1952 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
1953 cifs_sb->rsize = min(cifs_sb->rsize,
1954 (tcon->ses->server->maxBuf -
1955 MAX_CIFS_HDR_SIZE));
1958 /* volume_info.password is freed above when existing session found
1959 (in which case it is not needed anymore) but when new sesion is created
1960 the password ptr is put in the new session structure (in which case the
1961 password will be freed at unmount time) */
1962 kfree(volume_info.UNC);
1968 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
1969 char session_key[CIFS_SESSION_KEY_SIZE],
1970 const struct nls_table *nls_codepage)
1972 struct smb_hdr *smb_buffer;
1973 struct smb_hdr *smb_buffer_response;
1974 SESSION_SETUP_ANDX *pSMB;
1975 SESSION_SETUP_ANDX *pSMBr;
1980 int remaining_words = 0;
1981 int bytes_returned = 0;
1986 cFYI(1, ("In sesssetup"));
1989 user = ses->userName;
1990 domain = ses->domainName;
1991 smb_buffer = cifs_buf_get();
1992 if (smb_buffer == NULL) {
1995 smb_buffer_response = smb_buffer;
1996 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
1998 /* send SMBsessionSetup here */
1999 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2000 NULL /* no tCon exists yet */ , 13 /* wct */ );
2002 smb_buffer->Mid = GetNextMid(ses->server);
2003 pSMB->req_no_secext.AndXCommand = 0xFF;
2004 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2005 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2007 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2008 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2010 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2011 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2012 if (ses->capabilities & CAP_UNICODE) {
2013 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2014 capabilities |= CAP_UNICODE;
2016 if (ses->capabilities & CAP_STATUS32) {
2017 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2018 capabilities |= CAP_STATUS32;
2020 if (ses->capabilities & CAP_DFS) {
2021 smb_buffer->Flags2 |= SMBFLG2_DFS;
2022 capabilities |= CAP_DFS;
2024 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2026 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2027 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
2029 pSMB->req_no_secext.CaseSensitivePasswordLength =
2030 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
2031 bcc_ptr = pByteArea(smb_buffer);
2032 memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
2033 bcc_ptr += CIFS_SESSION_KEY_SIZE;
2034 memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
2035 bcc_ptr += CIFS_SESSION_KEY_SIZE;
2037 if (ses->capabilities & CAP_UNICODE) {
2038 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2043 bytes_returned = 0; /* skill null user */
2046 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2048 /* convert number of 16 bit words to bytes */
2049 bcc_ptr += 2 * bytes_returned;
2050 bcc_ptr += 2; /* trailing null */
2053 cifs_strtoUCS((__le16 *) bcc_ptr,
2054 "CIFS_LINUX_DOM", 32, nls_codepage);
2057 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2059 bcc_ptr += 2 * bytes_returned;
2062 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2064 bcc_ptr += 2 * bytes_returned;
2066 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
2068 bcc_ptr += 2 * bytes_returned;
2071 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2073 bcc_ptr += 2 * bytes_returned;
2077 strncpy(bcc_ptr, user, 200);
2078 bcc_ptr += strnlen(user, 200);
2082 if (domain == NULL) {
2083 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2084 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2086 strncpy(bcc_ptr, domain, 64);
2087 bcc_ptr += strnlen(domain, 64);
2091 strcpy(bcc_ptr, "Linux version ");
2092 bcc_ptr += strlen("Linux version ");
2093 strcpy(bcc_ptr, system_utsname.release);
2094 bcc_ptr += strlen(system_utsname.release) + 1;
2095 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2096 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2098 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2099 smb_buffer->smb_buf_length += count;
2100 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2102 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2103 &bytes_returned, 1);
2105 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2106 } else if ((smb_buffer_response->WordCount == 3)
2107 || (smb_buffer_response->WordCount == 4)) {
2108 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2109 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2110 if (action & GUEST_LOGIN)
2111 cFYI(1, (" Guest login")); /* do we want to mark SesInfo struct ? */
2112 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
2113 cFYI(1, ("UID = %d ", ses->Suid));
2114 /* response can have either 3 or 4 word count - Samba sends 3 */
2115 bcc_ptr = pByteArea(smb_buffer_response);
2116 if ((pSMBr->resp.hdr.WordCount == 3)
2117 || ((pSMBr->resp.hdr.WordCount == 4)
2118 && (blob_len < pSMBr->resp.ByteCount))) {
2119 if (pSMBr->resp.hdr.WordCount == 4)
2120 bcc_ptr += blob_len;
2122 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2123 if ((long) (bcc_ptr) % 2) {
2125 (BCC(smb_buffer_response) - 1) /2;
2126 bcc_ptr++; /* Unicode strings must be word aligned */
2129 BCC(smb_buffer_response) / 2;
2132 UniStrnlen((wchar_t *) bcc_ptr,
2133 remaining_words - 1);
2134 /* We look for obvious messed up bcc or strings in response so we do not go off
2135 the end since (at least) WIN2K and Windows XP have a major bug in not null
2136 terminating last Unicode string in response */
2137 ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL);
2138 if(ses->serverOS == NULL)
2139 goto sesssetup_nomem;
2140 cifs_strfromUCS_le(ses->serverOS,
2141 (__le16 *)bcc_ptr, len,nls_codepage);
2142 bcc_ptr += 2 * (len + 1);
2143 remaining_words -= len + 1;
2144 ses->serverOS[2 * len] = 0;
2145 ses->serverOS[1 + (2 * len)] = 0;
2146 if (remaining_words > 0) {
2147 len = UniStrnlen((wchar_t *)bcc_ptr,
2149 ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL);
2150 if(ses->serverNOS == NULL)
2151 goto sesssetup_nomem;
2152 cifs_strfromUCS_le(ses->serverNOS,
2153 (__le16 *)bcc_ptr,len,nls_codepage);
2154 bcc_ptr += 2 * (len + 1);
2155 ses->serverNOS[2 * len] = 0;
2156 ses->serverNOS[1 + (2 * len)] = 0;
2157 if(strncmp(ses->serverNOS,
2158 "NT LAN Manager 4",16) == 0) {
2159 cFYI(1,("NT4 server"));
2160 ses->flags |= CIFS_SES_NT4;
2162 remaining_words -= len + 1;
2163 if (remaining_words > 0) {
2164 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2165 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2167 kzalloc(2*(len+1),GFP_KERNEL);
2168 if(ses->serverDomain == NULL)
2169 goto sesssetup_nomem;
2170 cifs_strfromUCS_le(ses->serverDomain,
2171 (__le16 *)bcc_ptr,len,nls_codepage);
2172 bcc_ptr += 2 * (len + 1);
2173 ses->serverDomain[2*len] = 0;
2174 ses->serverDomain[1+(2*len)] = 0;
2175 } /* else no more room so create dummy domain string */
2178 kzalloc(2, GFP_KERNEL);
2179 } else { /* no room so create dummy domain and NOS string */
2180 /* if these kcallocs fail not much we
2181 can do, but better to not fail the
2184 kzalloc(2, GFP_KERNEL);
2186 kzalloc(2, GFP_KERNEL);
2188 } else { /* ASCII */
2189 len = strnlen(bcc_ptr, 1024);
2190 if (((long) bcc_ptr + len) - (long)
2191 pByteArea(smb_buffer_response)
2192 <= BCC(smb_buffer_response)) {
2193 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
2194 if(ses->serverOS == NULL)
2195 goto sesssetup_nomem;
2196 strncpy(ses->serverOS,bcc_ptr, len);
2199 bcc_ptr[0] = 0; /* null terminate the string */
2202 len = strnlen(bcc_ptr, 1024);
2203 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL);
2204 if(ses->serverNOS == NULL)
2205 goto sesssetup_nomem;
2206 strncpy(ses->serverNOS, bcc_ptr, len);
2211 len = strnlen(bcc_ptr, 1024);
2212 ses->serverDomain = kzalloc(len + 1,GFP_KERNEL);
2213 if(ses->serverDomain == NULL)
2214 goto sesssetup_nomem;
2215 strncpy(ses->serverDomain, bcc_ptr, len);
2221 ("Variable field of length %d extends beyond end of smb ",
2226 (" Security Blob Length extends beyond end of SMB"));
2230 (" Invalid Word count %d: ",
2231 smb_buffer_response->WordCount));
2234 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2235 since that could make reconnection harder, and
2236 reconnection might be needed to free memory */
2238 cifs_buf_release(smb_buffer);
2244 CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2245 char *SecurityBlob,int SecurityBlobLength,
2246 const struct nls_table *nls_codepage)
2248 struct smb_hdr *smb_buffer;
2249 struct smb_hdr *smb_buffer_response;
2250 SESSION_SETUP_ANDX *pSMB;
2251 SESSION_SETUP_ANDX *pSMBr;
2256 int remaining_words = 0;
2257 int bytes_returned = 0;
2262 cFYI(1, ("In spnego sesssetup "));
2265 user = ses->userName;
2266 domain = ses->domainName;
2268 smb_buffer = cifs_buf_get();
2269 if (smb_buffer == NULL) {
2272 smb_buffer_response = smb_buffer;
2273 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2275 /* send SMBsessionSetup here */
2276 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2277 NULL /* no tCon exists yet */ , 12 /* wct */ );
2279 smb_buffer->Mid = GetNextMid(ses->server);
2280 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2281 pSMB->req.AndXCommand = 0xFF;
2282 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2283 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2285 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2286 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2288 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2289 CAP_EXTENDED_SECURITY;
2290 if (ses->capabilities & CAP_UNICODE) {
2291 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2292 capabilities |= CAP_UNICODE;
2294 if (ses->capabilities & CAP_STATUS32) {
2295 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2296 capabilities |= CAP_STATUS32;
2298 if (ses->capabilities & CAP_DFS) {
2299 smb_buffer->Flags2 |= SMBFLG2_DFS;
2300 capabilities |= CAP_DFS;
2302 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2304 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2305 bcc_ptr = pByteArea(smb_buffer);
2306 memcpy(bcc_ptr, SecurityBlob, SecurityBlobLength);
2307 bcc_ptr += SecurityBlobLength;
2309 if (ses->capabilities & CAP_UNICODE) {
2310 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode strings */
2315 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100, nls_codepage);
2316 bcc_ptr += 2 * bytes_returned; /* convert num of 16 bit words to bytes */
2317 bcc_ptr += 2; /* trailing null */
2320 cifs_strtoUCS((__le16 *) bcc_ptr,
2321 "CIFS_LINUX_DOM", 32, nls_codepage);
2324 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2326 bcc_ptr += 2 * bytes_returned;
2329 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2331 bcc_ptr += 2 * bytes_returned;
2333 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
2335 bcc_ptr += 2 * bytes_returned;
2338 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2340 bcc_ptr += 2 * bytes_returned;
2343 strncpy(bcc_ptr, user, 200);
2344 bcc_ptr += strnlen(user, 200);
2347 if (domain == NULL) {
2348 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2349 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2351 strncpy(bcc_ptr, domain, 64);
2352 bcc_ptr += strnlen(domain, 64);
2356 strcpy(bcc_ptr, "Linux version ");
2357 bcc_ptr += strlen("Linux version ");
2358 strcpy(bcc_ptr, system_utsname.release);
2359 bcc_ptr += strlen(system_utsname.release) + 1;
2360 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2361 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2363 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2364 smb_buffer->smb_buf_length += count;
2365 pSMB->req.ByteCount = cpu_to_le16(count);
2367 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2368 &bytes_returned, 1);
2370 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2371 } else if ((smb_buffer_response->WordCount == 3)
2372 || (smb_buffer_response->WordCount == 4)) {
2373 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2375 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2376 if (action & GUEST_LOGIN)
2377 cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */
2379 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
2380 cFYI(1, ("UID = %d ", ses->Suid));
2381 bcc_ptr = pByteArea(smb_buffer_response); /* response can have either 3 or 4 word count - Samba sends 3 */
2383 /* BB Fix below to make endian neutral !! */
2385 if ((pSMBr->resp.hdr.WordCount == 3)
2386 || ((pSMBr->resp.hdr.WordCount == 4)
2388 pSMBr->resp.ByteCount))) {
2389 if (pSMBr->resp.hdr.WordCount == 4) {
2393 ("Security Blob Length %d ",
2397 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2398 if ((long) (bcc_ptr) % 2) {
2400 (BCC(smb_buffer_response)
2402 bcc_ptr++; /* Unicode strings must be word aligned */
2406 (smb_buffer_response) / 2;
2409 UniStrnlen((wchar_t *) bcc_ptr,
2410 remaining_words - 1);
2411 /* We look for obvious messed up bcc or strings in response so we do not go off
2412 the end since (at least) WIN2K and Windows XP have a major bug in not null
2413 terminating last Unicode string in response */
2415 kzalloc(2 * (len + 1), GFP_KERNEL);
2416 cifs_strfromUCS_le(ses->serverOS,
2420 bcc_ptr += 2 * (len + 1);
2421 remaining_words -= len + 1;
2422 ses->serverOS[2 * len] = 0;
2423 ses->serverOS[1 + (2 * len)] = 0;
2424 if (remaining_words > 0) {
2425 len = UniStrnlen((wchar_t *)bcc_ptr,
2429 kzalloc(2 * (len + 1),
2431 cifs_strfromUCS_le(ses->serverNOS,
2435 bcc_ptr += 2 * (len + 1);
2436 ses->serverNOS[2 * len] = 0;
2437 ses->serverNOS[1 + (2 * len)] = 0;
2438 remaining_words -= len + 1;
2439 if (remaining_words > 0) {
2440 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2441 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2442 ses->serverDomain = kzalloc(2*(len+1),GFP_KERNEL);
2443 cifs_strfromUCS_le(ses->serverDomain,
2446 bcc_ptr += 2*(len+1);
2447 ses->serverDomain[2*len] = 0;
2448 ses->serverDomain[1+(2*len)] = 0;
2449 } /* else no more room so create dummy domain string */
2452 kzalloc(2,GFP_KERNEL);
2453 } else { /* no room so create dummy domain and NOS string */
2454 ses->serverDomain = kzalloc(2, GFP_KERNEL);
2455 ses->serverNOS = kzalloc(2, GFP_KERNEL);
2457 } else { /* ASCII */
2459 len = strnlen(bcc_ptr, 1024);
2460 if (((long) bcc_ptr + len) - (long)
2461 pByteArea(smb_buffer_response)
2462 <= BCC(smb_buffer_response)) {
2463 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
2464 strncpy(ses->serverOS, bcc_ptr, len);
2467 bcc_ptr[0] = 0; /* null terminate the string */
2470 len = strnlen(bcc_ptr, 1024);
2471 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL);
2472 strncpy(ses->serverNOS, bcc_ptr, len);
2477 len = strnlen(bcc_ptr, 1024);
2478 ses->serverDomain = kzalloc(len + 1, GFP_KERNEL);
2479 strncpy(ses->serverDomain, bcc_ptr, len);
2485 ("Variable field of length %d extends beyond end of smb ",
2490 (" Security Blob Length extends beyond end of SMB"));
2493 cERROR(1, ("No session structure passed in."));
2497 (" Invalid Word count %d: ",
2498 smb_buffer_response->WordCount));
2503 cifs_buf_release(smb_buffer);
2509 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2510 struct cifsSesInfo *ses, int * pNTLMv2_flag,
2511 const struct nls_table *nls_codepage)
2513 struct smb_hdr *smb_buffer;
2514 struct smb_hdr *smb_buffer_response;
2515 SESSION_SETUP_ANDX *pSMB;
2516 SESSION_SETUP_ANDX *pSMBr;
2520 int remaining_words = 0;
2521 int bytes_returned = 0;
2523 int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
2524 PNEGOTIATE_MESSAGE SecurityBlob;
2525 PCHALLENGE_MESSAGE SecurityBlob2;
2526 __u32 negotiate_flags, capabilities;
2529 cFYI(1, ("In NTLMSSP sesssetup (negotiate) "));
2532 domain = ses->domainName;
2533 *pNTLMv2_flag = FALSE;
2534 smb_buffer = cifs_buf_get();
2535 if (smb_buffer == NULL) {
2538 smb_buffer_response = smb_buffer;
2539 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2540 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2542 /* send SMBsessionSetup here */
2543 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2544 NULL /* no tCon exists yet */ , 12 /* wct */ );
2546 smb_buffer->Mid = GetNextMid(ses->server);
2547 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2548 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2550 pSMB->req.AndXCommand = 0xFF;
2551 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2552 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2554 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2555 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2557 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2558 CAP_EXTENDED_SECURITY;
2559 if (ses->capabilities & CAP_UNICODE) {
2560 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2561 capabilities |= CAP_UNICODE;
2563 if (ses->capabilities & CAP_STATUS32) {
2564 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2565 capabilities |= CAP_STATUS32;
2567 if (ses->capabilities & CAP_DFS) {
2568 smb_buffer->Flags2 |= SMBFLG2_DFS;
2569 capabilities |= CAP_DFS;
2571 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2573 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2574 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2575 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2576 SecurityBlob->MessageType = NtLmNegotiate;
2578 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2579 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 |
2580 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2582 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2584 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2585 /* setup pointers to domain name and workstation name */
2586 bcc_ptr += SecurityBlobLength;
2588 SecurityBlob->WorkstationName.Buffer = 0;
2589 SecurityBlob->WorkstationName.Length = 0;
2590 SecurityBlob->WorkstationName.MaximumLength = 0;
2592 if (domain == NULL) {
2593 SecurityBlob->DomainName.Buffer = 0;
2594 SecurityBlob->DomainName.Length = 0;
2595 SecurityBlob->DomainName.MaximumLength = 0;
2598 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
2599 strncpy(bcc_ptr, domain, 63);
2600 len = strnlen(domain, 64);
2601 SecurityBlob->DomainName.MaximumLength =
2603 SecurityBlob->DomainName.Buffer =
2604 cpu_to_le32((long) &SecurityBlob->
2606 (long) &SecurityBlob->Signature);
2608 SecurityBlobLength += len;
2609 SecurityBlob->DomainName.Length =
2612 if (ses->capabilities & CAP_UNICODE) {
2613 if ((long) bcc_ptr % 2) {
2619 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2621 bcc_ptr += 2 * bytes_returned;
2623 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
2625 bcc_ptr += 2 * bytes_returned;
2626 bcc_ptr += 2; /* null terminate Linux version */
2628 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2630 bcc_ptr += 2 * bytes_returned;
2633 bcc_ptr += 2; /* null terminate network opsys string */
2636 bcc_ptr += 2; /* null domain */
2637 } else { /* ASCII */
2638 strcpy(bcc_ptr, "Linux version ");
2639 bcc_ptr += strlen("Linux version ");
2640 strcpy(bcc_ptr, system_utsname.release);
2641 bcc_ptr += strlen(system_utsname.release) + 1;
2642 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2643 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2644 bcc_ptr++; /* empty domain field */
2647 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2648 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2649 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2650 smb_buffer->smb_buf_length += count;
2651 pSMB->req.ByteCount = cpu_to_le16(count);
2653 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2654 &bytes_returned, 1);
2656 if (smb_buffer_response->Status.CifsError ==
2657 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2661 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2662 } else if ((smb_buffer_response->WordCount == 3)
2663 || (smb_buffer_response->WordCount == 4)) {
2664 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2665 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2667 if (action & GUEST_LOGIN)
2668 cFYI(1, (" Guest login"));
2669 /* Do we want to set anything in SesInfo struct when guest login? */
2671 bcc_ptr = pByteArea(smb_buffer_response);
2672 /* response can have either 3 or 4 word count - Samba sends 3 */
2674 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2675 if (SecurityBlob2->MessageType != NtLmChallenge) {
2677 ("Unexpected NTLMSSP message type received %d",
2678 SecurityBlob2->MessageType));
2680 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2681 cFYI(1, ("UID = %d ", ses->Suid));
2682 if ((pSMBr->resp.hdr.WordCount == 3)
2683 || ((pSMBr->resp.hdr.WordCount == 4)
2685 pSMBr->resp.ByteCount))) {
2687 if (pSMBr->resp.hdr.WordCount == 4) {
2688 bcc_ptr += blob_len;
2690 ("Security Blob Length %d ",
2694 cFYI(1, ("NTLMSSP Challenge rcvd "));
2696 memcpy(ses->server->cryptKey,
2697 SecurityBlob2->Challenge,
2698 CIFS_CRYPTO_KEY_SIZE);
2699 if(SecurityBlob2->NegotiateFlags & cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2700 *pNTLMv2_flag = TRUE;
2702 if((SecurityBlob2->NegotiateFlags &
2703 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2704 || (sign_CIFS_PDUs > 1))
2705 ses->server->secMode |=
2706 SECMODE_SIGN_REQUIRED;
2707 if ((SecurityBlob2->NegotiateFlags &
2708 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2709 ses->server->secMode |=
2710 SECMODE_SIGN_ENABLED;
2712 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2713 if ((long) (bcc_ptr) % 2) {
2715 (BCC(smb_buffer_response)
2717 bcc_ptr++; /* Unicode strings must be word aligned */
2721 (smb_buffer_response) / 2;
2724 UniStrnlen((wchar_t *) bcc_ptr,
2725 remaining_words - 1);
2726 /* We look for obvious messed up bcc or strings in response so we do not go off
2727 the end since (at least) WIN2K and Windows XP have a major bug in not null
2728 terminating last Unicode string in response */
2730 kzalloc(2 * (len + 1), GFP_KERNEL);
2731 cifs_strfromUCS_le(ses->serverOS,
2735 bcc_ptr += 2 * (len + 1);
2736 remaining_words -= len + 1;
2737 ses->serverOS[2 * len] = 0;
2738 ses->serverOS[1 + (2 * len)] = 0;
2739 if (remaining_words > 0) {
2740 len = UniStrnlen((wchar_t *)
2745 kzalloc(2 * (len + 1),
2747 cifs_strfromUCS_le(ses->
2753 bcc_ptr += 2 * (len + 1);
2754 ses->serverNOS[2 * len] = 0;
2757 remaining_words -= len + 1;
2758 if (remaining_words > 0) {
2759 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2760 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2772 ses->serverDomain[2*len]
2777 } /* else no more room so create dummy domain string */
2782 } else { /* no room so create dummy domain and NOS string */
2784 kzalloc(2, GFP_KERNEL);
2786 kzalloc(2, GFP_KERNEL);
2788 } else { /* ASCII */
2789 len = strnlen(bcc_ptr, 1024);
2790 if (((long) bcc_ptr + len) - (long)
2791 pByteArea(smb_buffer_response)
2792 <= BCC(smb_buffer_response)) {
2796 strncpy(ses->serverOS,
2800 bcc_ptr[0] = 0; /* null terminate string */
2803 len = strnlen(bcc_ptr, 1024);
2807 strncpy(ses->serverNOS, bcc_ptr, len);
2812 len = strnlen(bcc_ptr, 1024);
2816 strncpy(ses->serverDomain, bcc_ptr, len);
2822 ("Variable field of length %d extends beyond end of smb ",
2827 (" Security Blob Length extends beyond end of SMB"));
2830 cERROR(1, ("No session structure passed in."));
2834 (" Invalid Word count %d: ",
2835 smb_buffer_response->WordCount));
2840 cifs_buf_release(smb_buffer);
2845 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2846 char *ntlm_session_key, int ntlmv2_flag,
2847 const struct nls_table *nls_codepage)
2849 struct smb_hdr *smb_buffer;
2850 struct smb_hdr *smb_buffer_response;
2851 SESSION_SETUP_ANDX *pSMB;
2852 SESSION_SETUP_ANDX *pSMBr;
2857 int remaining_words = 0;
2858 int bytes_returned = 0;
2860 int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
2861 PAUTHENTICATE_MESSAGE SecurityBlob;
2862 __u32 negotiate_flags, capabilities;
2865 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2868 user = ses->userName;
2869 domain = ses->domainName;
2870 smb_buffer = cifs_buf_get();
2871 if (smb_buffer == NULL) {
2874 smb_buffer_response = smb_buffer;
2875 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2876 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2878 /* send SMBsessionSetup here */
2879 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2880 NULL /* no tCon exists yet */ , 12 /* wct */ );
2882 smb_buffer->Mid = GetNextMid(ses->server);
2883 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2884 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2885 pSMB->req.AndXCommand = 0xFF;
2886 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2887 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2889 pSMB->req.hdr.Uid = ses->Suid;
2891 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2892 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2894 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2895 CAP_EXTENDED_SECURITY;
2896 if (ses->capabilities & CAP_UNICODE) {
2897 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2898 capabilities |= CAP_UNICODE;
2900 if (ses->capabilities & CAP_STATUS32) {
2901 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2902 capabilities |= CAP_STATUS32;
2904 if (ses->capabilities & CAP_DFS) {
2905 smb_buffer->Flags2 |= SMBFLG2_DFS;
2906 capabilities |= CAP_DFS;
2908 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2910 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2911 SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
2912 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2913 SecurityBlob->MessageType = NtLmAuthenticate;
2914 bcc_ptr += SecurityBlobLength;
2916 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
2917 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
2918 0x80000000 | NTLMSSP_NEGOTIATE_128;
2920 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
2922 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2924 /* setup pointers to domain name and workstation name */
2926 SecurityBlob->WorkstationName.Buffer = 0;
2927 SecurityBlob->WorkstationName.Length = 0;
2928 SecurityBlob->WorkstationName.MaximumLength = 0;
2929 SecurityBlob->SessionKey.Length = 0;
2930 SecurityBlob->SessionKey.MaximumLength = 0;
2931 SecurityBlob->SessionKey.Buffer = 0;
2933 SecurityBlob->LmChallengeResponse.Length = 0;
2934 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
2935 SecurityBlob->LmChallengeResponse.Buffer = 0;
2937 SecurityBlob->NtChallengeResponse.Length =
2938 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
2939 SecurityBlob->NtChallengeResponse.MaximumLength =
2940 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
2941 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESSION_KEY_SIZE);
2942 SecurityBlob->NtChallengeResponse.Buffer =
2943 cpu_to_le32(SecurityBlobLength);
2944 SecurityBlobLength += CIFS_SESSION_KEY_SIZE;
2945 bcc_ptr += CIFS_SESSION_KEY_SIZE;
2947 if (ses->capabilities & CAP_UNICODE) {
2948 if (domain == NULL) {
2949 SecurityBlob->DomainName.Buffer = 0;
2950 SecurityBlob->DomainName.Length = 0;
2951 SecurityBlob->DomainName.MaximumLength = 0;
2954 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2957 SecurityBlob->DomainName.MaximumLength =
2959 SecurityBlob->DomainName.Buffer =
2960 cpu_to_le32(SecurityBlobLength);
2962 SecurityBlobLength += len;
2963 SecurityBlob->DomainName.Length =
2967 SecurityBlob->UserName.Buffer = 0;
2968 SecurityBlob->UserName.Length = 0;
2969 SecurityBlob->UserName.MaximumLength = 0;
2972 cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
2975 SecurityBlob->UserName.MaximumLength =
2977 SecurityBlob->UserName.Buffer =
2978 cpu_to_le32(SecurityBlobLength);
2980 SecurityBlobLength += len;
2981 SecurityBlob->UserName.Length =
2985 /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
2986 SecurityBlob->WorkstationName.Length *= 2;
2987 SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length);
2988 SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength);
2989 bcc_ptr += SecurityBlob->WorkstationName.Length;
2990 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
2991 SecurityBlob->WorkstationName.Length = cpu_to_le16(SecurityBlob->WorkstationName.Length); */
2993 if ((long) bcc_ptr % 2) {
2998 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3000 bcc_ptr += 2 * bytes_returned;
3002 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
3004 bcc_ptr += 2 * bytes_returned;
3005 bcc_ptr += 2; /* null term version string */
3007 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3009 bcc_ptr += 2 * bytes_returned;
3012 bcc_ptr += 2; /* null terminate network opsys string */
3015 bcc_ptr += 2; /* null domain */
3016 } else { /* ASCII */
3017 if (domain == NULL) {
3018 SecurityBlob->DomainName.Buffer = 0;
3019 SecurityBlob->DomainName.Length = 0;
3020 SecurityBlob->DomainName.MaximumLength = 0;
3023 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3024 strncpy(bcc_ptr, domain, 63);
3025 len = strnlen(domain, 64);
3026 SecurityBlob->DomainName.MaximumLength =
3028 SecurityBlob->DomainName.Buffer =
3029 cpu_to_le32(SecurityBlobLength);
3031 SecurityBlobLength += len;
3032 SecurityBlob->DomainName.Length = cpu_to_le16(len);
3035 SecurityBlob->UserName.Buffer = 0;
3036 SecurityBlob->UserName.Length = 0;
3037 SecurityBlob->UserName.MaximumLength = 0;
3040 strncpy(bcc_ptr, user, 63);
3041 len = strnlen(user, 64);
3042 SecurityBlob->UserName.MaximumLength =
3044 SecurityBlob->UserName.Buffer =
3045 cpu_to_le32(SecurityBlobLength);
3047 SecurityBlobLength += len;
3048 SecurityBlob->UserName.Length = cpu_to_le16(len);
3050 /* BB fill in our workstation name if known BB */
3052 strcpy(bcc_ptr, "Linux version ");
3053 bcc_ptr += strlen("Linux version ");
3054 strcpy(bcc_ptr, system_utsname.release);
3055 bcc_ptr += strlen(system_utsname.release) + 1;
3056 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3057 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3058 bcc_ptr++; /* null domain */
3061 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3062 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3063 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3064 smb_buffer->smb_buf_length += count;
3065 pSMB->req.ByteCount = cpu_to_le16(count);
3067 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3068 &bytes_returned, 1);
3070 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
3071 } else if ((smb_buffer_response->WordCount == 3)
3072 || (smb_buffer_response->WordCount == 4)) {
3073 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3075 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3076 if (action & GUEST_LOGIN)
3077 cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */
3078 /* if(SecurityBlob2->MessageType != NtLm??){
3079 cFYI("Unexpected message type on auth response is %d "));
3083 ("Does UID on challenge %d match auth response UID %d ",
3084 ses->Suid, smb_buffer_response->Uid));
3085 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format */
3086 bcc_ptr = pByteArea(smb_buffer_response);
3087 /* response can have either 3 or 4 word count - Samba sends 3 */
3088 if ((pSMBr->resp.hdr.WordCount == 3)
3089 || ((pSMBr->resp.hdr.WordCount == 4)
3091 pSMBr->resp.ByteCount))) {
3092 if (pSMBr->resp.hdr.WordCount == 4) {
3096 ("Security Blob Length %d ",
3101 ("NTLMSSP response to Authenticate "));
3103 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3104 if ((long) (bcc_ptr) % 2) {
3106 (BCC(smb_buffer_response)
3108 bcc_ptr++; /* Unicode strings must be word aligned */
3110 remaining_words = BCC(smb_buffer_response) / 2;
3113 UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
3114 /* We look for obvious messed up bcc or strings in response so we do not go off
3115 the end since (at least) WIN2K and Windows XP have a major bug in not null
3116 terminating last Unicode string in response */
3118 kzalloc(2 * (len + 1), GFP_KERNEL);
3119 cifs_strfromUCS_le(ses->serverOS,
3123 bcc_ptr += 2 * (len + 1);
3124 remaining_words -= len + 1;
3125 ses->serverOS[2 * len] = 0;
3126 ses->serverOS[1 + (2 * len)] = 0;
3127 if (remaining_words > 0) {
3128 len = UniStrnlen((wchar_t *)
3133 kzalloc(2 * (len + 1),
3135 cifs_strfromUCS_le(ses->
3141 bcc_ptr += 2 * (len + 1);
3142 ses->serverNOS[2 * len] = 0;
3143 ses->serverNOS[1+(2*len)] = 0;
3144 remaining_words -= len + 1;
3145 if (remaining_words > 0) {
3146 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3147 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3172 } /* else no more room so create dummy domain string */
3174 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3175 } else { /* no room so create dummy domain and NOS string */
3176 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3177 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3179 } else { /* ASCII */
3180 len = strnlen(bcc_ptr, 1024);
3181 if (((long) bcc_ptr + len) -
3182 (long) pByteArea(smb_buffer_response)
3183 <= BCC(smb_buffer_response)) {
3184 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
3185 strncpy(ses->serverOS,bcc_ptr, len);
3188 bcc_ptr[0] = 0; /* null terminate the string */
3191 len = strnlen(bcc_ptr, 1024);
3192 ses->serverNOS = kzalloc(len+1,GFP_KERNEL);
3193 strncpy(ses->serverNOS, bcc_ptr, len);
3198 len = strnlen(bcc_ptr, 1024);
3199 ses->serverDomain = kzalloc(len+1,GFP_KERNEL);
3200 strncpy(ses->serverDomain, bcc_ptr, len);
3206 ("Variable field of length %d extends beyond end of smb ",
3211 (" Security Blob Length extends beyond end of SMB"));
3214 cERROR(1, ("No session structure passed in."));
3218 (" Invalid Word count %d: ",
3219 smb_buffer_response->WordCount));
3224 cifs_buf_release(smb_buffer);
3230 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3231 const char *tree, struct cifsTconInfo *tcon,
3232 const struct nls_table *nls_codepage)
3234 struct smb_hdr *smb_buffer;
3235 struct smb_hdr *smb_buffer_response;
3238 unsigned char *bcc_ptr;
3246 smb_buffer = cifs_buf_get();
3247 if (smb_buffer == NULL) {
3250 smb_buffer_response = smb_buffer;
3252 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3253 NULL /*no tid */ , 4 /*wct */ );
3255 smb_buffer->Mid = GetNextMid(ses->server);
3256 smb_buffer->Uid = ses->Suid;
3257 pSMB = (TCONX_REQ *) smb_buffer;
3258 pSMBr = (TCONX_RSP *) smb_buffer_response;
3260 pSMB->AndXCommand = 0xFF;
3261 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3262 bcc_ptr = &pSMB->Password[0];
3263 if((ses->server->secMode) & SECMODE_USER) {
3264 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3265 bcc_ptr++; /* skip password */
3267 pSMB->PasswordLength = cpu_to_le16(CIFS_SESSION_KEY_SIZE);
3268 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3269 specified as required (when that support is added to
3270 the vfs in the future) as only NTLM or the much
3271 weaker LANMAN (which we do not send) is accepted
3272 by Samba (not sure whether other servers allow
3273 NTLMv2 password here) */
3274 SMBNTencrypt(ses->password,
3275 ses->server->cryptKey,
3278 bcc_ptr += CIFS_SESSION_KEY_SIZE;
3280 bcc_ptr++; /* align */
3283 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3284 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3286 if (ses->capabilities & CAP_STATUS32) {
3287 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3289 if (ses->capabilities & CAP_DFS) {
3290 smb_buffer->Flags2 |= SMBFLG2_DFS;
3292 if (ses->capabilities & CAP_UNICODE) {
3293 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3295 cifs_strtoUCS((__le16 *) bcc_ptr, tree, 100, nls_codepage);
3296 bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */
3297 bcc_ptr += 2; /* skip trailing null */
3298 } else { /* ASCII */
3299 strcpy(bcc_ptr, tree);
3300 bcc_ptr += strlen(tree) + 1;
3302 strcpy(bcc_ptr, "?????");
3303 bcc_ptr += strlen("?????");
3305 count = bcc_ptr - &pSMB->Password[0];
3306 pSMB->hdr.smb_buf_length += count;
3307 pSMB->ByteCount = cpu_to_le16(count);
3309 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
3311 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3312 /* above now done in SendReceive */
3313 if ((rc == 0) && (tcon != NULL)) {
3314 tcon->tidStatus = CifsGood;
3315 tcon->tid = smb_buffer_response->Tid;
3316 bcc_ptr = pByteArea(smb_buffer_response);
3317 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3318 /* skip service field (NB: this field is always ASCII) */
3319 bcc_ptr += length + 1;
3320 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3321 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3322 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3323 if ((bcc_ptr + (2 * length)) -
3324 pByteArea(smb_buffer_response) <=
3325 BCC(smb_buffer_response)) {
3326 kfree(tcon->nativeFileSystem);
3327 tcon->nativeFileSystem =
3328 kzalloc(length + 2, GFP_KERNEL);
3329 cifs_strfromUCS_le(tcon->nativeFileSystem,
3331 length, nls_codepage);
3332 bcc_ptr += 2 * length;
3333 bcc_ptr[0] = 0; /* null terminate the string */
3337 /* else do not bother copying these informational fields */
3339 length = strnlen(bcc_ptr, 1024);
3340 if ((bcc_ptr + length) -
3341 pByteArea(smb_buffer_response) <=
3342 BCC(smb_buffer_response)) {
3343 kfree(tcon->nativeFileSystem);
3344 tcon->nativeFileSystem =
3345 kzalloc(length + 1, GFP_KERNEL);
3346 strncpy(tcon->nativeFileSystem, bcc_ptr,
3349 /* else do not bother copying these informational fields */
3351 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3352 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3353 } else if ((rc == 0) && tcon == NULL) {
3354 /* all we need to save for IPC$ connection */
3355 ses->ipc_tid = smb_buffer_response->Tid;
3359 cifs_buf_release(smb_buffer);
3364 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3368 struct cifsSesInfo *ses = NULL;
3369 struct task_struct *cifsd_task;
3373 if (cifs_sb->tcon) {
3374 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3375 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3380 tconInfoFree(cifs_sb->tcon);
3381 if ((ses) && (ses->server)) {
3382 /* save off task so we do not refer to ses later */
3383 cifsd_task = ses->server->tsk;
3384 cFYI(1, ("About to do SMBLogoff "));
3385 rc = CIFSSMBLogoff(xid, ses);
3389 } else if (rc == -ESHUTDOWN) {
3390 cFYI(1,("Waking up socket by sending it signal"));
3392 send_sig(SIGKILL,cifsd_task,1);
3393 wait_for_completion(&cifsd_complete);
3396 } /* else - we have an smb session
3397 left on this socket do not kill cifsd */
3399 cFYI(1, ("No session or bad tcon"));
3402 cifs_sb->tcon = NULL;
3404 schedule_timeout_interruptible(msecs_to_jiffies(500));
3409 return rc; /* BB check if we should always return zero here */
3412 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3413 struct nls_table * nls_info)
3416 char ntlm_session_key[CIFS_SESSION_KEY_SIZE];
3417 int ntlmv2_flag = FALSE;
3420 /* what if server changes its buffer size after dropping the session? */
3421 if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
3422 rc = CIFSSMBNegotiate(xid, pSesInfo);
3423 if(rc == -EAGAIN) /* retry only once on 1st time connection */ {
3424 rc = CIFSSMBNegotiate(xid, pSesInfo);
3429 spin_lock(&GlobalMid_Lock);
3430 if(pSesInfo->server->tcpStatus != CifsExiting)
3431 pSesInfo->server->tcpStatus = CifsGood;
3434 spin_unlock(&GlobalMid_Lock);
3440 pSesInfo->capabilities = pSesInfo->server->capabilities;
3441 if(linuxExtEnabled == 0)
3442 pSesInfo->capabilities &= (~CAP_UNIX);
3443 /* pSesInfo->sequence_number = 0;*/
3444 cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d",
3445 pSesInfo->server->secMode,
3446 pSesInfo->server->capabilities,
3447 pSesInfo->server->timeZone));
3448 if (extended_security
3449 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3450 && (pSesInfo->server->secType == NTLMSSP)) {
3451 cFYI(1, ("New style sesssetup "));
3452 rc = CIFSSpnegoSessSetup(xid, pSesInfo,
3453 NULL /* security blob */,
3454 0 /* blob length */,
3456 } else if (extended_security
3457 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3458 && (pSesInfo->server->secType == RawNTLMSSP)) {
3459 cFYI(1, ("NTLMSSP sesssetup "));
3460 rc = CIFSNTLMSSPNegotiateSessSetup(xid,
3467 cFYI(1,("Can use more secure NTLM version 2 password hash"));
3468 if(CalcNTLMv2_partial_mac_key(pSesInfo,
3473 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
3475 CalcNTLMv2_response(pSesInfo,v2_response);
3477 cifs_calculate_ntlmv2_mac_key(
3478 pSesInfo->server->mac_signing_key,
3479 response, ntlm_session_key, */
3481 /* BB Put dummy sig in SessSetup PDU? */
3488 SMBNTencrypt(pSesInfo->password,
3489 pSesInfo->server->cryptKey,
3493 cifs_calculate_mac_key(
3494 pSesInfo->server->mac_signing_key,
3496 pSesInfo->password);
3498 /* for better security the weaker lanman hash not sent
3499 in AuthSessSetup so we no longer calculate it */
3501 rc = CIFSNTLMSSPAuthSessSetup(xid,
3507 } else { /* old style NTLM 0.12 session setup */
3508 SMBNTencrypt(pSesInfo->password,
3509 pSesInfo->server->cryptKey,
3513 cifs_calculate_mac_key(
3514 pSesInfo->server->mac_signing_key,
3515 ntlm_session_key, pSesInfo->password);
3517 rc = CIFSSessSetup(xid, pSesInfo,
3518 ntlm_session_key, nls_info);
3521 cERROR(1,("Send error in SessSetup = %d",rc));
3523 cFYI(1,("CIFS Session Established successfully"));
3524 pSesInfo->status = CifsGood;