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 <asm/uaccess.h>
33 #include <asm/processor.h>
36 #include "cifsproto.h"
37 #include "cifs_unicode.h"
38 #include "cifs_debug.h"
39 #include "cifs_fs_sb.h"
42 #include "rfc1002pdu.h"
45 #define RFC1001_PORT 139
47 extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
49 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
52 extern mempool_t *cifs_req_poolp;
60 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
61 char *iocharset; /* local code page for mapping to and from Unicode */
62 char source_rfc1001_name[16]; /* netbios name of client */
72 unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
73 unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/
74 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
76 unsigned remap:1; /* set to remap seven reserved chars in filenames */
77 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
81 unsigned short int port;
84 static int ipv4_connect(struct sockaddr_in *psin_server,
85 struct socket **csocket,
87 static int ipv6_connect(struct sockaddr_in6 *psin_server,
88 struct socket **csocket);
92 * cifs tcp session reconnection
94 * mark tcp session as reconnecting so temporarily locked
95 * mark all smb sessions as reconnecting for tcp session
96 * reconnect tcp session
97 * wake up waiters on reconnection? - (not needed currently)
101 cifs_reconnect(struct TCP_Server_Info *server)
104 struct list_head *tmp;
105 struct cifsSesInfo *ses;
106 struct cifsTconInfo *tcon;
107 struct mid_q_entry * mid_entry;
109 spin_lock(&GlobalMid_Lock);
110 if(server->tcpStatus == CifsExiting) {
111 /* the demux thread will exit normally
112 next time through the loop */
113 spin_unlock(&GlobalMid_Lock);
116 server->tcpStatus = CifsNeedReconnect;
117 spin_unlock(&GlobalMid_Lock);
120 cFYI(1, ("Reconnecting tcp session"));
122 /* before reconnecting the tcp session, mark the smb session (uid)
123 and the tid bad so they are not used until reconnected */
124 read_lock(&GlobalSMBSeslock);
125 list_for_each(tmp, &GlobalSMBSessionList) {
126 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
128 if (ses->server == server) {
129 ses->status = CifsNeedReconnect;
133 /* else tcp and smb sessions need reconnection */
135 list_for_each(tmp, &GlobalTreeConnectionList) {
136 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
137 if((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
138 tcon->tidStatus = CifsNeedReconnect;
141 read_unlock(&GlobalSMBSeslock);
142 /* do not want to be sending data on a socket we are freeing */
143 down(&server->tcpSem);
144 if(server->ssocket) {
145 cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state,
146 server->ssocket->flags));
147 server->ssocket->ops->shutdown(server->ssocket,SEND_SHUTDOWN);
148 cFYI(1,("Post shutdown state: 0x%x Flags: 0x%lx", server->ssocket->state,
149 server->ssocket->flags));
150 sock_release(server->ssocket);
151 server->ssocket = NULL;
154 spin_lock(&GlobalMid_Lock);
155 list_for_each(tmp, &server->pending_mid_q) {
156 mid_entry = list_entry(tmp, struct
160 if(mid_entry->midState == MID_REQUEST_SUBMITTED) {
161 /* Mark other intransit requests as needing
162 retry so we do not immediately mark the
163 session bad again (ie after we reconnect
164 below) as they timeout too */
165 mid_entry->midState = MID_RETRY_NEEDED;
169 spin_unlock(&GlobalMid_Lock);
172 while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
174 if(server->protocolType == IPV6) {
175 rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket);
177 rc = ipv4_connect(&server->addr.sockAddr,
179 server->workstation_RFC1001_name);
184 atomic_inc(&tcpSesReconnectCount);
185 spin_lock(&GlobalMid_Lock);
186 if(server->tcpStatus != CifsExiting)
187 server->tcpStatus = CifsGood;
188 server->sequence_number = 0;
189 spin_unlock(&GlobalMid_Lock);
190 /* atomic_set(&server->inFlight,0);*/
191 wake_up(&server->response_q);
199 0 not a transact2, or all data present
200 >0 transact2 with that much data missing
201 -EINVAL = invalid transact2
204 static int check2ndT2(struct smb_hdr * pSMB, unsigned int maxBufSize)
206 struct smb_t2_rsp * pSMBt;
208 int data_in_this_rsp;
211 if(pSMB->Command != SMB_COM_TRANSACTION2)
214 /* check for plausible wct, bcc and t2 data and parm sizes */
215 /* check for parm and data offset going beyond end of smb */
216 if(pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
217 cFYI(1,("invalid transact2 word count"));
221 pSMBt = (struct smb_t2_rsp *)pSMB;
223 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
224 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
226 remaining = total_data_size - data_in_this_rsp;
230 else if(remaining < 0) {
231 cFYI(1,("total data %d smaller than data in frame %d",
232 total_data_size, data_in_this_rsp));
235 cFYI(1,("missing %d bytes from transact2, check next response",
237 if(total_data_size > maxBufSize) {
238 cERROR(1,("TotalDataSize %d is over maximum buffer %d",
239 total_data_size,maxBufSize));
246 static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB)
248 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
249 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
254 char * data_area_of_target;
255 char * data_area_of_buf2;
258 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
260 if(total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
261 cFYI(1,("total data sizes of primary and secondary t2 differ"));
264 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
266 remaining = total_data_size - total_in_buf;
271 if(remaining == 0) /* nothing to do, ignore */
274 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
275 if(remaining < total_in_buf2) {
276 cFYI(1,("transact2 2nd response contains too much data"));
279 /* find end of first SMB data area */
280 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
281 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
282 /* validate target area */
284 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
285 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
287 data_area_of_target += total_in_buf;
289 /* copy second buffer into end of first buffer */
290 memcpy(data_area_of_target,data_area_of_buf2,total_in_buf2);
291 total_in_buf += total_in_buf2;
292 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
293 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
294 byte_count += total_in_buf2;
295 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
297 byte_count = be32_to_cpu(pTargetSMB->smb_buf_length);
298 byte_count += total_in_buf2;
300 /* BB also add check that we are not beyond maximum buffer size */
302 pTargetSMB->smb_buf_length = cpu_to_be32(byte_count);
304 if(remaining == total_in_buf2) {
305 cFYI(1,("found the last secondary response"));
306 return 0; /* we are done */
307 } else /* more responses to go */
313 cifs_demultiplex_thread(struct TCP_Server_Info *server)
316 unsigned int pdu_length, total_read;
317 struct smb_hdr *smb_buffer = NULL;
318 struct smb_hdr *bigbuf = NULL;
319 struct smb_hdr *smallbuf = NULL;
320 struct msghdr smb_msg;
322 struct socket *csocket = server->ssocket;
323 struct list_head *tmp;
324 struct cifsSesInfo *ses;
325 struct task_struct *task_to_wake = NULL;
326 struct mid_q_entry *mid_entry;
328 int isLargeBuf = FALSE;
333 allow_signal(SIGKILL);
334 current->flags |= PF_MEMALLOC;
335 server->tsk = current; /* save process info to wake at shutdown */
336 cFYI(1, ("Demultiplex PID: %d", current->pid));
337 write_lock(&GlobalSMBSeslock);
338 atomic_inc(&tcpSesAllocCount);
339 length = tcpSesAllocCount.counter;
340 write_unlock(&GlobalSMBSeslock);
342 mempool_resize(cifs_req_poolp,
343 length + cifs_min_rcv,
347 while (server->tcpStatus != CifsExiting) {
348 if (bigbuf == NULL) {
349 bigbuf = cifs_buf_get();
351 cERROR(1,("No memory for large SMB response"));
353 /* retry will check if exiting */
356 } else if(isLargeBuf) {
357 /* we are reusing a dirtry large buf, clear its start */
358 memset(bigbuf, 0, sizeof (struct smb_hdr));
361 if (smallbuf == NULL) {
362 smallbuf = cifs_small_buf_get();
363 if(smallbuf == NULL) {
364 cERROR(1,("No memory for SMB response"));
366 /* retry will check if exiting */
369 /* beginning of smb buffer is cleared in our buf_get */
370 } else /* if existing small buf clear beginning */
371 memset(smallbuf, 0, sizeof (struct smb_hdr));
375 smb_buffer = smallbuf;
376 iov.iov_base = smb_buffer;
378 smb_msg.msg_control = NULL;
379 smb_msg.msg_controllen = 0;
381 kernel_recvmsg(csocket, &smb_msg,
382 &iov, 1, 4, 0 /* BB see socket.h flags */);
384 if(server->tcpStatus == CifsExiting) {
386 } else if (server->tcpStatus == CifsNeedReconnect) {
387 cFYI(1,("Reconnect after server stopped responding"));
388 cifs_reconnect(server);
389 cFYI(1,("call to reconnect done"));
390 csocket = server->ssocket;
392 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
393 msleep(1); /* minimum sleep to prevent looping
394 allowing socket to clear and app threads to set
395 tcpStatus CifsNeedReconnect if server hung */
397 } else if (length <= 0) {
398 if(server->tcpStatus == CifsNew) {
399 cFYI(1,("tcp session abend after SMBnegprot"));
400 /* some servers kill the TCP session rather than
401 returning an SMB negprot error, in which
402 case reconnecting here is not going to help,
403 and so simply return error to mount */
406 if(length == -EINTR) {
407 cFYI(1,("cifsd thread killed"));
410 cFYI(1,("Reconnect after unexpected peek error %d",
412 cifs_reconnect(server);
413 csocket = server->ssocket;
414 wake_up(&server->response_q);
416 } else if (length < 4) {
418 ("Frame under four bytes received (%d bytes long)",
420 cifs_reconnect(server);
421 csocket = server->ssocket;
422 wake_up(&server->response_q);
426 /* the right amount was read from socket - 4 bytes */
428 pdu_length = ntohl(smb_buffer->smb_buf_length);
429 cFYI(1,("rfc1002 length(big endian)0x%x)", pdu_length+4));
431 temp = (char *) smb_buffer;
432 if (temp[0] == (char) RFC1002_SESSION_KEEP_ALIVE) {
434 } else if (temp[0] == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
435 cFYI(1,("Good RFC 1002 session rsp"));
437 } else if (temp[0] == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
438 /* we get this from Windows 98 instead of
439 an error on SMB negprot response */
440 cFYI(1,("Negative RFC1002 Session Response Error 0x%x)",
442 if(server->tcpStatus == CifsNew) {
443 /* if nack on negprot (rather than
444 ret of smb negprot error) reconnecting
445 not going to help, ret error to mount */
448 /* give server a second to
449 clean up before reconnect attempt */
451 /* always try 445 first on reconnect
452 since we get NACK on some if we ever
453 connected to port 139 (the NACK is
454 since we do not begin with RFC1001
455 session initialize frame) */
456 server->addr.sockAddr.sin_port =
458 cifs_reconnect(server);
459 csocket = server->ssocket;
460 wake_up(&server->response_q);
463 } else if (temp[0] != (char) 0) {
464 cERROR(1,("Unknown RFC 1002 frame"));
465 cifs_dump_mem(" Received Data: ", temp, length);
466 cifs_reconnect(server);
467 csocket = server->ssocket;
471 /* else we have an SMB response */
472 if((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
473 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
474 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
475 length, pdu_length+4));
476 cifs_reconnect(server);
477 csocket = server->ssocket;
478 wake_up(&server->response_q);
485 if(pdu_length > MAX_CIFS_HDR_SIZE - 4) {
487 memcpy(bigbuf, smallbuf, 4);
491 iov.iov_base = 4 + (char *)smb_buffer;
492 iov.iov_len = pdu_length;
493 for (total_read = 0; total_read < pdu_length;
494 total_read += length) {
495 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
496 pdu_length - total_read, 0);
497 if((server->tcpStatus == CifsExiting) ||
498 (length == -EINTR)) {
502 } else if (server->tcpStatus == CifsNeedReconnect) {
503 cifs_reconnect(server);
504 csocket = server->ssocket;
505 /* Reconnect wakes up rspns q */
506 /* Now we will reread sock */
509 } else if ((length == -ERESTARTSYS) ||
510 (length == -EAGAIN)) {
511 msleep(1); /* minimum sleep to prevent looping,
512 allowing socket to clear and app
513 threads to set tcpStatus
514 CifsNeedReconnect if server hung*/
516 } else if (length <= 0) {
517 cERROR(1,("Received no data, expecting %d",
518 pdu_length - total_read));
519 cifs_reconnect(server);
520 csocket = server->ssocket;
527 else if(reconnect == 1)
530 length += 4; /* account for rfc1002 hdr */
533 dump_smb(smb_buffer, length);
534 if (checkSMB (smb_buffer, smb_buffer->Mid, total_read+4)) {
535 cERROR(1, ("Bad SMB Received "));
541 spin_lock(&GlobalMid_Lock);
542 list_for_each(tmp, &server->pending_mid_q) {
543 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
545 if ((mid_entry->mid == smb_buffer->Mid) &&
546 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
547 (mid_entry->command == smb_buffer->Command)) {
548 if(check2ndT2(smb_buffer,server->maxBuf) > 0) {
549 /* We have a multipart transact2 resp */
551 if(mid_entry->resp_buf) {
552 /* merge response - fix up 1st*/
553 if(coalesce_t2(smb_buffer,
554 mid_entry->resp_buf)) {
557 /* all parts received */
562 cERROR(1,("1st trans2 resp needs bigbuf"));
563 /* BB maybe we can fix this up, switch
564 to already allocated large buffer? */
566 /* Have first buffer */
567 mid_entry->resp_buf =
569 mid_entry->largeBuf = 1;
575 mid_entry->resp_buf = smb_buffer;
577 mid_entry->largeBuf = 1;
579 mid_entry->largeBuf = 0;
581 task_to_wake = mid_entry->tsk;
582 mid_entry->midState = MID_RESPONSE_RECEIVED;
586 spin_unlock(&GlobalMid_Lock);
588 /* Was previous buf put in mpx struct for multi-rsp? */
590 /* smb buffer will be freed by user thread */
596 wake_up_process(task_to_wake);
597 } else if ((is_valid_oplock_break(smb_buffer) == FALSE)
598 && (isMultiRsp == FALSE)) {
599 cERROR(1, ("No task to wake, unknown frame rcvd!"));
600 cifs_dump_mem("Received Data is: ",temp,sizeof(struct smb_hdr));
602 } /* end while !EXITING */
604 spin_lock(&GlobalMid_Lock);
605 server->tcpStatus = CifsExiting;
607 /* check if we have blocked requests that need to free */
608 /* Note that cifs_max_pending is normally 50, but
609 can be set at module install time to as little as two */
610 if(atomic_read(&server->inFlight) >= cifs_max_pending)
611 atomic_set(&server->inFlight, cifs_max_pending - 1);
612 /* We do not want to set the max_pending too low or we
613 could end up with the counter going negative */
614 spin_unlock(&GlobalMid_Lock);
615 /* Although there should not be any requests blocked on
616 this queue it can not hurt to be paranoid and try to wake up requests
617 that may haven been blocked when more than 50 at time were on the wire
618 to the same server - they now will see the session is in exit state
619 and get out of SendReceive. */
620 wake_up_all(&server->request_q);
621 /* give those requests time to exit */
624 if(server->ssocket) {
625 sock_release(csocket);
626 server->ssocket = NULL;
628 /* buffer usuallly freed in free_mid - need to free it here on exit */
630 cifs_buf_release(bigbuf);
631 if (smallbuf != NULL)
632 cifs_small_buf_release(smallbuf);
634 read_lock(&GlobalSMBSeslock);
635 if (list_empty(&server->pending_mid_q)) {
636 /* loop through server session structures attached to this and
638 list_for_each(tmp, &GlobalSMBSessionList) {
640 list_entry(tmp, struct cifsSesInfo,
642 if (ses->server == server) {
643 ses->status = CifsExiting;
647 read_unlock(&GlobalSMBSeslock);
649 /* although we can not zero the server struct pointer yet,
650 since there are active requests which may depnd on them,
651 mark the corresponding SMB sessions as exiting too */
652 list_for_each(tmp, &GlobalSMBSessionList) {
653 ses = list_entry(tmp, struct cifsSesInfo,
655 if (ses->server == server) {
656 ses->status = CifsExiting;
660 spin_lock(&GlobalMid_Lock);
661 list_for_each(tmp, &server->pending_mid_q) {
662 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
663 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
665 ("Clearing Mid 0x%x - waking up ",mid_entry->mid));
666 task_to_wake = mid_entry->tsk;
668 wake_up_process(task_to_wake);
672 spin_unlock(&GlobalMid_Lock);
673 read_unlock(&GlobalSMBSeslock);
674 /* 1/8th of sec is more than enough time for them to exit */
678 if (list_empty(&server->pending_mid_q)) {
679 /* mpx threads have not exited yet give them
680 at least the smb send timeout time for long ops */
681 /* due to delays on oplock break requests, we need
682 to wait at least 45 seconds before giving up
683 on a request getting a response and going ahead
685 cFYI(1, ("Wait for exit from demultiplex thread"));
687 /* if threads still have not exited they are probably never
688 coming home not much else we can do but free the memory */
691 write_lock(&GlobalSMBSeslock);
692 atomic_dec(&tcpSesAllocCount);
693 length = tcpSesAllocCount.counter;
695 /* last chance to mark ses pointers invalid
696 if there are any pointing to this (e.g
697 if a crazy root user tried to kill cifsd
698 kernel thread explicitly this might happen) */
699 list_for_each(tmp, &GlobalSMBSessionList) {
700 ses = list_entry(tmp, struct cifsSesInfo,
702 if (ses->server == server) {
706 write_unlock(&GlobalSMBSeslock);
710 mempool_resize(cifs_req_poolp,
711 length + cifs_min_rcv,
720 cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
724 unsigned int temp_len, i, j;
730 memset(vol->source_rfc1001_name,0x20,15);
731 for(i=0;i < strnlen(system_utsname.nodename,15);i++) {
732 /* does not have to be a perfect mapping since the field is
733 informational, only used for servers that do not support
734 port 445 and it can be overridden at mount time */
735 vol->source_rfc1001_name[i] =
736 toupper(system_utsname.nodename[i]);
738 vol->source_rfc1001_name[15] = 0;
740 vol->linux_uid = current->uid; /* current->euid instead? */
741 vol->linux_gid = current->gid;
742 vol->dir_mode = S_IRWXUGO;
743 /* 2767 perms indicate mandatory locking support */
744 vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
746 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
749 /* default is always to request posix paths. */
750 vol->posix_paths = 1;
755 if(strncmp(options,"sep=",4) == 0) {
756 if(options[4] != 0) {
757 separator[0] = options[4];
760 cFYI(1,("Null separator not allowed"));
764 while ((data = strsep(&options, separator)) != NULL) {
767 if ((value = strchr(data, '=')) != NULL)
770 if (strnicmp(data, "user_xattr",10) == 0) {/*parse before user*/
772 } else if (strnicmp(data, "nouser_xattr",12) == 0) {
774 } else if (strnicmp(data, "user", 4) == 0) {
775 if (!value || !*value) {
777 "CIFS: invalid or missing username\n");
778 return 1; /* needs_arg; */
780 if (strnlen(value, 200) < 200) {
781 vol->username = value;
783 printk(KERN_WARNING "CIFS: username too long\n");
786 } else if (strnicmp(data, "pass", 4) == 0) {
788 vol->password = NULL;
790 } else if(value[0] == 0) {
791 /* check if string begins with double comma
792 since that would mean the password really
793 does start with a comma, and would not
794 indicate an empty string */
795 if(value[1] != separator[0]) {
796 vol->password = NULL;
800 temp_len = strlen(value);
801 /* removed password length check, NTLM passwords
802 can be arbitrarily long */
804 /* if comma in password, the string will be
805 prematurely null terminated. Commas in password are
806 specified across the cifs mount interface by a double
807 comma ie ,, and a comma used as in other cases ie ','
808 as a parameter delimiter/separator is single and due
809 to the strsep above is temporarily zeroed. */
811 /* NB: password legally can have multiple commas and
812 the only illegal character in a password is null */
814 if ((value[temp_len] == 0) &&
815 (value[temp_len+1] == separator[0])) {
817 value[temp_len] = separator[0];
818 temp_len+=2; /* move after the second comma */
819 while(value[temp_len] != 0) {
820 if (value[temp_len] == separator[0]) {
821 if (value[temp_len+1] ==
823 /* skip second comma */
826 /* single comma indicating start
833 if(value[temp_len] == 0) {
837 /* point option to start of next parm */
838 options = value + temp_len + 1;
840 /* go from value to value + temp_len condensing
841 double commas to singles. Note that this ends up
842 allocating a few bytes too many, which is ok */
843 vol->password = kcalloc(1, temp_len, GFP_KERNEL);
844 if(vol->password == NULL) {
845 printk("CIFS: no memory for pass\n");
848 for(i=0,j=0;i<temp_len;i++,j++) {
849 vol->password[j] = value[i];
850 if(value[i] == separator[0]
851 && value[i+1] == separator[0]) {
852 /* skip second comma */
856 vol->password[j] = 0;
858 vol->password = kcalloc(1, temp_len+1, GFP_KERNEL);
859 if(vol->password == NULL) {
860 printk("CIFS: no memory for pass\n");
863 strcpy(vol->password, value);
865 } else if (strnicmp(data, "ip", 2) == 0) {
866 if (!value || !*value) {
868 } else if (strnlen(value, 35) < 35) {
871 printk(KERN_WARNING "CIFS: ip address too long\n");
874 } else if ((strnicmp(data, "unc", 3) == 0)
875 || (strnicmp(data, "target", 6) == 0)
876 || (strnicmp(data, "path", 4) == 0)) {
877 if (!value || !*value) {
879 "CIFS: invalid path to network resource\n");
880 return 1; /* needs_arg; */
882 if ((temp_len = strnlen(value, 300)) < 300) {
883 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
886 strcpy(vol->UNC,value);
887 if (strncmp(vol->UNC, "//", 2) == 0) {
890 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
892 "CIFS: UNC Path does not begin with // or \\\\ \n");
896 printk(KERN_WARNING "CIFS: UNC name too long\n");
899 } else if ((strnicmp(data, "domain", 3) == 0)
900 || (strnicmp(data, "workgroup", 5) == 0)) {
901 if (!value || !*value) {
902 printk(KERN_WARNING "CIFS: invalid domain name\n");
903 return 1; /* needs_arg; */
905 /* BB are there cases in which a comma can be valid in
906 a domain name and need special handling? */
907 if (strnlen(value, 65) < 65) {
908 vol->domainname = value;
909 cFYI(1, ("Domain name set"));
911 printk(KERN_WARNING "CIFS: domain name too long\n");
914 } else if (strnicmp(data, "iocharset", 9) == 0) {
915 if (!value || !*value) {
916 printk(KERN_WARNING "CIFS: invalid iocharset specified\n");
917 return 1; /* needs_arg; */
919 if (strnlen(value, 65) < 65) {
920 if(strnicmp(value,"default",7))
921 vol->iocharset = value;
922 /* if iocharset not set load_nls_default used by caller */
923 cFYI(1, ("iocharset set to %s",value));
925 printk(KERN_WARNING "CIFS: iocharset name too long.\n");
928 } else if (strnicmp(data, "uid", 3) == 0) {
929 if (value && *value) {
931 simple_strtoul(value, &value, 0);
933 } else if (strnicmp(data, "gid", 3) == 0) {
934 if (value && *value) {
936 simple_strtoul(value, &value, 0);
938 } else if (strnicmp(data, "file_mode", 4) == 0) {
939 if (value && *value) {
941 simple_strtoul(value, &value, 0);
943 } else if (strnicmp(data, "dir_mode", 4) == 0) {
944 if (value && *value) {
946 simple_strtoul(value, &value, 0);
948 } else if (strnicmp(data, "dirmode", 4) == 0) {
949 if (value && *value) {
951 simple_strtoul(value, &value, 0);
953 } else if (strnicmp(data, "port", 4) == 0) {
954 if (value && *value) {
956 simple_strtoul(value, &value, 0);
958 } else if (strnicmp(data, "rsize", 5) == 0) {
959 if (value && *value) {
961 simple_strtoul(value, &value, 0);
963 } else if (strnicmp(data, "wsize", 5) == 0) {
964 if (value && *value) {
966 simple_strtoul(value, &value, 0);
968 } else if (strnicmp(data, "sockopt", 5) == 0) {
969 if (value && *value) {
971 simple_strtoul(value, &value, 0);
973 } else if (strnicmp(data, "netbiosname", 4) == 0) {
974 if (!value || !*value || (*value == ' ')) {
975 cFYI(1,("invalid (empty) netbiosname specified"));
977 memset(vol->source_rfc1001_name,0x20,15);
979 /* BB are there cases in which a comma can be
980 valid in this workstation netbios name (and need
981 special handling)? */
983 /* We do not uppercase netbiosname for user */
987 vol->source_rfc1001_name[i] = value[i];
989 /* The string has 16th byte zero still from
990 set at top of the function */
991 if((i==15) && (value[i] != 0))
992 printk(KERN_WARNING "CIFS: netbiosname longer than 15 and was truncated.\n");
994 } else if (strnicmp(data, "credentials", 4) == 0) {
996 } else if (strnicmp(data, "version", 3) == 0) {
998 } else if (strnicmp(data, "guest",5) == 0) {
1000 } else if (strnicmp(data, "rw", 2) == 0) {
1002 } else if ((strnicmp(data, "suid", 4) == 0) ||
1003 (strnicmp(data, "nosuid", 6) == 0) ||
1004 (strnicmp(data, "exec", 4) == 0) ||
1005 (strnicmp(data, "noexec", 6) == 0) ||
1006 (strnicmp(data, "nodev", 5) == 0) ||
1007 (strnicmp(data, "noauto", 6) == 0) ||
1008 (strnicmp(data, "dev", 3) == 0)) {
1009 /* The mount tool or mount.cifs helper (if present)
1010 uses these opts to set flags, and the flags are read
1011 by the kernel vfs layer before we get here (ie
1012 before read super) so there is no point trying to
1013 parse these options again and set anything and it
1014 is ok to just ignore them */
1016 } else if (strnicmp(data, "ro", 2) == 0) {
1018 } else if (strnicmp(data, "hard", 4) == 0) {
1020 } else if (strnicmp(data, "soft", 4) == 0) {
1022 } else if (strnicmp(data, "perm", 4) == 0) {
1024 } else if (strnicmp(data, "noperm", 6) == 0) {
1026 } else if (strnicmp(data, "mapchars", 8) == 0) {
1028 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1030 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1031 vol->posix_paths = 1;
1032 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1033 vol->posix_paths = 0;
1034 } else if (strnicmp(data, "setuids", 7) == 0) {
1036 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1038 } else if (strnicmp(data, "nohard", 6) == 0) {
1040 } else if (strnicmp(data, "nosoft", 6) == 0) {
1042 } else if (strnicmp(data, "nointr", 6) == 0) {
1044 } else if (strnicmp(data, "intr", 4) == 0) {
1046 } else if (strnicmp(data, "serverino",7) == 0) {
1047 vol->server_ino = 1;
1048 } else if (strnicmp(data, "noserverino",9) == 0) {
1049 vol->server_ino = 0;
1050 } else if (strnicmp(data, "acl",3) == 0) {
1051 vol->no_psx_acl = 0;
1052 } else if (strnicmp(data, "noacl",5) == 0) {
1053 vol->no_psx_acl = 1;
1054 } else if (strnicmp(data, "direct",6) == 0) {
1056 } else if (strnicmp(data, "forcedirectio",13) == 0) {
1058 } else if (strnicmp(data, "in6_addr",8) == 0) {
1059 if (!value || !*value) {
1060 vol->in6_addr = NULL;
1061 } else if (strnlen(value, 49) == 48) {
1062 vol->in6_addr = value;
1064 printk(KERN_WARNING "CIFS: ip v6 address not 48 characters long\n");
1067 } else if (strnicmp(data, "noac", 4) == 0) {
1068 printk(KERN_WARNING "CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
1070 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);
1072 if (vol->UNC == NULL) {
1073 if(devname == NULL) {
1074 printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n");
1077 if ((temp_len = strnlen(devname, 300)) < 300) {
1078 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
1079 if(vol->UNC == NULL)
1081 strcpy(vol->UNC,devname);
1082 if (strncmp(vol->UNC, "//", 2) == 0) {
1085 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1086 printk(KERN_WARNING "CIFS: UNC Path does not begin with // or \\\\ \n");
1090 printk(KERN_WARNING "CIFS: UNC name too long\n");
1094 if(vol->UNCip == NULL)
1095 vol->UNCip = &vol->UNC[2];
1100 static struct cifsSesInfo *
1101 cifs_find_tcp_session(struct in_addr * target_ip_addr,
1102 struct in6_addr *target_ip6_addr,
1103 char *userName, struct TCP_Server_Info **psrvTcp)
1105 struct list_head *tmp;
1106 struct cifsSesInfo *ses;
1108 read_lock(&GlobalSMBSeslock);
1110 list_for_each(tmp, &GlobalSMBSessionList) {
1111 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1113 if((target_ip_addr &&
1114 (ses->server->addr.sockAddr.sin_addr.s_addr
1115 == target_ip_addr->s_addr)) || (target_ip6_addr
1116 && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1117 target_ip6_addr,sizeof(*target_ip6_addr)))){
1118 /* BB lock server and tcp session and increment use count here?? */
1119 *psrvTcp = ses->server; /* found a match on the TCP session */
1120 /* BB check if reconnection needed */
1122 (ses->userName, userName,
1123 MAX_USERNAME_SIZE) == 0){
1124 read_unlock(&GlobalSMBSeslock);
1125 return ses; /* found exact match on both tcp and SMB sessions */
1129 /* else tcp and smb sessions need reconnection */
1131 read_unlock(&GlobalSMBSeslock);
1135 static struct cifsTconInfo *
1136 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1138 struct list_head *tmp;
1139 struct cifsTconInfo *tcon;
1141 read_lock(&GlobalSMBSeslock);
1142 list_for_each(tmp, &GlobalTreeConnectionList) {
1143 cFYI(1, ("Next tcon - "));
1144 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1146 if (tcon->ses->server) {
1148 (" old ip addr: %x == new ip %x ?",
1149 tcon->ses->server->addr.sockAddr.sin_addr.
1150 s_addr, new_target_ip_addr));
1151 if (tcon->ses->server->addr.sockAddr.sin_addr.
1152 s_addr == new_target_ip_addr) {
1153 /* BB lock tcon and server and tcp session and increment use count here? */
1154 /* found a match on the TCP session */
1155 /* BB check if reconnection needed */
1156 cFYI(1,("Matched ip, old UNC: %s == new: %s ?",
1157 tcon->treeName, uncName));
1159 (tcon->treeName, uncName,
1160 MAX_TREE_SIZE) == 0) {
1162 ("Matched UNC, old user: %s == new: %s ?",
1163 tcon->treeName, uncName));
1165 (tcon->ses->userName,
1167 MAX_USERNAME_SIZE) == 0) {
1168 read_unlock(&GlobalSMBSeslock);
1169 return tcon;/* also matched user (smb session)*/
1176 read_unlock(&GlobalSMBSeslock);
1181 connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1182 const char *old_path, const struct nls_table *nls_codepage,
1185 unsigned char *referrals = NULL;
1186 unsigned int num_referrals;
1189 rc = get_dfs_path(xid, pSesInfo,old_path, nls_codepage,
1190 &num_referrals, &referrals, remap);
1192 /* BB Add in code to: if valid refrl, if not ip address contact
1193 the helper that resolves tcp names, mount to it, try to
1194 tcon to it unmount it if fail */
1203 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1204 const char *old_path, const struct nls_table *nls_codepage,
1205 unsigned int *pnum_referrals,
1206 unsigned char ** preferrals, int remap)
1211 *pnum_referrals = 0;
1213 if (pSesInfo->ipc_tid == 0) {
1214 temp_unc = kmalloc(2 /* for slashes */ +
1215 strnlen(pSesInfo->serverName,SERVER_NAME_LEN_WITH_NULL * 2)
1216 + 1 + 4 /* slash IPC$ */ + 2,
1218 if (temp_unc == NULL)
1222 strcpy(temp_unc + 2, pSesInfo->serverName);
1223 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1224 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1226 ("CIFS Tcon rc = %d ipc_tid = %d", rc,pSesInfo->ipc_tid));
1230 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1231 pnum_referrals, nls_codepage, remap);
1236 /* See RFC1001 section 14 on representation of Netbios names */
1237 static void rfc1002mangle(char * target,char * source, unsigned int length)
1241 for(i=0,j=0;i<(length);i++) {
1242 /* mask a nibble at a time and encode */
1243 target[j] = 'A' + (0x0F & (source[i] >> 4));
1244 target[j+1] = 'A' + (0x0F & source[i]);
1252 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1253 char * netbios_name)
1257 __be16 orig_port = 0;
1259 if(*csocket == NULL) {
1260 rc = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket);
1262 cERROR(1, ("Error %d creating socket",rc));
1266 /* BB other socket options to set KEEPALIVE, NODELAY? */
1267 cFYI(1,("Socket created"));
1268 (*csocket)->sk->sk_allocation = GFP_NOFS;
1272 psin_server->sin_family = AF_INET;
1273 if(psin_server->sin_port) { /* user overrode default port */
1274 rc = (*csocket)->ops->connect(*csocket,
1275 (struct sockaddr *) psin_server,
1276 sizeof (struct sockaddr_in),0);
1282 /* save original port so we can retry user specified port
1283 later if fall back ports fail this time */
1284 orig_port = psin_server->sin_port;
1286 /* do not retry on the same port we just failed on */
1287 if(psin_server->sin_port != htons(CIFS_PORT)) {
1288 psin_server->sin_port = htons(CIFS_PORT);
1290 rc = (*csocket)->ops->connect(*csocket,
1291 (struct sockaddr *) psin_server,
1292 sizeof (struct sockaddr_in),0);
1298 psin_server->sin_port = htons(RFC1001_PORT);
1299 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1300 psin_server, sizeof (struct sockaddr_in),0);
1305 /* give up here - unless we want to retry on different
1306 protocol families some day */
1309 psin_server->sin_port = orig_port;
1310 cFYI(1,("Error %d connecting to server via ipv4",rc));
1311 sock_release(*csocket);
1315 /* Eventually check for other socket options to change from
1316 the default. sock_setsockopt not used because it expects
1317 user space buffer */
1318 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1320 /* send RFC1001 sessinit */
1322 if(psin_server->sin_port == htons(RFC1001_PORT)) {
1323 /* some servers require RFC1001 sessinit before sending
1324 negprot - BB check reconnection in case where second
1325 sessinit is sent but no second negprot */
1326 struct rfc1002_session_packet * ses_init_buf;
1327 struct smb_hdr * smb_buf;
1328 ses_init_buf = kcalloc(1, sizeof(struct rfc1002_session_packet), GFP_KERNEL);
1330 ses_init_buf->trailer.session_req.called_len = 32;
1331 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1332 DEFAULT_CIFS_CALLED_NAME,16);
1333 ses_init_buf->trailer.session_req.calling_len = 32;
1334 /* calling name ends in null (byte 16) from old smb
1336 if(netbios_name && (netbios_name[0] !=0)) {
1337 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1340 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1341 "LINUX_CIFS_CLNT",16);
1343 ses_init_buf->trailer.session_req.scope1 = 0;
1344 ses_init_buf->trailer.session_req.scope2 = 0;
1345 smb_buf = (struct smb_hdr *)ses_init_buf;
1346 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1347 smb_buf->smb_buf_length = 0x81000044;
1348 rc = smb_send(*csocket, smb_buf, 0x44,
1349 (struct sockaddr *)psin_server);
1350 kfree(ses_init_buf);
1352 /* else the negprot may still work without this
1353 even though malloc failed */
1361 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1365 __be16 orig_port = 0;
1367 if(*csocket == NULL) {
1368 rc = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, csocket);
1370 cERROR(1, ("Error %d creating ipv6 socket",rc));
1374 /* BB other socket options to set KEEPALIVE, NODELAY? */
1375 cFYI(1,("ipv6 Socket created"));
1376 (*csocket)->sk->sk_allocation = GFP_NOFS;
1380 psin_server->sin6_family = AF_INET6;
1382 if(psin_server->sin6_port) { /* user overrode default port */
1383 rc = (*csocket)->ops->connect(*csocket,
1384 (struct sockaddr *) psin_server,
1385 sizeof (struct sockaddr_in6),0);
1391 /* save original port so we can retry user specified port
1392 later if fall back ports fail this time */
1394 orig_port = psin_server->sin6_port;
1395 /* do not retry on the same port we just failed on */
1396 if(psin_server->sin6_port != htons(CIFS_PORT)) {
1397 psin_server->sin6_port = htons(CIFS_PORT);
1399 rc = (*csocket)->ops->connect(*csocket,
1400 (struct sockaddr *) psin_server,
1401 sizeof (struct sockaddr_in6),0);
1407 psin_server->sin6_port = htons(RFC1001_PORT);
1408 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1409 psin_server, sizeof (struct sockaddr_in6),0);
1414 /* give up here - unless we want to retry on different
1415 protocol families some day */
1418 psin_server->sin6_port = orig_port;
1419 cFYI(1,("Error %d connecting to server via ipv6",rc));
1420 sock_release(*csocket);
1424 /* Eventually check for other socket options to change from
1425 the default. sock_setsockopt not used because it expects
1426 user space buffer */
1427 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1433 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1434 char *mount_data, const char *devname)
1438 int address_type = AF_INET;
1439 struct socket *csocket = NULL;
1440 struct sockaddr_in sin_server;
1441 struct sockaddr_in6 sin_server6;
1442 struct smb_vol volume_info;
1443 struct cifsSesInfo *pSesInfo = NULL;
1444 struct cifsSesInfo *existingCifsSes = NULL;
1445 struct cifsTconInfo *tcon = NULL;
1446 struct TCP_Server_Info *srvTcp = NULL;
1450 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1452 memset(&volume_info,0,sizeof(struct smb_vol));
1453 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1455 kfree(volume_info.UNC);
1456 if(volume_info.password)
1457 kfree(volume_info.password);
1462 if (volume_info.username) {
1463 /* BB fixme parse for domain name here */
1464 cFYI(1, ("Username: %s ", volume_info.username));
1467 cifserror("No username specified ");
1468 /* In userspace mount helper we can get user name from alternate
1469 locations such as env variables and files on disk */
1471 kfree(volume_info.UNC);
1472 if(volume_info.password)
1473 kfree(volume_info.password);
1478 if (volume_info.UNCip && volume_info.UNC) {
1479 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,&sin_server.sin_addr.s_addr);
1482 /* not ipv4 address, try ipv6 */
1483 rc = cifs_inet_pton(AF_INET6,volume_info.UNCip,&sin_server6.sin6_addr.in6_u);
1485 address_type = AF_INET6;
1487 address_type = AF_INET;
1491 /* we failed translating address */
1493 kfree(volume_info.UNC);
1494 if(volume_info.password)
1495 kfree(volume_info.password);
1500 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1503 } else if (volume_info.UNCip){
1504 /* BB using ip addr as server name connect to the DFS root below */
1505 cERROR(1,("Connecting to DFS root not implemented yet"));
1507 kfree(volume_info.UNC);
1508 if(volume_info.password)
1509 kfree(volume_info.password);
1512 } else /* which servers DFS root would we conect to */ {
1514 ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified "));
1516 kfree(volume_info.UNC);
1517 if(volume_info.password)
1518 kfree(volume_info.password);
1523 /* this is needed for ASCII cp to Unicode converts */
1524 if(volume_info.iocharset == NULL) {
1525 cifs_sb->local_nls = load_nls_default();
1526 /* load_nls_default can not return null */
1528 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1529 if(cifs_sb->local_nls == NULL) {
1530 cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
1532 kfree(volume_info.UNC);
1533 if(volume_info.password)
1534 kfree(volume_info.password);
1540 if(address_type == AF_INET)
1541 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1542 NULL /* no ipv6 addr */,
1543 volume_info.username, &srvTcp);
1544 else if(address_type == AF_INET6)
1545 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1546 &sin_server6.sin6_addr,
1547 volume_info.username, &srvTcp);
1550 kfree(volume_info.UNC);
1551 if(volume_info.password)
1552 kfree(volume_info.password);
1559 cFYI(1, ("Existing tcp session with server found "));
1560 } else { /* create socket */
1561 if(volume_info.port)
1562 sin_server.sin_port = htons(volume_info.port);
1564 sin_server.sin_port = 0;
1565 rc = ipv4_connect(&sin_server,&csocket,volume_info.source_rfc1001_name);
1568 ("Error connecting to IPv4 socket. Aborting operation"));
1570 sock_release(csocket);
1572 kfree(volume_info.UNC);
1573 if(volume_info.password)
1574 kfree(volume_info.password);
1579 srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
1580 if (srvTcp == NULL) {
1582 sock_release(csocket);
1584 kfree(volume_info.UNC);
1585 if(volume_info.password)
1586 kfree(volume_info.password);
1590 memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
1591 memcpy(&srvTcp->addr.sockAddr, &sin_server, sizeof (struct sockaddr_in));
1592 atomic_set(&srvTcp->inFlight,0);
1593 /* BB Add code for ipv6 case too */
1594 srvTcp->ssocket = csocket;
1595 srvTcp->protocolType = IPV4;
1596 init_waitqueue_head(&srvTcp->response_q);
1597 init_waitqueue_head(&srvTcp->request_q);
1598 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
1599 /* at this point we are the only ones with the pointer
1600 to the struct since the kernel thread not created yet
1601 so no need to spinlock this init of tcpStatus */
1602 srvTcp->tcpStatus = CifsNew;
1603 init_MUTEX(&srvTcp->tcpSem);
1604 rc = (int)kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
1605 CLONE_FS | CLONE_FILES | CLONE_VM);
1608 sock_release(csocket);
1610 kfree(volume_info.UNC);
1611 if(volume_info.password)
1612 kfree(volume_info.password);
1617 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
1618 srvTcp->sequence_number = 0;
1622 if (existingCifsSes) {
1623 pSesInfo = existingCifsSes;
1624 cFYI(1, ("Existing smb sess found "));
1625 if(volume_info.password)
1626 kfree(volume_info.password);
1627 /* volume_info.UNC freed at end of function */
1629 cFYI(1, ("Existing smb sess not found "));
1630 pSesInfo = sesInfoAlloc();
1631 if (pSesInfo == NULL)
1634 pSesInfo->server = srvTcp;
1635 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
1636 NIPQUAD(sin_server.sin_addr.s_addr));
1640 /* volume_info.password freed at unmount */
1641 if (volume_info.password)
1642 pSesInfo->password = volume_info.password;
1643 if (volume_info.username)
1644 strncpy(pSesInfo->userName,
1645 volume_info.username,MAX_USERNAME_SIZE);
1646 if (volume_info.domainname)
1647 strncpy(pSesInfo->domainName,
1648 volume_info.domainname,MAX_USERNAME_SIZE);
1649 pSesInfo->linux_uid = volume_info.linux_uid;
1650 down(&pSesInfo->sesSem);
1651 rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls);
1652 up(&pSesInfo->sesSem);
1654 atomic_inc(&srvTcp->socketUseCount);
1656 if(volume_info.password)
1657 kfree(volume_info.password);
1660 /* search for existing tcon to this server share */
1662 if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize))
1663 cifs_sb->rsize = volume_info.rsize;
1665 cifs_sb->rsize = srvTcp->maxBuf - MAX_CIFS_HDR_SIZE; /* default */
1666 if((volume_info.wsize) && (volume_info.wsize <= CIFSMaxBufSize))
1667 cifs_sb->wsize = volume_info.wsize;
1669 cifs_sb->wsize = CIFSMaxBufSize; /* default */
1670 if(cifs_sb->rsize < PAGE_CACHE_SIZE) {
1671 cifs_sb->rsize = PAGE_CACHE_SIZE;
1672 cERROR(1,("Attempt to set readsize for mount to less than one page (4096)"));
1674 cifs_sb->mnt_uid = volume_info.linux_uid;
1675 cifs_sb->mnt_gid = volume_info.linux_gid;
1676 cifs_sb->mnt_file_mode = volume_info.file_mode;
1677 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
1678 cFYI(1,("file mode: 0x%x dir mode: 0x%x",cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
1680 if(volume_info.noperm)
1681 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
1682 if(volume_info.setuids)
1683 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
1684 if(volume_info.server_ino)
1685 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
1686 if(volume_info.remap)
1687 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
1688 if(volume_info.no_xattr)
1689 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
1691 if(volume_info.direct_io) {
1692 cERROR(1,("mounting share using direct i/o"));
1693 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
1697 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
1698 volume_info.username);
1700 cFYI(1, ("Found match on UNC path "));
1701 /* we can have only one retry value for a connection
1702 to a share so for resources mounted more than once
1703 to the same server share the last value passed in
1704 for the retry flag is used */
1705 tcon->retry = volume_info.retry;
1707 tcon = tconInfoAlloc();
1711 /* check for null share name ie connect to dfs root */
1713 /* BB check if this works for exactly length three strings */
1714 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
1715 && (strchr(volume_info.UNC + 3, '/') ==
1717 rc = connect_to_dfs_path(xid, pSesInfo,
1718 "", cifs_sb->local_nls,
1719 cifs_sb->mnt_cifs_flags &
1720 CIFS_MOUNT_MAP_SPECIAL_CHR);
1722 kfree(volume_info.UNC);
1726 rc = CIFSTCon(xid, pSesInfo,
1728 tcon, cifs_sb->local_nls);
1729 cFYI(1, ("CIFS Tcon rc = %d", rc));
1732 atomic_inc(&pSesInfo->inUse);
1733 tcon->retry = volume_info.retry;
1739 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
1740 sb->s_maxbytes = (u64) 1 << 63;
1742 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
1745 sb->s_time_gran = 100;
1747 /* on error free sesinfo and tcon struct if needed */
1749 /* if session setup failed, use count is zero but
1750 we still need to free cifsd thread */
1751 if(atomic_read(&srvTcp->socketUseCount) == 0) {
1752 spin_lock(&GlobalMid_Lock);
1753 srvTcp->tcpStatus = CifsExiting;
1754 spin_unlock(&GlobalMid_Lock);
1756 send_sig(SIGKILL,srvTcp->tsk,1);
1758 /* If find_unc succeeded then rc == 0 so we can not end */
1759 if (tcon) /* up accidently freeing someone elses tcon struct */
1761 if (existingCifsSes == NULL) {
1763 if ((pSesInfo->server) &&
1764 (pSesInfo->status == CifsGood)) {
1766 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
1767 /* if the socketUseCount is now zero */
1768 if((temp_rc == -ESHUTDOWN) &&
1769 (pSesInfo->server->tsk))
1770 send_sig(SIGKILL,pSesInfo->server->tsk,1);
1772 cFYI(1, ("No session or bad tcon"));
1773 sesInfoFree(pSesInfo);
1774 /* pSesInfo = NULL; */
1778 atomic_inc(&tcon->useCount);
1779 cifs_sb->tcon = tcon;
1780 tcon->ses = pSesInfo;
1782 /* do not care if following two calls succeed - informational only */
1783 CIFSSMBQFSDeviceInfo(xid, tcon);
1784 CIFSSMBQFSAttributeInfo(xid, tcon);
1785 if (tcon->ses->capabilities & CAP_UNIX) {
1786 if(!CIFSSMBQFSUnixInfo(xid, tcon)) {
1787 if(!volume_info.no_psx_acl) {
1788 if(CIFS_UNIX_POSIX_ACL_CAP &
1789 le64_to_cpu(tcon->fsUnixInfo.Capability))
1790 cFYI(1,("server negotiated posix acl support"));
1791 sb->s_flags |= MS_POSIXACL;
1794 /* Try and negotiate POSIX pathnames if we can. */
1795 if (volume_info.posix_paths && (CIFS_UNIX_POSIX_PATHNAMES_CAP &
1796 le64_to_cpu(tcon->fsUnixInfo.Capability))) {
1797 if (!CIFSSMBSetFSUnixInfo(xid, tcon, CIFS_UNIX_POSIX_PATHNAMES_CAP)) {
1798 cFYI(1,("negotiated posix pathnames support"));
1799 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_POSIX_PATHS;
1801 cFYI(1,("posix pathnames support requested but not supported"));
1808 /* volume_info.password is freed above when existing session found
1809 (in which case it is not needed anymore) but when new sesion is created
1810 the password ptr is put in the new session structure (in which case the
1811 password will be freed at unmount time) */
1813 kfree(volume_info.UNC);
1819 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
1820 char session_key[CIFS_SESSION_KEY_SIZE],
1821 const struct nls_table *nls_codepage)
1823 struct smb_hdr *smb_buffer;
1824 struct smb_hdr *smb_buffer_response;
1825 SESSION_SETUP_ANDX *pSMB;
1826 SESSION_SETUP_ANDX *pSMBr;
1831 int remaining_words = 0;
1832 int bytes_returned = 0;
1837 cFYI(1, ("In sesssetup "));
1840 user = ses->userName;
1841 domain = ses->domainName;
1842 smb_buffer = cifs_buf_get();
1843 if (smb_buffer == NULL) {
1846 smb_buffer_response = smb_buffer;
1847 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
1849 /* send SMBsessionSetup here */
1850 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
1851 NULL /* no tCon exists yet */ , 13 /* wct */ );
1853 pSMB->req_no_secext.AndXCommand = 0xFF;
1854 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
1855 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
1857 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
1858 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
1860 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
1861 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
1862 if (ses->capabilities & CAP_UNICODE) {
1863 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
1864 capabilities |= CAP_UNICODE;
1866 if (ses->capabilities & CAP_STATUS32) {
1867 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
1868 capabilities |= CAP_STATUS32;
1870 if (ses->capabilities & CAP_DFS) {
1871 smb_buffer->Flags2 |= SMBFLG2_DFS;
1872 capabilities |= CAP_DFS;
1874 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
1876 pSMB->req_no_secext.CaseInsensitivePasswordLength =
1877 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
1879 pSMB->req_no_secext.CaseSensitivePasswordLength =
1880 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
1881 bcc_ptr = pByteArea(smb_buffer);
1882 memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
1883 bcc_ptr += CIFS_SESSION_KEY_SIZE;
1884 memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
1885 bcc_ptr += CIFS_SESSION_KEY_SIZE;
1887 if (ses->capabilities & CAP_UNICODE) {
1888 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
1893 bytes_returned = 0; /* skill null user */
1896 cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100,
1898 /* convert number of 16 bit words to bytes */
1899 bcc_ptr += 2 * bytes_returned;
1900 bcc_ptr += 2; /* trailing null */
1903 cifs_strtoUCS((wchar_t *) bcc_ptr,
1904 "CIFS_LINUX_DOM", 32, nls_codepage);
1907 cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64,
1909 bcc_ptr += 2 * bytes_returned;
1912 cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",
1914 bcc_ptr += 2 * bytes_returned;
1916 cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release,
1918 bcc_ptr += 2 * bytes_returned;
1921 cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS,
1923 bcc_ptr += 2 * bytes_returned;
1927 strncpy(bcc_ptr, user, 200);
1928 bcc_ptr += strnlen(user, 200);
1932 if (domain == NULL) {
1933 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
1934 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
1936 strncpy(bcc_ptr, domain, 64);
1937 bcc_ptr += strnlen(domain, 64);
1941 strcpy(bcc_ptr, "Linux version ");
1942 bcc_ptr += strlen("Linux version ");
1943 strcpy(bcc_ptr, system_utsname.release);
1944 bcc_ptr += strlen(system_utsname.release) + 1;
1945 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
1946 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
1948 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
1949 smb_buffer->smb_buf_length += count;
1950 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
1952 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
1953 &bytes_returned, 1);
1955 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
1956 } else if ((smb_buffer_response->WordCount == 3)
1957 || (smb_buffer_response->WordCount == 4)) {
1958 __u16 action = le16_to_cpu(pSMBr->resp.Action);
1959 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
1960 if (action & GUEST_LOGIN)
1961 cFYI(1, (" Guest login")); /* do we want to mark SesInfo struct ? */
1962 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
1963 cFYI(1, ("UID = %d ", ses->Suid));
1964 /* response can have either 3 or 4 word count - Samba sends 3 */
1965 bcc_ptr = pByteArea(smb_buffer_response);
1966 if ((pSMBr->resp.hdr.WordCount == 3)
1967 || ((pSMBr->resp.hdr.WordCount == 4)
1968 && (blob_len < pSMBr->resp.ByteCount))) {
1969 if (pSMBr->resp.hdr.WordCount == 4)
1970 bcc_ptr += blob_len;
1972 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
1973 if ((long) (bcc_ptr) % 2) {
1975 (BCC(smb_buffer_response) - 1) /2;
1976 bcc_ptr++; /* Unicode strings must be word aligned */
1979 BCC(smb_buffer_response) / 2;
1982 UniStrnlen((wchar_t *) bcc_ptr,
1983 remaining_words - 1);
1984 /* We look for obvious messed up bcc or strings in response so we do not go off
1985 the end since (at least) WIN2K and Windows XP have a major bug in not null
1986 terminating last Unicode string in response */
1987 ses->serverOS = kcalloc(1, 2 * (len + 1), GFP_KERNEL);
1988 if(ses->serverOS == NULL)
1989 goto sesssetup_nomem;
1990 cifs_strfromUCS_le(ses->serverOS,
1991 (wchar_t *)bcc_ptr, len,nls_codepage);
1992 bcc_ptr += 2 * (len + 1);
1993 remaining_words -= len + 1;
1994 ses->serverOS[2 * len] = 0;
1995 ses->serverOS[1 + (2 * len)] = 0;
1996 if (remaining_words > 0) {
1997 len = UniStrnlen((wchar_t *)bcc_ptr,
1999 ses->serverNOS = kcalloc(1, 2 * (len + 1),GFP_KERNEL);
2000 if(ses->serverNOS == NULL)
2001 goto sesssetup_nomem;
2002 cifs_strfromUCS_le(ses->serverNOS,
2003 (wchar_t *)bcc_ptr,len,nls_codepage);
2004 bcc_ptr += 2 * (len + 1);
2005 ses->serverNOS[2 * len] = 0;
2006 ses->serverNOS[1 + (2 * len)] = 0;
2007 if(strncmp(ses->serverNOS,
2008 "NT LAN Manager 4",16) == 0) {
2009 cFYI(1,("NT4 server"));
2010 ses->flags |= CIFS_SES_NT4;
2012 remaining_words -= len + 1;
2013 if (remaining_words > 0) {
2014 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2015 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2017 kcalloc(1, 2*(len+1),GFP_KERNEL);
2018 if(ses->serverDomain == NULL)
2019 goto sesssetup_nomem;
2020 cifs_strfromUCS_le(ses->serverDomain,
2021 (wchar_t *)bcc_ptr,len,nls_codepage);
2022 bcc_ptr += 2 * (len + 1);
2023 ses->serverDomain[2*len] = 0;
2024 ses->serverDomain[1+(2*len)] = 0;
2025 } /* else no more room so create dummy domain string */
2028 kcalloc(1, 2, GFP_KERNEL);
2029 } else { /* no room so create dummy domain and NOS string */
2030 /* if these kcallocs fail not much we
2031 can do, but better to not fail the
2034 kcalloc(1, 2, GFP_KERNEL);
2036 kcalloc(1, 2, GFP_KERNEL);
2038 } else { /* ASCII */
2039 len = strnlen(bcc_ptr, 1024);
2040 if (((long) bcc_ptr + len) - (long)
2041 pByteArea(smb_buffer_response)
2042 <= BCC(smb_buffer_response)) {
2043 ses->serverOS = kcalloc(1, len + 1,GFP_KERNEL);
2044 if(ses->serverOS == NULL)
2045 goto sesssetup_nomem;
2046 strncpy(ses->serverOS,bcc_ptr, len);
2049 bcc_ptr[0] = 0; /* null terminate the string */
2052 len = strnlen(bcc_ptr, 1024);
2053 ses->serverNOS = kcalloc(1, len + 1,GFP_KERNEL);
2054 if(ses->serverNOS == NULL)
2055 goto sesssetup_nomem;
2056 strncpy(ses->serverNOS, bcc_ptr, len);
2061 len = strnlen(bcc_ptr, 1024);
2062 ses->serverDomain = kcalloc(1, len + 1,GFP_KERNEL);
2063 if(ses->serverDomain == NULL)
2064 goto sesssetup_nomem;
2065 strncpy(ses->serverDomain, bcc_ptr, len);
2071 ("Variable field of length %d extends beyond end of smb ",
2076 (" Security Blob Length extends beyond end of SMB"));
2080 (" Invalid Word count %d: ",
2081 smb_buffer_response->WordCount));
2084 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2085 since that could make reconnection harder, and
2086 reconnection might be needed to free memory */
2088 cifs_buf_release(smb_buffer);
2094 CIFSSpnegoSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2095 char *SecurityBlob,int SecurityBlobLength,
2096 const struct nls_table *nls_codepage)
2098 struct smb_hdr *smb_buffer;
2099 struct smb_hdr *smb_buffer_response;
2100 SESSION_SETUP_ANDX *pSMB;
2101 SESSION_SETUP_ANDX *pSMBr;
2106 int remaining_words = 0;
2107 int bytes_returned = 0;
2112 cFYI(1, ("In spnego sesssetup "));
2115 user = ses->userName;
2116 domain = ses->domainName;
2118 smb_buffer = cifs_buf_get();
2119 if (smb_buffer == NULL) {
2122 smb_buffer_response = smb_buffer;
2123 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2125 /* send SMBsessionSetup here */
2126 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2127 NULL /* no tCon exists yet */ , 12 /* wct */ );
2128 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2129 pSMB->req.AndXCommand = 0xFF;
2130 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2131 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2133 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2134 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2136 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2137 CAP_EXTENDED_SECURITY;
2138 if (ses->capabilities & CAP_UNICODE) {
2139 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2140 capabilities |= CAP_UNICODE;
2142 if (ses->capabilities & CAP_STATUS32) {
2143 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2144 capabilities |= CAP_STATUS32;
2146 if (ses->capabilities & CAP_DFS) {
2147 smb_buffer->Flags2 |= SMBFLG2_DFS;
2148 capabilities |= CAP_DFS;
2150 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2152 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2153 bcc_ptr = pByteArea(smb_buffer);
2154 memcpy(bcc_ptr, SecurityBlob, SecurityBlobLength);
2155 bcc_ptr += SecurityBlobLength;
2157 if (ses->capabilities & CAP_UNICODE) {
2158 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode strings */
2163 cifs_strtoUCS((wchar_t *) bcc_ptr, user, 100, nls_codepage);
2164 bcc_ptr += 2 * bytes_returned; /* convert num of 16 bit words to bytes */
2165 bcc_ptr += 2; /* trailing null */
2168 cifs_strtoUCS((wchar_t *) bcc_ptr,
2169 "CIFS_LINUX_DOM", 32, nls_codepage);
2172 cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64,
2174 bcc_ptr += 2 * bytes_returned;
2177 cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",
2179 bcc_ptr += 2 * bytes_returned;
2181 cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
2183 bcc_ptr += 2 * bytes_returned;
2186 cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS,
2188 bcc_ptr += 2 * bytes_returned;
2191 strncpy(bcc_ptr, user, 200);
2192 bcc_ptr += strnlen(user, 200);
2195 if (domain == NULL) {
2196 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2197 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2199 strncpy(bcc_ptr, domain, 64);
2200 bcc_ptr += strnlen(domain, 64);
2204 strcpy(bcc_ptr, "Linux version ");
2205 bcc_ptr += strlen("Linux version ");
2206 strcpy(bcc_ptr, system_utsname.release);
2207 bcc_ptr += strlen(system_utsname.release) + 1;
2208 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2209 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2211 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2212 smb_buffer->smb_buf_length += count;
2213 pSMB->req.ByteCount = cpu_to_le16(count);
2215 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2216 &bytes_returned, 1);
2218 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2219 } else if ((smb_buffer_response->WordCount == 3)
2220 || (smb_buffer_response->WordCount == 4)) {
2221 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2223 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2224 if (action & GUEST_LOGIN)
2225 cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */
2227 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
2228 cFYI(1, ("UID = %d ", ses->Suid));
2229 bcc_ptr = pByteArea(smb_buffer_response); /* response can have either 3 or 4 word count - Samba sends 3 */
2231 /* BB Fix below to make endian neutral !! */
2233 if ((pSMBr->resp.hdr.WordCount == 3)
2234 || ((pSMBr->resp.hdr.WordCount == 4)
2236 pSMBr->resp.ByteCount))) {
2237 if (pSMBr->resp.hdr.WordCount == 4) {
2241 ("Security Blob Length %d ",
2245 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2246 if ((long) (bcc_ptr) % 2) {
2248 (BCC(smb_buffer_response)
2250 bcc_ptr++; /* Unicode strings must be word aligned */
2254 (smb_buffer_response) / 2;
2257 UniStrnlen((wchar_t *) bcc_ptr,
2258 remaining_words - 1);
2259 /* We look for obvious messed up bcc or strings in response so we do not go off
2260 the end since (at least) WIN2K and Windows XP have a major bug in not null
2261 terminating last Unicode string in response */
2263 kcalloc(1, 2 * (len + 1), GFP_KERNEL);
2264 cifs_strfromUCS_le(ses->serverOS,
2268 bcc_ptr += 2 * (len + 1);
2269 remaining_words -= len + 1;
2270 ses->serverOS[2 * len] = 0;
2271 ses->serverOS[1 + (2 * len)] = 0;
2272 if (remaining_words > 0) {
2273 len = UniStrnlen((wchar_t *)bcc_ptr,
2277 kcalloc(1, 2 * (len + 1),
2279 cifs_strfromUCS_le(ses->serverNOS,
2283 bcc_ptr += 2 * (len + 1);
2284 ses->serverNOS[2 * len] = 0;
2285 ses->serverNOS[1 + (2 * len)] = 0;
2286 remaining_words -= len + 1;
2287 if (remaining_words > 0) {
2288 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2289 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2290 ses->serverDomain = kcalloc(1, 2*(len+1),GFP_KERNEL);
2291 cifs_strfromUCS_le(ses->serverDomain,
2295 bcc_ptr += 2*(len+1);
2296 ses->serverDomain[2*len] = 0;
2297 ses->serverDomain[1+(2*len)] = 0;
2298 } /* else no more room so create dummy domain string */
2301 kcalloc(1, 2,GFP_KERNEL);
2302 } else { /* no room so create dummy domain and NOS string */
2303 ses->serverDomain = kcalloc(1, 2, GFP_KERNEL);
2304 ses->serverNOS = kcalloc(1, 2, GFP_KERNEL);
2306 } else { /* ASCII */
2308 len = strnlen(bcc_ptr, 1024);
2309 if (((long) bcc_ptr + len) - (long)
2310 pByteArea(smb_buffer_response)
2311 <= BCC(smb_buffer_response)) {
2312 ses->serverOS = kcalloc(1, len + 1, GFP_KERNEL);
2313 strncpy(ses->serverOS, bcc_ptr, len);
2316 bcc_ptr[0] = 0; /* null terminate the string */
2319 len = strnlen(bcc_ptr, 1024);
2320 ses->serverNOS = kcalloc(1, len + 1,GFP_KERNEL);
2321 strncpy(ses->serverNOS, bcc_ptr, len);
2326 len = strnlen(bcc_ptr, 1024);
2327 ses->serverDomain = kcalloc(1, len + 1, GFP_KERNEL);
2328 strncpy(ses->serverDomain, bcc_ptr, len);
2334 ("Variable field of length %d extends beyond end of smb ",
2339 (" Security Blob Length extends beyond end of SMB"));
2342 cERROR(1, ("No session structure passed in."));
2346 (" Invalid Word count %d: ",
2347 smb_buffer_response->WordCount));
2352 cifs_buf_release(smb_buffer);
2358 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2359 struct cifsSesInfo *ses, int * pNTLMv2_flag,
2360 const struct nls_table *nls_codepage)
2362 struct smb_hdr *smb_buffer;
2363 struct smb_hdr *smb_buffer_response;
2364 SESSION_SETUP_ANDX *pSMB;
2365 SESSION_SETUP_ANDX *pSMBr;
2369 int remaining_words = 0;
2370 int bytes_returned = 0;
2372 int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
2373 PNEGOTIATE_MESSAGE SecurityBlob;
2374 PCHALLENGE_MESSAGE SecurityBlob2;
2375 __u32 negotiate_flags, capabilities;
2378 cFYI(1, ("In NTLMSSP sesssetup (negotiate) "));
2381 domain = ses->domainName;
2382 *pNTLMv2_flag = FALSE;
2383 smb_buffer = cifs_buf_get();
2384 if (smb_buffer == NULL) {
2387 smb_buffer_response = smb_buffer;
2388 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2389 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2391 /* send SMBsessionSetup here */
2392 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2393 NULL /* no tCon exists yet */ , 12 /* wct */ );
2394 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2395 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2397 pSMB->req.AndXCommand = 0xFF;
2398 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2399 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2401 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2402 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2404 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2405 CAP_EXTENDED_SECURITY;
2406 if (ses->capabilities & CAP_UNICODE) {
2407 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2408 capabilities |= CAP_UNICODE;
2410 if (ses->capabilities & CAP_STATUS32) {
2411 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2412 capabilities |= CAP_STATUS32;
2414 if (ses->capabilities & CAP_DFS) {
2415 smb_buffer->Flags2 |= SMBFLG2_DFS;
2416 capabilities |= CAP_DFS;
2418 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2420 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2421 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2422 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2423 SecurityBlob->MessageType = NtLmNegotiate;
2425 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2426 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM | 0x80000000 |
2427 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2429 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2431 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2432 /* setup pointers to domain name and workstation name */
2433 bcc_ptr += SecurityBlobLength;
2435 SecurityBlob->WorkstationName.Buffer = 0;
2436 SecurityBlob->WorkstationName.Length = 0;
2437 SecurityBlob->WorkstationName.MaximumLength = 0;
2439 if (domain == NULL) {
2440 SecurityBlob->DomainName.Buffer = 0;
2441 SecurityBlob->DomainName.Length = 0;
2442 SecurityBlob->DomainName.MaximumLength = 0;
2445 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
2446 strncpy(bcc_ptr, domain, 63);
2447 len = strnlen(domain, 64);
2448 SecurityBlob->DomainName.MaximumLength =
2450 SecurityBlob->DomainName.Buffer =
2451 cpu_to_le32((long) &SecurityBlob->
2453 (long) &SecurityBlob->Signature);
2455 SecurityBlobLength += len;
2456 SecurityBlob->DomainName.Length =
2459 if (ses->capabilities & CAP_UNICODE) {
2460 if ((long) bcc_ptr % 2) {
2466 cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",
2468 bcc_ptr += 2 * bytes_returned;
2470 cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
2472 bcc_ptr += 2 * bytes_returned;
2473 bcc_ptr += 2; /* null terminate Linux version */
2475 cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS,
2477 bcc_ptr += 2 * bytes_returned;
2480 bcc_ptr += 2; /* null terminate network opsys string */
2483 bcc_ptr += 2; /* null domain */
2484 } else { /* ASCII */
2485 strcpy(bcc_ptr, "Linux version ");
2486 bcc_ptr += strlen("Linux version ");
2487 strcpy(bcc_ptr, system_utsname.release);
2488 bcc_ptr += strlen(system_utsname.release) + 1;
2489 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2490 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2491 bcc_ptr++; /* empty domain field */
2494 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2495 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2496 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2497 smb_buffer->smb_buf_length += count;
2498 pSMB->req.ByteCount = cpu_to_le16(count);
2500 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2501 &bytes_returned, 1);
2503 if (smb_buffer_response->Status.CifsError ==
2504 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2508 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2509 } else if ((smb_buffer_response->WordCount == 3)
2510 || (smb_buffer_response->WordCount == 4)) {
2511 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2512 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2514 if (action & GUEST_LOGIN)
2515 cFYI(1, (" Guest login"));
2516 /* Do we want to set anything in SesInfo struct when guest login? */
2518 bcc_ptr = pByteArea(smb_buffer_response);
2519 /* response can have either 3 or 4 word count - Samba sends 3 */
2521 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2522 if (SecurityBlob2->MessageType != NtLmChallenge) {
2524 ("Unexpected NTLMSSP message type received %d",
2525 SecurityBlob2->MessageType));
2527 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2528 cFYI(1, ("UID = %d ", ses->Suid));
2529 if ((pSMBr->resp.hdr.WordCount == 3)
2530 || ((pSMBr->resp.hdr.WordCount == 4)
2532 pSMBr->resp.ByteCount))) {
2534 if (pSMBr->resp.hdr.WordCount == 4) {
2535 bcc_ptr += blob_len;
2537 ("Security Blob Length %d ",
2541 cFYI(1, ("NTLMSSP Challenge rcvd "));
2543 memcpy(ses->server->cryptKey,
2544 SecurityBlob2->Challenge,
2545 CIFS_CRYPTO_KEY_SIZE);
2546 if(SecurityBlob2->NegotiateFlags & cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2547 *pNTLMv2_flag = TRUE;
2549 if((SecurityBlob2->NegotiateFlags &
2550 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2551 || (sign_CIFS_PDUs > 1))
2552 ses->server->secMode |=
2553 SECMODE_SIGN_REQUIRED;
2554 if ((SecurityBlob2->NegotiateFlags &
2555 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2556 ses->server->secMode |=
2557 SECMODE_SIGN_ENABLED;
2559 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2560 if ((long) (bcc_ptr) % 2) {
2562 (BCC(smb_buffer_response)
2564 bcc_ptr++; /* Unicode strings must be word aligned */
2568 (smb_buffer_response) / 2;
2571 UniStrnlen((wchar_t *) bcc_ptr,
2572 remaining_words - 1);
2573 /* We look for obvious messed up bcc or strings in response so we do not go off
2574 the end since (at least) WIN2K and Windows XP have a major bug in not null
2575 terminating last Unicode string in response */
2577 kcalloc(1, 2 * (len + 1), GFP_KERNEL);
2578 cifs_strfromUCS_le(ses->serverOS,
2582 bcc_ptr += 2 * (len + 1);
2583 remaining_words -= len + 1;
2584 ses->serverOS[2 * len] = 0;
2585 ses->serverOS[1 + (2 * len)] = 0;
2586 if (remaining_words > 0) {
2587 len = UniStrnlen((wchar_t *)
2592 kcalloc(1, 2 * (len + 1),
2594 cifs_strfromUCS_le(ses->
2600 bcc_ptr += 2 * (len + 1);
2601 ses->serverNOS[2 * len] = 0;
2604 remaining_words -= len + 1;
2605 if (remaining_words > 0) {
2606 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2607 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2632 } /* else no more room so create dummy domain string */
2637 } else { /* no room so create dummy domain and NOS string */
2639 kcalloc(1, 2, GFP_KERNEL);
2641 kcalloc(1, 2, GFP_KERNEL);
2643 } else { /* ASCII */
2644 len = strnlen(bcc_ptr, 1024);
2645 if (((long) bcc_ptr + len) - (long)
2646 pByteArea(smb_buffer_response)
2647 <= BCC(smb_buffer_response)) {
2651 strncpy(ses->serverOS,
2655 bcc_ptr[0] = 0; /* null terminate string */
2658 len = strnlen(bcc_ptr, 1024);
2662 strncpy(ses->serverNOS, bcc_ptr, len);
2667 len = strnlen(bcc_ptr, 1024);
2671 strncpy(ses->serverDomain, bcc_ptr, len);
2677 ("Variable field of length %d extends beyond end of smb ",
2682 (" Security Blob Length extends beyond end of SMB"));
2685 cERROR(1, ("No session structure passed in."));
2689 (" Invalid Word count %d: ",
2690 smb_buffer_response->WordCount));
2695 cifs_buf_release(smb_buffer);
2700 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2701 char *ntlm_session_key, int ntlmv2_flag,
2702 const struct nls_table *nls_codepage)
2704 struct smb_hdr *smb_buffer;
2705 struct smb_hdr *smb_buffer_response;
2706 SESSION_SETUP_ANDX *pSMB;
2707 SESSION_SETUP_ANDX *pSMBr;
2712 int remaining_words = 0;
2713 int bytes_returned = 0;
2715 int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
2716 PAUTHENTICATE_MESSAGE SecurityBlob;
2717 __u32 negotiate_flags, capabilities;
2720 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2723 user = ses->userName;
2724 domain = ses->domainName;
2725 smb_buffer = cifs_buf_get();
2726 if (smb_buffer == NULL) {
2729 smb_buffer_response = smb_buffer;
2730 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2731 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2733 /* send SMBsessionSetup here */
2734 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2735 NULL /* no tCon exists yet */ , 12 /* wct */ );
2736 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2737 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2738 pSMB->req.AndXCommand = 0xFF;
2739 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2740 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2742 pSMB->req.hdr.Uid = ses->Suid;
2744 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2745 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2747 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2748 CAP_EXTENDED_SECURITY;
2749 if (ses->capabilities & CAP_UNICODE) {
2750 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2751 capabilities |= CAP_UNICODE;
2753 if (ses->capabilities & CAP_STATUS32) {
2754 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2755 capabilities |= CAP_STATUS32;
2757 if (ses->capabilities & CAP_DFS) {
2758 smb_buffer->Flags2 |= SMBFLG2_DFS;
2759 capabilities |= CAP_DFS;
2761 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2763 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2764 SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
2765 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2766 SecurityBlob->MessageType = NtLmAuthenticate;
2767 bcc_ptr += SecurityBlobLength;
2769 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
2770 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
2771 0x80000000 | NTLMSSP_NEGOTIATE_128;
2773 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
2775 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2777 /* setup pointers to domain name and workstation name */
2779 SecurityBlob->WorkstationName.Buffer = 0;
2780 SecurityBlob->WorkstationName.Length = 0;
2781 SecurityBlob->WorkstationName.MaximumLength = 0;
2782 SecurityBlob->SessionKey.Length = 0;
2783 SecurityBlob->SessionKey.MaximumLength = 0;
2784 SecurityBlob->SessionKey.Buffer = 0;
2786 SecurityBlob->LmChallengeResponse.Length = 0;
2787 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
2788 SecurityBlob->LmChallengeResponse.Buffer = 0;
2790 SecurityBlob->NtChallengeResponse.Length =
2791 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
2792 SecurityBlob->NtChallengeResponse.MaximumLength =
2793 cpu_to_le16(CIFS_SESSION_KEY_SIZE);
2794 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESSION_KEY_SIZE);
2795 SecurityBlob->NtChallengeResponse.Buffer =
2796 cpu_to_le32(SecurityBlobLength);
2797 SecurityBlobLength += CIFS_SESSION_KEY_SIZE;
2798 bcc_ptr += CIFS_SESSION_KEY_SIZE;
2800 if (ses->capabilities & CAP_UNICODE) {
2801 if (domain == NULL) {
2802 SecurityBlob->DomainName.Buffer = 0;
2803 SecurityBlob->DomainName.Length = 0;
2804 SecurityBlob->DomainName.MaximumLength = 0;
2807 cifs_strtoUCS((wchar_t *) bcc_ptr, domain, 64,
2810 SecurityBlob->DomainName.MaximumLength =
2812 SecurityBlob->DomainName.Buffer =
2813 cpu_to_le32(SecurityBlobLength);
2815 SecurityBlobLength += len;
2816 SecurityBlob->DomainName.Length =
2820 SecurityBlob->UserName.Buffer = 0;
2821 SecurityBlob->UserName.Length = 0;
2822 SecurityBlob->UserName.MaximumLength = 0;
2825 cifs_strtoUCS((wchar_t *) bcc_ptr, user, 64,
2828 SecurityBlob->UserName.MaximumLength =
2830 SecurityBlob->UserName.Buffer =
2831 cpu_to_le32(SecurityBlobLength);
2833 SecurityBlobLength += len;
2834 SecurityBlob->UserName.Length =
2838 /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((wchar_t *) bcc_ptr, "AMACHINE",64, nls_codepage);
2839 SecurityBlob->WorkstationName.Length *= 2;
2840 SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length);
2841 SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength);
2842 bcc_ptr += SecurityBlob->WorkstationName.Length;
2843 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
2844 SecurityBlob->WorkstationName.Length = cpu_to_le16(SecurityBlob->WorkstationName.Length); */
2846 if ((long) bcc_ptr % 2) {
2851 cifs_strtoUCS((wchar_t *) bcc_ptr, "Linux version ",
2853 bcc_ptr += 2 * bytes_returned;
2855 cifs_strtoUCS((wchar_t *) bcc_ptr, system_utsname.release, 32,
2857 bcc_ptr += 2 * bytes_returned;
2858 bcc_ptr += 2; /* null term version string */
2860 cifs_strtoUCS((wchar_t *) bcc_ptr, CIFS_NETWORK_OPSYS,
2862 bcc_ptr += 2 * bytes_returned;
2865 bcc_ptr += 2; /* null terminate network opsys string */
2868 bcc_ptr += 2; /* null domain */
2869 } else { /* ASCII */
2870 if (domain == NULL) {
2871 SecurityBlob->DomainName.Buffer = 0;
2872 SecurityBlob->DomainName.Length = 0;
2873 SecurityBlob->DomainName.MaximumLength = 0;
2876 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
2877 strncpy(bcc_ptr, domain, 63);
2878 len = strnlen(domain, 64);
2879 SecurityBlob->DomainName.MaximumLength =
2881 SecurityBlob->DomainName.Buffer =
2882 cpu_to_le32(SecurityBlobLength);
2884 SecurityBlobLength += len;
2885 SecurityBlob->DomainName.Length = cpu_to_le16(len);
2888 SecurityBlob->UserName.Buffer = 0;
2889 SecurityBlob->UserName.Length = 0;
2890 SecurityBlob->UserName.MaximumLength = 0;
2893 strncpy(bcc_ptr, user, 63);
2894 len = strnlen(user, 64);
2895 SecurityBlob->UserName.MaximumLength =
2897 SecurityBlob->UserName.Buffer =
2898 cpu_to_le32(SecurityBlobLength);
2900 SecurityBlobLength += len;
2901 SecurityBlob->UserName.Length = cpu_to_le16(len);
2903 /* BB fill in our workstation name if known BB */
2905 strcpy(bcc_ptr, "Linux version ");
2906 bcc_ptr += strlen("Linux version ");
2907 strcpy(bcc_ptr, system_utsname.release);
2908 bcc_ptr += strlen(system_utsname.release) + 1;
2909 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2910 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2911 bcc_ptr++; /* null domain */
2914 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2915 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2916 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2917 smb_buffer->smb_buf_length += count;
2918 pSMB->req.ByteCount = cpu_to_le16(count);
2920 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2921 &bytes_returned, 1);
2923 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2924 } else if ((smb_buffer_response->WordCount == 3)
2925 || (smb_buffer_response->WordCount == 4)) {
2926 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2928 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2929 if (action & GUEST_LOGIN)
2930 cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */
2931 /* if(SecurityBlob2->MessageType != NtLm??){
2932 cFYI("Unexpected message type on auth response is %d "));
2936 ("Does UID on challenge %d match auth response UID %d ",
2937 ses->Suid, smb_buffer_response->Uid));
2938 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format */
2939 bcc_ptr = pByteArea(smb_buffer_response);
2940 /* response can have either 3 or 4 word count - Samba sends 3 */
2941 if ((pSMBr->resp.hdr.WordCount == 3)
2942 || ((pSMBr->resp.hdr.WordCount == 4)
2944 pSMBr->resp.ByteCount))) {
2945 if (pSMBr->resp.hdr.WordCount == 4) {
2949 ("Security Blob Length %d ",
2954 ("NTLMSSP response to Authenticate "));
2956 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2957 if ((long) (bcc_ptr) % 2) {
2959 (BCC(smb_buffer_response)
2961 bcc_ptr++; /* Unicode strings must be word aligned */
2963 remaining_words = BCC(smb_buffer_response) / 2;
2966 UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
2967 /* We look for obvious messed up bcc or strings in response so we do not go off
2968 the end since (at least) WIN2K and Windows XP have a major bug in not null
2969 terminating last Unicode string in response */
2971 kcalloc(1, 2 * (len + 1), GFP_KERNEL);
2972 cifs_strfromUCS_le(ses->serverOS,
2976 bcc_ptr += 2 * (len + 1);
2977 remaining_words -= len + 1;
2978 ses->serverOS[2 * len] = 0;
2979 ses->serverOS[1 + (2 * len)] = 0;
2980 if (remaining_words > 0) {
2981 len = UniStrnlen((wchar_t *)
2986 kcalloc(1, 2 * (len + 1),
2988 cifs_strfromUCS_le(ses->
2994 bcc_ptr += 2 * (len + 1);
2995 ses->serverNOS[2 * len] = 0;
2996 ses->serverNOS[1+(2*len)] = 0;
2997 remaining_words -= len + 1;
2998 if (remaining_words > 0) {
2999 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3000 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3025 } /* else no more room so create dummy domain string */
3027 ses->serverDomain = kcalloc(1, 2,GFP_KERNEL);
3028 } else { /* no room so create dummy domain and NOS string */
3029 ses->serverDomain = kcalloc(1, 2, GFP_KERNEL);
3030 ses->serverNOS = kcalloc(1, 2, GFP_KERNEL);
3032 } else { /* ASCII */
3033 len = strnlen(bcc_ptr, 1024);
3034 if (((long) bcc_ptr + len) -
3035 (long) pByteArea(smb_buffer_response)
3036 <= BCC(smb_buffer_response)) {
3037 ses->serverOS = kcalloc(1, len + 1,GFP_KERNEL);
3038 strncpy(ses->serverOS,bcc_ptr, len);
3041 bcc_ptr[0] = 0; /* null terminate the string */
3044 len = strnlen(bcc_ptr, 1024);
3045 ses->serverNOS = kcalloc(1, len+1,GFP_KERNEL);
3046 strncpy(ses->serverNOS, bcc_ptr, len);
3051 len = strnlen(bcc_ptr, 1024);
3052 ses->serverDomain = kcalloc(1, len+1,GFP_KERNEL);
3053 strncpy(ses->serverDomain, bcc_ptr, len);
3059 ("Variable field of length %d extends beyond end of smb ",
3064 (" Security Blob Length extends beyond end of SMB"));
3067 cERROR(1, ("No session structure passed in."));
3071 (" Invalid Word count %d: ",
3072 smb_buffer_response->WordCount));
3077 cifs_buf_release(smb_buffer);
3083 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3084 const char *tree, struct cifsTconInfo *tcon,
3085 const struct nls_table *nls_codepage)
3087 struct smb_hdr *smb_buffer;
3088 struct smb_hdr *smb_buffer_response;
3091 unsigned char *bcc_ptr;
3099 smb_buffer = cifs_buf_get();
3100 if (smb_buffer == NULL) {
3103 smb_buffer_response = smb_buffer;
3105 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3106 NULL /*no tid */ , 4 /*wct */ );
3107 smb_buffer->Uid = ses->Suid;
3108 pSMB = (TCONX_REQ *) smb_buffer;
3109 pSMBr = (TCONX_RSP *) smb_buffer_response;
3111 pSMB->AndXCommand = 0xFF;
3112 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3113 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3114 bcc_ptr = &pSMB->Password[0];
3115 bcc_ptr++; /* skip password */
3117 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3118 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3120 if (ses->capabilities & CAP_STATUS32) {
3121 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3123 if (ses->capabilities & CAP_DFS) {
3124 smb_buffer->Flags2 |= SMBFLG2_DFS;
3126 if (ses->capabilities & CAP_UNICODE) {
3127 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3129 cifs_strtoUCS((wchar_t *) bcc_ptr, tree, 100, nls_codepage);
3130 bcc_ptr += 2 * length; /* convert num of 16 bit words to bytes */
3131 bcc_ptr += 2; /* skip trailing null */
3132 } else { /* ASCII */
3134 strcpy(bcc_ptr, tree);
3135 bcc_ptr += strlen(tree) + 1;
3137 strcpy(bcc_ptr, "?????");
3138 bcc_ptr += strlen("?????");
3140 count = bcc_ptr - &pSMB->Password[0];
3141 pSMB->hdr.smb_buf_length += count;
3142 pSMB->ByteCount = cpu_to_le16(count);
3144 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
3146 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3147 /* above now done in SendReceive */
3148 if ((rc == 0) && (tcon != NULL)) {
3149 tcon->tidStatus = CifsGood;
3150 tcon->tid = smb_buffer_response->Tid;
3151 bcc_ptr = pByteArea(smb_buffer_response);
3152 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3153 /* skip service field (NB: this field is always ASCII) */
3154 bcc_ptr += length + 1;
3155 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3156 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3157 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3158 if ((bcc_ptr + (2 * length)) -
3159 pByteArea(smb_buffer_response) <=
3160 BCC(smb_buffer_response)) {
3161 if(tcon->nativeFileSystem)
3162 kfree(tcon->nativeFileSystem);
3163 tcon->nativeFileSystem =
3164 kcalloc(1, length + 2, GFP_KERNEL);
3165 cifs_strfromUCS_le(tcon->nativeFileSystem,
3166 (wchar_t *) bcc_ptr,
3167 length, nls_codepage);
3168 bcc_ptr += 2 * length;
3169 bcc_ptr[0] = 0; /* null terminate the string */
3173 /* else do not bother copying these informational fields */
3175 length = strnlen(bcc_ptr, 1024);
3176 if ((bcc_ptr + length) -
3177 pByteArea(smb_buffer_response) <=
3178 BCC(smb_buffer_response)) {
3179 if(tcon->nativeFileSystem)
3180 kfree(tcon->nativeFileSystem);
3181 tcon->nativeFileSystem =
3182 kcalloc(1, length + 1, GFP_KERNEL);
3183 strncpy(tcon->nativeFileSystem, bcc_ptr,
3186 /* else do not bother copying these informational fields */
3188 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3189 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3190 } else if ((rc == 0) && tcon == NULL) {
3191 /* all we need to save for IPC$ connection */
3192 ses->ipc_tid = smb_buffer_response->Tid;
3196 cifs_buf_release(smb_buffer);
3201 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3205 struct cifsSesInfo *ses = NULL;
3206 struct task_struct *cifsd_task;
3210 if (cifs_sb->tcon) {
3211 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3212 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3217 tconInfoFree(cifs_sb->tcon);
3218 if ((ses) && (ses->server)) {
3219 /* save off task so we do not refer to ses later */
3220 cifsd_task = ses->server->tsk;
3221 cFYI(1, ("About to do SMBLogoff "));
3222 rc = CIFSSMBLogoff(xid, ses);
3226 } else if (rc == -ESHUTDOWN) {
3227 cFYI(1,("Waking up socket by sending it signal"));
3229 send_sig(SIGKILL,cifsd_task,1);
3231 } /* else - we have an smb session
3232 left on this socket do not kill cifsd */
3234 cFYI(1, ("No session or bad tcon"));
3237 cifs_sb->tcon = NULL;
3239 set_current_state(TASK_INTERRUPTIBLE);
3240 schedule_timeout(HZ / 2);
3246 return rc; /* BB check if we should always return zero here */
3249 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3250 struct nls_table * nls_info)
3253 char ntlm_session_key[CIFS_SESSION_KEY_SIZE];
3254 int ntlmv2_flag = FALSE;
3257 /* what if server changes its buffer size after dropping the session? */
3258 if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
3259 rc = CIFSSMBNegotiate(xid, pSesInfo);
3260 if(rc == -EAGAIN) /* retry only once on 1st time connection */ {
3261 rc = CIFSSMBNegotiate(xid, pSesInfo);
3266 spin_lock(&GlobalMid_Lock);
3267 if(pSesInfo->server->tcpStatus != CifsExiting)
3268 pSesInfo->server->tcpStatus = CifsGood;
3271 spin_unlock(&GlobalMid_Lock);
3277 pSesInfo->capabilities = pSesInfo->server->capabilities;
3278 if(linuxExtEnabled == 0)
3279 pSesInfo->capabilities &= (~CAP_UNIX);
3280 /* pSesInfo->sequence_number = 0;*/
3281 cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d",
3282 pSesInfo->server->secMode,
3283 pSesInfo->server->capabilities,
3284 pSesInfo->server->timeZone));
3285 if (extended_security
3286 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3287 && (pSesInfo->server->secType == NTLMSSP)) {
3288 cFYI(1, ("New style sesssetup "));
3289 rc = CIFSSpnegoSessSetup(xid, pSesInfo,
3290 NULL /* security blob */,
3291 0 /* blob length */,
3293 } else if (extended_security
3294 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3295 && (pSesInfo->server->secType == RawNTLMSSP)) {
3296 cFYI(1, ("NTLMSSP sesssetup "));
3297 rc = CIFSNTLMSSPNegotiateSessSetup(xid,
3304 cFYI(1,("Can use more secure NTLM version 2 password hash"));
3305 if(CalcNTLMv2_partial_mac_key(pSesInfo,
3310 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
3312 CalcNTLMv2_response(pSesInfo,v2_response);
3314 cifs_calculate_ntlmv2_mac_key(
3315 pSesInfo->server->mac_signing_key,
3316 response, ntlm_session_key, */
3318 /* BB Put dummy sig in SessSetup PDU? */
3325 SMBNTencrypt(pSesInfo->password,
3326 pSesInfo->server->cryptKey,
3330 cifs_calculate_mac_key(
3331 pSesInfo->server->mac_signing_key,
3333 pSesInfo->password);
3335 /* for better security the weaker lanman hash not sent
3336 in AuthSessSetup so we no longer calculate it */
3338 rc = CIFSNTLMSSPAuthSessSetup(xid,
3344 } else { /* old style NTLM 0.12 session setup */
3345 SMBNTencrypt(pSesInfo->password,
3346 pSesInfo->server->cryptKey,
3350 cifs_calculate_mac_key(
3351 pSesInfo->server->mac_signing_key,
3352 ntlm_session_key, pSesInfo->password);
3354 rc = CIFSSessSetup(xid, pSesInfo,
3355 ntlm_session_key, nls_info);
3358 cERROR(1,("Send error in SessSetup = %d",rc));
3360 cFYI(1,("CIFS Session Established successfully"));
3361 pSesInfo->status = CifsGood;