4 * Copyright (C) International Business Machines Corp., 2002,2006
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 SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
55 extern mempool_t *cifs_req_poolp;
63 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
64 char *iocharset; /* local code page for mapping to and from Unicode */
65 char source_rfc1001_name[16]; /* netbios name of client */
66 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
77 unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
79 unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/
80 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
82 unsigned remap:1; /* set to remap seven reserved chars in filenames */
83 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
85 unsigned nullauth:1; /* attempt to authenticate with null user */
86 unsigned nocase; /* request case insensitive filenames */
87 unsigned nobrl; /* disable sending byte range locks to srv */
91 unsigned short int port;
95 static int ipv4_connect(struct sockaddr_in *psin_server,
96 struct socket **csocket,
98 char * server_netb_name);
99 static int ipv6_connect(struct sockaddr_in6 *psin_server,
100 struct socket **csocket);
104 * cifs tcp session reconnection
106 * mark tcp session as reconnecting so temporarily locked
107 * mark all smb sessions as reconnecting for tcp session
108 * reconnect tcp session
109 * wake up waiters on reconnection? - (not needed currently)
113 cifs_reconnect(struct TCP_Server_Info *server)
116 struct list_head *tmp;
117 struct cifsSesInfo *ses;
118 struct cifsTconInfo *tcon;
119 struct mid_q_entry * mid_entry;
121 spin_lock(&GlobalMid_Lock);
122 if(server->tcpStatus == CifsExiting) {
123 /* the demux thread will exit normally
124 next time through the loop */
125 spin_unlock(&GlobalMid_Lock);
128 server->tcpStatus = CifsNeedReconnect;
129 spin_unlock(&GlobalMid_Lock);
132 cFYI(1, ("Reconnecting tcp session"));
134 /* before reconnecting the tcp session, mark the smb session (uid)
135 and the tid bad so they are not used until reconnected */
136 read_lock(&GlobalSMBSeslock);
137 list_for_each(tmp, &GlobalSMBSessionList) {
138 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
140 if (ses->server == server) {
141 ses->status = CifsNeedReconnect;
145 /* else tcp and smb sessions need reconnection */
147 list_for_each(tmp, &GlobalTreeConnectionList) {
148 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
149 if((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
150 tcon->tidStatus = CifsNeedReconnect;
153 read_unlock(&GlobalSMBSeslock);
154 /* do not want to be sending data on a socket we are freeing */
155 down(&server->tcpSem);
156 if(server->ssocket) {
157 cFYI(1,("State: 0x%x Flags: 0x%lx", server->ssocket->state,
158 server->ssocket->flags));
159 server->ssocket->ops->shutdown(server->ssocket,SEND_SHUTDOWN);
160 cFYI(1,("Post shutdown state: 0x%x Flags: 0x%lx", server->ssocket->state,
161 server->ssocket->flags));
162 sock_release(server->ssocket);
163 server->ssocket = NULL;
166 spin_lock(&GlobalMid_Lock);
167 list_for_each(tmp, &server->pending_mid_q) {
168 mid_entry = list_entry(tmp, struct
172 if(mid_entry->midState == MID_REQUEST_SUBMITTED) {
173 /* Mark other intransit requests as needing
174 retry so we do not immediately mark the
175 session bad again (ie after we reconnect
176 below) as they timeout too */
177 mid_entry->midState = MID_RETRY_NEEDED;
181 spin_unlock(&GlobalMid_Lock);
184 while ((server->tcpStatus != CifsExiting) && (server->tcpStatus != CifsGood))
187 if(server->protocolType == IPV6) {
188 rc = ipv6_connect(&server->addr.sockAddr6,&server->ssocket);
190 rc = ipv4_connect(&server->addr.sockAddr,
192 server->workstation_RFC1001_name,
193 server->server_RFC1001_name);
196 cFYI(1,("reconnect error %d",rc));
199 atomic_inc(&tcpSesReconnectCount);
200 spin_lock(&GlobalMid_Lock);
201 if(server->tcpStatus != CifsExiting)
202 server->tcpStatus = CifsGood;
203 server->sequence_number = 0;
204 spin_unlock(&GlobalMid_Lock);
205 /* atomic_set(&server->inFlight,0);*/
206 wake_up(&server->response_q);
214 0 not a transact2, or all data present
215 >0 transact2 with that much data missing
216 -EINVAL = invalid transact2
219 static int check2ndT2(struct smb_hdr * pSMB, unsigned int maxBufSize)
221 struct smb_t2_rsp * pSMBt;
223 int data_in_this_rsp;
226 if(pSMB->Command != SMB_COM_TRANSACTION2)
229 /* check for plausible wct, bcc and t2 data and parm sizes */
230 /* check for parm and data offset going beyond end of smb */
231 if(pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
232 cFYI(1,("invalid transact2 word count"));
236 pSMBt = (struct smb_t2_rsp *)pSMB;
238 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
239 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
241 remaining = total_data_size - data_in_this_rsp;
245 else if(remaining < 0) {
246 cFYI(1,("total data %d smaller than data in frame %d",
247 total_data_size, data_in_this_rsp));
250 cFYI(1,("missing %d bytes from transact2, check next response",
252 if(total_data_size > maxBufSize) {
253 cERROR(1,("TotalDataSize %d is over maximum buffer %d",
254 total_data_size,maxBufSize));
261 static int coalesce_t2(struct smb_hdr * psecond, struct smb_hdr *pTargetSMB)
263 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
264 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
269 char * data_area_of_target;
270 char * data_area_of_buf2;
273 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
275 if(total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
276 cFYI(1,("total data sizes of primary and secondary t2 differ"));
279 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
281 remaining = total_data_size - total_in_buf;
286 if(remaining == 0) /* nothing to do, ignore */
289 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
290 if(remaining < total_in_buf2) {
291 cFYI(1,("transact2 2nd response contains too much data"));
294 /* find end of first SMB data area */
295 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
296 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
297 /* validate target area */
299 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
300 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
302 data_area_of_target += total_in_buf;
304 /* copy second buffer into end of first buffer */
305 memcpy(data_area_of_target,data_area_of_buf2,total_in_buf2);
306 total_in_buf += total_in_buf2;
307 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
308 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
309 byte_count += total_in_buf2;
310 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
312 byte_count = pTargetSMB->smb_buf_length;
313 byte_count += total_in_buf2;
315 /* BB also add check that we are not beyond maximum buffer size */
317 pTargetSMB->smb_buf_length = byte_count;
319 if(remaining == total_in_buf2) {
320 cFYI(1,("found the last secondary response"));
321 return 0; /* we are done */
322 } else /* more responses to go */
328 cifs_demultiplex_thread(struct TCP_Server_Info *server)
331 unsigned int pdu_length, total_read;
332 struct smb_hdr *smb_buffer = NULL;
333 struct smb_hdr *bigbuf = NULL;
334 struct smb_hdr *smallbuf = NULL;
335 struct msghdr smb_msg;
337 struct socket *csocket = server->ssocket;
338 struct list_head *tmp;
339 struct cifsSesInfo *ses;
340 struct task_struct *task_to_wake = NULL;
341 struct mid_q_entry *mid_entry;
343 int isLargeBuf = FALSE;
348 allow_signal(SIGKILL);
349 current->flags |= PF_MEMALLOC;
350 server->tsk = current; /* save process info to wake at shutdown */
351 cFYI(1, ("Demultiplex PID: %d", current->pid));
352 write_lock(&GlobalSMBSeslock);
353 atomic_inc(&tcpSesAllocCount);
354 length = tcpSesAllocCount.counter;
355 write_unlock(&GlobalSMBSeslock);
356 complete(&cifsd_complete);
358 mempool_resize(cifs_req_poolp,
359 length + cifs_min_rcv,
363 while (server->tcpStatus != CifsExiting) {
366 if (bigbuf == NULL) {
367 bigbuf = cifs_buf_get();
369 cERROR(1, ("No memory for large SMB response"));
371 /* retry will check if exiting */
374 } else if (isLargeBuf) {
375 /* we are reusing a dirty large buf, clear its start */
376 memset(bigbuf, 0, sizeof (struct smb_hdr));
379 if (smallbuf == NULL) {
380 smallbuf = cifs_small_buf_get();
382 cERROR(1, ("No memory for SMB response"));
384 /* retry will check if exiting */
387 /* beginning of smb buffer is cleared in our buf_get */
388 } else /* if existing small buf clear beginning */
389 memset(smallbuf, 0, sizeof (struct smb_hdr));
393 smb_buffer = smallbuf;
394 iov.iov_base = smb_buffer;
396 smb_msg.msg_control = NULL;
397 smb_msg.msg_controllen = 0;
399 kernel_recvmsg(csocket, &smb_msg,
400 &iov, 1, 4, 0 /* BB see socket.h flags */);
402 if (server->tcpStatus == CifsExiting) {
404 } else if (server->tcpStatus == CifsNeedReconnect) {
405 cFYI(1, ("Reconnect after server stopped responding"));
406 cifs_reconnect(server);
407 cFYI(1, ("call to reconnect done"));
408 csocket = server->ssocket;
410 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
411 msleep(1); /* minimum sleep to prevent looping
412 allowing socket to clear and app threads to set
413 tcpStatus CifsNeedReconnect if server hung */
415 } else if (length <= 0) {
416 if (server->tcpStatus == CifsNew) {
417 cFYI(1, ("tcp session abend after SMBnegprot"));
418 /* some servers kill the TCP session rather than
419 returning an SMB negprot error, in which
420 case reconnecting here is not going to help,
421 and so simply return error to mount */
424 if (!try_to_freeze() && (length == -EINTR)) {
425 cFYI(1,("cifsd thread killed"));
428 cFYI(1,("Reconnect after unexpected peek error %d",
430 cifs_reconnect(server);
431 csocket = server->ssocket;
432 wake_up(&server->response_q);
434 } else if (length < 4) {
436 ("Frame under four bytes received (%d bytes long)",
438 cifs_reconnect(server);
439 csocket = server->ssocket;
440 wake_up(&server->response_q);
444 /* The right amount was read from socket - 4 bytes */
445 /* so we can now interpret the length field */
447 /* the first byte big endian of the length field,
448 is actually not part of the length but the type
449 with the most common, zero, as regular data */
450 temp = *((char *) smb_buffer);
452 /* Note that FC 1001 length is big endian on the wire,
453 but we convert it here so it is always manipulated
454 as host byte order */
455 pdu_length = ntohl(smb_buffer->smb_buf_length);
456 smb_buffer->smb_buf_length = pdu_length;
458 cFYI(1,("rfc1002 length 0x%x)", pdu_length+4));
460 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
462 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
463 cFYI(1,("Good RFC 1002 session rsp"));
465 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
466 /* we get this from Windows 98 instead of
467 an error on SMB negprot response */
468 cFYI(1,("Negative RFC1002 Session Response Error 0x%x)",
470 if(server->tcpStatus == CifsNew) {
471 /* if nack on negprot (rather than
472 ret of smb negprot error) reconnecting
473 not going to help, ret error to mount */
476 /* give server a second to
477 clean up before reconnect attempt */
479 /* always try 445 first on reconnect
480 since we get NACK on some if we ever
481 connected to port 139 (the NACK is
482 since we do not begin with RFC1001
483 session initialize frame) */
484 server->addr.sockAddr.sin_port =
486 cifs_reconnect(server);
487 csocket = server->ssocket;
488 wake_up(&server->response_q);
491 } else if (temp != (char) 0) {
492 cERROR(1,("Unknown RFC 1002 frame"));
493 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
495 cifs_reconnect(server);
496 csocket = server->ssocket;
500 /* else we have an SMB response */
501 if((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
502 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
503 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
504 length, pdu_length+4));
505 cifs_reconnect(server);
506 csocket = server->ssocket;
507 wake_up(&server->response_q);
514 if(pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
516 memcpy(bigbuf, smallbuf, 4);
520 iov.iov_base = 4 + (char *)smb_buffer;
521 iov.iov_len = pdu_length;
522 for (total_read = 0; total_read < pdu_length;
523 total_read += length) {
524 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
525 pdu_length - total_read, 0);
526 if((server->tcpStatus == CifsExiting) ||
527 (length == -EINTR)) {
531 } else if (server->tcpStatus == CifsNeedReconnect) {
532 cifs_reconnect(server);
533 csocket = server->ssocket;
534 /* Reconnect wakes up rspns q */
535 /* Now we will reread sock */
538 } else if ((length == -ERESTARTSYS) ||
539 (length == -EAGAIN)) {
540 msleep(1); /* minimum sleep to prevent looping,
541 allowing socket to clear and app
542 threads to set tcpStatus
543 CifsNeedReconnect if server hung*/
545 } else if (length <= 0) {
546 cERROR(1,("Received no data, expecting %d",
547 pdu_length - total_read));
548 cifs_reconnect(server);
549 csocket = server->ssocket;
556 else if(reconnect == 1)
559 length += 4; /* account for rfc1002 hdr */
562 dump_smb(smb_buffer, length);
563 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
564 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
570 spin_lock(&GlobalMid_Lock);
571 list_for_each(tmp, &server->pending_mid_q) {
572 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
574 if ((mid_entry->mid == smb_buffer->Mid) &&
575 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
576 (mid_entry->command == smb_buffer->Command)) {
577 if(check2ndT2(smb_buffer,server->maxBuf) > 0) {
578 /* We have a multipart transact2 resp */
580 if(mid_entry->resp_buf) {
581 /* merge response - fix up 1st*/
582 if(coalesce_t2(smb_buffer,
583 mid_entry->resp_buf)) {
584 mid_entry->multiRsp = 1;
587 /* all parts received */
588 mid_entry->multiEnd = 1;
593 cERROR(1,("1st trans2 resp needs bigbuf"));
594 /* BB maybe we can fix this up, switch
595 to already allocated large buffer? */
597 /* Have first buffer */
598 mid_entry->resp_buf =
600 mid_entry->largeBuf = 1;
606 mid_entry->resp_buf = smb_buffer;
608 mid_entry->largeBuf = 1;
610 mid_entry->largeBuf = 0;
612 task_to_wake = mid_entry->tsk;
613 mid_entry->midState = MID_RESPONSE_RECEIVED;
614 #ifdef CONFIG_CIFS_STATS2
615 mid_entry->when_received = jiffies;
617 /* so we do not time out requests to server
618 which is still responding (since server could
619 be busy but not dead) */
620 server->lstrp = jiffies;
624 spin_unlock(&GlobalMid_Lock);
626 /* Was previous buf put in mpx struct for multi-rsp? */
628 /* smb buffer will be freed by user thread */
634 wake_up_process(task_to_wake);
635 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE)
636 && (isMultiRsp == FALSE)) {
637 cERROR(1, ("No task to wake, unknown frame rcvd! NumMids %d", midCount.counter));
638 cifs_dump_mem("Received Data is: ",(char *)smb_buffer,
639 sizeof(struct smb_hdr));
640 #ifdef CONFIG_CIFS_DEBUG2
641 cifs_dump_detail(smb_buffer);
642 cifs_dump_mids(server);
643 #endif /* CIFS_DEBUG2 */
646 } /* end while !EXITING */
648 spin_lock(&GlobalMid_Lock);
649 server->tcpStatus = CifsExiting;
651 /* check if we have blocked requests that need to free */
652 /* Note that cifs_max_pending is normally 50, but
653 can be set at module install time to as little as two */
654 if(atomic_read(&server->inFlight) >= cifs_max_pending)
655 atomic_set(&server->inFlight, cifs_max_pending - 1);
656 /* We do not want to set the max_pending too low or we
657 could end up with the counter going negative */
658 spin_unlock(&GlobalMid_Lock);
659 /* Although there should not be any requests blocked on
660 this queue it can not hurt to be paranoid and try to wake up requests
661 that may haven been blocked when more than 50 at time were on the wire
662 to the same server - they now will see the session is in exit state
663 and get out of SendReceive. */
664 wake_up_all(&server->request_q);
665 /* give those requests time to exit */
668 if(server->ssocket) {
669 sock_release(csocket);
670 server->ssocket = NULL;
672 /* buffer usuallly freed in free_mid - need to free it here on exit */
674 cifs_buf_release(bigbuf);
675 if (smallbuf != NULL)
676 cifs_small_buf_release(smallbuf);
678 read_lock(&GlobalSMBSeslock);
679 if (list_empty(&server->pending_mid_q)) {
680 /* loop through server session structures attached to this and
682 list_for_each(tmp, &GlobalSMBSessionList) {
684 list_entry(tmp, struct cifsSesInfo,
686 if (ses->server == server) {
687 ses->status = CifsExiting;
691 read_unlock(&GlobalSMBSeslock);
693 /* although we can not zero the server struct pointer yet,
694 since there are active requests which may depnd on them,
695 mark the corresponding SMB sessions as exiting too */
696 list_for_each(tmp, &GlobalSMBSessionList) {
697 ses = list_entry(tmp, struct cifsSesInfo,
699 if (ses->server == server) {
700 ses->status = CifsExiting;
704 spin_lock(&GlobalMid_Lock);
705 list_for_each(tmp, &server->pending_mid_q) {
706 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
707 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
709 ("Clearing Mid 0x%x - waking up ",mid_entry->mid));
710 task_to_wake = mid_entry->tsk;
712 wake_up_process(task_to_wake);
716 spin_unlock(&GlobalMid_Lock);
717 read_unlock(&GlobalSMBSeslock);
718 /* 1/8th of sec is more than enough time for them to exit */
722 if (!list_empty(&server->pending_mid_q)) {
723 /* mpx threads have not exited yet give them
724 at least the smb send timeout time for long ops */
725 /* due to delays on oplock break requests, we need
726 to wait at least 45 seconds before giving up
727 on a request getting a response and going ahead
729 cFYI(1, ("Wait for exit from demultiplex thread"));
731 /* if threads still have not exited they are probably never
732 coming home not much else we can do but free the memory */
735 write_lock(&GlobalSMBSeslock);
736 atomic_dec(&tcpSesAllocCount);
737 length = tcpSesAllocCount.counter;
739 /* last chance to mark ses pointers invalid
740 if there are any pointing to this (e.g
741 if a crazy root user tried to kill cifsd
742 kernel thread explicitly this might happen) */
743 list_for_each(tmp, &GlobalSMBSessionList) {
744 ses = list_entry(tmp, struct cifsSesInfo,
746 if (ses->server == server) {
750 write_unlock(&GlobalSMBSeslock);
754 mempool_resize(cifs_req_poolp,
755 length + cifs_min_rcv,
759 complete_and_exit(&cifsd_complete, 0);
764 cifs_parse_mount_options(char *options, const char *devname,struct smb_vol *vol)
768 unsigned int temp_len, i, j;
774 memset(vol->source_rfc1001_name,0x20,15);
775 for(i=0;i < strnlen(system_utsname.nodename,15);i++) {
776 /* does not have to be a perfect mapping since the field is
777 informational, only used for servers that do not support
778 port 445 and it can be overridden at mount time */
779 vol->source_rfc1001_name[i] =
780 toupper(system_utsname.nodename[i]);
782 vol->source_rfc1001_name[15] = 0;
783 /* null target name indicates to use *SMBSERVR default called name
784 if we end up sending RFC1001 session initialize */
785 vol->target_rfc1001_name[0] = 0;
786 vol->linux_uid = current->uid; /* current->euid instead? */
787 vol->linux_gid = current->gid;
788 vol->dir_mode = S_IRWXUGO;
789 /* 2767 perms indicate mandatory locking support */
790 vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
792 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
794 /* default is always to request posix paths. */
795 vol->posix_paths = 1;
800 if(strncmp(options,"sep=",4) == 0) {
801 if(options[4] != 0) {
802 separator[0] = options[4];
805 cFYI(1,("Null separator not allowed"));
809 while ((data = strsep(&options, separator)) != NULL) {
812 if ((value = strchr(data, '=')) != NULL)
815 if (strnicmp(data, "user_xattr",10) == 0) {/*parse before user*/
817 } else if (strnicmp(data, "nouser_xattr",12) == 0) {
819 } else if (strnicmp(data, "user", 4) == 0) {
820 if (!value || !*value) {
822 "CIFS: invalid or missing username\n");
823 return 1; /* needs_arg; */
825 if (strnlen(value, 200) < 200) {
826 vol->username = value;
828 printk(KERN_WARNING "CIFS: username too long\n");
831 } else if (strnicmp(data, "pass", 4) == 0) {
833 vol->password = NULL;
835 } else if(value[0] == 0) {
836 /* check if string begins with double comma
837 since that would mean the password really
838 does start with a comma, and would not
839 indicate an empty string */
840 if(value[1] != separator[0]) {
841 vol->password = NULL;
845 temp_len = strlen(value);
846 /* removed password length check, NTLM passwords
847 can be arbitrarily long */
849 /* if comma in password, the string will be
850 prematurely null terminated. Commas in password are
851 specified across the cifs mount interface by a double
852 comma ie ,, and a comma used as in other cases ie ','
853 as a parameter delimiter/separator is single and due
854 to the strsep above is temporarily zeroed. */
856 /* NB: password legally can have multiple commas and
857 the only illegal character in a password is null */
859 if ((value[temp_len] == 0) &&
860 (value[temp_len+1] == separator[0])) {
862 value[temp_len] = separator[0];
863 temp_len+=2; /* move after the second comma */
864 while(value[temp_len] != 0) {
865 if (value[temp_len] == separator[0]) {
866 if (value[temp_len+1] ==
868 /* skip second comma */
871 /* single comma indicating start
878 if(value[temp_len] == 0) {
882 /* point option to start of next parm */
883 options = value + temp_len + 1;
885 /* go from value to value + temp_len condensing
886 double commas to singles. Note that this ends up
887 allocating a few bytes too many, which is ok */
888 vol->password = kzalloc(temp_len, GFP_KERNEL);
889 if(vol->password == NULL) {
890 printk("CIFS: no memory for pass\n");
893 for(i=0,j=0;i<temp_len;i++,j++) {
894 vol->password[j] = value[i];
895 if(value[i] == separator[0]
896 && value[i+1] == separator[0]) {
897 /* skip second comma */
901 vol->password[j] = 0;
903 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
904 if(vol->password == NULL) {
905 printk("CIFS: no memory for pass\n");
908 strcpy(vol->password, value);
910 } else if (strnicmp(data, "ip", 2) == 0) {
911 if (!value || !*value) {
913 } else if (strnlen(value, 35) < 35) {
916 printk(KERN_WARNING "CIFS: ip address too long\n");
919 } else if (strnicmp(data, "sec", 3) == 0) {
920 if (!value || !*value) {
921 cERROR(1,("no security value specified"));
923 } else if (strnicmp(value, "krb5i", 5) == 0) {
924 vol->secFlg |= CIFSSEC_MAY_KRB5 |
926 } else if (strnicmp(value, "krb5p", 5) == 0) {
927 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
929 cERROR(1,("Krb5 cifs privacy not supported"));
931 } else if (strnicmp(value, "krb5", 4) == 0) {
932 vol->secFlg |= CIFSSEC_MAY_KRB5;
933 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
934 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
936 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
937 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
938 } else if (strnicmp(value, "ntlmi", 5) == 0) {
939 vol->secFlg |= CIFSSEC_MAY_NTLM |
941 } else if (strnicmp(value, "ntlm", 4) == 0) {
942 /* ntlm is default so can be turned off too */
943 vol->secFlg |= CIFSSEC_MAY_NTLM;
944 } else if (strnicmp(value, "nontlm", 6) == 0) {
945 /* BB is there a better way to do this? */
946 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
947 #ifdef CONFIG_CIFS_WEAK_PW_HASH
948 } else if (strnicmp(value, "lanman", 6) == 0) {
949 vol->secFlg |= CIFSSEC_MAY_LANMAN;
951 } else if (strnicmp(value, "none", 4) == 0) {
954 cERROR(1,("bad security option: %s", value));
957 } else if ((strnicmp(data, "unc", 3) == 0)
958 || (strnicmp(data, "target", 6) == 0)
959 || (strnicmp(data, "path", 4) == 0)) {
960 if (!value || !*value) {
962 "CIFS: invalid path to network resource\n");
963 return 1; /* needs_arg; */
965 if ((temp_len = strnlen(value, 300)) < 300) {
966 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
969 strcpy(vol->UNC,value);
970 if (strncmp(vol->UNC, "//", 2) == 0) {
973 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
975 "CIFS: UNC Path does not begin with // or \\\\ \n");
979 printk(KERN_WARNING "CIFS: UNC name too long\n");
982 } else if ((strnicmp(data, "domain", 3) == 0)
983 || (strnicmp(data, "workgroup", 5) == 0)) {
984 if (!value || !*value) {
985 printk(KERN_WARNING "CIFS: invalid domain name\n");
986 return 1; /* needs_arg; */
988 /* BB are there cases in which a comma can be valid in
989 a domain name and need special handling? */
990 if (strnlen(value, 256) < 256) {
991 vol->domainname = value;
992 cFYI(1, ("Domain name set"));
994 printk(KERN_WARNING "CIFS: domain name too long\n");
997 } else if (strnicmp(data, "prefixpath", 10) == 0) {
998 if (!value || !*value) {
1000 "CIFS: invalid path prefix\n");
1001 return 1; /* needs_arg; */
1003 if ((temp_len = strnlen(value, 1024)) < 1024) {
1005 temp_len++; /* missing leading slash */
1006 vol->prepath = kmalloc(temp_len+1,GFP_KERNEL);
1007 if(vol->prepath == NULL)
1009 if(value[0] != '/') {
1010 vol->prepath[0] = '/';
1011 strcpy(vol->prepath+1,value);
1013 strcpy(vol->prepath,value);
1014 cFYI(1,("prefix path %s",vol->prepath));
1016 printk(KERN_WARNING "CIFS: prefix too long\n");
1019 } else if (strnicmp(data, "iocharset", 9) == 0) {
1020 if (!value || !*value) {
1021 printk(KERN_WARNING "CIFS: invalid iocharset specified\n");
1022 return 1; /* needs_arg; */
1024 if (strnlen(value, 65) < 65) {
1025 if(strnicmp(value,"default",7))
1026 vol->iocharset = value;
1027 /* if iocharset not set load_nls_default used by caller */
1028 cFYI(1, ("iocharset set to %s",value));
1030 printk(KERN_WARNING "CIFS: iocharset name too long.\n");
1033 } else if (strnicmp(data, "uid", 3) == 0) {
1034 if (value && *value) {
1036 simple_strtoul(value, &value, 0);
1038 } else if (strnicmp(data, "gid", 3) == 0) {
1039 if (value && *value) {
1041 simple_strtoul(value, &value, 0);
1043 } else if (strnicmp(data, "file_mode", 4) == 0) {
1044 if (value && *value) {
1046 simple_strtoul(value, &value, 0);
1048 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1049 if (value && *value) {
1051 simple_strtoul(value, &value, 0);
1053 } else if (strnicmp(data, "dirmode", 4) == 0) {
1054 if (value && *value) {
1056 simple_strtoul(value, &value, 0);
1058 } else if (strnicmp(data, "port", 4) == 0) {
1059 if (value && *value) {
1061 simple_strtoul(value, &value, 0);
1063 } else if (strnicmp(data, "rsize", 5) == 0) {
1064 if (value && *value) {
1066 simple_strtoul(value, &value, 0);
1068 } else if (strnicmp(data, "wsize", 5) == 0) {
1069 if (value && *value) {
1071 simple_strtoul(value, &value, 0);
1073 } else if (strnicmp(data, "sockopt", 5) == 0) {
1074 if (value && *value) {
1076 simple_strtoul(value, &value, 0);
1078 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1079 if (!value || !*value || (*value == ' ')) {
1080 cFYI(1,("invalid (empty) netbiosname specified"));
1082 memset(vol->source_rfc1001_name,0x20,15);
1084 /* BB are there cases in which a comma can be
1085 valid in this workstation netbios name (and need
1086 special handling)? */
1088 /* We do not uppercase netbiosname for user */
1092 vol->source_rfc1001_name[i] = value[i];
1094 /* The string has 16th byte zero still from
1095 set at top of the function */
1096 if((i==15) && (value[i] != 0))
1097 printk(KERN_WARNING "CIFS: netbiosname longer than 15 truncated.\n");
1099 } else if (strnicmp(data, "servern", 7) == 0) {
1100 /* servernetbiosname specified override *SMBSERVER */
1101 if (!value || !*value || (*value == ' ')) {
1102 cFYI(1,("empty server netbiosname specified"));
1104 /* last byte, type, is 0x20 for servr type */
1105 memset(vol->target_rfc1001_name,0x20,16);
1108 /* BB are there cases in which a comma can be
1109 valid in this workstation netbios name (and need
1110 special handling)? */
1112 /* user or mount helper must uppercase netbiosname */
1116 vol->target_rfc1001_name[i] = value[i];
1118 /* The string has 16th byte zero still from
1119 set at top of the function */
1120 if((i==15) && (value[i] != 0))
1121 printk(KERN_WARNING "CIFS: server netbiosname longer than 15 truncated.\n");
1123 } else if (strnicmp(data, "credentials", 4) == 0) {
1125 } else if (strnicmp(data, "version", 3) == 0) {
1127 } else if (strnicmp(data, "guest",5) == 0) {
1129 } else if (strnicmp(data, "rw", 2) == 0) {
1131 } else if ((strnicmp(data, "suid", 4) == 0) ||
1132 (strnicmp(data, "nosuid", 6) == 0) ||
1133 (strnicmp(data, "exec", 4) == 0) ||
1134 (strnicmp(data, "noexec", 6) == 0) ||
1135 (strnicmp(data, "nodev", 5) == 0) ||
1136 (strnicmp(data, "noauto", 6) == 0) ||
1137 (strnicmp(data, "dev", 3) == 0)) {
1138 /* The mount tool or mount.cifs helper (if present)
1139 uses these opts to set flags, and the flags are read
1140 by the kernel vfs layer before we get here (ie
1141 before read super) so there is no point trying to
1142 parse these options again and set anything and it
1143 is ok to just ignore them */
1145 } else if (strnicmp(data, "ro", 2) == 0) {
1147 } else if (strnicmp(data, "hard", 4) == 0) {
1149 } else if (strnicmp(data, "soft", 4) == 0) {
1151 } else if (strnicmp(data, "perm", 4) == 0) {
1153 } else if (strnicmp(data, "noperm", 6) == 0) {
1155 } else if (strnicmp(data, "mapchars", 8) == 0) {
1157 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1159 } else if (strnicmp(data, "sfu", 3) == 0) {
1161 } else if (strnicmp(data, "nosfu", 5) == 0) {
1163 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1164 vol->posix_paths = 1;
1165 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1166 vol->posix_paths = 0;
1167 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1168 (strnicmp(data, "ignorecase", 10) == 0)) {
1170 } else if (strnicmp(data, "brl", 3) == 0) {
1172 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1173 (strnicmp(data, "nolock", 6) == 0)) {
1175 /* turn off mandatory locking in mode
1176 if remote locking is turned off since the
1177 local vfs will do advisory */
1178 if(vol->file_mode == (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1179 vol->file_mode = S_IALLUGO;
1180 } else if (strnicmp(data, "setuids", 7) == 0) {
1182 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1184 } else if (strnicmp(data, "nohard", 6) == 0) {
1186 } else if (strnicmp(data, "nosoft", 6) == 0) {
1188 } else if (strnicmp(data, "nointr", 6) == 0) {
1190 } else if (strnicmp(data, "intr", 4) == 0) {
1192 } else if (strnicmp(data, "serverino",7) == 0) {
1193 vol->server_ino = 1;
1194 } else if (strnicmp(data, "noserverino",9) == 0) {
1195 vol->server_ino = 0;
1196 } else if (strnicmp(data, "cifsacl",7) == 0) {
1198 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1200 } else if (strnicmp(data, "acl",3) == 0) {
1201 vol->no_psx_acl = 0;
1202 } else if (strnicmp(data, "noacl",5) == 0) {
1203 vol->no_psx_acl = 1;
1204 } else if (strnicmp(data, "sign",4) == 0) {
1205 vol->secFlg |= CIFSSEC_MUST_SIGN;
1206 /* } else if (strnicmp(data, "seal",4) == 0) {
1207 vol->secFlg |= CIFSSEC_MUST_SEAL; */
1208 } else if (strnicmp(data, "direct",6) == 0) {
1210 } else if (strnicmp(data, "forcedirectio",13) == 0) {
1212 } else if (strnicmp(data, "in6_addr",8) == 0) {
1213 if (!value || !*value) {
1214 vol->in6_addr = NULL;
1215 } else if (strnlen(value, 49) == 48) {
1216 vol->in6_addr = value;
1218 printk(KERN_WARNING "CIFS: ip v6 address not 48 characters long\n");
1221 } else if (strnicmp(data, "noac", 4) == 0) {
1222 printk(KERN_WARNING "CIFS: Mount option noac not supported. Instead set /proc/fs/cifs/LookupCacheEnabled to 0\n");
1224 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",data);
1226 if (vol->UNC == NULL) {
1227 if(devname == NULL) {
1228 printk(KERN_WARNING "CIFS: Missing UNC name for mount target\n");
1231 if ((temp_len = strnlen(devname, 300)) < 300) {
1232 vol->UNC = kmalloc(temp_len+1,GFP_KERNEL);
1233 if(vol->UNC == NULL)
1235 strcpy(vol->UNC,devname);
1236 if (strncmp(vol->UNC, "//", 2) == 0) {
1239 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1240 printk(KERN_WARNING "CIFS: UNC Path does not begin with // or \\\\ \n");
1244 printk(KERN_WARNING "CIFS: UNC name too long\n");
1248 if(vol->UNCip == NULL)
1249 vol->UNCip = &vol->UNC[2];
1254 static struct cifsSesInfo *
1255 cifs_find_tcp_session(struct in_addr * target_ip_addr,
1256 struct in6_addr *target_ip6_addr,
1257 char *userName, struct TCP_Server_Info **psrvTcp)
1259 struct list_head *tmp;
1260 struct cifsSesInfo *ses;
1262 read_lock(&GlobalSMBSeslock);
1264 list_for_each(tmp, &GlobalSMBSessionList) {
1265 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1267 if((target_ip_addr &&
1268 (ses->server->addr.sockAddr.sin_addr.s_addr
1269 == target_ip_addr->s_addr)) || (target_ip6_addr
1270 && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1271 target_ip6_addr,sizeof(*target_ip6_addr)))){
1272 /* BB lock server and tcp session and increment use count here?? */
1273 *psrvTcp = ses->server; /* found a match on the TCP session */
1274 /* BB check if reconnection needed */
1276 (ses->userName, userName,
1277 MAX_USERNAME_SIZE) == 0){
1278 read_unlock(&GlobalSMBSeslock);
1279 return ses; /* found exact match on both tcp and SMB sessions */
1283 /* else tcp and smb sessions need reconnection */
1285 read_unlock(&GlobalSMBSeslock);
1289 static struct cifsTconInfo *
1290 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1292 struct list_head *tmp;
1293 struct cifsTconInfo *tcon;
1295 read_lock(&GlobalSMBSeslock);
1296 list_for_each(tmp, &GlobalTreeConnectionList) {
1297 cFYI(1, ("Next tcon"));
1298 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1300 if (tcon->ses->server) {
1302 ("old ip addr: %x == new ip %x ?",
1303 tcon->ses->server->addr.sockAddr.sin_addr.
1304 s_addr, new_target_ip_addr));
1305 if (tcon->ses->server->addr.sockAddr.sin_addr.
1306 s_addr == new_target_ip_addr) {
1307 /* BB lock tcon, server and tcp session and increment use count here? */
1308 /* found a match on the TCP session */
1309 /* BB check if reconnection needed */
1310 cFYI(1,("IP match, old UNC: %s new: %s",
1311 tcon->treeName, uncName));
1313 (tcon->treeName, uncName,
1314 MAX_TREE_SIZE) == 0) {
1316 ("and old usr: %s new: %s",
1317 tcon->treeName, uncName));
1319 (tcon->ses->userName,
1321 MAX_USERNAME_SIZE) == 0) {
1322 read_unlock(&GlobalSMBSeslock);
1323 /* matched smb session
1332 read_unlock(&GlobalSMBSeslock);
1337 connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1338 const char *old_path, const struct nls_table *nls_codepage,
1341 unsigned char *referrals = NULL;
1342 unsigned int num_referrals;
1345 rc = get_dfs_path(xid, pSesInfo,old_path, nls_codepage,
1346 &num_referrals, &referrals, remap);
1348 /* BB Add in code to: if valid refrl, if not ip address contact
1349 the helper that resolves tcp names, mount to it, try to
1350 tcon to it unmount it if fail */
1358 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1359 const char *old_path, const struct nls_table *nls_codepage,
1360 unsigned int *pnum_referrals,
1361 unsigned char ** preferrals, int remap)
1366 *pnum_referrals = 0;
1368 if (pSesInfo->ipc_tid == 0) {
1369 temp_unc = kmalloc(2 /* for slashes */ +
1370 strnlen(pSesInfo->serverName,SERVER_NAME_LEN_WITH_NULL * 2)
1371 + 1 + 4 /* slash IPC$ */ + 2,
1373 if (temp_unc == NULL)
1377 strcpy(temp_unc + 2, pSesInfo->serverName);
1378 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1379 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1381 ("CIFS Tcon rc = %d ipc_tid = %d", rc,pSesInfo->ipc_tid));
1385 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1386 pnum_referrals, nls_codepage, remap);
1391 /* See RFC1001 section 14 on representation of Netbios names */
1392 static void rfc1002mangle(char * target,char * source, unsigned int length)
1396 for(i=0,j=0;i<(length);i++) {
1397 /* mask a nibble at a time and encode */
1398 target[j] = 'A' + (0x0F & (source[i] >> 4));
1399 target[j+1] = 'A' + (0x0F & source[i]);
1407 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1408 char * netbios_name, char * target_name)
1412 __be16 orig_port = 0;
1414 if(*csocket == NULL) {
1415 rc = sock_create_kern(PF_INET, SOCK_STREAM, IPPROTO_TCP, csocket);
1417 cERROR(1, ("Error %d creating socket",rc));
1421 /* BB other socket options to set KEEPALIVE, NODELAY? */
1422 cFYI(1,("Socket created"));
1423 (*csocket)->sk->sk_allocation = GFP_NOFS;
1427 psin_server->sin_family = AF_INET;
1428 if(psin_server->sin_port) { /* user overrode default port */
1429 rc = (*csocket)->ops->connect(*csocket,
1430 (struct sockaddr *) psin_server,
1431 sizeof (struct sockaddr_in),0);
1437 /* save original port so we can retry user specified port
1438 later if fall back ports fail this time */
1439 orig_port = psin_server->sin_port;
1441 /* do not retry on the same port we just failed on */
1442 if(psin_server->sin_port != htons(CIFS_PORT)) {
1443 psin_server->sin_port = htons(CIFS_PORT);
1445 rc = (*csocket)->ops->connect(*csocket,
1446 (struct sockaddr *) psin_server,
1447 sizeof (struct sockaddr_in),0);
1453 psin_server->sin_port = htons(RFC1001_PORT);
1454 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1455 psin_server, sizeof (struct sockaddr_in),0);
1460 /* give up here - unless we want to retry on different
1461 protocol families some day */
1464 psin_server->sin_port = orig_port;
1465 cFYI(1,("Error %d connecting to server via ipv4",rc));
1466 sock_release(*csocket);
1470 /* Eventually check for other socket options to change from
1471 the default. sock_setsockopt not used because it expects
1472 user space buffer */
1473 cFYI(1,("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",(*csocket)->sk->sk_sndbuf,
1474 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1475 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1476 /* make the bufsizes depend on wsize/rsize and max requests */
1477 if((*csocket)->sk->sk_sndbuf < (200 * 1024))
1478 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1479 if((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1480 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1482 /* send RFC1001 sessinit */
1483 if(psin_server->sin_port == htons(RFC1001_PORT)) {
1484 /* some servers require RFC1001 sessinit before sending
1485 negprot - BB check reconnection in case where second
1486 sessinit is sent but no second negprot */
1487 struct rfc1002_session_packet * ses_init_buf;
1488 struct smb_hdr * smb_buf;
1489 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet), GFP_KERNEL);
1491 ses_init_buf->trailer.session_req.called_len = 32;
1492 if(target_name && (target_name[0] != 0)) {
1493 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1496 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1497 DEFAULT_CIFS_CALLED_NAME,16);
1500 ses_init_buf->trailer.session_req.calling_len = 32;
1501 /* calling name ends in null (byte 16) from old smb
1503 if(netbios_name && (netbios_name[0] !=0)) {
1504 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1507 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1508 "LINUX_CIFS_CLNT",16);
1510 ses_init_buf->trailer.session_req.scope1 = 0;
1511 ses_init_buf->trailer.session_req.scope2 = 0;
1512 smb_buf = (struct smb_hdr *)ses_init_buf;
1513 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1514 smb_buf->smb_buf_length = 0x81000044;
1515 rc = smb_send(*csocket, smb_buf, 0x44,
1516 (struct sockaddr *)psin_server);
1517 kfree(ses_init_buf);
1518 msleep(1); /* RFC1001 layer in at least one server
1519 requires very short break before negprot
1520 presumably because not expecting negprot
1521 to follow so fast. This is a simple
1522 solution that works without
1523 complicating the code and causes no
1524 significant slowing down on mount
1525 for everyone else */
1527 /* else the negprot may still work without this
1528 even though malloc failed */
1536 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1540 __be16 orig_port = 0;
1542 if(*csocket == NULL) {
1543 rc = sock_create_kern(PF_INET6, SOCK_STREAM, IPPROTO_TCP, csocket);
1545 cERROR(1, ("Error %d creating ipv6 socket",rc));
1549 /* BB other socket options to set KEEPALIVE, NODELAY? */
1550 cFYI(1,("ipv6 Socket created"));
1551 (*csocket)->sk->sk_allocation = GFP_NOFS;
1555 psin_server->sin6_family = AF_INET6;
1557 if(psin_server->sin6_port) { /* user overrode default port */
1558 rc = (*csocket)->ops->connect(*csocket,
1559 (struct sockaddr *) psin_server,
1560 sizeof (struct sockaddr_in6),0);
1566 /* save original port so we can retry user specified port
1567 later if fall back ports fail this time */
1569 orig_port = psin_server->sin6_port;
1570 /* do not retry on the same port we just failed on */
1571 if(psin_server->sin6_port != htons(CIFS_PORT)) {
1572 psin_server->sin6_port = htons(CIFS_PORT);
1574 rc = (*csocket)->ops->connect(*csocket,
1575 (struct sockaddr *) psin_server,
1576 sizeof (struct sockaddr_in6),0);
1582 psin_server->sin6_port = htons(RFC1001_PORT);
1583 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1584 psin_server, sizeof (struct sockaddr_in6),0);
1589 /* give up here - unless we want to retry on different
1590 protocol families some day */
1593 psin_server->sin6_port = orig_port;
1594 cFYI(1,("Error %d connecting to server via ipv6",rc));
1595 sock_release(*csocket);
1599 /* Eventually check for other socket options to change from
1600 the default. sock_setsockopt not used because it expects
1601 user space buffer */
1602 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1608 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1609 char *mount_data, const char *devname)
1613 int address_type = AF_INET;
1614 struct socket *csocket = NULL;
1615 struct sockaddr_in sin_server;
1616 struct sockaddr_in6 sin_server6;
1617 struct smb_vol volume_info;
1618 struct cifsSesInfo *pSesInfo = NULL;
1619 struct cifsSesInfo *existingCifsSes = NULL;
1620 struct cifsTconInfo *tcon = NULL;
1621 struct TCP_Server_Info *srvTcp = NULL;
1625 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1627 memset(&volume_info,0,sizeof(struct smb_vol));
1628 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1629 kfree(volume_info.UNC);
1630 kfree(volume_info.password);
1631 kfree(volume_info.prepath);
1636 if (volume_info.username) {
1637 /* BB fixme parse for domain name here */
1638 cFYI(1, ("Username: %s ", volume_info.username));
1641 cifserror("No username specified");
1642 /* In userspace mount helper we can get user name from alternate
1643 locations such as env variables and files on disk */
1644 kfree(volume_info.UNC);
1645 kfree(volume_info.password);
1646 kfree(volume_info.prepath);
1651 if (volume_info.UNCip && volume_info.UNC) {
1652 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,&sin_server.sin_addr.s_addr);
1655 /* not ipv4 address, try ipv6 */
1656 rc = cifs_inet_pton(AF_INET6,volume_info.UNCip,&sin_server6.sin6_addr.in6_u);
1658 address_type = AF_INET6;
1660 address_type = AF_INET;
1664 /* we failed translating address */
1665 kfree(volume_info.UNC);
1666 kfree(volume_info.password);
1667 kfree(volume_info.prepath);
1672 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1675 } else if (volume_info.UNCip){
1676 /* BB using ip addr as server name connect to the DFS root below */
1677 cERROR(1,("Connecting to DFS root not implemented yet"));
1678 kfree(volume_info.UNC);
1679 kfree(volume_info.password);
1680 kfree(volume_info.prepath);
1683 } else /* which servers DFS root would we conect to */ {
1685 ("CIFS mount error: No UNC path (e.g. -o unc=//192.168.1.100/public) specified"));
1686 kfree(volume_info.UNC);
1687 kfree(volume_info.password);
1688 kfree(volume_info.prepath);
1693 /* this is needed for ASCII cp to Unicode converts */
1694 if(volume_info.iocharset == NULL) {
1695 cifs_sb->local_nls = load_nls_default();
1696 /* load_nls_default can not return null */
1698 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1699 if(cifs_sb->local_nls == NULL) {
1700 cERROR(1,("CIFS mount error: iocharset %s not found",volume_info.iocharset));
1701 kfree(volume_info.UNC);
1702 kfree(volume_info.password);
1703 kfree(volume_info.prepath);
1709 if(address_type == AF_INET)
1710 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1711 NULL /* no ipv6 addr */,
1712 volume_info.username, &srvTcp);
1713 else if(address_type == AF_INET6)
1714 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1715 &sin_server6.sin6_addr,
1716 volume_info.username, &srvTcp);
1718 kfree(volume_info.UNC);
1719 kfree(volume_info.password);
1720 kfree(volume_info.prepath);
1727 cFYI(1, ("Existing tcp session with server found"));
1728 } else { /* create socket */
1729 if(volume_info.port)
1730 sin_server.sin_port = htons(volume_info.port);
1732 sin_server.sin_port = 0;
1733 rc = ipv4_connect(&sin_server,&csocket,
1734 volume_info.source_rfc1001_name,
1735 volume_info.target_rfc1001_name);
1738 ("Error connecting to IPv4 socket. Aborting operation"));
1740 sock_release(csocket);
1741 kfree(volume_info.UNC);
1742 kfree(volume_info.password);
1743 kfree(volume_info.prepath);
1748 srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
1749 if (srvTcp == NULL) {
1751 sock_release(csocket);
1752 kfree(volume_info.UNC);
1753 kfree(volume_info.password);
1754 kfree(volume_info.prepath);
1758 memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
1759 memcpy(&srvTcp->addr.sockAddr, &sin_server, sizeof (struct sockaddr_in));
1760 atomic_set(&srvTcp->inFlight,0);
1761 /* BB Add code for ipv6 case too */
1762 srvTcp->ssocket = csocket;
1763 srvTcp->protocolType = IPV4;
1764 init_waitqueue_head(&srvTcp->response_q);
1765 init_waitqueue_head(&srvTcp->request_q);
1766 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
1767 /* at this point we are the only ones with the pointer
1768 to the struct since the kernel thread not created yet
1769 so no need to spinlock this init of tcpStatus */
1770 srvTcp->tcpStatus = CifsNew;
1771 init_MUTEX(&srvTcp->tcpSem);
1772 rc = (int)kernel_thread((void *)(void *)cifs_demultiplex_thread, srvTcp,
1773 CLONE_FS | CLONE_FILES | CLONE_VM);
1776 sock_release(csocket);
1777 kfree(volume_info.UNC);
1778 kfree(volume_info.password);
1779 kfree(volume_info.prepath);
1783 wait_for_completion(&cifsd_complete);
1785 memcpy(srvTcp->workstation_RFC1001_name, volume_info.source_rfc1001_name,16);
1786 memcpy(srvTcp->server_RFC1001_name, volume_info.target_rfc1001_name,16);
1787 srvTcp->sequence_number = 0;
1791 if (existingCifsSes) {
1792 pSesInfo = existingCifsSes;
1793 cFYI(1, ("Existing smb sess found"));
1794 kfree(volume_info.password);
1795 /* volume_info.UNC freed at end of function */
1797 cFYI(1, ("Existing smb sess not found"));
1798 pSesInfo = sesInfoAlloc();
1799 if (pSesInfo == NULL)
1802 pSesInfo->server = srvTcp;
1803 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
1804 NIPQUAD(sin_server.sin_addr.s_addr));
1808 /* volume_info.password freed at unmount */
1809 if (volume_info.password)
1810 pSesInfo->password = volume_info.password;
1811 if (volume_info.username)
1812 strncpy(pSesInfo->userName,
1813 volume_info.username,MAX_USERNAME_SIZE);
1814 if (volume_info.domainname) {
1815 int len = strlen(volume_info.domainname);
1816 pSesInfo->domainName =
1817 kmalloc(len + 1, GFP_KERNEL);
1818 if(pSesInfo->domainName)
1819 strcpy(pSesInfo->domainName,
1820 volume_info.domainname);
1822 pSesInfo->linux_uid = volume_info.linux_uid;
1823 pSesInfo->overrideSecFlg = volume_info.secFlg;
1824 down(&pSesInfo->sesSem);
1825 /* BB FIXME need to pass vol->secFlgs BB */
1826 rc = cifs_setup_session(xid,pSesInfo, cifs_sb->local_nls);
1827 up(&pSesInfo->sesSem);
1829 atomic_inc(&srvTcp->socketUseCount);
1831 kfree(volume_info.password);
1834 /* search for existing tcon to this server share */
1836 if(volume_info.rsize > CIFSMaxBufSize) {
1837 cERROR(1,("rsize %d too large, using MaxBufSize",
1838 volume_info.rsize));
1839 cifs_sb->rsize = CIFSMaxBufSize;
1840 } else if((volume_info.rsize) && (volume_info.rsize <= CIFSMaxBufSize))
1841 cifs_sb->rsize = volume_info.rsize;
1843 cifs_sb->rsize = CIFSMaxBufSize;
1845 if(volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
1846 cERROR(1,("wsize %d too large using 4096 instead",
1847 volume_info.wsize));
1848 cifs_sb->wsize = 4096;
1849 } else if(volume_info.wsize)
1850 cifs_sb->wsize = volume_info.wsize;
1853 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
1855 /* old default of CIFSMaxBufSize was too small now
1856 that SMB Write2 can send multiple pages in kvec.
1857 RFC1001 does not describe what happens when frame
1858 bigger than 128K is sent so use that as max in
1859 conjunction with 52K kvec constraint on arch with 4K
1862 if(cifs_sb->rsize < 2048) {
1863 cifs_sb->rsize = 2048;
1864 /* Windows ME may prefer this */
1865 cFYI(1,("readsize set to minimum 2048"));
1867 /* calculate prepath */
1868 cifs_sb->prepath = volume_info.prepath;
1869 if(cifs_sb->prepath) {
1870 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
1871 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
1872 volume_info.prepath = NULL;
1874 cifs_sb->prepathlen = 0;
1875 cifs_sb->mnt_uid = volume_info.linux_uid;
1876 cifs_sb->mnt_gid = volume_info.linux_gid;
1877 cifs_sb->mnt_file_mode = volume_info.file_mode;
1878 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
1879 cFYI(1,("file mode: 0x%x dir mode: 0x%x",
1880 cifs_sb->mnt_file_mode,cifs_sb->mnt_dir_mode));
1882 if(volume_info.noperm)
1883 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
1884 if(volume_info.setuids)
1885 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
1886 if(volume_info.server_ino)
1887 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
1888 if(volume_info.remap)
1889 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
1890 if(volume_info.no_xattr)
1891 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
1892 if(volume_info.sfu_emul)
1893 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
1894 if(volume_info.nobrl)
1895 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
1896 if(volume_info.cifs_acl)
1897 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
1899 if(volume_info.direct_io) {
1900 cFYI(1,("mounting share using direct i/o"));
1901 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
1905 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
1906 volume_info.username);
1908 cFYI(1, ("Found match on UNC path"));
1909 /* we can have only one retry value for a connection
1910 to a share so for resources mounted more than once
1911 to the same server share the last value passed in
1912 for the retry flag is used */
1913 tcon->retry = volume_info.retry;
1914 tcon->nocase = volume_info.nocase;
1916 tcon = tconInfoAlloc();
1920 /* check for null share name ie connect to dfs root */
1922 /* BB check if this works for exactly length three strings */
1923 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
1924 && (strchr(volume_info.UNC + 3, '/') ==
1926 rc = connect_to_dfs_path(xid, pSesInfo,
1927 "", cifs_sb->local_nls,
1928 cifs_sb->mnt_cifs_flags &
1929 CIFS_MOUNT_MAP_SPECIAL_CHR);
1930 kfree(volume_info.UNC);
1934 rc = CIFSTCon(xid, pSesInfo,
1936 tcon, cifs_sb->local_nls);
1937 cFYI(1, ("CIFS Tcon rc = %d", rc));
1940 atomic_inc(&pSesInfo->inUse);
1941 tcon->retry = volume_info.retry;
1942 tcon->nocase = volume_info.nocase;
1948 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
1949 sb->s_maxbytes = (u64) 1 << 63;
1951 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
1954 sb->s_time_gran = 100;
1956 /* on error free sesinfo and tcon struct if needed */
1958 /* if session setup failed, use count is zero but
1959 we still need to free cifsd thread */
1960 if(atomic_read(&srvTcp->socketUseCount) == 0) {
1961 spin_lock(&GlobalMid_Lock);
1962 srvTcp->tcpStatus = CifsExiting;
1963 spin_unlock(&GlobalMid_Lock);
1965 send_sig(SIGKILL,srvTcp->tsk,1);
1966 wait_for_completion(&cifsd_complete);
1969 /* If find_unc succeeded then rc == 0 so we can not end */
1970 if (tcon) /* up accidently freeing someone elses tcon struct */
1972 if (existingCifsSes == NULL) {
1974 if ((pSesInfo->server) &&
1975 (pSesInfo->status == CifsGood)) {
1977 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
1978 /* if the socketUseCount is now zero */
1979 if((temp_rc == -ESHUTDOWN) &&
1980 (pSesInfo->server->tsk)) {
1981 send_sig(SIGKILL,pSesInfo->server->tsk,1);
1982 wait_for_completion(&cifsd_complete);
1985 cFYI(1, ("No session or bad tcon"));
1986 sesInfoFree(pSesInfo);
1987 /* pSesInfo = NULL; */
1991 atomic_inc(&tcon->useCount);
1992 cifs_sb->tcon = tcon;
1993 tcon->ses = pSesInfo;
1995 /* do not care if following two calls succeed - informational */
1996 CIFSSMBQFSDeviceInfo(xid, tcon);
1997 CIFSSMBQFSAttributeInfo(xid, tcon);
1999 if (tcon->ses->capabilities & CAP_UNIX) {
2000 if(!CIFSSMBQFSUnixInfo(xid, tcon)) {
2002 le64_to_cpu(tcon->fsUnixInfo.Capability);
2003 cap &= CIFS_UNIX_CAP_MASK;
2004 if(volume_info.no_psx_acl)
2005 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2006 else if(CIFS_UNIX_POSIX_ACL_CAP & cap) {
2007 cFYI(1,("negotiated posix acl support"));
2008 sb->s_flags |= MS_POSIXACL;
2011 if(volume_info.posix_paths == 0)
2012 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2013 else if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2014 cFYI(1,("negotiate posix pathnames"));
2015 cifs_sb->mnt_cifs_flags |=
2016 CIFS_MOUNT_POSIX_PATHS;
2019 cFYI(1,("Negotiate caps 0x%x",(int)cap));
2020 #ifdef CONFIG_CIFS_DEBUG2
2021 if(cap & CIFS_UNIX_FCNTL_CAP)
2022 cFYI(1,("FCNTL cap"));
2023 if(cap & CIFS_UNIX_EXTATTR_CAP)
2024 cFYI(1,("EXTATTR cap"));
2025 if(cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2026 cFYI(1,("POSIX path cap"));
2027 if(cap & CIFS_UNIX_XATTR_CAP)
2028 cFYI(1,("XATTR cap"));
2029 if(cap & CIFS_UNIX_POSIX_ACL_CAP)
2030 cFYI(1,("POSIX ACL cap"));
2031 #endif /* CIFS_DEBUG2 */
2032 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
2033 cFYI(1,("setting capabilities failed"));
2037 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2038 cifs_sb->wsize = min(cifs_sb->wsize,
2039 (tcon->ses->server->maxBuf -
2040 MAX_CIFS_HDR_SIZE));
2041 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2042 cifs_sb->rsize = min(cifs_sb->rsize,
2043 (tcon->ses->server->maxBuf -
2044 MAX_CIFS_HDR_SIZE));
2047 /* volume_info.password is freed above when existing session found
2048 (in which case it is not needed anymore) but when new sesion is created
2049 the password ptr is put in the new session structure (in which case the
2050 password will be freed at unmount time) */
2051 kfree(volume_info.UNC);
2052 kfree(volume_info.prepath);
2058 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2059 char session_key[CIFS_SESS_KEY_SIZE],
2060 const struct nls_table *nls_codepage)
2062 struct smb_hdr *smb_buffer;
2063 struct smb_hdr *smb_buffer_response;
2064 SESSION_SETUP_ANDX *pSMB;
2065 SESSION_SETUP_ANDX *pSMBr;
2070 int remaining_words = 0;
2071 int bytes_returned = 0;
2076 cFYI(1, ("In sesssetup"));
2079 user = ses->userName;
2080 domain = ses->domainName;
2081 smb_buffer = cifs_buf_get();
2082 if (smb_buffer == NULL) {
2085 smb_buffer_response = smb_buffer;
2086 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2088 /* send SMBsessionSetup here */
2089 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2090 NULL /* no tCon exists yet */ , 13 /* wct */ );
2092 smb_buffer->Mid = GetNextMid(ses->server);
2093 pSMB->req_no_secext.AndXCommand = 0xFF;
2094 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2095 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2097 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2098 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2100 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2101 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2102 if (ses->capabilities & CAP_UNICODE) {
2103 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2104 capabilities |= CAP_UNICODE;
2106 if (ses->capabilities & CAP_STATUS32) {
2107 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2108 capabilities |= CAP_STATUS32;
2110 if (ses->capabilities & CAP_DFS) {
2111 smb_buffer->Flags2 |= SMBFLG2_DFS;
2112 capabilities |= CAP_DFS;
2114 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2116 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2117 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2119 pSMB->req_no_secext.CaseSensitivePasswordLength =
2120 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2121 bcc_ptr = pByteArea(smb_buffer);
2122 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2123 bcc_ptr += CIFS_SESS_KEY_SIZE;
2124 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2125 bcc_ptr += CIFS_SESS_KEY_SIZE;
2127 if (ses->capabilities & CAP_UNICODE) {
2128 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2133 bytes_returned = 0; /* skip null user */
2136 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2138 /* convert number of 16 bit words to bytes */
2139 bcc_ptr += 2 * bytes_returned;
2140 bcc_ptr += 2; /* trailing null */
2143 cifs_strtoUCS((__le16 *) bcc_ptr,
2144 "CIFS_LINUX_DOM", 32, nls_codepage);
2147 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2149 bcc_ptr += 2 * bytes_returned;
2152 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2154 bcc_ptr += 2 * bytes_returned;
2156 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
2158 bcc_ptr += 2 * bytes_returned;
2161 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2163 bcc_ptr += 2 * bytes_returned;
2167 strncpy(bcc_ptr, user, 200);
2168 bcc_ptr += strnlen(user, 200);
2172 if (domain == NULL) {
2173 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2174 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2176 strncpy(bcc_ptr, domain, 64);
2177 bcc_ptr += strnlen(domain, 64);
2181 strcpy(bcc_ptr, "Linux version ");
2182 bcc_ptr += strlen("Linux version ");
2183 strcpy(bcc_ptr, system_utsname.release);
2184 bcc_ptr += strlen(system_utsname.release) + 1;
2185 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2186 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2188 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2189 smb_buffer->smb_buf_length += count;
2190 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2192 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2193 &bytes_returned, 1);
2195 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2196 } else if ((smb_buffer_response->WordCount == 3)
2197 || (smb_buffer_response->WordCount == 4)) {
2198 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2199 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2200 if (action & GUEST_LOGIN)
2201 cFYI(1, (" Guest login")); /* do we want to mark SesInfo struct ? */
2202 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format (le) */
2203 cFYI(1, ("UID = %d ", ses->Suid));
2204 /* response can have either 3 or 4 word count - Samba sends 3 */
2205 bcc_ptr = pByteArea(smb_buffer_response);
2206 if ((pSMBr->resp.hdr.WordCount == 3)
2207 || ((pSMBr->resp.hdr.WordCount == 4)
2208 && (blob_len < pSMBr->resp.ByteCount))) {
2209 if (pSMBr->resp.hdr.WordCount == 4)
2210 bcc_ptr += blob_len;
2212 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2213 if ((long) (bcc_ptr) % 2) {
2215 (BCC(smb_buffer_response) - 1) /2;
2216 bcc_ptr++; /* Unicode strings must be word aligned */
2219 BCC(smb_buffer_response) / 2;
2222 UniStrnlen((wchar_t *) bcc_ptr,
2223 remaining_words - 1);
2224 /* We look for obvious messed up bcc or strings in response so we do not go off
2225 the end since (at least) WIN2K and Windows XP have a major bug in not null
2226 terminating last Unicode string in response */
2228 kfree(ses->serverOS);
2229 ses->serverOS = kzalloc(2 * (len + 1), GFP_KERNEL);
2230 if(ses->serverOS == NULL)
2231 goto sesssetup_nomem;
2232 cifs_strfromUCS_le(ses->serverOS,
2233 (__le16 *)bcc_ptr, len,nls_codepage);
2234 bcc_ptr += 2 * (len + 1);
2235 remaining_words -= len + 1;
2236 ses->serverOS[2 * len] = 0;
2237 ses->serverOS[1 + (2 * len)] = 0;
2238 if (remaining_words > 0) {
2239 len = UniStrnlen((wchar_t *)bcc_ptr,
2241 kfree(ses->serverNOS);
2242 ses->serverNOS = kzalloc(2 * (len + 1),GFP_KERNEL);
2243 if(ses->serverNOS == NULL)
2244 goto sesssetup_nomem;
2245 cifs_strfromUCS_le(ses->serverNOS,
2246 (__le16 *)bcc_ptr,len,nls_codepage);
2247 bcc_ptr += 2 * (len + 1);
2248 ses->serverNOS[2 * len] = 0;
2249 ses->serverNOS[1 + (2 * len)] = 0;
2250 if(strncmp(ses->serverNOS,
2251 "NT LAN Manager 4",16) == 0) {
2252 cFYI(1,("NT4 server"));
2253 ses->flags |= CIFS_SES_NT4;
2255 remaining_words -= len + 1;
2256 if (remaining_words > 0) {
2257 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2258 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2259 if(ses->serverDomain)
2260 kfree(ses->serverDomain);
2262 kzalloc(2*(len+1),GFP_KERNEL);
2263 if(ses->serverDomain == NULL)
2264 goto sesssetup_nomem;
2265 cifs_strfromUCS_le(ses->serverDomain,
2266 (__le16 *)bcc_ptr,len,nls_codepage);
2267 bcc_ptr += 2 * (len + 1);
2268 ses->serverDomain[2*len] = 0;
2269 ses->serverDomain[1+(2*len)] = 0;
2270 } /* else no more room so create dummy domain string */
2272 if(ses->serverDomain)
2273 kfree(ses->serverDomain);
2275 kzalloc(2, GFP_KERNEL);
2277 } else { /* no room so create dummy domain and NOS string */
2278 /* if these kcallocs fail not much we
2279 can do, but better to not fail the
2281 kfree(ses->serverDomain);
2283 kzalloc(2, GFP_KERNEL);
2284 kfree(ses->serverNOS);
2286 kzalloc(2, GFP_KERNEL);
2288 } else { /* ASCII */
2289 len = strnlen(bcc_ptr, 1024);
2290 if (((long) bcc_ptr + len) - (long)
2291 pByteArea(smb_buffer_response)
2292 <= BCC(smb_buffer_response)) {
2293 kfree(ses->serverOS);
2294 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
2295 if(ses->serverOS == NULL)
2296 goto sesssetup_nomem;
2297 strncpy(ses->serverOS,bcc_ptr, len);
2300 bcc_ptr[0] = 0; /* null terminate the string */
2303 len = strnlen(bcc_ptr, 1024);
2304 kfree(ses->serverNOS);
2305 ses->serverNOS = kzalloc(len + 1,GFP_KERNEL);
2306 if(ses->serverNOS == NULL)
2307 goto sesssetup_nomem;
2308 strncpy(ses->serverNOS, bcc_ptr, len);
2313 len = strnlen(bcc_ptr, 1024);
2314 if(ses->serverDomain)
2315 kfree(ses->serverDomain);
2316 ses->serverDomain = kzalloc(len + 1,GFP_KERNEL);
2317 if(ses->serverDomain == NULL)
2318 goto sesssetup_nomem;
2319 strncpy(ses->serverDomain, bcc_ptr, len);
2325 ("Variable field of length %d extends beyond end of smb ",
2330 (" Security Blob Length extends beyond end of SMB"));
2334 (" Invalid Word count %d: ",
2335 smb_buffer_response->WordCount));
2338 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2339 since that could make reconnection harder, and
2340 reconnection might be needed to free memory */
2342 cifs_buf_release(smb_buffer);
2348 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2349 struct cifsSesInfo *ses, int * pNTLMv2_flag,
2350 const struct nls_table *nls_codepage)
2352 struct smb_hdr *smb_buffer;
2353 struct smb_hdr *smb_buffer_response;
2354 SESSION_SETUP_ANDX *pSMB;
2355 SESSION_SETUP_ANDX *pSMBr;
2359 int remaining_words = 0;
2360 int bytes_returned = 0;
2362 int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
2363 PNEGOTIATE_MESSAGE SecurityBlob;
2364 PCHALLENGE_MESSAGE SecurityBlob2;
2365 __u32 negotiate_flags, capabilities;
2368 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2371 domain = ses->domainName;
2372 *pNTLMv2_flag = FALSE;
2373 smb_buffer = cifs_buf_get();
2374 if (smb_buffer == NULL) {
2377 smb_buffer_response = smb_buffer;
2378 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2379 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2381 /* send SMBsessionSetup here */
2382 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2383 NULL /* no tCon exists yet */ , 12 /* wct */ );
2385 smb_buffer->Mid = GetNextMid(ses->server);
2386 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2387 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2389 pSMB->req.AndXCommand = 0xFF;
2390 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2391 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2393 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2394 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2396 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2397 CAP_EXTENDED_SECURITY;
2398 if (ses->capabilities & CAP_UNICODE) {
2399 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2400 capabilities |= CAP_UNICODE;
2402 if (ses->capabilities & CAP_STATUS32) {
2403 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2404 capabilities |= CAP_STATUS32;
2406 if (ses->capabilities & CAP_DFS) {
2407 smb_buffer->Flags2 |= SMBFLG2_DFS;
2408 capabilities |= CAP_DFS;
2410 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2412 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2413 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2414 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2415 SecurityBlob->MessageType = NtLmNegotiate;
2417 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2418 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2419 NTLMSSP_NEGOTIATE_56 |
2420 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2422 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2423 /* if(ntlmv2_support)
2424 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2425 /* setup pointers to domain name and workstation name */
2426 bcc_ptr += SecurityBlobLength;
2428 SecurityBlob->WorkstationName.Buffer = 0;
2429 SecurityBlob->WorkstationName.Length = 0;
2430 SecurityBlob->WorkstationName.MaximumLength = 0;
2432 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2433 along with username on auth request (ie the response to challenge) */
2434 SecurityBlob->DomainName.Buffer = 0;
2435 SecurityBlob->DomainName.Length = 0;
2436 SecurityBlob->DomainName.MaximumLength = 0;
2437 if (ses->capabilities & CAP_UNICODE) {
2438 if ((long) bcc_ptr % 2) {
2444 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2446 bcc_ptr += 2 * bytes_returned;
2448 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
2450 bcc_ptr += 2 * bytes_returned;
2451 bcc_ptr += 2; /* null terminate Linux version */
2453 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2455 bcc_ptr += 2 * bytes_returned;
2458 bcc_ptr += 2; /* null terminate network opsys string */
2461 bcc_ptr += 2; /* null domain */
2462 } else { /* ASCII */
2463 strcpy(bcc_ptr, "Linux version ");
2464 bcc_ptr += strlen("Linux version ");
2465 strcpy(bcc_ptr, system_utsname.release);
2466 bcc_ptr += strlen(system_utsname.release) + 1;
2467 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2468 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2469 bcc_ptr++; /* empty domain field */
2472 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2473 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2474 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2475 smb_buffer->smb_buf_length += count;
2476 pSMB->req.ByteCount = cpu_to_le16(count);
2478 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2479 &bytes_returned, 1);
2481 if (smb_buffer_response->Status.CifsError ==
2482 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2486 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2487 } else if ((smb_buffer_response->WordCount == 3)
2488 || (smb_buffer_response->WordCount == 4)) {
2489 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2490 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2492 if (action & GUEST_LOGIN)
2493 cFYI(1, (" Guest login"));
2494 /* Do we want to set anything in SesInfo struct when guest login? */
2496 bcc_ptr = pByteArea(smb_buffer_response);
2497 /* response can have either 3 or 4 word count - Samba sends 3 */
2499 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2500 if (SecurityBlob2->MessageType != NtLmChallenge) {
2502 ("Unexpected NTLMSSP message type received %d",
2503 SecurityBlob2->MessageType));
2505 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2506 cFYI(1, ("UID = %d", ses->Suid));
2507 if ((pSMBr->resp.hdr.WordCount == 3)
2508 || ((pSMBr->resp.hdr.WordCount == 4)
2510 pSMBr->resp.ByteCount))) {
2512 if (pSMBr->resp.hdr.WordCount == 4) {
2513 bcc_ptr += blob_len;
2514 cFYI(1, ("Security Blob Length %d",
2518 cFYI(1, ("NTLMSSP Challenge rcvd"));
2520 memcpy(ses->server->cryptKey,
2521 SecurityBlob2->Challenge,
2522 CIFS_CRYPTO_KEY_SIZE);
2523 if(SecurityBlob2->NegotiateFlags &
2524 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2525 *pNTLMv2_flag = TRUE;
2527 if((SecurityBlob2->NegotiateFlags &
2528 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2529 || (sign_CIFS_PDUs > 1))
2530 ses->server->secMode |=
2531 SECMODE_SIGN_REQUIRED;
2532 if ((SecurityBlob2->NegotiateFlags &
2533 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2534 ses->server->secMode |=
2535 SECMODE_SIGN_ENABLED;
2537 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2538 if ((long) (bcc_ptr) % 2) {
2540 (BCC(smb_buffer_response)
2542 bcc_ptr++; /* Unicode strings must be word aligned */
2546 (smb_buffer_response) / 2;
2549 UniStrnlen((wchar_t *) bcc_ptr,
2550 remaining_words - 1);
2551 /* We look for obvious messed up bcc or strings in response so we do not go off
2552 the end since (at least) WIN2K and Windows XP have a major bug in not null
2553 terminating last Unicode string in response */
2555 kfree(ses->serverOS);
2557 kzalloc(2 * (len + 1), GFP_KERNEL);
2558 cifs_strfromUCS_le(ses->serverOS,
2562 bcc_ptr += 2 * (len + 1);
2563 remaining_words -= len + 1;
2564 ses->serverOS[2 * len] = 0;
2565 ses->serverOS[1 + (2 * len)] = 0;
2566 if (remaining_words > 0) {
2567 len = UniStrnlen((wchar_t *)
2571 kfree(ses->serverNOS);
2573 kzalloc(2 * (len + 1),
2575 cifs_strfromUCS_le(ses->
2581 bcc_ptr += 2 * (len + 1);
2582 ses->serverNOS[2 * len] = 0;
2585 remaining_words -= len + 1;
2586 if (remaining_words > 0) {
2587 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2588 /* last string is not always null terminated (for e.g. for Windows XP & 2000) */
2589 kfree(ses->serverDomain);
2601 ses->serverDomain[2*len]
2606 } /* else no more room so create dummy domain string */
2608 kfree(ses->serverDomain);
2613 } else { /* no room so create dummy domain and NOS string */
2614 kfree(ses->serverDomain);
2616 kzalloc(2, GFP_KERNEL);
2617 kfree(ses->serverNOS);
2619 kzalloc(2, GFP_KERNEL);
2621 } else { /* ASCII */
2622 len = strnlen(bcc_ptr, 1024);
2623 if (((long) bcc_ptr + len) - (long)
2624 pByteArea(smb_buffer_response)
2625 <= BCC(smb_buffer_response)) {
2627 kfree(ses->serverOS);
2631 strncpy(ses->serverOS,
2635 bcc_ptr[0] = 0; /* null terminate string */
2638 len = strnlen(bcc_ptr, 1024);
2639 kfree(ses->serverNOS);
2643 strncpy(ses->serverNOS, bcc_ptr, len);
2648 len = strnlen(bcc_ptr, 1024);
2649 kfree(ses->serverDomain);
2653 strncpy(ses->serverDomain, bcc_ptr, len);
2659 ("Variable field of length %d extends beyond end of smb",
2664 (" Security Blob Length extends beyond end of SMB"));
2667 cERROR(1, ("No session structure passed in."));
2671 (" Invalid Word count %d:",
2672 smb_buffer_response->WordCount));
2677 cifs_buf_release(smb_buffer);
2682 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2683 char *ntlm_session_key, int ntlmv2_flag,
2684 const struct nls_table *nls_codepage)
2686 struct smb_hdr *smb_buffer;
2687 struct smb_hdr *smb_buffer_response;
2688 SESSION_SETUP_ANDX *pSMB;
2689 SESSION_SETUP_ANDX *pSMBr;
2694 int remaining_words = 0;
2695 int bytes_returned = 0;
2697 int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
2698 PAUTHENTICATE_MESSAGE SecurityBlob;
2699 __u32 negotiate_flags, capabilities;
2702 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2705 user = ses->userName;
2706 domain = ses->domainName;
2707 smb_buffer = cifs_buf_get();
2708 if (smb_buffer == NULL) {
2711 smb_buffer_response = smb_buffer;
2712 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2713 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2715 /* send SMBsessionSetup here */
2716 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2717 NULL /* no tCon exists yet */ , 12 /* wct */ );
2719 smb_buffer->Mid = GetNextMid(ses->server);
2720 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2721 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2722 pSMB->req.AndXCommand = 0xFF;
2723 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2724 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2726 pSMB->req.hdr.Uid = ses->Suid;
2728 if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2729 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2731 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2732 CAP_EXTENDED_SECURITY;
2733 if (ses->capabilities & CAP_UNICODE) {
2734 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2735 capabilities |= CAP_UNICODE;
2737 if (ses->capabilities & CAP_STATUS32) {
2738 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2739 capabilities |= CAP_STATUS32;
2741 if (ses->capabilities & CAP_DFS) {
2742 smb_buffer->Flags2 |= SMBFLG2_DFS;
2743 capabilities |= CAP_DFS;
2745 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2747 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2748 SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
2749 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2750 SecurityBlob->MessageType = NtLmAuthenticate;
2751 bcc_ptr += SecurityBlobLength;
2753 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
2754 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
2755 0x80000000 | NTLMSSP_NEGOTIATE_128;
2757 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
2759 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2761 /* setup pointers to domain name and workstation name */
2763 SecurityBlob->WorkstationName.Buffer = 0;
2764 SecurityBlob->WorkstationName.Length = 0;
2765 SecurityBlob->WorkstationName.MaximumLength = 0;
2766 SecurityBlob->SessionKey.Length = 0;
2767 SecurityBlob->SessionKey.MaximumLength = 0;
2768 SecurityBlob->SessionKey.Buffer = 0;
2770 SecurityBlob->LmChallengeResponse.Length = 0;
2771 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
2772 SecurityBlob->LmChallengeResponse.Buffer = 0;
2774 SecurityBlob->NtChallengeResponse.Length =
2775 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2776 SecurityBlob->NtChallengeResponse.MaximumLength =
2777 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2778 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
2779 SecurityBlob->NtChallengeResponse.Buffer =
2780 cpu_to_le32(SecurityBlobLength);
2781 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
2782 bcc_ptr += CIFS_SESS_KEY_SIZE;
2784 if (ses->capabilities & CAP_UNICODE) {
2785 if (domain == NULL) {
2786 SecurityBlob->DomainName.Buffer = 0;
2787 SecurityBlob->DomainName.Length = 0;
2788 SecurityBlob->DomainName.MaximumLength = 0;
2791 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2794 SecurityBlob->DomainName.MaximumLength =
2796 SecurityBlob->DomainName.Buffer =
2797 cpu_to_le32(SecurityBlobLength);
2799 SecurityBlobLength += len;
2800 SecurityBlob->DomainName.Length =
2804 SecurityBlob->UserName.Buffer = 0;
2805 SecurityBlob->UserName.Length = 0;
2806 SecurityBlob->UserName.MaximumLength = 0;
2809 cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
2812 SecurityBlob->UserName.MaximumLength =
2814 SecurityBlob->UserName.Buffer =
2815 cpu_to_le32(SecurityBlobLength);
2817 SecurityBlobLength += len;
2818 SecurityBlob->UserName.Length =
2822 /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
2823 SecurityBlob->WorkstationName.Length *= 2;
2824 SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length);
2825 SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength);
2826 bcc_ptr += SecurityBlob->WorkstationName.Length;
2827 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
2828 SecurityBlob->WorkstationName.Length = cpu_to_le16(SecurityBlob->WorkstationName.Length); */
2830 if ((long) bcc_ptr % 2) {
2835 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2837 bcc_ptr += 2 * bytes_returned;
2839 cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release, 32,
2841 bcc_ptr += 2 * bytes_returned;
2842 bcc_ptr += 2; /* null term version string */
2844 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2846 bcc_ptr += 2 * bytes_returned;
2849 bcc_ptr += 2; /* null terminate network opsys string */
2852 bcc_ptr += 2; /* null domain */
2853 } else { /* ASCII */
2854 if (domain == NULL) {
2855 SecurityBlob->DomainName.Buffer = 0;
2856 SecurityBlob->DomainName.Length = 0;
2857 SecurityBlob->DomainName.MaximumLength = 0;
2860 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
2861 strncpy(bcc_ptr, domain, 63);
2862 len = strnlen(domain, 64);
2863 SecurityBlob->DomainName.MaximumLength =
2865 SecurityBlob->DomainName.Buffer =
2866 cpu_to_le32(SecurityBlobLength);
2868 SecurityBlobLength += len;
2869 SecurityBlob->DomainName.Length = cpu_to_le16(len);
2872 SecurityBlob->UserName.Buffer = 0;
2873 SecurityBlob->UserName.Length = 0;
2874 SecurityBlob->UserName.MaximumLength = 0;
2877 strncpy(bcc_ptr, user, 63);
2878 len = strnlen(user, 64);
2879 SecurityBlob->UserName.MaximumLength =
2881 SecurityBlob->UserName.Buffer =
2882 cpu_to_le32(SecurityBlobLength);
2884 SecurityBlobLength += len;
2885 SecurityBlob->UserName.Length = cpu_to_le16(len);
2887 /* BB fill in our workstation name if known BB */
2889 strcpy(bcc_ptr, "Linux version ");
2890 bcc_ptr += strlen("Linux version ");
2891 strcpy(bcc_ptr, system_utsname.release);
2892 bcc_ptr += strlen(system_utsname.release) + 1;
2893 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2894 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2895 bcc_ptr++; /* null domain */
2898 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2899 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2900 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2901 smb_buffer->smb_buf_length += count;
2902 pSMB->req.ByteCount = cpu_to_le16(count);
2904 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2905 &bytes_returned, 1);
2907 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2908 } else if ((smb_buffer_response->WordCount == 3)
2909 || (smb_buffer_response->WordCount == 4)) {
2910 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2912 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2913 if (action & GUEST_LOGIN)
2914 cFYI(1, (" Guest login")); /* BB do we want to set anything in SesInfo struct ? */
2915 /* if(SecurityBlob2->MessageType != NtLm??){
2916 cFYI("Unexpected message type on auth response is %d "));
2920 ("Does UID on challenge %d match auth response UID %d ",
2921 ses->Suid, smb_buffer_response->Uid));
2922 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format */
2923 bcc_ptr = pByteArea(smb_buffer_response);
2924 /* response can have either 3 or 4 word count - Samba sends 3 */
2925 if ((pSMBr->resp.hdr.WordCount == 3)
2926 || ((pSMBr->resp.hdr.WordCount == 4)
2928 pSMBr->resp.ByteCount))) {
2929 if (pSMBr->resp.hdr.WordCount == 4) {
2933 ("Security Blob Length %d ",
2938 ("NTLMSSP response to Authenticate "));
2940 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2941 if ((long) (bcc_ptr) % 2) {
2943 (BCC(smb_buffer_response)
2945 bcc_ptr++; /* Unicode strings must be word aligned */
2947 remaining_words = BCC(smb_buffer_response) / 2;
2950 UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
2951 /* We look for obvious messed up bcc or strings in response so we do not go off
2952 the end since (at least) WIN2K and Windows XP have a major bug in not null
2953 terminating last Unicode string in response */
2955 kfree(ses->serverOS);
2957 kzalloc(2 * (len + 1), GFP_KERNEL);
2958 cifs_strfromUCS_le(ses->serverOS,
2962 bcc_ptr += 2 * (len + 1);
2963 remaining_words -= len + 1;
2964 ses->serverOS[2 * len] = 0;
2965 ses->serverOS[1 + (2 * len)] = 0;
2966 if (remaining_words > 0) {
2967 len = UniStrnlen((wchar_t *)
2971 kfree(ses->serverNOS);
2973 kzalloc(2 * (len + 1),
2975 cifs_strfromUCS_le(ses->
2981 bcc_ptr += 2 * (len + 1);
2982 ses->serverNOS[2 * len] = 0;
2983 ses->serverNOS[1+(2*len)] = 0;
2984 remaining_words -= len + 1;
2985 if (remaining_words > 0) {
2986 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2987 /* last string not always null terminated (e.g. for Windows XP & 2000) */
2988 if(ses->serverDomain)
2989 kfree(ses->serverDomain);
3014 } /* else no more room so create dummy domain string */
3016 if(ses->serverDomain)
3017 kfree(ses->serverDomain);
3018 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3020 } else { /* no room so create dummy domain and NOS string */
3021 if(ses->serverDomain)
3022 kfree(ses->serverDomain);
3023 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3024 kfree(ses->serverNOS);
3025 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3027 } else { /* ASCII */
3028 len = strnlen(bcc_ptr, 1024);
3029 if (((long) bcc_ptr + len) -
3030 (long) pByteArea(smb_buffer_response)
3031 <= BCC(smb_buffer_response)) {
3033 kfree(ses->serverOS);
3034 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
3035 strncpy(ses->serverOS,bcc_ptr, len);
3038 bcc_ptr[0] = 0; /* null terminate the string */
3041 len = strnlen(bcc_ptr, 1024);
3042 kfree(ses->serverNOS);
3043 ses->serverNOS = kzalloc(len+1,GFP_KERNEL);
3044 strncpy(ses->serverNOS, bcc_ptr, len);
3049 len = strnlen(bcc_ptr, 1024);
3050 if(ses->serverDomain)
3051 kfree(ses->serverDomain);
3052 ses->serverDomain = kzalloc(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 */ );
3108 smb_buffer->Mid = GetNextMid(ses->server);
3109 smb_buffer->Uid = ses->Suid;
3110 pSMB = (TCONX_REQ *) smb_buffer;
3111 pSMBr = (TCONX_RSP *) smb_buffer_response;
3113 pSMB->AndXCommand = 0xFF;
3114 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3115 bcc_ptr = &pSMB->Password[0];
3116 if((ses->server->secMode) & SECMODE_USER) {
3117 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3118 *bcc_ptr = 0; /* password is null byte */
3119 bcc_ptr++; /* skip password */
3120 /* already aligned so no need to do it below */
3122 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3123 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3124 specified as required (when that support is added to
3125 the vfs in the future) as only NTLM or the much
3126 weaker LANMAN (which we do not send by default) is accepted
3127 by Samba (not sure whether other servers allow
3128 NTLMv2 password here) */
3129 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3130 if((extended_security & CIFSSEC_MAY_LANMAN) &&
3131 (ses->server->secType == LANMAN))
3132 calc_lanman_hash(ses, bcc_ptr);
3134 #endif /* CIFS_WEAK_PW_HASH */
3135 SMBNTencrypt(ses->password,
3136 ses->server->cryptKey,
3139 bcc_ptr += CIFS_SESS_KEY_SIZE;
3140 if(ses->capabilities & CAP_UNICODE) {
3141 /* must align unicode strings */
3142 *bcc_ptr = 0; /* null byte password */
3147 if(ses->server->secMode &
3148 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3149 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3151 if (ses->capabilities & CAP_STATUS32) {
3152 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3154 if (ses->capabilities & CAP_DFS) {
3155 smb_buffer->Flags2 |= SMBFLG2_DFS;
3157 if (ses->capabilities & CAP_UNICODE) {
3158 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3160 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3161 6 /* max utf8 char length in bytes */ *
3162 (/* server len*/ + 256 /* share len */), nls_codepage);
3163 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3164 bcc_ptr += 2; /* skip trailing null */
3165 } else { /* ASCII */
3166 strcpy(bcc_ptr, tree);
3167 bcc_ptr += strlen(tree) + 1;
3169 strcpy(bcc_ptr, "?????");
3170 bcc_ptr += strlen("?????");
3172 count = bcc_ptr - &pSMB->Password[0];
3173 pSMB->hdr.smb_buf_length += count;
3174 pSMB->ByteCount = cpu_to_le16(count);
3176 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
3178 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3179 /* above now done in SendReceive */
3180 if ((rc == 0) && (tcon != NULL)) {
3181 tcon->tidStatus = CifsGood;
3182 tcon->tid = smb_buffer_response->Tid;
3183 bcc_ptr = pByteArea(smb_buffer_response);
3184 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3185 /* skip service field (NB: this field is always ASCII) */
3186 bcc_ptr += length + 1;
3187 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3188 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3189 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3190 if ((bcc_ptr + (2 * length)) -
3191 pByteArea(smb_buffer_response) <=
3192 BCC(smb_buffer_response)) {
3193 kfree(tcon->nativeFileSystem);
3194 tcon->nativeFileSystem =
3195 kzalloc(length + 2, GFP_KERNEL);
3196 cifs_strfromUCS_le(tcon->nativeFileSystem,
3198 length, nls_codepage);
3199 bcc_ptr += 2 * length;
3200 bcc_ptr[0] = 0; /* null terminate the string */
3204 /* else do not bother copying these informational fields */
3206 length = strnlen(bcc_ptr, 1024);
3207 if ((bcc_ptr + length) -
3208 pByteArea(smb_buffer_response) <=
3209 BCC(smb_buffer_response)) {
3210 kfree(tcon->nativeFileSystem);
3211 tcon->nativeFileSystem =
3212 kzalloc(length + 1, GFP_KERNEL);
3213 strncpy(tcon->nativeFileSystem, bcc_ptr,
3216 /* else do not bother copying these informational fields */
3218 if(smb_buffer_response->WordCount == 3)
3219 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3222 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3223 } else if ((rc == 0) && tcon == NULL) {
3224 /* all we need to save for IPC$ connection */
3225 ses->ipc_tid = smb_buffer_response->Tid;
3229 cifs_buf_release(smb_buffer);
3234 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3238 struct cifsSesInfo *ses = NULL;
3239 struct task_struct *cifsd_task;
3244 if (cifs_sb->tcon) {
3245 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3246 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3251 tconInfoFree(cifs_sb->tcon);
3252 if ((ses) && (ses->server)) {
3253 /* save off task so we do not refer to ses later */
3254 cifsd_task = ses->server->tsk;
3255 cFYI(1, ("About to do SMBLogoff "));
3256 rc = CIFSSMBLogoff(xid, ses);
3260 } else if (rc == -ESHUTDOWN) {
3261 cFYI(1,("Waking up socket by sending it signal"));
3263 send_sig(SIGKILL,cifsd_task,1);
3264 wait_for_completion(&cifsd_complete);
3267 } /* else - we have an smb session
3268 left on this socket do not kill cifsd */
3270 cFYI(1, ("No session or bad tcon"));
3273 cifs_sb->tcon = NULL;
3274 tmp = cifs_sb->prepath;
3275 cifs_sb->prepathlen = 0;
3276 cifs_sb->prepath = NULL;
3279 schedule_timeout_interruptible(msecs_to_jiffies(500));
3284 return rc; /* BB check if we should always return zero here */
3287 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3288 struct nls_table * nls_info)
3291 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3292 int ntlmv2_flag = FALSE;
3295 /* what if server changes its buffer size after dropping the session? */
3296 if(pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
3297 rc = CIFSSMBNegotiate(xid, pSesInfo);
3298 if(rc == -EAGAIN) /* retry only once on 1st time connection */ {
3299 rc = CIFSSMBNegotiate(xid, pSesInfo);
3304 spin_lock(&GlobalMid_Lock);
3305 if(pSesInfo->server->tcpStatus != CifsExiting)
3306 pSesInfo->server->tcpStatus = CifsGood;
3309 spin_unlock(&GlobalMid_Lock);
3315 pSesInfo->capabilities = pSesInfo->server->capabilities;
3316 if(linuxExtEnabled == 0)
3317 pSesInfo->capabilities &= (~CAP_UNIX);
3318 /* pSesInfo->sequence_number = 0;*/
3319 cFYI(1,("Security Mode: 0x%x Capabilities: 0x%x Time Zone: %d",
3320 pSesInfo->server->secMode,
3321 pSesInfo->server->capabilities,
3322 pSesInfo->server->timeZone));
3323 if(experimEnabled < 2)
3324 rc = CIFS_SessSetup(xid, pSesInfo,
3325 first_time, nls_info);
3326 else if (extended_security
3327 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3328 && (pSesInfo->server->secType == NTLMSSP)) {
3330 } else if (extended_security
3331 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3332 && (pSesInfo->server->secType == RawNTLMSSP)) {
3333 cFYI(1, ("NTLMSSP sesssetup"));
3334 rc = CIFSNTLMSSPNegotiateSessSetup(xid,
3341 cFYI(1,("Can use more secure NTLM version 2 password hash"));
3342 if(CalcNTLMv2_partial_mac_key(pSesInfo,
3347 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
3349 CalcNTLMv2_response(pSesInfo,v2_response);
3351 cifs_calculate_ntlmv2_mac_key(
3352 pSesInfo->server->mac_signing_key,
3353 response, ntlm_session_key, */
3355 /* BB Put dummy sig in SessSetup PDU? */
3362 SMBNTencrypt(pSesInfo->password,
3363 pSesInfo->server->cryptKey,
3367 cifs_calculate_mac_key(
3368 pSesInfo->server->mac_signing_key,
3370 pSesInfo->password);
3372 /* for better security the weaker lanman hash not sent
3373 in AuthSessSetup so we no longer calculate it */
3375 rc = CIFSNTLMSSPAuthSessSetup(xid,
3381 } else { /* old style NTLM 0.12 session setup */
3382 SMBNTencrypt(pSesInfo->password,
3383 pSesInfo->server->cryptKey,
3387 cifs_calculate_mac_key(
3388 pSesInfo->server->mac_signing_key,
3389 ntlm_session_key, pSesInfo->password);
3391 rc = CIFSSessSetup(xid, pSesInfo,
3392 ntlm_session_key, nls_info);
3395 cERROR(1,("Send error in SessSetup = %d",rc));
3397 cFYI(1,("CIFS Session Established successfully"));
3398 pSesInfo->status = CifsGood;