4 * Copyright (C) International Business Machines Corp., 2002,2007
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <linux/net.h>
23 #include <linux/string.h>
24 #include <linux/list.h>
25 #include <linux/wait.h>
26 #include <linux/ipv6.h>
27 #include <linux/pagemap.h>
28 #include <linux/ctype.h>
29 #include <linux/utsname.h>
30 #include <linux/mempool.h>
31 #include <linux/delay.h>
32 #include <linux/completion.h>
33 #include <linux/kthread.h>
34 #include <linux/pagevec.h>
35 #include <linux/freezer.h>
36 #include <asm/uaccess.h>
37 #include <asm/processor.h>
40 #include "cifsproto.h"
41 #include "cifs_unicode.h"
42 #include "cifs_debug.h"
43 #include "cifs_fs_sb.h"
46 #include "rfc1002pdu.h"
50 #define RFC1001_PORT 139
52 static DECLARE_COMPLETION(cifsd_complete);
54 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
57 extern mempool_t *cifs_req_poolp;
65 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
66 char *iocharset; /* local code page for mapping to and from Unicode */
67 char source_rfc1001_name[16]; /* netbios name of client */
68 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
78 unsigned override_uid:1;
79 unsigned override_gid:1;
81 unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
83 unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/
84 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
86 unsigned remap:1; /* set to remap seven reserved chars in filenames */
87 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
89 unsigned nullauth:1; /* attempt to authenticate with null user */
90 unsigned nocase; /* request case insensitive filenames */
91 unsigned nobrl; /* disable sending byte range locks to srv */
95 unsigned short int port;
99 static int ipv4_connect(struct sockaddr_in *psin_server,
100 struct socket **csocket,
102 char *server_netb_name);
103 static int ipv6_connect(struct sockaddr_in6 *psin_server,
104 struct socket **csocket);
108 * cifs tcp session reconnection
110 * mark tcp session as reconnecting so temporarily locked
111 * mark all smb sessions as reconnecting for tcp session
112 * reconnect tcp session
113 * wake up waiters on reconnection? - (not needed currently)
117 cifs_reconnect(struct TCP_Server_Info *server)
120 struct list_head *tmp;
121 struct cifsSesInfo *ses;
122 struct cifsTconInfo *tcon;
123 struct mid_q_entry *mid_entry;
125 spin_lock(&GlobalMid_Lock);
126 if ( kthread_should_stop() ) {
127 /* the demux thread will exit normally
128 next time through the loop */
129 spin_unlock(&GlobalMid_Lock);
132 server->tcpStatus = CifsNeedReconnect;
133 spin_unlock(&GlobalMid_Lock);
136 cFYI(1, ("Reconnecting tcp session"));
138 /* before reconnecting the tcp session, mark the smb session (uid)
139 and the tid bad so they are not used until reconnected */
140 read_lock(&GlobalSMBSeslock);
141 list_for_each(tmp, &GlobalSMBSessionList) {
142 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
144 if (ses->server == server) {
145 ses->status = CifsNeedReconnect;
149 /* else tcp and smb sessions need reconnection */
151 list_for_each(tmp, &GlobalTreeConnectionList) {
152 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
153 if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
154 tcon->tidStatus = CifsNeedReconnect;
157 read_unlock(&GlobalSMBSeslock);
158 /* do not want to be sending data on a socket we are freeing */
159 down(&server->tcpSem);
160 if (server->ssocket) {
161 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
162 server->ssocket->flags));
163 server->ssocket->ops->shutdown(server->ssocket, SEND_SHUTDOWN);
164 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
165 server->ssocket->state,
166 server->ssocket->flags));
167 sock_release(server->ssocket);
168 server->ssocket = NULL;
171 spin_lock(&GlobalMid_Lock);
172 list_for_each(tmp, &server->pending_mid_q) {
173 mid_entry = list_entry(tmp, struct
177 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
178 /* Mark other intransit requests as needing
179 retry so we do not immediately mark the
180 session bad again (ie after we reconnect
181 below) as they timeout too */
182 mid_entry->midState = MID_RETRY_NEEDED;
186 spin_unlock(&GlobalMid_Lock);
189 while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
191 if (server->protocolType == IPV6) {
192 rc = ipv6_connect(&server->addr.sockAddr6,
195 rc = ipv4_connect(&server->addr.sockAddr,
197 server->workstation_RFC1001_name,
198 server->server_RFC1001_name);
201 cFYI(1, ("reconnect error %d", rc));
204 atomic_inc(&tcpSesReconnectCount);
205 spin_lock(&GlobalMid_Lock);
206 if ( !kthread_should_stop() )
207 server->tcpStatus = CifsGood;
208 server->sequence_number = 0;
209 spin_unlock(&GlobalMid_Lock);
210 /* atomic_set(&server->inFlight,0);*/
211 wake_up(&server->response_q);
219 0 not a transact2, or all data present
220 >0 transact2 with that much data missing
221 -EINVAL = invalid transact2
224 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
226 struct smb_t2_rsp *pSMBt;
228 int data_in_this_rsp;
231 if (pSMB->Command != SMB_COM_TRANSACTION2)
234 /* check for plausible wct, bcc and t2 data and parm sizes */
235 /* check for parm and data offset going beyond end of smb */
236 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
237 cFYI(1, ("invalid transact2 word count"));
241 pSMBt = (struct smb_t2_rsp *)pSMB;
243 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
244 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
246 remaining = total_data_size - data_in_this_rsp;
250 else if (remaining < 0) {
251 cFYI(1, ("total data %d smaller than data in frame %d",
252 total_data_size, data_in_this_rsp));
255 cFYI(1, ("missing %d bytes from transact2, check next response",
257 if (total_data_size > maxBufSize) {
258 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
259 total_data_size, maxBufSize));
266 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
268 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
269 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
274 char *data_area_of_target;
275 char *data_area_of_buf2;
278 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
280 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
281 cFYI(1, ("total data sizes of primary and secondary t2 differ"));
284 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
286 remaining = total_data_size - total_in_buf;
291 if (remaining == 0) /* nothing to do, ignore */
294 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
295 if (remaining < total_in_buf2) {
296 cFYI(1, ("transact2 2nd response contains too much data"));
299 /* find end of first SMB data area */
300 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
301 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
302 /* validate target area */
304 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
305 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
307 data_area_of_target += total_in_buf;
309 /* copy second buffer into end of first buffer */
310 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
311 total_in_buf += total_in_buf2;
312 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
313 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
314 byte_count += total_in_buf2;
315 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
317 byte_count = pTargetSMB->smb_buf_length;
318 byte_count += total_in_buf2;
320 /* BB also add check that we are not beyond maximum buffer size */
322 pTargetSMB->smb_buf_length = byte_count;
324 if (remaining == total_in_buf2) {
325 cFYI(1, ("found the last secondary response"));
326 return 0; /* we are done */
327 } else /* more responses to go */
333 cifs_demultiplex_thread(struct TCP_Server_Info *server)
336 unsigned int pdu_length, total_read;
337 struct smb_hdr *smb_buffer = NULL;
338 struct smb_hdr *bigbuf = NULL;
339 struct smb_hdr *smallbuf = NULL;
340 struct msghdr smb_msg;
342 struct socket *csocket = server->ssocket;
343 struct list_head *tmp;
344 struct cifsSesInfo *ses;
345 struct task_struct *task_to_wake = NULL;
346 struct mid_q_entry *mid_entry;
348 int isLargeBuf = FALSE;
352 current->flags |= PF_MEMALLOC;
353 server->tsk = current; /* save process info to wake at shutdown */
354 cFYI(1, ("Demultiplex PID: %d", current->pid));
355 write_lock(&GlobalSMBSeslock);
356 atomic_inc(&tcpSesAllocCount);
357 length = tcpSesAllocCount.counter;
358 write_unlock(&GlobalSMBSeslock);
359 complete(&cifsd_complete);
361 mempool_resize(cifs_req_poolp,
362 length + cifs_min_rcv,
366 while (!kthread_should_stop()) {
369 if (bigbuf == NULL) {
370 bigbuf = cifs_buf_get();
372 cERROR(1, ("No memory for large SMB response"));
374 /* retry will check if exiting */
377 } else if (isLargeBuf) {
378 /* we are reusing a dirty large buf, clear its start */
379 memset(bigbuf, 0, sizeof (struct smb_hdr));
382 if (smallbuf == NULL) {
383 smallbuf = cifs_small_buf_get();
385 cERROR(1, ("No memory for SMB response"));
387 /* retry will check if exiting */
390 /* beginning of smb buffer is cleared in our buf_get */
391 } else /* if existing small buf clear beginning */
392 memset(smallbuf, 0, sizeof (struct smb_hdr));
396 smb_buffer = smallbuf;
397 iov.iov_base = smb_buffer;
399 smb_msg.msg_control = NULL;
400 smb_msg.msg_controllen = 0;
402 kernel_recvmsg(csocket, &smb_msg,
403 &iov, 1, 4, 0 /* BB see socket.h flags */);
405 if ( kthread_should_stop() ) {
407 } else if (server->tcpStatus == CifsNeedReconnect) {
408 cFYI(1, ("Reconnect after server stopped responding"));
409 cifs_reconnect(server);
410 cFYI(1, ("call to reconnect done"));
411 csocket = server->ssocket;
413 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
414 msleep(1); /* minimum sleep to prevent looping
415 allowing socket to clear and app threads to set
416 tcpStatus CifsNeedReconnect if server hung */
418 } else if (length <= 0) {
419 if (server->tcpStatus == CifsNew) {
420 cFYI(1, ("tcp session abend after SMBnegprot"));
421 /* some servers kill the TCP session rather than
422 returning an SMB negprot error, in which
423 case reconnecting here is not going to help,
424 and so simply return error to mount */
427 if (!try_to_freeze() && (length == -EINTR)) {
428 cFYI(1, ("cifsd thread killed"));
431 cFYI(1, ("Reconnect after unexpected peek error %d",
433 cifs_reconnect(server);
434 csocket = server->ssocket;
435 wake_up(&server->response_q);
437 } else if (length < 4) {
439 ("Frame under four bytes received (%d bytes long)",
441 cifs_reconnect(server);
442 csocket = server->ssocket;
443 wake_up(&server->response_q);
447 /* The right amount was read from socket - 4 bytes */
448 /* so we can now interpret the length field */
450 /* the first byte big endian of the length field,
451 is actually not part of the length but the type
452 with the most common, zero, as regular data */
453 temp = *((char *) smb_buffer);
455 /* Note that FC 1001 length is big endian on the wire,
456 but we convert it here so it is always manipulated
457 as host byte order */
458 pdu_length = ntohl(smb_buffer->smb_buf_length);
459 smb_buffer->smb_buf_length = pdu_length;
461 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
463 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
465 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
466 cFYI(1, ("Good RFC 1002 session rsp"));
468 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
469 /* we get this from Windows 98 instead of
470 an error on SMB negprot response */
471 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
473 if (server->tcpStatus == CifsNew) {
474 /* if nack on negprot (rather than
475 ret of smb negprot error) reconnecting
476 not going to help, ret error to mount */
479 /* give server a second to
480 clean up before reconnect attempt */
482 /* always try 445 first on reconnect
483 since we get NACK on some if we ever
484 connected to port 139 (the NACK is
485 since we do not begin with RFC1001
486 session initialize frame) */
487 server->addr.sockAddr.sin_port =
489 cifs_reconnect(server);
490 csocket = server->ssocket;
491 wake_up(&server->response_q);
494 } else if (temp != (char) 0) {
495 cERROR(1, ("Unknown RFC 1002 frame"));
496 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
498 cifs_reconnect(server);
499 csocket = server->ssocket;
503 /* else we have an SMB response */
504 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
505 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
506 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
507 length, pdu_length+4));
508 cifs_reconnect(server);
509 csocket = server->ssocket;
510 wake_up(&server->response_q);
517 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
519 memcpy(bigbuf, smallbuf, 4);
523 iov.iov_base = 4 + (char *)smb_buffer;
524 iov.iov_len = pdu_length;
525 for (total_read = 0; total_read < pdu_length;
526 total_read += length) {
527 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
528 pdu_length - total_read, 0);
529 if ( kthread_should_stop() ||
530 (length == -EINTR)) {
534 } else if (server->tcpStatus == CifsNeedReconnect) {
535 cifs_reconnect(server);
536 csocket = server->ssocket;
537 /* Reconnect wakes up rspns q */
538 /* Now we will reread sock */
541 } else if ((length == -ERESTARTSYS) ||
542 (length == -EAGAIN)) {
543 msleep(1); /* minimum sleep to prevent looping,
544 allowing socket to clear and app
545 threads to set tcpStatus
546 CifsNeedReconnect if server hung*/
548 } else if (length <= 0) {
549 cERROR(1, ("Received no data, expecting %d",
550 pdu_length - total_read));
551 cifs_reconnect(server);
552 csocket = server->ssocket;
559 else if (reconnect == 1)
562 length += 4; /* account for rfc1002 hdr */
565 dump_smb(smb_buffer, length);
566 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
567 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
573 spin_lock(&GlobalMid_Lock);
574 list_for_each(tmp, &server->pending_mid_q) {
575 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
577 if ((mid_entry->mid == smb_buffer->Mid) &&
578 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
579 (mid_entry->command == smb_buffer->Command)) {
580 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
581 /* We have a multipart transact2 resp */
583 if (mid_entry->resp_buf) {
584 /* merge response - fix up 1st*/
585 if (coalesce_t2(smb_buffer,
586 mid_entry->resp_buf)) {
587 mid_entry->multiRsp = 1;
590 /* all parts received */
591 mid_entry->multiEnd = 1;
596 cERROR(1,("1st trans2 resp needs bigbuf"));
597 /* BB maybe we can fix this up, switch
598 to already allocated large buffer? */
600 /* Have first buffer */
601 mid_entry->resp_buf =
603 mid_entry->largeBuf = 1;
609 mid_entry->resp_buf = smb_buffer;
611 mid_entry->largeBuf = 1;
613 mid_entry->largeBuf = 0;
615 task_to_wake = mid_entry->tsk;
616 mid_entry->midState = MID_RESPONSE_RECEIVED;
617 #ifdef CONFIG_CIFS_STATS2
618 mid_entry->when_received = jiffies;
620 /* so we do not time out requests to server
621 which is still responding (since server could
622 be busy but not dead) */
623 server->lstrp = jiffies;
627 spin_unlock(&GlobalMid_Lock);
629 /* Was previous buf put in mpx struct for multi-rsp? */
631 /* smb buffer will be freed by user thread */
637 wake_up_process(task_to_wake);
638 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE)
639 && (isMultiRsp == FALSE)) {
640 cERROR(1, ("No task to wake, unknown frame received! "
641 "NumMids %d", midCount.counter));
642 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
643 sizeof(struct smb_hdr));
644 #ifdef CONFIG_CIFS_DEBUG2
645 cifs_dump_detail(smb_buffer);
646 cifs_dump_mids(server);
647 #endif /* CIFS_DEBUG2 */
650 } /* end while !EXITING */
652 spin_lock(&GlobalMid_Lock);
653 server->tcpStatus = CifsExiting;
655 /* check if we have blocked requests that need to free */
656 /* Note that cifs_max_pending is normally 50, but
657 can be set at module install time to as little as two */
658 if (atomic_read(&server->inFlight) >= cifs_max_pending)
659 atomic_set(&server->inFlight, cifs_max_pending - 1);
660 /* We do not want to set the max_pending too low or we
661 could end up with the counter going negative */
662 spin_unlock(&GlobalMid_Lock);
663 /* Although there should not be any requests blocked on
664 this queue it can not hurt to be paranoid and try to wake up requests
665 that may haven been blocked when more than 50 at time were on the wire
666 to the same server - they now will see the session is in exit state
667 and get out of SendReceive. */
668 wake_up_all(&server->request_q);
669 /* give those requests time to exit */
672 if (server->ssocket) {
673 sock_release(csocket);
674 server->ssocket = NULL;
676 /* buffer usuallly freed in free_mid - need to free it here on exit */
678 cifs_buf_release(bigbuf);
679 if (smallbuf != NULL)
680 cifs_small_buf_release(smallbuf);
682 read_lock(&GlobalSMBSeslock);
683 if (list_empty(&server->pending_mid_q)) {
684 /* loop through server session structures attached to this and
686 list_for_each(tmp, &GlobalSMBSessionList) {
688 list_entry(tmp, struct cifsSesInfo,
690 if (ses->server == server) {
691 ses->status = CifsExiting;
695 read_unlock(&GlobalSMBSeslock);
697 /* although we can not zero the server struct pointer yet,
698 since there are active requests which may depnd on them,
699 mark the corresponding SMB sessions as exiting too */
700 list_for_each(tmp, &GlobalSMBSessionList) {
701 ses = list_entry(tmp, struct cifsSesInfo,
703 if (ses->server == server) {
704 ses->status = CifsExiting;
708 spin_lock(&GlobalMid_Lock);
709 list_for_each(tmp, &server->pending_mid_q) {
710 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
711 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
712 cFYI(1, ("Clearing Mid 0x%x - waking up ",
714 task_to_wake = mid_entry->tsk;
716 wake_up_process(task_to_wake);
720 spin_unlock(&GlobalMid_Lock);
721 read_unlock(&GlobalSMBSeslock);
722 /* 1/8th of sec is more than enough time for them to exit */
726 if (!list_empty(&server->pending_mid_q)) {
727 /* mpx threads have not exited yet give them
728 at least the smb send timeout time for long ops */
729 /* due to delays on oplock break requests, we need
730 to wait at least 45 seconds before giving up
731 on a request getting a response and going ahead
733 cFYI(1, ("Wait for exit from demultiplex thread"));
735 /* if threads still have not exited they are probably never
736 coming home not much else we can do but free the memory */
739 write_lock(&GlobalSMBSeslock);
740 atomic_dec(&tcpSesAllocCount);
741 length = tcpSesAllocCount.counter;
743 /* last chance to mark ses pointers invalid
744 if there are any pointing to this (e.g
745 if a crazy root user tried to kill cifsd
746 kernel thread explicitly this might happen) */
747 list_for_each(tmp, &GlobalSMBSessionList) {
748 ses = list_entry(tmp, struct cifsSesInfo,
750 if (ses->server == server) {
754 write_unlock(&GlobalSMBSeslock);
758 mempool_resize(cifs_req_poolp,
759 length + cifs_min_rcv,
767 cifs_parse_mount_options(char *options, const char *devname,
772 unsigned int temp_len, i, j;
778 if (Local_System_Name[0] != 0)
779 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
781 char *nodename = utsname()->nodename;
782 int n = strnlen(nodename, 15);
783 memset(vol->source_rfc1001_name, 0x20, 15);
784 for (i = 0; i < n; i++) {
785 /* does not have to be perfect mapping since field is
786 informational, only used for servers that do not support
787 port 445 and it can be overridden at mount time */
788 vol->source_rfc1001_name[i] = toupper(nodename[i]);
791 vol->source_rfc1001_name[15] = 0;
792 /* null target name indicates to use *SMBSERVR default called name
793 if we end up sending RFC1001 session initialize */
794 vol->target_rfc1001_name[0] = 0;
795 vol->linux_uid = current->uid; /* current->euid instead? */
796 vol->linux_gid = current->gid;
797 vol->dir_mode = S_IRWXUGO;
798 /* 2767 perms indicate mandatory locking support */
799 vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
801 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
803 /* default is always to request posix paths. */
804 vol->posix_paths = 1;
809 if (strncmp(options, "sep=", 4) == 0) {
810 if (options[4] != 0) {
811 separator[0] = options[4];
814 cFYI(1, ("Null separator not allowed"));
818 while ((data = strsep(&options, separator)) != NULL) {
821 if ((value = strchr(data, '=')) != NULL)
824 /* Have to parse this before we parse for "user" */
825 if (strnicmp(data, "user_xattr", 10) == 0) {
827 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
829 } else if (strnicmp(data, "user", 4) == 0) {
832 "CIFS: invalid or missing username\n");
833 return 1; /* needs_arg; */
834 } else if (!*value) {
835 /* null user, ie anonymous, authentication */
838 if (strnlen(value, 200) < 200) {
839 vol->username = value;
841 printk(KERN_WARNING "CIFS: username too long\n");
844 } else if (strnicmp(data, "pass", 4) == 0) {
846 vol->password = NULL;
848 } else if (value[0] == 0) {
849 /* check if string begins with double comma
850 since that would mean the password really
851 does start with a comma, and would not
852 indicate an empty string */
853 if (value[1] != separator[0]) {
854 vol->password = NULL;
858 temp_len = strlen(value);
859 /* removed password length check, NTLM passwords
860 can be arbitrarily long */
862 /* if comma in password, the string will be
863 prematurely null terminated. Commas in password are
864 specified across the cifs mount interface by a double
865 comma ie ,, and a comma used as in other cases ie ','
866 as a parameter delimiter/separator is single and due
867 to the strsep above is temporarily zeroed. */
869 /* NB: password legally can have multiple commas and
870 the only illegal character in a password is null */
872 if ((value[temp_len] == 0) &&
873 (value[temp_len+1] == separator[0])) {
875 value[temp_len] = separator[0];
876 temp_len += 2; /* move after second comma */
877 while (value[temp_len] != 0) {
878 if (value[temp_len] == separator[0]) {
879 if (value[temp_len+1] ==
881 /* skip second comma */
884 /* single comma indicating start
891 if (value[temp_len] == 0) {
895 /* point option to start of next parm */
896 options = value + temp_len + 1;
898 /* go from value to value + temp_len condensing
899 double commas to singles. Note that this ends up
900 allocating a few bytes too many, which is ok */
901 vol->password = kzalloc(temp_len, GFP_KERNEL);
902 if (vol->password == NULL) {
903 printk(KERN_WARNING "CIFS: no memory "
907 for (i = 0, j = 0; i < temp_len; i++, j++) {
908 vol->password[j] = value[i];
909 if (value[i] == separator[0]
910 && value[i+1] == separator[0]) {
911 /* skip second comma */
915 vol->password[j] = 0;
917 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
918 if (vol->password == NULL) {
919 printk(KERN_WARNING "CIFS: no memory "
923 strcpy(vol->password, value);
925 } else if (strnicmp(data, "ip", 2) == 0) {
926 if (!value || !*value) {
928 } else if (strnlen(value, 35) < 35) {
931 printk(KERN_WARNING "CIFS: ip address "
935 } else if (strnicmp(data, "sec", 3) == 0) {
936 if (!value || !*value) {
937 cERROR(1, ("no security value specified"));
939 } else if (strnicmp(value, "krb5i", 5) == 0) {
940 vol->secFlg |= CIFSSEC_MAY_KRB5 |
942 } else if (strnicmp(value, "krb5p", 5) == 0) {
943 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
945 cERROR(1, ("Krb5 cifs privacy not supported"));
947 } else if (strnicmp(value, "krb5", 4) == 0) {
948 vol->secFlg |= CIFSSEC_MAY_KRB5;
949 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
950 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
952 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
953 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
954 } else if (strnicmp(value, "ntlmi", 5) == 0) {
955 vol->secFlg |= CIFSSEC_MAY_NTLM |
957 } else if (strnicmp(value, "ntlm", 4) == 0) {
958 /* ntlm is default so can be turned off too */
959 vol->secFlg |= CIFSSEC_MAY_NTLM;
960 } else if (strnicmp(value, "nontlm", 6) == 0) {
961 /* BB is there a better way to do this? */
962 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
963 #ifdef CONFIG_CIFS_WEAK_PW_HASH
964 } else if (strnicmp(value, "lanman", 6) == 0) {
965 vol->secFlg |= CIFSSEC_MAY_LANMAN;
967 } else if (strnicmp(value, "none", 4) == 0) {
970 cERROR(1, ("bad security option: %s", value));
973 } else if ((strnicmp(data, "unc", 3) == 0)
974 || (strnicmp(data, "target", 6) == 0)
975 || (strnicmp(data, "path", 4) == 0)) {
976 if (!value || !*value) {
977 printk(KERN_WARNING "CIFS: invalid path to "
978 "network resource\n");
979 return 1; /* needs_arg; */
981 if ((temp_len = strnlen(value, 300)) < 300) {
982 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
983 if (vol->UNC == NULL)
985 strcpy(vol->UNC, value);
986 if (strncmp(vol->UNC, "//", 2) == 0) {
989 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
991 "CIFS: UNC Path does not begin "
992 "with // or \\\\ \n");
996 printk(KERN_WARNING "CIFS: UNC name too long\n");
999 } else if ((strnicmp(data, "domain", 3) == 0)
1000 || (strnicmp(data, "workgroup", 5) == 0)) {
1001 if (!value || !*value) {
1002 printk(KERN_WARNING "CIFS: invalid domain name\n");
1003 return 1; /* needs_arg; */
1005 /* BB are there cases in which a comma can be valid in
1006 a domain name and need special handling? */
1007 if (strnlen(value, 256) < 256) {
1008 vol->domainname = value;
1009 cFYI(1, ("Domain name set"));
1011 printk(KERN_WARNING "CIFS: domain name too "
1015 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1016 if (!value || !*value) {
1018 "CIFS: invalid path prefix\n");
1019 return 1; /* needs_argument */
1021 if ((temp_len = strnlen(value, 1024)) < 1024) {
1022 if (value[0] != '/')
1023 temp_len++; /* missing leading slash */
1024 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1025 if (vol->prepath == NULL)
1027 if (value[0] != '/') {
1028 vol->prepath[0] = '/';
1029 strcpy(vol->prepath+1, value);
1031 strcpy(vol->prepath, value);
1032 cFYI(1, ("prefix path %s", vol->prepath));
1034 printk(KERN_WARNING "CIFS: prefix too long\n");
1037 } else if (strnicmp(data, "iocharset", 9) == 0) {
1038 if (!value || !*value) {
1039 printk(KERN_WARNING "CIFS: invalid iocharset specified\n");
1040 return 1; /* needs_arg; */
1042 if (strnlen(value, 65) < 65) {
1043 if (strnicmp(value, "default", 7))
1044 vol->iocharset = value;
1045 /* if iocharset not set then load_nls_default
1046 is used by caller */
1047 cFYI(1, ("iocharset set to %s", value));
1049 printk(KERN_WARNING "CIFS: iocharset name too long.\n");
1052 } else if (strnicmp(data, "uid", 3) == 0) {
1053 if (value && *value) {
1055 simple_strtoul(value, &value, 0);
1056 vol->override_uid = 1;
1058 } else if (strnicmp(data, "gid", 3) == 0) {
1059 if (value && *value) {
1061 simple_strtoul(value, &value, 0);
1062 vol->override_gid = 1;
1064 } else if (strnicmp(data, "file_mode", 4) == 0) {
1065 if (value && *value) {
1067 simple_strtoul(value, &value, 0);
1069 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1070 if (value && *value) {
1072 simple_strtoul(value, &value, 0);
1074 } else if (strnicmp(data, "dirmode", 4) == 0) {
1075 if (value && *value) {
1077 simple_strtoul(value, &value, 0);
1079 } else if (strnicmp(data, "port", 4) == 0) {
1080 if (value && *value) {
1082 simple_strtoul(value, &value, 0);
1084 } else if (strnicmp(data, "rsize", 5) == 0) {
1085 if (value && *value) {
1087 simple_strtoul(value, &value, 0);
1089 } else if (strnicmp(data, "wsize", 5) == 0) {
1090 if (value && *value) {
1092 simple_strtoul(value, &value, 0);
1094 } else if (strnicmp(data, "sockopt", 5) == 0) {
1095 if (value && *value) {
1097 simple_strtoul(value, &value, 0);
1099 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1100 if (!value || !*value || (*value == ' ')) {
1101 cFYI(1, ("invalid (empty) netbiosname specified"));
1103 memset(vol->source_rfc1001_name, 0x20, 15);
1104 for (i = 0; i < 15; i++) {
1105 /* BB are there cases in which a comma can be
1106 valid in this workstation netbios name (and need
1107 special handling)? */
1109 /* We do not uppercase netbiosname for user */
1113 vol->source_rfc1001_name[i] =
1116 /* The string has 16th byte zero still from
1117 set at top of the function */
1118 if ((i == 15) && (value[i] != 0))
1119 printk(KERN_WARNING "CIFS: netbiosname"
1120 " longer than 15 truncated.\n");
1122 } else if (strnicmp(data, "servern", 7) == 0) {
1123 /* servernetbiosname specified override *SMBSERVER */
1124 if (!value || !*value || (*value == ' ')) {
1125 cFYI(1, ("empty server netbiosname specified"));
1127 /* last byte, type, is 0x20 for servr type */
1128 memset(vol->target_rfc1001_name, 0x20, 16);
1130 for (i = 0; i < 15; i++) {
1131 /* BB are there cases in which a comma can be
1132 valid in this workstation netbios name
1133 (and need special handling)? */
1135 /* user or mount helper must uppercase
1140 vol->target_rfc1001_name[i] =
1143 /* The string has 16th byte zero still from
1144 set at top of the function */
1145 if ((i == 15) && (value[i] != 0))
1146 printk(KERN_WARNING "CIFS: server net"
1147 "biosname longer than 15 truncated.\n");
1149 } else if (strnicmp(data, "credentials", 4) == 0) {
1151 } else if (strnicmp(data, "version", 3) == 0) {
1153 } else if (strnicmp(data, "guest", 5) == 0) {
1155 } else if (strnicmp(data, "rw", 2) == 0) {
1157 } else if ((strnicmp(data, "suid", 4) == 0) ||
1158 (strnicmp(data, "nosuid", 6) == 0) ||
1159 (strnicmp(data, "exec", 4) == 0) ||
1160 (strnicmp(data, "noexec", 6) == 0) ||
1161 (strnicmp(data, "nodev", 5) == 0) ||
1162 (strnicmp(data, "noauto", 6) == 0) ||
1163 (strnicmp(data, "dev", 3) == 0)) {
1164 /* The mount tool or mount.cifs helper (if present)
1165 uses these opts to set flags, and the flags are read
1166 by the kernel vfs layer before we get here (ie
1167 before read super) so there is no point trying to
1168 parse these options again and set anything and it
1169 is ok to just ignore them */
1171 } else if (strnicmp(data, "ro", 2) == 0) {
1173 } else if (strnicmp(data, "hard", 4) == 0) {
1175 } else if (strnicmp(data, "soft", 4) == 0) {
1177 } else if (strnicmp(data, "perm", 4) == 0) {
1179 } else if (strnicmp(data, "noperm", 6) == 0) {
1181 } else if (strnicmp(data, "mapchars", 8) == 0) {
1183 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1185 } else if (strnicmp(data, "sfu", 3) == 0) {
1187 } else if (strnicmp(data, "nosfu", 5) == 0) {
1189 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1190 vol->posix_paths = 1;
1191 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1192 vol->posix_paths = 0;
1193 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1194 (strnicmp(data, "ignorecase", 10) == 0)) {
1196 } else if (strnicmp(data, "brl", 3) == 0) {
1198 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1199 (strnicmp(data, "nolock", 6) == 0)) {
1201 /* turn off mandatory locking in mode
1202 if remote locking is turned off since the
1203 local vfs will do advisory */
1204 if (vol->file_mode ==
1205 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1206 vol->file_mode = S_IALLUGO;
1207 } else if (strnicmp(data, "setuids", 7) == 0) {
1209 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1211 } else if (strnicmp(data, "nohard", 6) == 0) {
1213 } else if (strnicmp(data, "nosoft", 6) == 0) {
1215 } else if (strnicmp(data, "nointr", 6) == 0) {
1217 } else if (strnicmp(data, "intr", 4) == 0) {
1219 } else if (strnicmp(data, "serverino", 7) == 0) {
1220 vol->server_ino = 1;
1221 } else if (strnicmp(data, "noserverino", 9) == 0) {
1222 vol->server_ino = 0;
1223 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1225 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1227 } else if (strnicmp(data, "acl", 3) == 0) {
1228 vol->no_psx_acl = 0;
1229 } else if (strnicmp(data, "noacl", 5) == 0) {
1230 vol->no_psx_acl = 1;
1231 } else if (strnicmp(data, "sign", 4) == 0) {
1232 vol->secFlg |= CIFSSEC_MUST_SIGN;
1233 /* } else if (strnicmp(data, "seal",4) == 0) {
1234 vol->secFlg |= CIFSSEC_MUST_SEAL; */
1235 } else if (strnicmp(data, "direct", 6) == 0) {
1237 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1239 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1240 if (!value || !*value) {
1241 vol->in6_addr = NULL;
1242 } else if (strnlen(value, 49) == 48) {
1243 vol->in6_addr = value;
1245 printk(KERN_WARNING "CIFS: ip v6 address not "
1246 "48 characters long\n");
1249 } else if (strnicmp(data, "noac", 4) == 0) {
1250 printk(KERN_WARNING "CIFS: Mount option noac not "
1251 "supported. Instead set "
1252 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1254 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1257 if (vol->UNC == NULL) {
1258 if (devname == NULL) {
1259 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1263 if ((temp_len = strnlen(devname, 300)) < 300) {
1264 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1265 if (vol->UNC == NULL)
1267 strcpy(vol->UNC, devname);
1268 if (strncmp(vol->UNC, "//", 2) == 0) {
1271 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1272 printk(KERN_WARNING "CIFS: UNC Path does not "
1273 "begin with // or \\\\ \n");
1277 printk(KERN_WARNING "CIFS: UNC name too long\n");
1281 if (vol->UNCip == NULL)
1282 vol->UNCip = &vol->UNC[2];
1287 static struct cifsSesInfo *
1288 cifs_find_tcp_session(struct in_addr *target_ip_addr,
1289 struct in6_addr *target_ip6_addr,
1290 char *userName, struct TCP_Server_Info **psrvTcp)
1292 struct list_head *tmp;
1293 struct cifsSesInfo *ses;
1295 read_lock(&GlobalSMBSeslock);
1297 list_for_each(tmp, &GlobalSMBSessionList) {
1298 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1300 if ((target_ip_addr &&
1301 (ses->server->addr.sockAddr.sin_addr.s_addr
1302 == target_ip_addr->s_addr)) || (target_ip6_addr
1303 && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1304 target_ip6_addr, sizeof(*target_ip6_addr)))) {
1305 /* BB lock server and tcp session and increment
1308 /* found a match on the TCP session */
1309 *psrvTcp = ses->server;
1311 /* BB check if reconnection needed */
1313 (ses->userName, userName,
1314 MAX_USERNAME_SIZE) == 0){
1315 read_unlock(&GlobalSMBSeslock);
1316 /* Found exact match on both TCP and
1322 /* else tcp and smb sessions need reconnection */
1324 read_unlock(&GlobalSMBSeslock);
1328 static struct cifsTconInfo *
1329 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1331 struct list_head *tmp;
1332 struct cifsTconInfo *tcon;
1334 read_lock(&GlobalSMBSeslock);
1335 list_for_each(tmp, &GlobalTreeConnectionList) {
1336 cFYI(1, ("Next tcon"));
1337 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1339 if (tcon->ses->server) {
1341 ("old ip addr: %x == new ip %x ?",
1342 tcon->ses->server->addr.sockAddr.sin_addr.
1343 s_addr, new_target_ip_addr));
1344 if (tcon->ses->server->addr.sockAddr.sin_addr.
1345 s_addr == new_target_ip_addr) {
1346 /* BB lock tcon, server and tcp session and increment use count here? */
1347 /* found a match on the TCP session */
1348 /* BB check if reconnection needed */
1350 ("IP match, old UNC: %s new: %s",
1351 tcon->treeName, uncName));
1353 (tcon->treeName, uncName,
1354 MAX_TREE_SIZE) == 0) {
1356 ("and old usr: %s new: %s",
1357 tcon->treeName, uncName));
1359 (tcon->ses->userName,
1361 MAX_USERNAME_SIZE) == 0) {
1362 read_unlock(&GlobalSMBSeslock);
1363 /* matched smb session
1372 read_unlock(&GlobalSMBSeslock);
1377 connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1378 const char *old_path, const struct nls_table *nls_codepage,
1381 unsigned char *referrals = NULL;
1382 unsigned int num_referrals;
1385 rc = get_dfs_path(xid, pSesInfo, old_path, nls_codepage,
1386 &num_referrals, &referrals, remap);
1388 /* BB Add in code to: if valid refrl, if not ip address contact
1389 the helper that resolves tcp names, mount to it, try to
1390 tcon to it unmount it if fail */
1398 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1399 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1400 unsigned char **preferrals, int remap)
1405 *pnum_referrals = 0;
1407 if (pSesInfo->ipc_tid == 0) {
1408 temp_unc = kmalloc(2 /* for slashes */ +
1409 strnlen(pSesInfo->serverName,
1410 SERVER_NAME_LEN_WITH_NULL * 2)
1411 + 1 + 4 /* slash IPC$ */ + 2,
1413 if (temp_unc == NULL)
1417 strcpy(temp_unc + 2, pSesInfo->serverName);
1418 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1419 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1421 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1425 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1426 pnum_referrals, nls_codepage, remap);
1431 /* See RFC1001 section 14 on representation of Netbios names */
1432 static void rfc1002mangle(char *target, char *source, unsigned int length)
1436 for (i = 0, j = 0; i < (length); i++) {
1437 /* mask a nibble at a time and encode */
1438 target[j] = 'A' + (0x0F & (source[i] >> 4));
1439 target[j+1] = 'A' + (0x0F & source[i]);
1447 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1448 char *netbios_name, char *target_name)
1452 __be16 orig_port = 0;
1454 if (*csocket == NULL) {
1455 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1456 IPPROTO_TCP, csocket);
1458 cERROR(1, ("Error %d creating socket", rc));
1462 /* BB other socket options to set KEEPALIVE, NODELAY? */
1463 cFYI(1, ("Socket created"));
1464 (*csocket)->sk->sk_allocation = GFP_NOFS;
1468 psin_server->sin_family = AF_INET;
1469 if (psin_server->sin_port) { /* user overrode default port */
1470 rc = (*csocket)->ops->connect(*csocket,
1471 (struct sockaddr *) psin_server,
1472 sizeof (struct sockaddr_in), 0);
1478 /* save original port so we can retry user specified port
1479 later if fall back ports fail this time */
1480 orig_port = psin_server->sin_port;
1482 /* do not retry on the same port we just failed on */
1483 if (psin_server->sin_port != htons(CIFS_PORT)) {
1484 psin_server->sin_port = htons(CIFS_PORT);
1486 rc = (*csocket)->ops->connect(*csocket,
1487 (struct sockaddr *) psin_server,
1488 sizeof (struct sockaddr_in), 0);
1494 psin_server->sin_port = htons(RFC1001_PORT);
1495 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1497 sizeof (struct sockaddr_in), 0);
1502 /* give up here - unless we want to retry on different
1503 protocol families some day */
1506 psin_server->sin_port = orig_port;
1507 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1508 sock_release(*csocket);
1512 /* Eventually check for other socket options to change from
1513 the default. sock_setsockopt not used because it expects
1514 user space buffer */
1515 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1516 (*csocket)->sk->sk_sndbuf,
1517 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1518 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1519 /* make the bufsizes depend on wsize/rsize and max requests */
1520 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1521 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1522 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1523 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1525 /* send RFC1001 sessinit */
1526 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1527 /* some servers require RFC1001 sessinit before sending
1528 negprot - BB check reconnection in case where second
1529 sessinit is sent but no second negprot */
1530 struct rfc1002_session_packet *ses_init_buf;
1531 struct smb_hdr *smb_buf;
1532 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1535 ses_init_buf->trailer.session_req.called_len = 32;
1536 if (target_name && (target_name[0] != 0)) {
1537 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1540 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1541 DEFAULT_CIFS_CALLED_NAME, 16);
1544 ses_init_buf->trailer.session_req.calling_len = 32;
1545 /* calling name ends in null (byte 16) from old smb
1547 if (netbios_name && (netbios_name[0] != 0)) {
1548 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1551 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1552 "LINUX_CIFS_CLNT", 16);
1554 ses_init_buf->trailer.session_req.scope1 = 0;
1555 ses_init_buf->trailer.session_req.scope2 = 0;
1556 smb_buf = (struct smb_hdr *)ses_init_buf;
1557 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1558 smb_buf->smb_buf_length = 0x81000044;
1559 rc = smb_send(*csocket, smb_buf, 0x44,
1560 (struct sockaddr *)psin_server);
1561 kfree(ses_init_buf);
1562 msleep(1); /* RFC1001 layer in at least one server
1563 requires very short break before negprot
1564 presumably because not expecting negprot
1565 to follow so fast. This is a simple
1566 solution that works without
1567 complicating the code and causes no
1568 significant slowing down on mount
1569 for everyone else */
1571 /* else the negprot may still work without this
1572 even though malloc failed */
1580 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1584 __be16 orig_port = 0;
1586 if (*csocket == NULL) {
1587 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1588 IPPROTO_TCP, csocket);
1590 cERROR(1, ("Error %d creating ipv6 socket", rc));
1594 /* BB other socket options to set KEEPALIVE, NODELAY? */
1595 cFYI(1, ("ipv6 Socket created"));
1596 (*csocket)->sk->sk_allocation = GFP_NOFS;
1600 psin_server->sin6_family = AF_INET6;
1602 if (psin_server->sin6_port) { /* user overrode default port */
1603 rc = (*csocket)->ops->connect(*csocket,
1604 (struct sockaddr *) psin_server,
1605 sizeof (struct sockaddr_in6), 0);
1611 /* save original port so we can retry user specified port
1612 later if fall back ports fail this time */
1614 orig_port = psin_server->sin6_port;
1615 /* do not retry on the same port we just failed on */
1616 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1617 psin_server->sin6_port = htons(CIFS_PORT);
1619 rc = (*csocket)->ops->connect(*csocket,
1620 (struct sockaddr *) psin_server,
1621 sizeof (struct sockaddr_in6), 0);
1627 psin_server->sin6_port = htons(RFC1001_PORT);
1628 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1629 psin_server, sizeof (struct sockaddr_in6), 0);
1634 /* give up here - unless we want to retry on different
1635 protocol families some day */
1638 psin_server->sin6_port = orig_port;
1639 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1640 sock_release(*csocket);
1644 /* Eventually check for other socket options to change from
1645 the default. sock_setsockopt not used because it expects
1646 user space buffer */
1647 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1652 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1653 struct super_block *sb, struct smb_vol *vol_info)
1655 /* if we are reconnecting then should we check to see if
1656 * any requested capabilities changed locally e.g. via
1657 * remount but we can not do much about it here
1658 * if they have (even if we could detect it by the following)
1659 * Perhaps we could add a backpointer to array of sb from tcon
1660 * or if we change to make all sb to same share the same
1661 * sb as NFS - then we only have one backpointer to sb.
1662 * What if we wanted to mount the server share twice once with
1663 * and once without posixacls or posix paths? */
1664 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1667 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1668 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1670 /* check for reconnect case in which we do not
1671 want to change the mount behavior if we can avoid it */
1672 if (vol_info == NULL) {
1673 /* turn off POSIX ACL and PATHNAMES if not set
1674 originally at mount time */
1675 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1676 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1677 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0)
1678 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1685 cap &= CIFS_UNIX_CAP_MASK;
1686 if (vol_info && vol_info->no_psx_acl)
1687 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1688 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
1689 cFYI(1, ("negotiated posix acl support"));
1691 sb->s_flags |= MS_POSIXACL;
1694 if (vol_info && vol_info->posix_paths == 0)
1695 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1696 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1697 cFYI(1, ("negotiate posix pathnames"));
1699 CIFS_SB(sb)->mnt_cifs_flags |=
1700 CIFS_MOUNT_POSIX_PATHS;
1703 /* We might be setting the path sep back to a different
1704 form if we are reconnecting and the server switched its
1705 posix path capability for this share */
1706 if (sb && (CIFS_SB(sb)->prepathlen > 0))
1707 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1709 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
1710 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
1711 CIFS_SB(sb)->rsize = 127 * 1024;
1712 #ifdef CONFIG_CIFS_DEBUG2
1713 cFYI(1, ("larger reads not supported by srv"));
1719 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
1720 #ifdef CONFIG_CIFS_DEBUG2
1721 if (cap & CIFS_UNIX_FCNTL_CAP)
1722 cFYI(1, ("FCNTL cap"));
1723 if (cap & CIFS_UNIX_EXTATTR_CAP)
1724 cFYI(1, ("EXTATTR cap"));
1725 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1726 cFYI(1, ("POSIX path cap"));
1727 if (cap & CIFS_UNIX_XATTR_CAP)
1728 cFYI(1, ("XATTR cap"));
1729 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
1730 cFYI(1, ("POSIX ACL cap"));
1731 if (cap & CIFS_UNIX_LARGE_READ_CAP)
1732 cFYI(1, ("very large read cap"));
1733 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
1734 cFYI(1, ("very large write cap"));
1735 #endif /* CIFS_DEBUG2 */
1736 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1737 cFYI(1, ("setting capabilities failed"));
1743 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1744 char *mount_data, const char *devname)
1748 int address_type = AF_INET;
1749 struct socket *csocket = NULL;
1750 struct sockaddr_in sin_server;
1751 struct sockaddr_in6 sin_server6;
1752 struct smb_vol volume_info;
1753 struct cifsSesInfo *pSesInfo = NULL;
1754 struct cifsSesInfo *existingCifsSes = NULL;
1755 struct cifsTconInfo *tcon = NULL;
1756 struct TCP_Server_Info *srvTcp = NULL;
1760 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1762 memset(&volume_info, 0, sizeof(struct smb_vol));
1763 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1764 kfree(volume_info.UNC);
1765 kfree(volume_info.password);
1766 kfree(volume_info.prepath);
1771 if (volume_info.nullauth) {
1772 cFYI(1, ("null user"));
1773 volume_info.username = NULL;
1774 } else if (volume_info.username) {
1775 /* BB fixme parse for domain name here */
1776 cFYI(1, ("Username: %s", volume_info.username));
1778 cifserror("No username specified");
1779 /* In userspace mount helper we can get user name from alternate
1780 locations such as env variables and files on disk */
1781 kfree(volume_info.UNC);
1782 kfree(volume_info.password);
1783 kfree(volume_info.prepath);
1788 if (volume_info.UNCip && volume_info.UNC) {
1789 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
1790 &sin_server.sin_addr.s_addr);
1793 /* not ipv4 address, try ipv6 */
1794 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
1795 &sin_server6.sin6_addr.in6_u);
1797 address_type = AF_INET6;
1799 address_type = AF_INET;
1803 /* we failed translating address */
1804 kfree(volume_info.UNC);
1805 kfree(volume_info.password);
1806 kfree(volume_info.prepath);
1811 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1814 } else if (volume_info.UNCip) {
1815 /* BB using ip addr as server name to connect to the
1817 cERROR(1, ("Connecting to DFS root not implemented yet"));
1818 kfree(volume_info.UNC);
1819 kfree(volume_info.password);
1820 kfree(volume_info.prepath);
1823 } else /* which servers DFS root would we conect to */ {
1825 ("CIFS mount error: No UNC path (e.g. -o "
1826 "unc=//192.168.1.100/public) specified"));
1827 kfree(volume_info.UNC);
1828 kfree(volume_info.password);
1829 kfree(volume_info.prepath);
1834 /* this is needed for ASCII cp to Unicode converts */
1835 if (volume_info.iocharset == NULL) {
1836 cifs_sb->local_nls = load_nls_default();
1837 /* load_nls_default can not return null */
1839 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1840 if (cifs_sb->local_nls == NULL) {
1841 cERROR(1, ("CIFS mount error: iocharset %s not found",
1842 volume_info.iocharset));
1843 kfree(volume_info.UNC);
1844 kfree(volume_info.password);
1845 kfree(volume_info.prepath);
1851 if (address_type == AF_INET)
1852 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1853 NULL /* no ipv6 addr */,
1854 volume_info.username, &srvTcp);
1855 else if (address_type == AF_INET6) {
1856 cFYI(1, ("looking for ipv6 address"));
1857 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1858 &sin_server6.sin6_addr,
1859 volume_info.username, &srvTcp);
1861 kfree(volume_info.UNC);
1862 kfree(volume_info.password);
1863 kfree(volume_info.prepath);
1869 cFYI(1, ("Existing tcp session with server found"));
1870 } else { /* create socket */
1871 if (volume_info.port)
1872 sin_server.sin_port = htons(volume_info.port);
1874 sin_server.sin_port = 0;
1875 if (address_type == AF_INET6) {
1876 cFYI(1, ("attempting ipv6 connect"));
1877 /* BB should we allow ipv6 on port 139? */
1878 /* other OS never observed in Wild doing 139 with v6 */
1879 rc = ipv6_connect(&sin_server6, &csocket);
1881 rc = ipv4_connect(&sin_server, &csocket,
1882 volume_info.source_rfc1001_name,
1883 volume_info.target_rfc1001_name);
1885 cERROR(1, ("Error connecting to IPv4 socket. "
1886 "Aborting operation"));
1887 if (csocket != NULL)
1888 sock_release(csocket);
1889 kfree(volume_info.UNC);
1890 kfree(volume_info.password);
1891 kfree(volume_info.prepath);
1896 srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
1897 if (srvTcp == NULL) {
1899 sock_release(csocket);
1900 kfree(volume_info.UNC);
1901 kfree(volume_info.password);
1902 kfree(volume_info.prepath);
1906 memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
1907 memcpy(&srvTcp->addr.sockAddr, &sin_server,
1908 sizeof (struct sockaddr_in));
1909 atomic_set(&srvTcp->inFlight, 0);
1910 /* BB Add code for ipv6 case too */
1911 srvTcp->ssocket = csocket;
1912 srvTcp->protocolType = IPV4;
1913 init_waitqueue_head(&srvTcp->response_q);
1914 init_waitqueue_head(&srvTcp->request_q);
1915 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
1916 /* at this point we are the only ones with the pointer
1917 to the struct since the kernel thread not created yet
1918 so no need to spinlock this init of tcpStatus */
1919 srvTcp->tcpStatus = CifsNew;
1920 init_MUTEX(&srvTcp->tcpSem);
1921 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
1922 if ( IS_ERR(srvTcp->tsk) ) {
1923 rc = PTR_ERR(srvTcp->tsk);
1924 cERROR(1, ("error %d create cifsd thread", rc));
1926 sock_release(csocket);
1927 kfree(volume_info.UNC);
1928 kfree(volume_info.password);
1929 kfree(volume_info.prepath);
1933 wait_for_completion(&cifsd_complete);
1935 memcpy(srvTcp->workstation_RFC1001_name,
1936 volume_info.source_rfc1001_name, 16);
1937 memcpy(srvTcp->server_RFC1001_name,
1938 volume_info.target_rfc1001_name, 16);
1939 srvTcp->sequence_number = 0;
1943 if (existingCifsSes) {
1944 pSesInfo = existingCifsSes;
1945 cFYI(1, ("Existing smb sess found"));
1946 kfree(volume_info.password);
1947 /* volume_info.UNC freed at end of function */
1949 cFYI(1, ("Existing smb sess not found"));
1950 pSesInfo = sesInfoAlloc();
1951 if (pSesInfo == NULL)
1954 pSesInfo->server = srvTcp;
1955 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
1956 NIPQUAD(sin_server.sin_addr.s_addr));
1960 /* volume_info.password freed at unmount */
1961 if (volume_info.password)
1962 pSesInfo->password = volume_info.password;
1963 if (volume_info.username)
1964 strncpy(pSesInfo->userName,
1965 volume_info.username,
1967 if (volume_info.domainname) {
1968 int len = strlen(volume_info.domainname);
1969 pSesInfo->domainName =
1970 kmalloc(len + 1, GFP_KERNEL);
1971 if (pSesInfo->domainName)
1972 strcpy(pSesInfo->domainName,
1973 volume_info.domainname);
1975 pSesInfo->linux_uid = volume_info.linux_uid;
1976 pSesInfo->overrideSecFlg = volume_info.secFlg;
1977 down(&pSesInfo->sesSem);
1978 /* BB FIXME need to pass vol->secFlgs BB */
1979 rc = cifs_setup_session(xid, pSesInfo,
1980 cifs_sb->local_nls);
1981 up(&pSesInfo->sesSem);
1983 atomic_inc(&srvTcp->socketUseCount);
1985 kfree(volume_info.password);
1988 /* search for existing tcon to this server share */
1990 if (volume_info.rsize > CIFSMaxBufSize) {
1991 cERROR(1, ("rsize %d too large, using MaxBufSize",
1992 volume_info.rsize));
1993 cifs_sb->rsize = CIFSMaxBufSize;
1994 } else if ((volume_info.rsize) &&
1995 (volume_info.rsize <= CIFSMaxBufSize))
1996 cifs_sb->rsize = volume_info.rsize;
1998 cifs_sb->rsize = CIFSMaxBufSize;
2000 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2001 cERROR(1, ("wsize %d too large, using 4096 instead",
2002 volume_info.wsize));
2003 cifs_sb->wsize = 4096;
2004 } else if (volume_info.wsize)
2005 cifs_sb->wsize = volume_info.wsize;
2008 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2010 /* old default of CIFSMaxBufSize was too small now
2011 that SMB Write2 can send multiple pages in kvec.
2012 RFC1001 does not describe what happens when frame
2013 bigger than 128K is sent so use that as max in
2014 conjunction with 52K kvec constraint on arch with 4K
2017 if (cifs_sb->rsize < 2048) {
2018 cifs_sb->rsize = 2048;
2019 /* Windows ME may prefer this */
2020 cFYI(1, ("readsize set to minimum: 2048"));
2022 /* calculate prepath */
2023 cifs_sb->prepath = volume_info.prepath;
2024 if (cifs_sb->prepath) {
2025 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2026 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
2027 volume_info.prepath = NULL;
2029 cifs_sb->prepathlen = 0;
2030 cifs_sb->mnt_uid = volume_info.linux_uid;
2031 cifs_sb->mnt_gid = volume_info.linux_gid;
2032 cifs_sb->mnt_file_mode = volume_info.file_mode;
2033 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
2034 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2035 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2037 if (volume_info.noperm)
2038 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2039 if (volume_info.setuids)
2040 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2041 if (volume_info.server_ino)
2042 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2043 if (volume_info.remap)
2044 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2045 if (volume_info.no_xattr)
2046 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2047 if (volume_info.sfu_emul)
2048 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2049 if (volume_info.nobrl)
2050 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2051 if (volume_info.cifs_acl)
2052 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2053 if (volume_info.override_uid)
2054 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2055 if (volume_info.override_gid)
2056 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2057 if (volume_info.direct_io) {
2058 cFYI(1, ("mounting share using direct i/o"));
2059 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2063 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
2064 volume_info.username);
2066 cFYI(1, ("Found match on UNC path"));
2067 /* we can have only one retry value for a connection
2068 to a share so for resources mounted more than once
2069 to the same server share the last value passed in
2070 for the retry flag is used */
2071 tcon->retry = volume_info.retry;
2072 tcon->nocase = volume_info.nocase;
2074 tcon = tconInfoAlloc();
2078 /* check for null share name ie connecting to
2081 /* BB check if this works for exactly length
2083 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2084 && (strchr(volume_info.UNC + 3, '/') ==
2086 rc = connect_to_dfs_path(xid, pSesInfo,
2087 "", cifs_sb->local_nls,
2088 cifs_sb->mnt_cifs_flags &
2089 CIFS_MOUNT_MAP_SPECIAL_CHR);
2090 kfree(volume_info.UNC);
2094 /* BB Do we need to wrap sesSem around
2095 * this TCon call and Unix SetFS as
2096 * we do on SessSetup and reconnect? */
2097 rc = CIFSTCon(xid, pSesInfo,
2099 tcon, cifs_sb->local_nls);
2100 cFYI(1, ("CIFS Tcon rc = %d", rc));
2103 atomic_inc(&pSesInfo->inUse);
2104 tcon->retry = volume_info.retry;
2105 tcon->nocase = volume_info.nocase;
2111 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2112 sb->s_maxbytes = (u64) 1 << 63;
2114 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2117 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2118 sb->s_time_gran = 100;
2120 /* on error free sesinfo and tcon struct if needed */
2122 /* if session setup failed, use count is zero but
2123 we still need to free cifsd thread */
2124 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2125 spin_lock(&GlobalMid_Lock);
2126 srvTcp->tcpStatus = CifsExiting;
2127 spin_unlock(&GlobalMid_Lock);
2129 struct task_struct *tsk;
2130 /* If we could verify that kthread_stop would
2131 always wake up processes blocked in
2132 tcp in recv_mesg then we could remove the
2134 force_sig(SIGKILL, srvTcp->tsk);
2140 /* If find_unc succeeded then rc == 0 so we can not end */
2141 if (tcon) /* up accidently freeing someone elses tcon struct */
2143 if (existingCifsSes == NULL) {
2145 if ((pSesInfo->server) &&
2146 (pSesInfo->status == CifsGood)) {
2148 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2149 /* if the socketUseCount is now zero */
2150 if ((temp_rc == -ESHUTDOWN) &&
2151 (pSesInfo->server) &&
2152 (pSesInfo->server->tsk)) {
2153 struct task_struct *tsk;
2155 pSesInfo->server->tsk);
2156 tsk = pSesInfo->server->tsk;
2161 cFYI(1, ("No session or bad tcon"));
2162 sesInfoFree(pSesInfo);
2163 /* pSesInfo = NULL; */
2167 atomic_inc(&tcon->useCount);
2168 cifs_sb->tcon = tcon;
2169 tcon->ses = pSesInfo;
2171 /* do not care if following two calls succeed - informational */
2172 CIFSSMBQFSDeviceInfo(xid, tcon);
2173 CIFSSMBQFSAttributeInfo(xid, tcon);
2175 /* tell server which Unix caps we support */
2176 if (tcon->ses->capabilities & CAP_UNIX)
2177 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2178 else if (cifs_sb->rsize > (1024 * 127)) {
2179 cifs_sb->rsize = 1024 * 127;
2180 #ifdef CONFIG_CIFS_DEBUG2
2181 cFYI(1, ("no very large read support, rsize 127K"));
2185 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2186 cifs_sb->wsize = min(cifs_sb->wsize,
2187 (tcon->ses->server->maxBuf -
2188 MAX_CIFS_HDR_SIZE));
2189 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2190 cifs_sb->rsize = min(cifs_sb->rsize,
2191 (tcon->ses->server->maxBuf -
2192 MAX_CIFS_HDR_SIZE));
2195 /* volume_info.password is freed above when existing session found
2196 (in which case it is not needed anymore) but when new sesion is created
2197 the password ptr is put in the new session structure (in which case the
2198 password will be freed at unmount time) */
2199 kfree(volume_info.UNC);
2200 kfree(volume_info.prepath);
2206 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2207 char session_key[CIFS_SESS_KEY_SIZE],
2208 const struct nls_table *nls_codepage)
2210 struct smb_hdr *smb_buffer;
2211 struct smb_hdr *smb_buffer_response;
2212 SESSION_SETUP_ANDX *pSMB;
2213 SESSION_SETUP_ANDX *pSMBr;
2218 int remaining_words = 0;
2219 int bytes_returned = 0;
2224 cFYI(1, ("In sesssetup"));
2227 user = ses->userName;
2228 domain = ses->domainName;
2229 smb_buffer = cifs_buf_get();
2230 if (smb_buffer == NULL) {
2233 smb_buffer_response = smb_buffer;
2234 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2236 /* send SMBsessionSetup here */
2237 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2238 NULL /* no tCon exists yet */ , 13 /* wct */ );
2240 smb_buffer->Mid = GetNextMid(ses->server);
2241 pSMB->req_no_secext.AndXCommand = 0xFF;
2242 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2243 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2245 if (ses->server->secMode &
2246 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2247 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2249 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2250 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2251 if (ses->capabilities & CAP_UNICODE) {
2252 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2253 capabilities |= CAP_UNICODE;
2255 if (ses->capabilities & CAP_STATUS32) {
2256 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2257 capabilities |= CAP_STATUS32;
2259 if (ses->capabilities & CAP_DFS) {
2260 smb_buffer->Flags2 |= SMBFLG2_DFS;
2261 capabilities |= CAP_DFS;
2263 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2265 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2266 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2268 pSMB->req_no_secext.CaseSensitivePasswordLength =
2269 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2270 bcc_ptr = pByteArea(smb_buffer);
2271 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2272 bcc_ptr += CIFS_SESS_KEY_SIZE;
2273 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2274 bcc_ptr += CIFS_SESS_KEY_SIZE;
2276 if (ses->capabilities & CAP_UNICODE) {
2277 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2282 bytes_returned = 0; /* skip null user */
2285 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2287 /* convert number of 16 bit words to bytes */
2288 bcc_ptr += 2 * bytes_returned;
2289 bcc_ptr += 2; /* trailing null */
2292 cifs_strtoUCS((__le16 *) bcc_ptr,
2293 "CIFS_LINUX_DOM", 32, nls_codepage);
2296 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2298 bcc_ptr += 2 * bytes_returned;
2301 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2303 bcc_ptr += 2 * bytes_returned;
2305 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2307 bcc_ptr += 2 * bytes_returned;
2310 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2312 bcc_ptr += 2 * bytes_returned;
2316 strncpy(bcc_ptr, user, 200);
2317 bcc_ptr += strnlen(user, 200);
2321 if (domain == NULL) {
2322 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2323 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2325 strncpy(bcc_ptr, domain, 64);
2326 bcc_ptr += strnlen(domain, 64);
2330 strcpy(bcc_ptr, "Linux version ");
2331 bcc_ptr += strlen("Linux version ");
2332 strcpy(bcc_ptr, utsname()->release);
2333 bcc_ptr += strlen(utsname()->release) + 1;
2334 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2335 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2337 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2338 smb_buffer->smb_buf_length += count;
2339 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2341 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2342 &bytes_returned, 1);
2344 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2345 } else if ((smb_buffer_response->WordCount == 3)
2346 || (smb_buffer_response->WordCount == 4)) {
2347 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2348 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2349 if (action & GUEST_LOGIN)
2350 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2351 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2353 cFYI(1, ("UID = %d ", ses->Suid));
2354 /* response can have either 3 or 4 word count - Samba sends 3 */
2355 bcc_ptr = pByteArea(smb_buffer_response);
2356 if ((pSMBr->resp.hdr.WordCount == 3)
2357 || ((pSMBr->resp.hdr.WordCount == 4)
2358 && (blob_len < pSMBr->resp.ByteCount))) {
2359 if (pSMBr->resp.hdr.WordCount == 4)
2360 bcc_ptr += blob_len;
2362 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2363 if ((long) (bcc_ptr) % 2) {
2365 (BCC(smb_buffer_response) - 1) / 2;
2366 /* Unicode strings must be word
2371 BCC(smb_buffer_response) / 2;
2374 UniStrnlen((wchar_t *) bcc_ptr,
2375 remaining_words - 1);
2376 /* We look for obvious messed up bcc or strings in response so we do not go off
2377 the end since (at least) WIN2K and Windows XP have a major bug in not null
2378 terminating last Unicode string in response */
2380 kfree(ses->serverOS);
2381 ses->serverOS = kzalloc(2 * (len + 1),
2383 if (ses->serverOS == NULL)
2384 goto sesssetup_nomem;
2385 cifs_strfromUCS_le(ses->serverOS,
2388 bcc_ptr += 2 * (len + 1);
2389 remaining_words -= len + 1;
2390 ses->serverOS[2 * len] = 0;
2391 ses->serverOS[1 + (2 * len)] = 0;
2392 if (remaining_words > 0) {
2393 len = UniStrnlen((wchar_t *)bcc_ptr,
2395 kfree(ses->serverNOS);
2396 ses->serverNOS = kzalloc(2 * (len + 1),
2398 if (ses->serverNOS == NULL)
2399 goto sesssetup_nomem;
2400 cifs_strfromUCS_le(ses->serverNOS,
2403 bcc_ptr += 2 * (len + 1);
2404 ses->serverNOS[2 * len] = 0;
2405 ses->serverNOS[1 + (2 * len)] = 0;
2406 if (strncmp(ses->serverNOS,
2407 "NT LAN Manager 4", 16) == 0) {
2408 cFYI(1, ("NT4 server"));
2409 ses->flags |= CIFS_SES_NT4;
2411 remaining_words -= len + 1;
2412 if (remaining_words > 0) {
2413 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2414 /* last string is not always null terminated
2415 (for e.g. for Windows XP & 2000) */
2416 if (ses->serverDomain)
2417 kfree(ses->serverDomain);
2421 if (ses->serverDomain == NULL)
2422 goto sesssetup_nomem;
2423 cifs_strfromUCS_le(ses->serverDomain,
2426 bcc_ptr += 2 * (len + 1);
2427 ses->serverDomain[2*len] = 0;
2428 ses->serverDomain[1+(2*len)] = 0;
2429 } else { /* else no more room so create
2430 dummy domain string */
2431 if (ses->serverDomain)
2432 kfree(ses->serverDomain);
2434 kzalloc(2, GFP_KERNEL);
2436 } else { /* no room so create dummy domain
2439 /* if these kcallocs fail not much we
2440 can do, but better to not fail the
2442 kfree(ses->serverDomain);
2444 kzalloc(2, GFP_KERNEL);
2445 kfree(ses->serverNOS);
2447 kzalloc(2, GFP_KERNEL);
2449 } else { /* ASCII */
2450 len = strnlen(bcc_ptr, 1024);
2451 if (((long) bcc_ptr + len) - (long)
2452 pByteArea(smb_buffer_response)
2453 <= BCC(smb_buffer_response)) {
2454 kfree(ses->serverOS);
2455 ses->serverOS = kzalloc(len + 1,
2457 if (ses->serverOS == NULL)
2458 goto sesssetup_nomem;
2459 strncpy(ses->serverOS, bcc_ptr, len);
2462 /* null terminate the string */
2466 len = strnlen(bcc_ptr, 1024);
2467 kfree(ses->serverNOS);
2468 ses->serverNOS = kzalloc(len + 1,
2470 if (ses->serverNOS == NULL)
2471 goto sesssetup_nomem;
2472 strncpy(ses->serverNOS, bcc_ptr, len);
2477 len = strnlen(bcc_ptr, 1024);
2478 if (ses->serverDomain)
2479 kfree(ses->serverDomain);
2480 ses->serverDomain = kzalloc(len + 1,
2482 if (ses->serverDomain == NULL)
2483 goto sesssetup_nomem;
2484 strncpy(ses->serverDomain, bcc_ptr,
2491 ("Variable field of length %d "
2492 "extends beyond end of smb ",
2497 (" Security Blob Length extends beyond "
2502 (" Invalid Word count %d: ",
2503 smb_buffer_response->WordCount));
2506 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2507 since that could make reconnection harder, and
2508 reconnection might be needed to free memory */
2510 cifs_buf_release(smb_buffer);
2516 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2517 struct cifsSesInfo *ses, int *pNTLMv2_flag,
2518 const struct nls_table *nls_codepage)
2520 struct smb_hdr *smb_buffer;
2521 struct smb_hdr *smb_buffer_response;
2522 SESSION_SETUP_ANDX *pSMB;
2523 SESSION_SETUP_ANDX *pSMBr;
2527 int remaining_words = 0;
2528 int bytes_returned = 0;
2530 int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
2531 PNEGOTIATE_MESSAGE SecurityBlob;
2532 PCHALLENGE_MESSAGE SecurityBlob2;
2533 __u32 negotiate_flags, capabilities;
2536 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2539 domain = ses->domainName;
2540 *pNTLMv2_flag = FALSE;
2541 smb_buffer = cifs_buf_get();
2542 if (smb_buffer == NULL) {
2545 smb_buffer_response = smb_buffer;
2546 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2547 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2549 /* send SMBsessionSetup here */
2550 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2551 NULL /* no tCon exists yet */ , 12 /* wct */ );
2553 smb_buffer->Mid = GetNextMid(ses->server);
2554 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2555 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2557 pSMB->req.AndXCommand = 0xFF;
2558 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2559 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2561 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2562 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2564 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2565 CAP_EXTENDED_SECURITY;
2566 if (ses->capabilities & CAP_UNICODE) {
2567 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2568 capabilities |= CAP_UNICODE;
2570 if (ses->capabilities & CAP_STATUS32) {
2571 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2572 capabilities |= CAP_STATUS32;
2574 if (ses->capabilities & CAP_DFS) {
2575 smb_buffer->Flags2 |= SMBFLG2_DFS;
2576 capabilities |= CAP_DFS;
2578 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2580 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2581 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2582 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2583 SecurityBlob->MessageType = NtLmNegotiate;
2585 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2586 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2587 NTLMSSP_NEGOTIATE_56 |
2588 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2590 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2591 /* if (ntlmv2_support)
2592 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2593 /* setup pointers to domain name and workstation name */
2594 bcc_ptr += SecurityBlobLength;
2596 SecurityBlob->WorkstationName.Buffer = 0;
2597 SecurityBlob->WorkstationName.Length = 0;
2598 SecurityBlob->WorkstationName.MaximumLength = 0;
2600 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2601 along with username on auth request (ie the response to challenge) */
2602 SecurityBlob->DomainName.Buffer = 0;
2603 SecurityBlob->DomainName.Length = 0;
2604 SecurityBlob->DomainName.MaximumLength = 0;
2605 if (ses->capabilities & CAP_UNICODE) {
2606 if ((long) bcc_ptr % 2) {
2612 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2614 bcc_ptr += 2 * bytes_returned;
2616 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2618 bcc_ptr += 2 * bytes_returned;
2619 bcc_ptr += 2; /* null terminate Linux version */
2621 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2623 bcc_ptr += 2 * bytes_returned;
2626 bcc_ptr += 2; /* null terminate network opsys string */
2629 bcc_ptr += 2; /* null domain */
2630 } else { /* ASCII */
2631 strcpy(bcc_ptr, "Linux version ");
2632 bcc_ptr += strlen("Linux version ");
2633 strcpy(bcc_ptr, utsname()->release);
2634 bcc_ptr += strlen(utsname()->release) + 1;
2635 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2636 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2637 bcc_ptr++; /* empty domain field */
2640 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2641 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2642 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2643 smb_buffer->smb_buf_length += count;
2644 pSMB->req.ByteCount = cpu_to_le16(count);
2646 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2647 &bytes_returned, 1);
2649 if (smb_buffer_response->Status.CifsError ==
2650 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2654 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2655 } else if ((smb_buffer_response->WordCount == 3)
2656 || (smb_buffer_response->WordCount == 4)) {
2657 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2658 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2660 if (action & GUEST_LOGIN)
2661 cFYI(1, (" Guest login"));
2662 /* Do we want to set anything in SesInfo struct when guest login? */
2664 bcc_ptr = pByteArea(smb_buffer_response);
2665 /* response can have either 3 or 4 word count - Samba sends 3 */
2667 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2668 if (SecurityBlob2->MessageType != NtLmChallenge) {
2670 ("Unexpected NTLMSSP message type received %d",
2671 SecurityBlob2->MessageType));
2673 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2674 cFYI(1, ("UID = %d", ses->Suid));
2675 if ((pSMBr->resp.hdr.WordCount == 3)
2676 || ((pSMBr->resp.hdr.WordCount == 4)
2678 pSMBr->resp.ByteCount))) {
2680 if (pSMBr->resp.hdr.WordCount == 4) {
2681 bcc_ptr += blob_len;
2682 cFYI(1, ("Security Blob Length %d",
2686 cFYI(1, ("NTLMSSP Challenge rcvd"));
2688 memcpy(ses->server->cryptKey,
2689 SecurityBlob2->Challenge,
2690 CIFS_CRYPTO_KEY_SIZE);
2691 if (SecurityBlob2->NegotiateFlags &
2692 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2693 *pNTLMv2_flag = TRUE;
2695 if ((SecurityBlob2->NegotiateFlags &
2696 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2697 || (sign_CIFS_PDUs > 1))
2698 ses->server->secMode |=
2699 SECMODE_SIGN_REQUIRED;
2700 if ((SecurityBlob2->NegotiateFlags &
2701 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2702 ses->server->secMode |=
2703 SECMODE_SIGN_ENABLED;
2705 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2706 if ((long) (bcc_ptr) % 2) {
2708 (BCC(smb_buffer_response)
2710 /* Must word align unicode strings */
2715 (smb_buffer_response) / 2;
2718 UniStrnlen((wchar_t *) bcc_ptr,
2719 remaining_words - 1);
2720 /* We look for obvious messed up bcc or strings in response so we do not go off
2721 the end since (at least) WIN2K and Windows XP have a major bug in not null
2722 terminating last Unicode string in response */
2724 kfree(ses->serverOS);
2726 kzalloc(2 * (len + 1), GFP_KERNEL);
2727 cifs_strfromUCS_le(ses->serverOS,
2731 bcc_ptr += 2 * (len + 1);
2732 remaining_words -= len + 1;
2733 ses->serverOS[2 * len] = 0;
2734 ses->serverOS[1 + (2 * len)] = 0;
2735 if (remaining_words > 0) {
2736 len = UniStrnlen((wchar_t *)
2740 kfree(ses->serverNOS);
2742 kzalloc(2 * (len + 1),
2744 cifs_strfromUCS_le(ses->
2750 bcc_ptr += 2 * (len + 1);
2751 ses->serverNOS[2 * len] = 0;
2754 remaining_words -= len + 1;
2755 if (remaining_words > 0) {
2756 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2757 /* last string not always null terminated
2758 (for e.g. for Windows XP & 2000) */
2759 kfree(ses->serverDomain);
2771 ses->serverDomain[2*len]
2776 } /* else no more room so create dummy domain string */
2778 kfree(ses->serverDomain);
2783 } else { /* no room so create dummy domain and NOS string */
2784 kfree(ses->serverDomain);
2786 kzalloc(2, GFP_KERNEL);
2787 kfree(ses->serverNOS);
2789 kzalloc(2, GFP_KERNEL);
2791 } else { /* ASCII */
2792 len = strnlen(bcc_ptr, 1024);
2793 if (((long) bcc_ptr + len) - (long)
2794 pByteArea(smb_buffer_response)
2795 <= BCC(smb_buffer_response)) {
2797 kfree(ses->serverOS);
2801 strncpy(ses->serverOS,
2805 bcc_ptr[0] = 0; /* null terminate string */
2808 len = strnlen(bcc_ptr, 1024);
2809 kfree(ses->serverNOS);
2813 strncpy(ses->serverNOS, bcc_ptr, len);
2818 len = strnlen(bcc_ptr, 1024);
2819 kfree(ses->serverDomain);
2823 strncpy(ses->serverDomain,
2830 ("Variable field of length %d extends beyond end of smb",
2834 cERROR(1, ("Security Blob Length extends beyond"
2838 cERROR(1, ("No session structure passed in."));
2842 (" Invalid Word count %d:",
2843 smb_buffer_response->WordCount));
2848 cifs_buf_release(smb_buffer);
2853 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2854 char *ntlm_session_key, int ntlmv2_flag,
2855 const struct nls_table *nls_codepage)
2857 struct smb_hdr *smb_buffer;
2858 struct smb_hdr *smb_buffer_response;
2859 SESSION_SETUP_ANDX *pSMB;
2860 SESSION_SETUP_ANDX *pSMBr;
2865 int remaining_words = 0;
2866 int bytes_returned = 0;
2868 int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
2869 PAUTHENTICATE_MESSAGE SecurityBlob;
2870 __u32 negotiate_flags, capabilities;
2873 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2876 user = ses->userName;
2877 domain = ses->domainName;
2878 smb_buffer = cifs_buf_get();
2879 if (smb_buffer == NULL) {
2882 smb_buffer_response = smb_buffer;
2883 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2884 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2886 /* send SMBsessionSetup here */
2887 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2888 NULL /* no tCon exists yet */ , 12 /* wct */ );
2890 smb_buffer->Mid = GetNextMid(ses->server);
2891 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2892 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2893 pSMB->req.AndXCommand = 0xFF;
2894 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2895 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2897 pSMB->req.hdr.Uid = ses->Suid;
2899 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2900 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2902 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2903 CAP_EXTENDED_SECURITY;
2904 if (ses->capabilities & CAP_UNICODE) {
2905 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2906 capabilities |= CAP_UNICODE;
2908 if (ses->capabilities & CAP_STATUS32) {
2909 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2910 capabilities |= CAP_STATUS32;
2912 if (ses->capabilities & CAP_DFS) {
2913 smb_buffer->Flags2 |= SMBFLG2_DFS;
2914 capabilities |= CAP_DFS;
2916 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2918 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2919 SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
2920 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2921 SecurityBlob->MessageType = NtLmAuthenticate;
2922 bcc_ptr += SecurityBlobLength;
2924 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
2925 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
2926 0x80000000 | NTLMSSP_NEGOTIATE_128;
2928 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
2930 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2932 /* setup pointers to domain name and workstation name */
2934 SecurityBlob->WorkstationName.Buffer = 0;
2935 SecurityBlob->WorkstationName.Length = 0;
2936 SecurityBlob->WorkstationName.MaximumLength = 0;
2937 SecurityBlob->SessionKey.Length = 0;
2938 SecurityBlob->SessionKey.MaximumLength = 0;
2939 SecurityBlob->SessionKey.Buffer = 0;
2941 SecurityBlob->LmChallengeResponse.Length = 0;
2942 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
2943 SecurityBlob->LmChallengeResponse.Buffer = 0;
2945 SecurityBlob->NtChallengeResponse.Length =
2946 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2947 SecurityBlob->NtChallengeResponse.MaximumLength =
2948 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2949 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
2950 SecurityBlob->NtChallengeResponse.Buffer =
2951 cpu_to_le32(SecurityBlobLength);
2952 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
2953 bcc_ptr += CIFS_SESS_KEY_SIZE;
2955 if (ses->capabilities & CAP_UNICODE) {
2956 if (domain == NULL) {
2957 SecurityBlob->DomainName.Buffer = 0;
2958 SecurityBlob->DomainName.Length = 0;
2959 SecurityBlob->DomainName.MaximumLength = 0;
2962 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2965 SecurityBlob->DomainName.MaximumLength =
2967 SecurityBlob->DomainName.Buffer =
2968 cpu_to_le32(SecurityBlobLength);
2970 SecurityBlobLength += len;
2971 SecurityBlob->DomainName.Length =
2975 SecurityBlob->UserName.Buffer = 0;
2976 SecurityBlob->UserName.Length = 0;
2977 SecurityBlob->UserName.MaximumLength = 0;
2980 cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
2983 SecurityBlob->UserName.MaximumLength =
2985 SecurityBlob->UserName.Buffer =
2986 cpu_to_le32(SecurityBlobLength);
2988 SecurityBlobLength += len;
2989 SecurityBlob->UserName.Length =
2993 /* SecurityBlob->WorkstationName.Length = cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
2994 SecurityBlob->WorkstationName.Length *= 2;
2995 SecurityBlob->WorkstationName.MaximumLength = cpu_to_le16(SecurityBlob->WorkstationName.Length);
2996 SecurityBlob->WorkstationName.Buffer = cpu_to_le32(SecurityBlobLength);
2997 bcc_ptr += SecurityBlob->WorkstationName.Length;
2998 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
2999 SecurityBlob->WorkstationName.Length = cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3001 if ((long) bcc_ptr % 2) {
3006 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3008 bcc_ptr += 2 * bytes_returned;
3010 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3012 bcc_ptr += 2 * bytes_returned;
3013 bcc_ptr += 2; /* null term version string */
3015 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3017 bcc_ptr += 2 * bytes_returned;
3020 bcc_ptr += 2; /* null terminate network opsys string */
3023 bcc_ptr += 2; /* null domain */
3024 } else { /* ASCII */
3025 if (domain == NULL) {
3026 SecurityBlob->DomainName.Buffer = 0;
3027 SecurityBlob->DomainName.Length = 0;
3028 SecurityBlob->DomainName.MaximumLength = 0;
3031 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3032 strncpy(bcc_ptr, domain, 63);
3033 len = strnlen(domain, 64);
3034 SecurityBlob->DomainName.MaximumLength =
3036 SecurityBlob->DomainName.Buffer =
3037 cpu_to_le32(SecurityBlobLength);
3039 SecurityBlobLength += len;
3040 SecurityBlob->DomainName.Length = cpu_to_le16(len);
3043 SecurityBlob->UserName.Buffer = 0;
3044 SecurityBlob->UserName.Length = 0;
3045 SecurityBlob->UserName.MaximumLength = 0;
3048 strncpy(bcc_ptr, user, 63);
3049 len = strnlen(user, 64);
3050 SecurityBlob->UserName.MaximumLength =
3052 SecurityBlob->UserName.Buffer =
3053 cpu_to_le32(SecurityBlobLength);
3055 SecurityBlobLength += len;
3056 SecurityBlob->UserName.Length = cpu_to_le16(len);
3058 /* BB fill in our workstation name if known BB */
3060 strcpy(bcc_ptr, "Linux version ");
3061 bcc_ptr += strlen("Linux version ");
3062 strcpy(bcc_ptr, utsname()->release);
3063 bcc_ptr += strlen(utsname()->release) + 1;
3064 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3065 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3066 bcc_ptr++; /* null domain */
3069 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3070 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3071 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3072 smb_buffer->smb_buf_length += count;
3073 pSMB->req.ByteCount = cpu_to_le16(count);
3075 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3076 &bytes_returned, 1);
3078 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
3079 } else if ((smb_buffer_response->WordCount == 3)
3080 || (smb_buffer_response->WordCount == 4)) {
3081 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3083 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3084 if (action & GUEST_LOGIN)
3085 cFYI(1, (" Guest login")); /* BB Should we set anything
3086 in SesInfo struct ? */
3087 /* if (SecurityBlob2->MessageType != NtLm??) {
3088 cFYI("Unexpected message type on auth response is %d"));
3093 ("Check challenge UID %d vs auth response UID %d",
3094 ses->Suid, smb_buffer_response->Uid));
3095 /* UID left in wire format */
3096 ses->Suid = smb_buffer_response->Uid;
3097 bcc_ptr = pByteArea(smb_buffer_response);
3098 /* response can have either 3 or 4 word count - Samba sends 3 */
3099 if ((pSMBr->resp.hdr.WordCount == 3)
3100 || ((pSMBr->resp.hdr.WordCount == 4)
3102 pSMBr->resp.ByteCount))) {
3103 if (pSMBr->resp.hdr.WordCount == 4) {
3107 ("Security Blob Length %d ",
3112 ("NTLMSSP response to Authenticate "));
3114 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3115 if ((long) (bcc_ptr) % 2) {
3117 (BCC(smb_buffer_response)
3119 bcc_ptr++; /* Unicode strings must be word aligned */
3121 remaining_words = BCC(smb_buffer_response) / 2;
3124 UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
3125 /* We look for obvious messed up bcc or strings in response so we do not go off
3126 the end since (at least) WIN2K and Windows XP have a major bug in not null
3127 terminating last Unicode string in response */
3129 kfree(ses->serverOS);
3131 kzalloc(2 * (len + 1), GFP_KERNEL);
3132 cifs_strfromUCS_le(ses->serverOS,
3136 bcc_ptr += 2 * (len + 1);
3137 remaining_words -= len + 1;
3138 ses->serverOS[2 * len] = 0;
3139 ses->serverOS[1 + (2 * len)] = 0;
3140 if (remaining_words > 0) {
3141 len = UniStrnlen((wchar_t *)
3145 kfree(ses->serverNOS);
3147 kzalloc(2 * (len + 1),
3149 cifs_strfromUCS_le(ses->
3155 bcc_ptr += 2 * (len + 1);
3156 ses->serverNOS[2 * len] = 0;
3157 ses->serverNOS[1+(2*len)] = 0;
3158 remaining_words -= len + 1;
3159 if (remaining_words > 0) {
3160 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3161 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3162 if (ses->serverDomain)
3163 kfree(ses->serverDomain);
3188 } /* else no more room so create dummy domain string */
3190 if (ses->serverDomain)
3191 kfree(ses->serverDomain);
3192 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3194 } else { /* no room so create dummy domain and NOS string */
3195 if (ses->serverDomain)
3196 kfree(ses->serverDomain);
3197 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3198 kfree(ses->serverNOS);
3199 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3201 } else { /* ASCII */
3202 len = strnlen(bcc_ptr, 1024);
3203 if (((long) bcc_ptr + len) -
3204 (long) pByteArea(smb_buffer_response)
3205 <= BCC(smb_buffer_response)) {
3207 kfree(ses->serverOS);
3208 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
3209 strncpy(ses->serverOS,bcc_ptr, len);
3212 bcc_ptr[0] = 0; /* null terminate the string */
3215 len = strnlen(bcc_ptr, 1024);
3216 kfree(ses->serverNOS);
3217 ses->serverNOS = kzalloc(len+1,
3219 strncpy(ses->serverNOS, bcc_ptr, len);
3224 len = strnlen(bcc_ptr, 1024);
3225 if (ses->serverDomain)
3226 kfree(ses->serverDomain);
3227 ses->serverDomain = kzalloc(len+1,GFP_KERNEL);
3228 strncpy(ses->serverDomain, bcc_ptr, len);
3234 ("Variable field of length %d extends beyond end of smb ",
3239 (" Security Blob Length extends beyond end of SMB"));
3242 cERROR(1, ("No session structure passed in."));
3246 (" Invalid Word count %d: ",
3247 smb_buffer_response->WordCount));
3252 cifs_buf_release(smb_buffer);
3258 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3259 const char *tree, struct cifsTconInfo *tcon,
3260 const struct nls_table *nls_codepage)
3262 struct smb_hdr *smb_buffer;
3263 struct smb_hdr *smb_buffer_response;
3266 unsigned char *bcc_ptr;
3274 smb_buffer = cifs_buf_get();
3275 if (smb_buffer == NULL) {
3278 smb_buffer_response = smb_buffer;
3280 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3281 NULL /*no tid */ , 4 /*wct */ );
3283 smb_buffer->Mid = GetNextMid(ses->server);
3284 smb_buffer->Uid = ses->Suid;
3285 pSMB = (TCONX_REQ *) smb_buffer;
3286 pSMBr = (TCONX_RSP *) smb_buffer_response;
3288 pSMB->AndXCommand = 0xFF;
3289 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3290 bcc_ptr = &pSMB->Password[0];
3291 if ((ses->server->secMode) & SECMODE_USER) {
3292 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3293 *bcc_ptr = 0; /* password is null byte */
3294 bcc_ptr++; /* skip password */
3295 /* already aligned so no need to do it below */
3297 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3298 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3299 specified as required (when that support is added to
3300 the vfs in the future) as only NTLM or the much
3301 weaker LANMAN (which we do not send by default) is accepted
3302 by Samba (not sure whether other servers allow
3303 NTLMv2 password here) */
3304 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3305 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3306 (ses->server->secType == LANMAN))
3307 calc_lanman_hash(ses, bcc_ptr);
3309 #endif /* CIFS_WEAK_PW_HASH */
3310 SMBNTencrypt(ses->password,
3311 ses->server->cryptKey,
3314 bcc_ptr += CIFS_SESS_KEY_SIZE;
3315 if (ses->capabilities & CAP_UNICODE) {
3316 /* must align unicode strings */
3317 *bcc_ptr = 0; /* null byte password */
3322 if (ses->server->secMode &
3323 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3324 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3326 if (ses->capabilities & CAP_STATUS32) {
3327 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3329 if (ses->capabilities & CAP_DFS) {
3330 smb_buffer->Flags2 |= SMBFLG2_DFS;
3332 if (ses->capabilities & CAP_UNICODE) {
3333 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3335 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3336 6 /* max utf8 char length in bytes */ *
3337 (/* server len*/ + 256 /* share len */), nls_codepage);
3338 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3339 bcc_ptr += 2; /* skip trailing null */
3340 } else { /* ASCII */
3341 strcpy(bcc_ptr, tree);
3342 bcc_ptr += strlen(tree) + 1;
3344 strcpy(bcc_ptr, "?????");
3345 bcc_ptr += strlen("?????");
3347 count = bcc_ptr - &pSMB->Password[0];
3348 pSMB->hdr.smb_buf_length += count;
3349 pSMB->ByteCount = cpu_to_le16(count);
3351 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
3353 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3354 /* above now done in SendReceive */
3355 if ((rc == 0) && (tcon != NULL)) {
3356 tcon->tidStatus = CifsGood;
3357 tcon->tid = smb_buffer_response->Tid;
3358 bcc_ptr = pByteArea(smb_buffer_response);
3359 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3360 /* skip service field (NB: this field is always ASCII) */
3361 bcc_ptr += length + 1;
3362 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3363 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3364 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3365 if ((bcc_ptr + (2 * length)) -
3366 pByteArea(smb_buffer_response) <=
3367 BCC(smb_buffer_response)) {
3368 kfree(tcon->nativeFileSystem);
3369 tcon->nativeFileSystem =
3370 kzalloc(length + 2, GFP_KERNEL);
3371 cifs_strfromUCS_le(tcon->nativeFileSystem,
3373 length, nls_codepage);
3374 bcc_ptr += 2 * length;
3375 bcc_ptr[0] = 0; /* null terminate the string */
3379 /* else do not bother copying these information fields*/
3381 length = strnlen(bcc_ptr, 1024);
3382 if ((bcc_ptr + length) -
3383 pByteArea(smb_buffer_response) <=
3384 BCC(smb_buffer_response)) {
3385 kfree(tcon->nativeFileSystem);
3386 tcon->nativeFileSystem =
3387 kzalloc(length + 1, GFP_KERNEL);
3388 strncpy(tcon->nativeFileSystem, bcc_ptr,
3391 /* else do not bother copying these information fields*/
3393 if ((smb_buffer_response->WordCount == 3) ||
3394 (smb_buffer_response->WordCount == 7))
3395 /* field is in same location */
3396 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3399 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3400 } else if ((rc == 0) && tcon == NULL) {
3401 /* all we need to save for IPC$ connection */
3402 ses->ipc_tid = smb_buffer_response->Tid;
3406 cifs_buf_release(smb_buffer);
3411 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3415 struct cifsSesInfo *ses = NULL;
3416 struct task_struct *cifsd_task;
3421 if (cifs_sb->tcon) {
3422 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3423 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3428 tconInfoFree(cifs_sb->tcon);
3429 if ((ses) && (ses->server)) {
3430 /* save off task so we do not refer to ses later */
3431 cifsd_task = ses->server->tsk;
3432 cFYI(1, ("About to do SMBLogoff "));
3433 rc = CIFSSMBLogoff(xid, ses);
3437 } else if (rc == -ESHUTDOWN) {
3438 cFYI(1, ("Waking up socket by sending signal"));
3440 force_sig(SIGKILL, cifsd_task);
3441 kthread_stop(cifsd_task);
3444 } /* else - we have an smb session
3445 left on this socket do not kill cifsd */
3447 cFYI(1, ("No session or bad tcon"));
3450 cifs_sb->tcon = NULL;
3451 tmp = cifs_sb->prepath;
3452 cifs_sb->prepathlen = 0;
3453 cifs_sb->prepath = NULL;
3456 schedule_timeout_interruptible(msecs_to_jiffies(500));
3461 return rc; /* BB check if we should always return zero here */
3464 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3465 struct nls_table *nls_info)
3468 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3469 int ntlmv2_flag = FALSE;
3472 /* what if server changes its buffer size after dropping the session? */
3473 if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
3474 rc = CIFSSMBNegotiate(xid, pSesInfo);
3475 if (rc == -EAGAIN) /* retry only once on 1st time connection */ {
3476 rc = CIFSSMBNegotiate(xid, pSesInfo);
3481 spin_lock(&GlobalMid_Lock);
3482 if (pSesInfo->server->tcpStatus != CifsExiting)
3483 pSesInfo->server->tcpStatus = CifsGood;
3486 spin_unlock(&GlobalMid_Lock);
3492 pSesInfo->flags = 0;
3493 pSesInfo->capabilities = pSesInfo->server->capabilities;
3494 if (linuxExtEnabled == 0)
3495 pSesInfo->capabilities &= (~CAP_UNIX);
3496 /* pSesInfo->sequence_number = 0;*/
3498 ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3499 pSesInfo->server->secMode,
3500 pSesInfo->server->capabilities,
3501 pSesInfo->server->timeAdj));
3502 if (experimEnabled < 2)
3503 rc = CIFS_SessSetup(xid, pSesInfo,
3504 first_time, nls_info);
3505 else if (extended_security
3506 && (pSesInfo->capabilities
3507 & CAP_EXTENDED_SECURITY)
3508 && (pSesInfo->server->secType == NTLMSSP)) {
3510 } else if (extended_security
3511 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3512 && (pSesInfo->server->secType == RawNTLMSSP)) {
3513 cFYI(1, ("NTLMSSP sesssetup"));
3514 rc = CIFSNTLMSSPNegotiateSessSetup(xid,
3521 cFYI(1, ("more secure NTLM ver2 hash"));
3522 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3527 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
3529 CalcNTLMv2_response(pSesInfo,
3532 cifs_calculate_ntlmv2_mac_key(
3533 pSesInfo->server->mac_signing_key,
3534 response, ntlm_session_key,*/
3536 /* BB Put dummy sig in SessSetup PDU? */
3543 SMBNTencrypt(pSesInfo->password,
3544 pSesInfo->server->cryptKey,
3548 cifs_calculate_mac_key(
3549 &pSesInfo->server->mac_signing_key,
3551 pSesInfo->password);
3553 /* for better security the weaker lanman hash not sent
3554 in AuthSessSetup so we no longer calculate it */
3556 rc = CIFSNTLMSSPAuthSessSetup(xid,
3562 } else { /* old style NTLM 0.12 session setup */
3563 SMBNTencrypt(pSesInfo->password,
3564 pSesInfo->server->cryptKey,
3568 cifs_calculate_mac_key(
3569 &pSesInfo->server->mac_signing_key,
3570 ntlm_session_key, pSesInfo->password);
3572 rc = CIFSSessSetup(xid, pSesInfo,
3573 ntlm_session_key, nls_info);
3576 cERROR(1, ("Send error in SessSetup = %d", rc));
3578 cFYI(1, ("CIFS Session Established successfully"));
3579 pSesInfo->status = CifsGood;