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. */
88 unsigned no_linux_ext:1;
90 unsigned nullauth:1; /* attempt to authenticate with null user */
91 unsigned nocase; /* request case insensitive filenames */
92 unsigned nobrl; /* disable sending byte range locks to srv */
96 unsigned short int port;
100 static int ipv4_connect(struct sockaddr_in *psin_server,
101 struct socket **csocket,
103 char *server_netb_name);
104 static int ipv6_connect(struct sockaddr_in6 *psin_server,
105 struct socket **csocket);
109 * cifs tcp session reconnection
111 * mark tcp session as reconnecting so temporarily locked
112 * mark all smb sessions as reconnecting for tcp session
113 * reconnect tcp session
114 * wake up waiters on reconnection? - (not needed currently)
118 cifs_reconnect(struct TCP_Server_Info *server)
121 struct list_head *tmp;
122 struct cifsSesInfo *ses;
123 struct cifsTconInfo *tcon;
124 struct mid_q_entry *mid_entry;
126 spin_lock(&GlobalMid_Lock);
127 if ( kthread_should_stop() ) {
128 /* the demux thread will exit normally
129 next time through the loop */
130 spin_unlock(&GlobalMid_Lock);
133 server->tcpStatus = CifsNeedReconnect;
134 spin_unlock(&GlobalMid_Lock);
137 cFYI(1, ("Reconnecting tcp session"));
139 /* before reconnecting the tcp session, mark the smb session (uid)
140 and the tid bad so they are not used until reconnected */
141 read_lock(&GlobalSMBSeslock);
142 list_for_each(tmp, &GlobalSMBSessionList) {
143 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
145 if (ses->server == server) {
146 ses->status = CifsNeedReconnect;
150 /* else tcp and smb sessions need reconnection */
152 list_for_each(tmp, &GlobalTreeConnectionList) {
153 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
154 if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
155 tcon->tidStatus = CifsNeedReconnect;
158 read_unlock(&GlobalSMBSeslock);
159 /* do not want to be sending data on a socket we are freeing */
160 down(&server->tcpSem);
161 if (server->ssocket) {
162 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
163 server->ssocket->flags));
164 server->ssocket->ops->shutdown(server->ssocket, SEND_SHUTDOWN);
165 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
166 server->ssocket->state,
167 server->ssocket->flags));
168 sock_release(server->ssocket);
169 server->ssocket = NULL;
172 spin_lock(&GlobalMid_Lock);
173 list_for_each(tmp, &server->pending_mid_q) {
174 mid_entry = list_entry(tmp, struct
178 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
179 /* Mark other intransit requests as needing
180 retry so we do not immediately mark the
181 session bad again (ie after we reconnect
182 below) as they timeout too */
183 mid_entry->midState = MID_RETRY_NEEDED;
187 spin_unlock(&GlobalMid_Lock);
190 while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
192 if (server->protocolType == IPV6) {
193 rc = ipv6_connect(&server->addr.sockAddr6,
196 rc = ipv4_connect(&server->addr.sockAddr,
198 server->workstation_RFC1001_name,
199 server->server_RFC1001_name);
202 cFYI(1, ("reconnect error %d", rc));
205 atomic_inc(&tcpSesReconnectCount);
206 spin_lock(&GlobalMid_Lock);
207 if ( !kthread_should_stop() )
208 server->tcpStatus = CifsGood;
209 server->sequence_number = 0;
210 spin_unlock(&GlobalMid_Lock);
211 /* atomic_set(&server->inFlight,0);*/
212 wake_up(&server->response_q);
220 0 not a transact2, or all data present
221 >0 transact2 with that much data missing
222 -EINVAL = invalid transact2
225 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
227 struct smb_t2_rsp *pSMBt;
229 int data_in_this_rsp;
232 if (pSMB->Command != SMB_COM_TRANSACTION2)
235 /* check for plausible wct, bcc and t2 data and parm sizes */
236 /* check for parm and data offset going beyond end of smb */
237 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
238 cFYI(1, ("invalid transact2 word count"));
242 pSMBt = (struct smb_t2_rsp *)pSMB;
244 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
245 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
247 remaining = total_data_size - data_in_this_rsp;
251 else if (remaining < 0) {
252 cFYI(1, ("total data %d smaller than data in frame %d",
253 total_data_size, data_in_this_rsp));
256 cFYI(1, ("missing %d bytes from transact2, check next response",
258 if (total_data_size > maxBufSize) {
259 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
260 total_data_size, maxBufSize));
267 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
269 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
270 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
275 char *data_area_of_target;
276 char *data_area_of_buf2;
279 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
281 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
282 cFYI(1, ("total data size of primary and secondary t2 differ"));
285 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
287 remaining = total_data_size - total_in_buf;
292 if (remaining == 0) /* nothing to do, ignore */
295 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
296 if (remaining < total_in_buf2) {
297 cFYI(1, ("transact2 2nd response contains too much data"));
300 /* find end of first SMB data area */
301 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
302 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
303 /* validate target area */
305 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
306 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
308 data_area_of_target += total_in_buf;
310 /* copy second buffer into end of first buffer */
311 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
312 total_in_buf += total_in_buf2;
313 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
314 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
315 byte_count += total_in_buf2;
316 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
318 byte_count = pTargetSMB->smb_buf_length;
319 byte_count += total_in_buf2;
321 /* BB also add check that we are not beyond maximum buffer size */
323 pTargetSMB->smb_buf_length = byte_count;
325 if (remaining == total_in_buf2) {
326 cFYI(1, ("found the last secondary response"));
327 return 0; /* we are done */
328 } else /* more responses to go */
334 cifs_demultiplex_thread(struct TCP_Server_Info *server)
337 unsigned int pdu_length, total_read;
338 struct smb_hdr *smb_buffer = NULL;
339 struct smb_hdr *bigbuf = NULL;
340 struct smb_hdr *smallbuf = NULL;
341 struct msghdr smb_msg;
343 struct socket *csocket = server->ssocket;
344 struct list_head *tmp;
345 struct cifsSesInfo *ses;
346 struct task_struct *task_to_wake = NULL;
347 struct mid_q_entry *mid_entry;
349 int isLargeBuf = FALSE;
353 current->flags |= PF_MEMALLOC;
354 server->tsk = current; /* save process info to wake at shutdown */
355 cFYI(1, ("Demultiplex PID: %d", current->pid));
356 write_lock(&GlobalSMBSeslock);
357 atomic_inc(&tcpSesAllocCount);
358 length = tcpSesAllocCount.counter;
359 write_unlock(&GlobalSMBSeslock);
360 complete(&cifsd_complete);
362 mempool_resize(cifs_req_poolp,
363 length + cifs_min_rcv,
368 while (!kthread_should_stop()) {
371 if (bigbuf == NULL) {
372 bigbuf = cifs_buf_get();
374 cERROR(1, ("No memory for large SMB response"));
376 /* retry will check if exiting */
379 } else if (isLargeBuf) {
380 /* we are reusing a dirty large buf, clear its start */
381 memset(bigbuf, 0, sizeof (struct smb_hdr));
384 if (smallbuf == NULL) {
385 smallbuf = cifs_small_buf_get();
387 cERROR(1, ("No memory for SMB response"));
389 /* retry will check if exiting */
392 /* beginning of smb buffer is cleared in our buf_get */
393 } else /* if existing small buf clear beginning */
394 memset(smallbuf, 0, sizeof (struct smb_hdr));
398 smb_buffer = smallbuf;
399 iov.iov_base = smb_buffer;
401 smb_msg.msg_control = NULL;
402 smb_msg.msg_controllen = 0;
403 pdu_length = 4; /* enough to get RFC1001 header */
406 kernel_recvmsg(csocket, &smb_msg,
407 &iov, 1, pdu_length, 0 /* BB other flags? */);
409 if ( kthread_should_stop() ) {
411 } else if (server->tcpStatus == CifsNeedReconnect) {
412 cFYI(1, ("Reconnect after server stopped responding"));
413 cifs_reconnect(server);
414 cFYI(1, ("call to reconnect done"));
415 csocket = server->ssocket;
417 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
418 msleep(1); /* minimum sleep to prevent looping
419 allowing socket to clear and app threads to set
420 tcpStatus CifsNeedReconnect if server hung */
422 } else if (length <= 0) {
423 if (server->tcpStatus == CifsNew) {
424 cFYI(1, ("tcp session abend after SMBnegprot"));
425 /* some servers kill the TCP session rather than
426 returning an SMB negprot error, in which
427 case reconnecting here is not going to help,
428 and so simply return error to mount */
431 if (!try_to_freeze() && (length == -EINTR)) {
432 cFYI(1, ("cifsd thread killed"));
435 cFYI(1, ("Reconnect after unexpected peek error %d",
437 cifs_reconnect(server);
438 csocket = server->ssocket;
439 wake_up(&server->response_q);
441 } else if (length < 4) {
442 cFYI(1, ("less than four bytes received (%d bytes)",
444 pdu_length -= length;
445 cifs_reconnect(server);
450 /* The right amount was read from socket - 4 bytes */
451 /* so we can now interpret the length field */
453 /* the first byte big endian of the length field,
454 is actually not part of the length but the type
455 with the most common, zero, as regular data */
456 temp = *((char *) smb_buffer);
458 /* Note that FC 1001 length is big endian on the wire,
459 but we convert it here so it is always manipulated
460 as host byte order */
461 pdu_length = ntohl(smb_buffer->smb_buf_length);
462 smb_buffer->smb_buf_length = pdu_length;
464 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
466 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
468 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
469 cFYI(1, ("Good RFC 1002 session rsp"));
471 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
472 /* we get this from Windows 98 instead of
473 an error on SMB negprot response */
474 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
476 if (server->tcpStatus == CifsNew) {
477 /* if nack on negprot (rather than
478 ret of smb negprot error) reconnecting
479 not going to help, ret error to mount */
482 /* give server a second to
483 clean up before reconnect attempt */
485 /* always try 445 first on reconnect
486 since we get NACK on some if we ever
487 connected to port 139 (the NACK is
488 since we do not begin with RFC1001
489 session initialize frame) */
490 server->addr.sockAddr.sin_port =
492 cifs_reconnect(server);
493 csocket = server->ssocket;
494 wake_up(&server->response_q);
497 } else if (temp != (char) 0) {
498 cERROR(1, ("Unknown RFC 1002 frame"));
499 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
501 cifs_reconnect(server);
502 csocket = server->ssocket;
506 /* else we have an SMB response */
507 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
508 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
509 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
510 length, pdu_length+4));
511 cifs_reconnect(server);
512 csocket = server->ssocket;
513 wake_up(&server->response_q);
520 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
522 memcpy(bigbuf, smallbuf, 4);
526 iov.iov_base = 4 + (char *)smb_buffer;
527 iov.iov_len = pdu_length;
528 for (total_read = 0; total_read < pdu_length;
529 total_read += length) {
530 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
531 pdu_length - total_read, 0);
532 if ( kthread_should_stop() ||
533 (length == -EINTR)) {
537 } else if (server->tcpStatus == CifsNeedReconnect) {
538 cifs_reconnect(server);
539 csocket = server->ssocket;
540 /* Reconnect wakes up rspns q */
541 /* Now we will reread sock */
544 } else if ((length == -ERESTARTSYS) ||
545 (length == -EAGAIN)) {
546 msleep(1); /* minimum sleep to prevent looping,
547 allowing socket to clear and app
548 threads to set tcpStatus
549 CifsNeedReconnect if server hung*/
551 } else if (length <= 0) {
552 cERROR(1, ("Received no data, expecting %d",
553 pdu_length - total_read));
554 cifs_reconnect(server);
555 csocket = server->ssocket;
562 else if (reconnect == 1)
565 length += 4; /* account for rfc1002 hdr */
568 dump_smb(smb_buffer, length);
569 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
570 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
576 spin_lock(&GlobalMid_Lock);
577 list_for_each(tmp, &server->pending_mid_q) {
578 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
580 if ((mid_entry->mid == smb_buffer->Mid) &&
581 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
582 (mid_entry->command == smb_buffer->Command)) {
583 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
584 /* We have a multipart transact2 resp */
586 if (mid_entry->resp_buf) {
587 /* merge response - fix up 1st*/
588 if (coalesce_t2(smb_buffer,
589 mid_entry->resp_buf)) {
590 mid_entry->multiRsp = 1;
593 /* all parts received */
594 mid_entry->multiEnd = 1;
599 cERROR(1,("1st trans2 resp needs bigbuf"));
600 /* BB maybe we can fix this up, switch
601 to already allocated large buffer? */
603 /* Have first buffer */
604 mid_entry->resp_buf =
606 mid_entry->largeBuf = 1;
612 mid_entry->resp_buf = smb_buffer;
614 mid_entry->largeBuf = 1;
616 mid_entry->largeBuf = 0;
618 task_to_wake = mid_entry->tsk;
619 mid_entry->midState = MID_RESPONSE_RECEIVED;
620 #ifdef CONFIG_CIFS_STATS2
621 mid_entry->when_received = jiffies;
623 /* so we do not time out requests to server
624 which is still responding (since server could
625 be busy but not dead) */
626 server->lstrp = jiffies;
630 spin_unlock(&GlobalMid_Lock);
632 /* Was previous buf put in mpx struct for multi-rsp? */
634 /* smb buffer will be freed by user thread */
640 wake_up_process(task_to_wake);
641 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE)
642 && (isMultiRsp == FALSE)) {
643 cERROR(1, ("No task to wake, unknown frame received! "
644 "NumMids %d", midCount.counter));
645 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
646 sizeof(struct smb_hdr));
647 #ifdef CONFIG_CIFS_DEBUG2
648 cifs_dump_detail(smb_buffer);
649 cifs_dump_mids(server);
650 #endif /* CIFS_DEBUG2 */
653 } /* end while !EXITING */
655 spin_lock(&GlobalMid_Lock);
656 server->tcpStatus = CifsExiting;
658 /* check if we have blocked requests that need to free */
659 /* Note that cifs_max_pending is normally 50, but
660 can be set at module install time to as little as two */
661 if (atomic_read(&server->inFlight) >= cifs_max_pending)
662 atomic_set(&server->inFlight, cifs_max_pending - 1);
663 /* We do not want to set the max_pending too low or we
664 could end up with the counter going negative */
665 spin_unlock(&GlobalMid_Lock);
666 /* Although there should not be any requests blocked on
667 this queue it can not hurt to be paranoid and try to wake up requests
668 that may haven been blocked when more than 50 at time were on the wire
669 to the same server - they now will see the session is in exit state
670 and get out of SendReceive. */
671 wake_up_all(&server->request_q);
672 /* give those requests time to exit */
675 if (server->ssocket) {
676 sock_release(csocket);
677 server->ssocket = NULL;
679 /* buffer usuallly freed in free_mid - need to free it here on exit */
681 cifs_buf_release(bigbuf);
682 if (smallbuf != NULL)
683 cifs_small_buf_release(smallbuf);
685 read_lock(&GlobalSMBSeslock);
686 if (list_empty(&server->pending_mid_q)) {
687 /* loop through server session structures attached to this and
689 list_for_each(tmp, &GlobalSMBSessionList) {
691 list_entry(tmp, struct cifsSesInfo,
693 if (ses->server == server) {
694 ses->status = CifsExiting;
698 read_unlock(&GlobalSMBSeslock);
700 /* although we can not zero the server struct pointer yet,
701 since there are active requests which may depnd on them,
702 mark the corresponding SMB sessions as exiting too */
703 list_for_each(tmp, &GlobalSMBSessionList) {
704 ses = list_entry(tmp, struct cifsSesInfo,
706 if (ses->server == server) {
707 ses->status = CifsExiting;
711 spin_lock(&GlobalMid_Lock);
712 list_for_each(tmp, &server->pending_mid_q) {
713 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
714 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
715 cFYI(1, ("Clearing Mid 0x%x - waking up ",
717 task_to_wake = mid_entry->tsk;
719 wake_up_process(task_to_wake);
723 spin_unlock(&GlobalMid_Lock);
724 read_unlock(&GlobalSMBSeslock);
725 /* 1/8th of sec is more than enough time for them to exit */
729 if (!list_empty(&server->pending_mid_q)) {
730 /* mpx threads have not exited yet give them
731 at least the smb send timeout time for long ops */
732 /* due to delays on oplock break requests, we need
733 to wait at least 45 seconds before giving up
734 on a request getting a response and going ahead
736 cFYI(1, ("Wait for exit from demultiplex thread"));
738 /* if threads still have not exited they are probably never
739 coming home not much else we can do but free the memory */
742 write_lock(&GlobalSMBSeslock);
743 atomic_dec(&tcpSesAllocCount);
744 length = tcpSesAllocCount.counter;
746 /* last chance to mark ses pointers invalid
747 if there are any pointing to this (e.g
748 if a crazy root user tried to kill cifsd
749 kernel thread explicitly this might happen) */
750 list_for_each(tmp, &GlobalSMBSessionList) {
751 ses = list_entry(tmp, struct cifsSesInfo,
753 if (ses->server == server) {
757 write_unlock(&GlobalSMBSeslock);
761 mempool_resize(cifs_req_poolp,
762 length + cifs_min_rcv,
770 cifs_parse_mount_options(char *options, const char *devname,
775 unsigned int temp_len, i, j;
781 if (Local_System_Name[0] != 0)
782 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
784 char *nodename = utsname()->nodename;
785 int n = strnlen(nodename, 15);
786 memset(vol->source_rfc1001_name, 0x20, 15);
787 for (i = 0; i < n; i++) {
788 /* does not have to be perfect mapping since field is
789 informational, only used for servers that do not support
790 port 445 and it can be overridden at mount time */
791 vol->source_rfc1001_name[i] = toupper(nodename[i]);
794 vol->source_rfc1001_name[15] = 0;
795 /* null target name indicates to use *SMBSERVR default called name
796 if we end up sending RFC1001 session initialize */
797 vol->target_rfc1001_name[0] = 0;
798 vol->linux_uid = current->uid; /* current->euid instead? */
799 vol->linux_gid = current->gid;
800 vol->dir_mode = S_IRWXUGO;
801 /* 2767 perms indicate mandatory locking support */
802 vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
804 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
806 /* default is always to request posix paths. */
807 vol->posix_paths = 1;
812 if (strncmp(options, "sep=", 4) == 0) {
813 if (options[4] != 0) {
814 separator[0] = options[4];
817 cFYI(1, ("Null separator not allowed"));
821 while ((data = strsep(&options, separator)) != NULL) {
824 if ((value = strchr(data, '=')) != NULL)
827 /* Have to parse this before we parse for "user" */
828 if (strnicmp(data, "user_xattr", 10) == 0) {
830 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
832 } else if (strnicmp(data, "user", 4) == 0) {
835 "CIFS: invalid or missing username\n");
836 return 1; /* needs_arg; */
837 } else if (!*value) {
838 /* null user, ie anonymous, authentication */
841 if (strnlen(value, 200) < 200) {
842 vol->username = value;
844 printk(KERN_WARNING "CIFS: username too long\n");
847 } else if (strnicmp(data, "pass", 4) == 0) {
849 vol->password = NULL;
851 } else if (value[0] == 0) {
852 /* check if string begins with double comma
853 since that would mean the password really
854 does start with a comma, and would not
855 indicate an empty string */
856 if (value[1] != separator[0]) {
857 vol->password = NULL;
861 temp_len = strlen(value);
862 /* removed password length check, NTLM passwords
863 can be arbitrarily long */
865 /* if comma in password, the string will be
866 prematurely null terminated. Commas in password are
867 specified across the cifs mount interface by a double
868 comma ie ,, and a comma used as in other cases ie ','
869 as a parameter delimiter/separator is single and due
870 to the strsep above is temporarily zeroed. */
872 /* NB: password legally can have multiple commas and
873 the only illegal character in a password is null */
875 if ((value[temp_len] == 0) &&
876 (value[temp_len+1] == separator[0])) {
878 value[temp_len] = separator[0];
879 temp_len += 2; /* move after second comma */
880 while (value[temp_len] != 0) {
881 if (value[temp_len] == separator[0]) {
882 if (value[temp_len+1] ==
884 /* skip second comma */
887 /* single comma indicating start
894 if (value[temp_len] == 0) {
898 /* point option to start of next parm */
899 options = value + temp_len + 1;
901 /* go from value to value + temp_len condensing
902 double commas to singles. Note that this ends up
903 allocating a few bytes too many, which is ok */
904 vol->password = kzalloc(temp_len, GFP_KERNEL);
905 if (vol->password == NULL) {
906 printk(KERN_WARNING "CIFS: no memory "
910 for (i = 0, j = 0; i < temp_len; i++, j++) {
911 vol->password[j] = value[i];
912 if (value[i] == separator[0]
913 && value[i+1] == separator[0]) {
914 /* skip second comma */
918 vol->password[j] = 0;
920 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
921 if (vol->password == NULL) {
922 printk(KERN_WARNING "CIFS: no memory "
926 strcpy(vol->password, value);
928 } else if (strnicmp(data, "ip", 2) == 0) {
929 if (!value || !*value) {
931 } else if (strnlen(value, 35) < 35) {
934 printk(KERN_WARNING "CIFS: ip address "
938 } else if (strnicmp(data, "sec", 3) == 0) {
939 if (!value || !*value) {
940 cERROR(1, ("no security value specified"));
942 } else if (strnicmp(value, "krb5i", 5) == 0) {
943 vol->secFlg |= CIFSSEC_MAY_KRB5 |
945 } else if (strnicmp(value, "krb5p", 5) == 0) {
946 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
948 cERROR(1, ("Krb5 cifs privacy not supported"));
950 } else if (strnicmp(value, "krb5", 4) == 0) {
951 vol->secFlg |= CIFSSEC_MAY_KRB5;
952 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
953 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
955 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
956 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
957 } else if (strnicmp(value, "ntlmi", 5) == 0) {
958 vol->secFlg |= CIFSSEC_MAY_NTLM |
960 } else if (strnicmp(value, "ntlm", 4) == 0) {
961 /* ntlm is default so can be turned off too */
962 vol->secFlg |= CIFSSEC_MAY_NTLM;
963 } else if (strnicmp(value, "nontlm", 6) == 0) {
964 /* BB is there a better way to do this? */
965 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
966 #ifdef CONFIG_CIFS_WEAK_PW_HASH
967 } else if (strnicmp(value, "lanman", 6) == 0) {
968 vol->secFlg |= CIFSSEC_MAY_LANMAN;
970 } else if (strnicmp(value, "none", 4) == 0) {
973 cERROR(1, ("bad security option: %s", value));
976 } else if ((strnicmp(data, "unc", 3) == 0)
977 || (strnicmp(data, "target", 6) == 0)
978 || (strnicmp(data, "path", 4) == 0)) {
979 if (!value || !*value) {
980 printk(KERN_WARNING "CIFS: invalid path to "
981 "network resource\n");
982 return 1; /* needs_arg; */
984 if ((temp_len = strnlen(value, 300)) < 300) {
985 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
986 if (vol->UNC == NULL)
988 strcpy(vol->UNC, value);
989 if (strncmp(vol->UNC, "//", 2) == 0) {
992 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
994 "CIFS: UNC Path does not begin "
995 "with // or \\\\ \n");
999 printk(KERN_WARNING "CIFS: UNC name too long\n");
1002 } else if ((strnicmp(data, "domain", 3) == 0)
1003 || (strnicmp(data, "workgroup", 5) == 0)) {
1004 if (!value || !*value) {
1005 printk(KERN_WARNING "CIFS: invalid domain name\n");
1006 return 1; /* needs_arg; */
1008 /* BB are there cases in which a comma can be valid in
1009 a domain name and need special handling? */
1010 if (strnlen(value, 256) < 256) {
1011 vol->domainname = value;
1012 cFYI(1, ("Domain name set"));
1014 printk(KERN_WARNING "CIFS: domain name too "
1018 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1019 if (!value || !*value) {
1021 "CIFS: invalid path prefix\n");
1022 return 1; /* needs_argument */
1024 if ((temp_len = strnlen(value, 1024)) < 1024) {
1025 if (value[0] != '/')
1026 temp_len++; /* missing leading slash */
1027 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1028 if (vol->prepath == NULL)
1030 if (value[0] != '/') {
1031 vol->prepath[0] = '/';
1032 strcpy(vol->prepath+1, value);
1034 strcpy(vol->prepath, value);
1035 cFYI(1, ("prefix path %s", vol->prepath));
1037 printk(KERN_WARNING "CIFS: prefix too long\n");
1040 } else if (strnicmp(data, "iocharset", 9) == 0) {
1041 if (!value || !*value) {
1042 printk(KERN_WARNING "CIFS: invalid iocharset "
1044 return 1; /* needs_arg; */
1046 if (strnlen(value, 65) < 65) {
1047 if (strnicmp(value, "default", 7))
1048 vol->iocharset = value;
1049 /* if iocharset not set then load_nls_default
1050 is used by caller */
1051 cFYI(1, ("iocharset set to %s", value));
1053 printk(KERN_WARNING "CIFS: iocharset name "
1057 } else if (strnicmp(data, "uid", 3) == 0) {
1058 if (value && *value) {
1060 simple_strtoul(value, &value, 0);
1061 vol->override_uid = 1;
1063 } else if (strnicmp(data, "gid", 3) == 0) {
1064 if (value && *value) {
1066 simple_strtoul(value, &value, 0);
1067 vol->override_gid = 1;
1069 } else if (strnicmp(data, "file_mode", 4) == 0) {
1070 if (value && *value) {
1072 simple_strtoul(value, &value, 0);
1074 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1075 if (value && *value) {
1077 simple_strtoul(value, &value, 0);
1079 } else if (strnicmp(data, "dirmode", 4) == 0) {
1080 if (value && *value) {
1082 simple_strtoul(value, &value, 0);
1084 } else if (strnicmp(data, "port", 4) == 0) {
1085 if (value && *value) {
1087 simple_strtoul(value, &value, 0);
1089 } else if (strnicmp(data, "rsize", 5) == 0) {
1090 if (value && *value) {
1092 simple_strtoul(value, &value, 0);
1094 } else if (strnicmp(data, "wsize", 5) == 0) {
1095 if (value && *value) {
1097 simple_strtoul(value, &value, 0);
1099 } else if (strnicmp(data, "sockopt", 5) == 0) {
1100 if (value && *value) {
1102 simple_strtoul(value, &value, 0);
1104 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1105 if (!value || !*value || (*value == ' ')) {
1106 cFYI(1, ("invalid (empty) netbiosname"));
1108 memset(vol->source_rfc1001_name, 0x20, 15);
1109 for (i = 0; i < 15; i++) {
1110 /* BB are there cases in which a comma can be
1111 valid in this workstation netbios name (and need
1112 special handling)? */
1114 /* We do not uppercase netbiosname for user */
1118 vol->source_rfc1001_name[i] =
1121 /* The string has 16th byte zero still from
1122 set at top of the function */
1123 if ((i == 15) && (value[i] != 0))
1124 printk(KERN_WARNING "CIFS: netbiosname"
1125 " longer than 15 truncated.\n");
1127 } else if (strnicmp(data, "servern", 7) == 0) {
1128 /* servernetbiosname specified override *SMBSERVER */
1129 if (!value || !*value || (*value == ' ')) {
1130 cFYI(1, ("empty server netbiosname specified"));
1132 /* last byte, type, is 0x20 for servr type */
1133 memset(vol->target_rfc1001_name, 0x20, 16);
1135 for (i = 0; i < 15; i++) {
1136 /* BB are there cases in which a comma can be
1137 valid in this workstation netbios name
1138 (and need special handling)? */
1140 /* user or mount helper must uppercase
1145 vol->target_rfc1001_name[i] =
1148 /* The string has 16th byte zero still from
1149 set at top of the function */
1150 if ((i == 15) && (value[i] != 0))
1151 printk(KERN_WARNING "CIFS: server net"
1152 "biosname longer than 15 truncated.\n");
1154 } else if (strnicmp(data, "credentials", 4) == 0) {
1156 } else if (strnicmp(data, "version", 3) == 0) {
1158 } else if (strnicmp(data, "guest", 5) == 0) {
1160 } else if (strnicmp(data, "rw", 2) == 0) {
1162 } else if ((strnicmp(data, "suid", 4) == 0) ||
1163 (strnicmp(data, "nosuid", 6) == 0) ||
1164 (strnicmp(data, "exec", 4) == 0) ||
1165 (strnicmp(data, "noexec", 6) == 0) ||
1166 (strnicmp(data, "nodev", 5) == 0) ||
1167 (strnicmp(data, "noauto", 6) == 0) ||
1168 (strnicmp(data, "dev", 3) == 0)) {
1169 /* The mount tool or mount.cifs helper (if present)
1170 uses these opts to set flags, and the flags are read
1171 by the kernel vfs layer before we get here (ie
1172 before read super) so there is no point trying to
1173 parse these options again and set anything and it
1174 is ok to just ignore them */
1176 } else if (strnicmp(data, "ro", 2) == 0) {
1178 } else if (strnicmp(data, "hard", 4) == 0) {
1180 } else if (strnicmp(data, "soft", 4) == 0) {
1182 } else if (strnicmp(data, "perm", 4) == 0) {
1184 } else if (strnicmp(data, "noperm", 6) == 0) {
1186 } else if (strnicmp(data, "mapchars", 8) == 0) {
1188 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1190 } else if (strnicmp(data, "sfu", 3) == 0) {
1192 } else if (strnicmp(data, "nosfu", 5) == 0) {
1194 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1195 vol->posix_paths = 1;
1196 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1197 vol->posix_paths = 0;
1198 } else if (strnicmp(data, "nounix", 6) == 0) {
1199 vol->no_linux_ext = 1;
1200 } else if (strnicmp(data, "nolinux", 7) == 0) {
1201 vol->no_linux_ext = 1;
1202 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1203 (strnicmp(data, "ignorecase", 10) == 0)) {
1205 } else if (strnicmp(data, "brl", 3) == 0) {
1207 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1208 (strnicmp(data, "nolock", 6) == 0)) {
1210 /* turn off mandatory locking in mode
1211 if remote locking is turned off since the
1212 local vfs will do advisory */
1213 if (vol->file_mode ==
1214 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1215 vol->file_mode = S_IALLUGO;
1216 } else if (strnicmp(data, "setuids", 7) == 0) {
1218 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1220 } else if (strnicmp(data, "nohard", 6) == 0) {
1222 } else if (strnicmp(data, "nosoft", 6) == 0) {
1224 } else if (strnicmp(data, "nointr", 6) == 0) {
1226 } else if (strnicmp(data, "intr", 4) == 0) {
1228 } else if (strnicmp(data, "serverino", 7) == 0) {
1229 vol->server_ino = 1;
1230 } else if (strnicmp(data, "noserverino", 9) == 0) {
1231 vol->server_ino = 0;
1232 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1234 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1236 } else if (strnicmp(data, "acl", 3) == 0) {
1237 vol->no_psx_acl = 0;
1238 } else if (strnicmp(data, "noacl", 5) == 0) {
1239 vol->no_psx_acl = 1;
1240 } else if (strnicmp(data, "sign", 4) == 0) {
1241 vol->secFlg |= CIFSSEC_MUST_SIGN;
1242 /* } else if (strnicmp(data, "seal",4) == 0) {
1243 vol->secFlg |= CIFSSEC_MUST_SEAL; */
1244 } else if (strnicmp(data, "direct", 6) == 0) {
1246 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1248 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1249 if (!value || !*value) {
1250 vol->in6_addr = NULL;
1251 } else if (strnlen(value, 49) == 48) {
1252 vol->in6_addr = value;
1254 printk(KERN_WARNING "CIFS: ip v6 address not "
1255 "48 characters long\n");
1258 } else if (strnicmp(data, "noac", 4) == 0) {
1259 printk(KERN_WARNING "CIFS: Mount option noac not "
1260 "supported. Instead set "
1261 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1263 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1266 if (vol->UNC == NULL) {
1267 if (devname == NULL) {
1268 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1272 if ((temp_len = strnlen(devname, 300)) < 300) {
1273 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1274 if (vol->UNC == NULL)
1276 strcpy(vol->UNC, devname);
1277 if (strncmp(vol->UNC, "//", 2) == 0) {
1280 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1281 printk(KERN_WARNING "CIFS: UNC Path does not "
1282 "begin with // or \\\\ \n");
1286 printk(KERN_WARNING "CIFS: UNC name too long\n");
1290 if (vol->UNCip == NULL)
1291 vol->UNCip = &vol->UNC[2];
1296 static struct cifsSesInfo *
1297 cifs_find_tcp_session(struct in_addr *target_ip_addr,
1298 struct in6_addr *target_ip6_addr,
1299 char *userName, struct TCP_Server_Info **psrvTcp)
1301 struct list_head *tmp;
1302 struct cifsSesInfo *ses;
1304 read_lock(&GlobalSMBSeslock);
1306 list_for_each(tmp, &GlobalSMBSessionList) {
1307 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1309 if ((target_ip_addr &&
1310 (ses->server->addr.sockAddr.sin_addr.s_addr
1311 == target_ip_addr->s_addr)) || (target_ip6_addr
1312 && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1313 target_ip6_addr, sizeof(*target_ip6_addr)))) {
1314 /* BB lock server and tcp session and increment
1317 /* found a match on the TCP session */
1318 *psrvTcp = ses->server;
1320 /* BB check if reconnection needed */
1322 (ses->userName, userName,
1323 MAX_USERNAME_SIZE) == 0){
1324 read_unlock(&GlobalSMBSeslock);
1325 /* Found exact match on both TCP and
1331 /* else tcp and smb sessions need reconnection */
1333 read_unlock(&GlobalSMBSeslock);
1337 static struct cifsTconInfo *
1338 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1340 struct list_head *tmp;
1341 struct cifsTconInfo *tcon;
1343 read_lock(&GlobalSMBSeslock);
1344 list_for_each(tmp, &GlobalTreeConnectionList) {
1345 cFYI(1, ("Next tcon"));
1346 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1348 if (tcon->ses->server) {
1350 ("old ip addr: %x == new ip %x ?",
1351 tcon->ses->server->addr.sockAddr.sin_addr.
1352 s_addr, new_target_ip_addr));
1353 if (tcon->ses->server->addr.sockAddr.sin_addr.
1354 s_addr == new_target_ip_addr) {
1355 /* BB lock tcon, server and tcp session and increment use count here? */
1356 /* found a match on the TCP session */
1357 /* BB check if reconnection needed */
1359 ("IP match, old UNC: %s new: %s",
1360 tcon->treeName, uncName));
1362 (tcon->treeName, uncName,
1363 MAX_TREE_SIZE) == 0) {
1365 ("and old usr: %s new: %s",
1366 tcon->treeName, uncName));
1368 (tcon->ses->userName,
1370 MAX_USERNAME_SIZE) == 0) {
1371 read_unlock(&GlobalSMBSeslock);
1372 /* matched smb session
1381 read_unlock(&GlobalSMBSeslock);
1386 connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1387 const char *old_path, const struct nls_table *nls_codepage,
1390 unsigned char *referrals = NULL;
1391 unsigned int num_referrals;
1394 rc = get_dfs_path(xid, pSesInfo, old_path, nls_codepage,
1395 &num_referrals, &referrals, remap);
1397 /* BB Add in code to: if valid refrl, if not ip address contact
1398 the helper that resolves tcp names, mount to it, try to
1399 tcon to it unmount it if fail */
1407 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1408 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1409 unsigned char **preferrals, int remap)
1414 *pnum_referrals = 0;
1416 if (pSesInfo->ipc_tid == 0) {
1417 temp_unc = kmalloc(2 /* for slashes */ +
1418 strnlen(pSesInfo->serverName,
1419 SERVER_NAME_LEN_WITH_NULL * 2)
1420 + 1 + 4 /* slash IPC$ */ + 2,
1422 if (temp_unc == NULL)
1426 strcpy(temp_unc + 2, pSesInfo->serverName);
1427 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1428 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1430 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1434 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1435 pnum_referrals, nls_codepage, remap);
1440 /* See RFC1001 section 14 on representation of Netbios names */
1441 static void rfc1002mangle(char *target, char *source, unsigned int length)
1445 for (i = 0, j = 0; i < (length); i++) {
1446 /* mask a nibble at a time and encode */
1447 target[j] = 'A' + (0x0F & (source[i] >> 4));
1448 target[j+1] = 'A' + (0x0F & source[i]);
1456 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1457 char *netbios_name, char *target_name)
1461 __be16 orig_port = 0;
1463 if (*csocket == NULL) {
1464 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1465 IPPROTO_TCP, csocket);
1467 cERROR(1, ("Error %d creating socket", rc));
1471 /* BB other socket options to set KEEPALIVE, NODELAY? */
1472 cFYI(1, ("Socket created"));
1473 (*csocket)->sk->sk_allocation = GFP_NOFS;
1477 psin_server->sin_family = AF_INET;
1478 if (psin_server->sin_port) { /* user overrode default port */
1479 rc = (*csocket)->ops->connect(*csocket,
1480 (struct sockaddr *) psin_server,
1481 sizeof (struct sockaddr_in), 0);
1487 /* save original port so we can retry user specified port
1488 later if fall back ports fail this time */
1489 orig_port = psin_server->sin_port;
1491 /* do not retry on the same port we just failed on */
1492 if (psin_server->sin_port != htons(CIFS_PORT)) {
1493 psin_server->sin_port = htons(CIFS_PORT);
1495 rc = (*csocket)->ops->connect(*csocket,
1496 (struct sockaddr *) psin_server,
1497 sizeof (struct sockaddr_in), 0);
1503 psin_server->sin_port = htons(RFC1001_PORT);
1504 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1506 sizeof (struct sockaddr_in), 0);
1511 /* give up here - unless we want to retry on different
1512 protocol families some day */
1515 psin_server->sin_port = orig_port;
1516 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1517 sock_release(*csocket);
1521 /* Eventually check for other socket options to change from
1522 the default. sock_setsockopt not used because it expects
1523 user space buffer */
1524 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1525 (*csocket)->sk->sk_sndbuf,
1526 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1527 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1528 /* make the bufsizes depend on wsize/rsize and max requests */
1529 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1530 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1531 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1532 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1534 /* send RFC1001 sessinit */
1535 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1536 /* some servers require RFC1001 sessinit before sending
1537 negprot - BB check reconnection in case where second
1538 sessinit is sent but no second negprot */
1539 struct rfc1002_session_packet *ses_init_buf;
1540 struct smb_hdr *smb_buf;
1541 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1544 ses_init_buf->trailer.session_req.called_len = 32;
1545 if (target_name && (target_name[0] != 0)) {
1546 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1549 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1550 DEFAULT_CIFS_CALLED_NAME, 16);
1553 ses_init_buf->trailer.session_req.calling_len = 32;
1554 /* calling name ends in null (byte 16) from old smb
1556 if (netbios_name && (netbios_name[0] != 0)) {
1557 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1560 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1561 "LINUX_CIFS_CLNT", 16);
1563 ses_init_buf->trailer.session_req.scope1 = 0;
1564 ses_init_buf->trailer.session_req.scope2 = 0;
1565 smb_buf = (struct smb_hdr *)ses_init_buf;
1566 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1567 smb_buf->smb_buf_length = 0x81000044;
1568 rc = smb_send(*csocket, smb_buf, 0x44,
1569 (struct sockaddr *)psin_server);
1570 kfree(ses_init_buf);
1571 msleep(1); /* RFC1001 layer in at least one server
1572 requires very short break before negprot
1573 presumably because not expecting negprot
1574 to follow so fast. This is a simple
1575 solution that works without
1576 complicating the code and causes no
1577 significant slowing down on mount
1578 for everyone else */
1580 /* else the negprot may still work without this
1581 even though malloc failed */
1589 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1593 __be16 orig_port = 0;
1595 if (*csocket == NULL) {
1596 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1597 IPPROTO_TCP, csocket);
1599 cERROR(1, ("Error %d creating ipv6 socket", rc));
1603 /* BB other socket options to set KEEPALIVE, NODELAY? */
1604 cFYI(1, ("ipv6 Socket created"));
1605 (*csocket)->sk->sk_allocation = GFP_NOFS;
1609 psin_server->sin6_family = AF_INET6;
1611 if (psin_server->sin6_port) { /* user overrode default port */
1612 rc = (*csocket)->ops->connect(*csocket,
1613 (struct sockaddr *) psin_server,
1614 sizeof (struct sockaddr_in6), 0);
1620 /* save original port so we can retry user specified port
1621 later if fall back ports fail this time */
1623 orig_port = psin_server->sin6_port;
1624 /* do not retry on the same port we just failed on */
1625 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1626 psin_server->sin6_port = htons(CIFS_PORT);
1628 rc = (*csocket)->ops->connect(*csocket,
1629 (struct sockaddr *) psin_server,
1630 sizeof (struct sockaddr_in6), 0);
1636 psin_server->sin6_port = htons(RFC1001_PORT);
1637 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1638 psin_server, sizeof (struct sockaddr_in6), 0);
1643 /* give up here - unless we want to retry on different
1644 protocol families some day */
1647 psin_server->sin6_port = orig_port;
1648 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1649 sock_release(*csocket);
1653 /* Eventually check for other socket options to change from
1654 the default. sock_setsockopt not used because it expects
1655 user space buffer */
1656 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1661 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1662 struct super_block *sb, struct smb_vol *vol_info)
1664 /* if we are reconnecting then should we check to see if
1665 * any requested capabilities changed locally e.g. via
1666 * remount but we can not do much about it here
1667 * if they have (even if we could detect it by the following)
1668 * Perhaps we could add a backpointer to array of sb from tcon
1669 * or if we change to make all sb to same share the same
1670 * sb as NFS - then we only have one backpointer to sb.
1671 * What if we wanted to mount the server share twice once with
1672 * and once without posixacls or posix paths? */
1673 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1675 if (vol_info && vol_info->no_linux_ext) {
1676 tcon->fsUnixInfo.Capability = 0;
1677 tcon->unix_ext = 0; /* Unix Extensions disabled */
1678 cFYI(1, ("Linux protocol extensions disabled"));
1680 } else if (vol_info)
1681 tcon->unix_ext = 1; /* Unix Extensions supported */
1683 if (tcon->unix_ext == 0) {
1684 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1688 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1689 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1691 /* check for reconnect case in which we do not
1692 want to change the mount behavior if we can avoid it */
1693 if (vol_info == NULL) {
1694 /* turn off POSIX ACL and PATHNAMES if not set
1695 originally at mount time */
1696 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1697 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1698 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0)
1699 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1702 cap &= CIFS_UNIX_CAP_MASK;
1703 if (vol_info && vol_info->no_psx_acl)
1704 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1705 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
1706 cFYI(1, ("negotiated posix acl support"));
1708 sb->s_flags |= MS_POSIXACL;
1711 if (vol_info && vol_info->posix_paths == 0)
1712 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1713 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1714 cFYI(1, ("negotiate posix pathnames"));
1716 CIFS_SB(sb)->mnt_cifs_flags |=
1717 CIFS_MOUNT_POSIX_PATHS;
1720 /* We might be setting the path sep back to a different
1721 form if we are reconnecting and the server switched its
1722 posix path capability for this share */
1723 if (sb && (CIFS_SB(sb)->prepathlen > 0))
1724 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1726 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
1727 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
1728 CIFS_SB(sb)->rsize = 127 * 1024;
1729 #ifdef CONFIG_CIFS_DEBUG2
1730 cFYI(1, ("larger reads not supported by srv"));
1736 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
1737 #ifdef CONFIG_CIFS_DEBUG2
1738 if (cap & CIFS_UNIX_FCNTL_CAP)
1739 cFYI(1, ("FCNTL cap"));
1740 if (cap & CIFS_UNIX_EXTATTR_CAP)
1741 cFYI(1, ("EXTATTR cap"));
1742 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1743 cFYI(1, ("POSIX path cap"));
1744 if (cap & CIFS_UNIX_XATTR_CAP)
1745 cFYI(1, ("XATTR cap"));
1746 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
1747 cFYI(1, ("POSIX ACL cap"));
1748 if (cap & CIFS_UNIX_LARGE_READ_CAP)
1749 cFYI(1, ("very large read cap"));
1750 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
1751 cFYI(1, ("very large write cap"));
1752 #endif /* CIFS_DEBUG2 */
1753 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1754 cFYI(1, ("setting capabilities failed"));
1760 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1761 char *mount_data, const char *devname)
1765 int address_type = AF_INET;
1766 struct socket *csocket = NULL;
1767 struct sockaddr_in sin_server;
1768 struct sockaddr_in6 sin_server6;
1769 struct smb_vol volume_info;
1770 struct cifsSesInfo *pSesInfo = NULL;
1771 struct cifsSesInfo *existingCifsSes = NULL;
1772 struct cifsTconInfo *tcon = NULL;
1773 struct TCP_Server_Info *srvTcp = NULL;
1777 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1779 memset(&volume_info, 0, sizeof(struct smb_vol));
1780 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1781 kfree(volume_info.UNC);
1782 kfree(volume_info.password);
1783 kfree(volume_info.prepath);
1788 if (volume_info.nullauth) {
1789 cFYI(1, ("null user"));
1790 volume_info.username = NULL;
1791 } else if (volume_info.username) {
1792 /* BB fixme parse for domain name here */
1793 cFYI(1, ("Username: %s", volume_info.username));
1795 cifserror("No username specified");
1796 /* In userspace mount helper we can get user name from alternate
1797 locations such as env variables and files on disk */
1798 kfree(volume_info.UNC);
1799 kfree(volume_info.password);
1800 kfree(volume_info.prepath);
1805 if (volume_info.UNCip && volume_info.UNC) {
1806 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
1807 &sin_server.sin_addr.s_addr);
1810 /* not ipv4 address, try ipv6 */
1811 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
1812 &sin_server6.sin6_addr.in6_u);
1814 address_type = AF_INET6;
1816 address_type = AF_INET;
1820 /* we failed translating address */
1821 kfree(volume_info.UNC);
1822 kfree(volume_info.password);
1823 kfree(volume_info.prepath);
1828 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1831 } else if (volume_info.UNCip) {
1832 /* BB using ip addr as server name to connect to the
1834 cERROR(1, ("Connecting to DFS root not implemented yet"));
1835 kfree(volume_info.UNC);
1836 kfree(volume_info.password);
1837 kfree(volume_info.prepath);
1840 } else /* which servers DFS root would we conect to */ {
1842 ("CIFS mount error: No UNC path (e.g. -o "
1843 "unc=//192.168.1.100/public) specified"));
1844 kfree(volume_info.UNC);
1845 kfree(volume_info.password);
1846 kfree(volume_info.prepath);
1851 /* this is needed for ASCII cp to Unicode converts */
1852 if (volume_info.iocharset == NULL) {
1853 cifs_sb->local_nls = load_nls_default();
1854 /* load_nls_default can not return null */
1856 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1857 if (cifs_sb->local_nls == NULL) {
1858 cERROR(1, ("CIFS mount error: iocharset %s not found",
1859 volume_info.iocharset));
1860 kfree(volume_info.UNC);
1861 kfree(volume_info.password);
1862 kfree(volume_info.prepath);
1868 if (address_type == AF_INET)
1869 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1870 NULL /* no ipv6 addr */,
1871 volume_info.username, &srvTcp);
1872 else if (address_type == AF_INET6) {
1873 cFYI(1, ("looking for ipv6 address"));
1874 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1875 &sin_server6.sin6_addr,
1876 volume_info.username, &srvTcp);
1878 kfree(volume_info.UNC);
1879 kfree(volume_info.password);
1880 kfree(volume_info.prepath);
1886 cFYI(1, ("Existing tcp session with server found"));
1887 } else { /* create socket */
1888 if (volume_info.port)
1889 sin_server.sin_port = htons(volume_info.port);
1891 sin_server.sin_port = 0;
1892 if (address_type == AF_INET6) {
1893 cFYI(1, ("attempting ipv6 connect"));
1894 /* BB should we allow ipv6 on port 139? */
1895 /* other OS never observed in Wild doing 139 with v6 */
1896 rc = ipv6_connect(&sin_server6, &csocket);
1898 rc = ipv4_connect(&sin_server, &csocket,
1899 volume_info.source_rfc1001_name,
1900 volume_info.target_rfc1001_name);
1902 cERROR(1, ("Error connecting to IPv4 socket. "
1903 "Aborting operation"));
1904 if (csocket != NULL)
1905 sock_release(csocket);
1906 kfree(volume_info.UNC);
1907 kfree(volume_info.password);
1908 kfree(volume_info.prepath);
1913 srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
1914 if (srvTcp == NULL) {
1916 sock_release(csocket);
1917 kfree(volume_info.UNC);
1918 kfree(volume_info.password);
1919 kfree(volume_info.prepath);
1923 memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
1924 memcpy(&srvTcp->addr.sockAddr, &sin_server,
1925 sizeof (struct sockaddr_in));
1926 atomic_set(&srvTcp->inFlight, 0);
1927 /* BB Add code for ipv6 case too */
1928 srvTcp->ssocket = csocket;
1929 srvTcp->protocolType = IPV4;
1930 init_waitqueue_head(&srvTcp->response_q);
1931 init_waitqueue_head(&srvTcp->request_q);
1932 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
1933 /* at this point we are the only ones with the pointer
1934 to the struct since the kernel thread not created yet
1935 so no need to spinlock this init of tcpStatus */
1936 srvTcp->tcpStatus = CifsNew;
1937 init_MUTEX(&srvTcp->tcpSem);
1938 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
1939 if ( IS_ERR(srvTcp->tsk) ) {
1940 rc = PTR_ERR(srvTcp->tsk);
1941 cERROR(1, ("error %d create cifsd thread", rc));
1943 sock_release(csocket);
1944 kfree(volume_info.UNC);
1945 kfree(volume_info.password);
1946 kfree(volume_info.prepath);
1950 wait_for_completion(&cifsd_complete);
1952 memcpy(srvTcp->workstation_RFC1001_name,
1953 volume_info.source_rfc1001_name, 16);
1954 memcpy(srvTcp->server_RFC1001_name,
1955 volume_info.target_rfc1001_name, 16);
1956 srvTcp->sequence_number = 0;
1960 if (existingCifsSes) {
1961 pSesInfo = existingCifsSes;
1962 cFYI(1, ("Existing smb sess found"));
1963 kfree(volume_info.password);
1964 /* volume_info.UNC freed at end of function */
1966 cFYI(1, ("Existing smb sess not found"));
1967 pSesInfo = sesInfoAlloc();
1968 if (pSesInfo == NULL)
1971 pSesInfo->server = srvTcp;
1972 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
1973 NIPQUAD(sin_server.sin_addr.s_addr));
1977 /* volume_info.password freed at unmount */
1978 if (volume_info.password)
1979 pSesInfo->password = volume_info.password;
1980 if (volume_info.username)
1981 strncpy(pSesInfo->userName,
1982 volume_info.username,
1984 if (volume_info.domainname) {
1985 int len = strlen(volume_info.domainname);
1986 pSesInfo->domainName =
1987 kmalloc(len + 1, GFP_KERNEL);
1988 if (pSesInfo->domainName)
1989 strcpy(pSesInfo->domainName,
1990 volume_info.domainname);
1992 pSesInfo->linux_uid = volume_info.linux_uid;
1993 pSesInfo->overrideSecFlg = volume_info.secFlg;
1994 down(&pSesInfo->sesSem);
1995 /* BB FIXME need to pass vol->secFlgs BB */
1996 rc = cifs_setup_session(xid, pSesInfo,
1997 cifs_sb->local_nls);
1998 up(&pSesInfo->sesSem);
2000 atomic_inc(&srvTcp->socketUseCount);
2002 kfree(volume_info.password);
2005 /* search for existing tcon to this server share */
2007 if (volume_info.rsize > CIFSMaxBufSize) {
2008 cERROR(1, ("rsize %d too large, using MaxBufSize",
2009 volume_info.rsize));
2010 cifs_sb->rsize = CIFSMaxBufSize;
2011 } else if ((volume_info.rsize) &&
2012 (volume_info.rsize <= CIFSMaxBufSize))
2013 cifs_sb->rsize = volume_info.rsize;
2015 cifs_sb->rsize = CIFSMaxBufSize;
2017 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2018 cERROR(1, ("wsize %d too large, using 4096 instead",
2019 volume_info.wsize));
2020 cifs_sb->wsize = 4096;
2021 } else if (volume_info.wsize)
2022 cifs_sb->wsize = volume_info.wsize;
2025 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2027 /* old default of CIFSMaxBufSize was too small now
2028 that SMB Write2 can send multiple pages in kvec.
2029 RFC1001 does not describe what happens when frame
2030 bigger than 128K is sent so use that as max in
2031 conjunction with 52K kvec constraint on arch with 4K
2034 if (cifs_sb->rsize < 2048) {
2035 cifs_sb->rsize = 2048;
2036 /* Windows ME may prefer this */
2037 cFYI(1, ("readsize set to minimum: 2048"));
2039 /* calculate prepath */
2040 cifs_sb->prepath = volume_info.prepath;
2041 if (cifs_sb->prepath) {
2042 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2043 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
2044 volume_info.prepath = NULL;
2046 cifs_sb->prepathlen = 0;
2047 cifs_sb->mnt_uid = volume_info.linux_uid;
2048 cifs_sb->mnt_gid = volume_info.linux_gid;
2049 cifs_sb->mnt_file_mode = volume_info.file_mode;
2050 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
2051 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2052 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2054 if (volume_info.noperm)
2055 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2056 if (volume_info.setuids)
2057 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2058 if (volume_info.server_ino)
2059 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2060 if (volume_info.remap)
2061 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2062 if (volume_info.no_xattr)
2063 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2064 if (volume_info.sfu_emul)
2065 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2066 if (volume_info.nobrl)
2067 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2068 if (volume_info.cifs_acl)
2069 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2070 if (volume_info.override_uid)
2071 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2072 if (volume_info.override_gid)
2073 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2074 if (volume_info.direct_io) {
2075 cFYI(1, ("mounting share using direct i/o"));
2076 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2080 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
2081 volume_info.username);
2083 cFYI(1, ("Found match on UNC path"));
2084 /* we can have only one retry value for a connection
2085 to a share so for resources mounted more than once
2086 to the same server share the last value passed in
2087 for the retry flag is used */
2088 tcon->retry = volume_info.retry;
2089 tcon->nocase = volume_info.nocase;
2091 tcon = tconInfoAlloc();
2095 /* check for null share name ie connecting to
2098 /* BB check if this works for exactly length
2100 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2101 && (strchr(volume_info.UNC + 3, '/') ==
2103 rc = connect_to_dfs_path(xid, pSesInfo,
2104 "", cifs_sb->local_nls,
2105 cifs_sb->mnt_cifs_flags &
2106 CIFS_MOUNT_MAP_SPECIAL_CHR);
2107 kfree(volume_info.UNC);
2111 /* BB Do we need to wrap sesSem around
2112 * this TCon call and Unix SetFS as
2113 * we do on SessSetup and reconnect? */
2114 rc = CIFSTCon(xid, pSesInfo,
2116 tcon, cifs_sb->local_nls);
2117 cFYI(1, ("CIFS Tcon rc = %d", rc));
2120 atomic_inc(&pSesInfo->inUse);
2121 tcon->retry = volume_info.retry;
2122 tcon->nocase = volume_info.nocase;
2128 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2129 sb->s_maxbytes = (u64) 1 << 63;
2131 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2134 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2135 sb->s_time_gran = 100;
2137 /* on error free sesinfo and tcon struct if needed */
2139 /* if session setup failed, use count is zero but
2140 we still need to free cifsd thread */
2141 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2142 spin_lock(&GlobalMid_Lock);
2143 srvTcp->tcpStatus = CifsExiting;
2144 spin_unlock(&GlobalMid_Lock);
2146 struct task_struct *tsk;
2147 /* If we could verify that kthread_stop would
2148 always wake up processes blocked in
2149 tcp in recv_mesg then we could remove the
2151 force_sig(SIGKILL, srvTcp->tsk);
2157 /* If find_unc succeeded then rc == 0 so we can not end */
2158 if (tcon) /* up accidently freeing someone elses tcon struct */
2160 if (existingCifsSes == NULL) {
2162 if ((pSesInfo->server) &&
2163 (pSesInfo->status == CifsGood)) {
2165 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2166 /* if the socketUseCount is now zero */
2167 if ((temp_rc == -ESHUTDOWN) &&
2168 (pSesInfo->server) &&
2169 (pSesInfo->server->tsk)) {
2170 struct task_struct *tsk;
2172 pSesInfo->server->tsk);
2173 tsk = pSesInfo->server->tsk;
2178 cFYI(1, ("No session or bad tcon"));
2179 sesInfoFree(pSesInfo);
2180 /* pSesInfo = NULL; */
2184 atomic_inc(&tcon->useCount);
2185 cifs_sb->tcon = tcon;
2186 tcon->ses = pSesInfo;
2188 /* do not care if following two calls succeed - informational */
2189 CIFSSMBQFSDeviceInfo(xid, tcon);
2190 CIFSSMBQFSAttributeInfo(xid, tcon);
2192 /* tell server which Unix caps we support */
2193 if (tcon->ses->capabilities & CAP_UNIX)
2194 /* reset of caps checks mount to see if unix extensions
2195 disabled for just this mount */
2196 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2198 tcon->unix_ext = 0; /* server does not support them */
2200 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2201 cifs_sb->rsize = 1024 * 127;
2202 #ifdef CONFIG_CIFS_DEBUG2
2203 cFYI(1, ("no very large read support, rsize now 127K"));
2206 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2207 cifs_sb->wsize = min(cifs_sb->wsize,
2208 (tcon->ses->server->maxBuf -
2209 MAX_CIFS_HDR_SIZE));
2210 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2211 cifs_sb->rsize = min(cifs_sb->rsize,
2212 (tcon->ses->server->maxBuf -
2213 MAX_CIFS_HDR_SIZE));
2216 /* volume_info.password is freed above when existing session found
2217 (in which case it is not needed anymore) but when new sesion is created
2218 the password ptr is put in the new session structure (in which case the
2219 password will be freed at unmount time) */
2220 kfree(volume_info.UNC);
2221 kfree(volume_info.prepath);
2227 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2228 char session_key[CIFS_SESS_KEY_SIZE],
2229 const struct nls_table *nls_codepage)
2231 struct smb_hdr *smb_buffer;
2232 struct smb_hdr *smb_buffer_response;
2233 SESSION_SETUP_ANDX *pSMB;
2234 SESSION_SETUP_ANDX *pSMBr;
2239 int remaining_words = 0;
2240 int bytes_returned = 0;
2245 cFYI(1, ("In sesssetup"));
2248 user = ses->userName;
2249 domain = ses->domainName;
2250 smb_buffer = cifs_buf_get();
2251 if (smb_buffer == NULL) {
2254 smb_buffer_response = smb_buffer;
2255 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2257 /* send SMBsessionSetup here */
2258 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2259 NULL /* no tCon exists yet */ , 13 /* wct */ );
2261 smb_buffer->Mid = GetNextMid(ses->server);
2262 pSMB->req_no_secext.AndXCommand = 0xFF;
2263 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2264 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2266 if (ses->server->secMode &
2267 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2268 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2270 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2271 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2272 if (ses->capabilities & CAP_UNICODE) {
2273 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2274 capabilities |= CAP_UNICODE;
2276 if (ses->capabilities & CAP_STATUS32) {
2277 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2278 capabilities |= CAP_STATUS32;
2280 if (ses->capabilities & CAP_DFS) {
2281 smb_buffer->Flags2 |= SMBFLG2_DFS;
2282 capabilities |= CAP_DFS;
2284 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2286 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2287 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2289 pSMB->req_no_secext.CaseSensitivePasswordLength =
2290 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2291 bcc_ptr = pByteArea(smb_buffer);
2292 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2293 bcc_ptr += CIFS_SESS_KEY_SIZE;
2294 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2295 bcc_ptr += CIFS_SESS_KEY_SIZE;
2297 if (ses->capabilities & CAP_UNICODE) {
2298 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2303 bytes_returned = 0; /* skip null user */
2306 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2308 /* convert number of 16 bit words to bytes */
2309 bcc_ptr += 2 * bytes_returned;
2310 bcc_ptr += 2; /* trailing null */
2313 cifs_strtoUCS((__le16 *) bcc_ptr,
2314 "CIFS_LINUX_DOM", 32, nls_codepage);
2317 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2319 bcc_ptr += 2 * bytes_returned;
2322 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2324 bcc_ptr += 2 * bytes_returned;
2326 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2328 bcc_ptr += 2 * bytes_returned;
2331 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2333 bcc_ptr += 2 * bytes_returned;
2337 strncpy(bcc_ptr, user, 200);
2338 bcc_ptr += strnlen(user, 200);
2342 if (domain == NULL) {
2343 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2344 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2346 strncpy(bcc_ptr, domain, 64);
2347 bcc_ptr += strnlen(domain, 64);
2351 strcpy(bcc_ptr, "Linux version ");
2352 bcc_ptr += strlen("Linux version ");
2353 strcpy(bcc_ptr, utsname()->release);
2354 bcc_ptr += strlen(utsname()->release) + 1;
2355 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2356 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2358 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2359 smb_buffer->smb_buf_length += count;
2360 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2362 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2363 &bytes_returned, 1);
2365 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2366 } else if ((smb_buffer_response->WordCount == 3)
2367 || (smb_buffer_response->WordCount == 4)) {
2368 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2369 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2370 if (action & GUEST_LOGIN)
2371 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2372 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2374 cFYI(1, ("UID = %d ", ses->Suid));
2375 /* response can have either 3 or 4 word count - Samba sends 3 */
2376 bcc_ptr = pByteArea(smb_buffer_response);
2377 if ((pSMBr->resp.hdr.WordCount == 3)
2378 || ((pSMBr->resp.hdr.WordCount == 4)
2379 && (blob_len < pSMBr->resp.ByteCount))) {
2380 if (pSMBr->resp.hdr.WordCount == 4)
2381 bcc_ptr += blob_len;
2383 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2384 if ((long) (bcc_ptr) % 2) {
2386 (BCC(smb_buffer_response) - 1) / 2;
2387 /* Unicode strings must be word
2392 BCC(smb_buffer_response) / 2;
2395 UniStrnlen((wchar_t *) bcc_ptr,
2396 remaining_words - 1);
2397 /* We look for obvious messed up bcc or strings in response so we do not go off
2398 the end since (at least) WIN2K and Windows XP have a major bug in not null
2399 terminating last Unicode string in response */
2401 kfree(ses->serverOS);
2402 ses->serverOS = kzalloc(2 * (len + 1),
2404 if (ses->serverOS == NULL)
2405 goto sesssetup_nomem;
2406 cifs_strfromUCS_le(ses->serverOS,
2409 bcc_ptr += 2 * (len + 1);
2410 remaining_words -= len + 1;
2411 ses->serverOS[2 * len] = 0;
2412 ses->serverOS[1 + (2 * len)] = 0;
2413 if (remaining_words > 0) {
2414 len = UniStrnlen((wchar_t *)bcc_ptr,
2416 kfree(ses->serverNOS);
2417 ses->serverNOS = kzalloc(2 * (len + 1),
2419 if (ses->serverNOS == NULL)
2420 goto sesssetup_nomem;
2421 cifs_strfromUCS_le(ses->serverNOS,
2424 bcc_ptr += 2 * (len + 1);
2425 ses->serverNOS[2 * len] = 0;
2426 ses->serverNOS[1 + (2 * len)] = 0;
2427 if (strncmp(ses->serverNOS,
2428 "NT LAN Manager 4", 16) == 0) {
2429 cFYI(1, ("NT4 server"));
2430 ses->flags |= CIFS_SES_NT4;
2432 remaining_words -= len + 1;
2433 if (remaining_words > 0) {
2434 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2435 /* last string is not always null terminated
2436 (for e.g. for Windows XP & 2000) */
2437 if (ses->serverDomain)
2438 kfree(ses->serverDomain);
2442 if (ses->serverDomain == NULL)
2443 goto sesssetup_nomem;
2444 cifs_strfromUCS_le(ses->serverDomain,
2447 bcc_ptr += 2 * (len + 1);
2448 ses->serverDomain[2*len] = 0;
2449 ses->serverDomain[1+(2*len)] = 0;
2450 } else { /* else no more room so create
2451 dummy domain string */
2452 if (ses->serverDomain)
2453 kfree(ses->serverDomain);
2455 kzalloc(2, GFP_KERNEL);
2457 } else { /* no room so create dummy domain
2460 /* if these kcallocs fail not much we
2461 can do, but better to not fail the
2463 kfree(ses->serverDomain);
2465 kzalloc(2, GFP_KERNEL);
2466 kfree(ses->serverNOS);
2468 kzalloc(2, GFP_KERNEL);
2470 } else { /* ASCII */
2471 len = strnlen(bcc_ptr, 1024);
2472 if (((long) bcc_ptr + len) - (long)
2473 pByteArea(smb_buffer_response)
2474 <= BCC(smb_buffer_response)) {
2475 kfree(ses->serverOS);
2476 ses->serverOS = kzalloc(len + 1,
2478 if (ses->serverOS == NULL)
2479 goto sesssetup_nomem;
2480 strncpy(ses->serverOS, bcc_ptr, len);
2483 /* null terminate the string */
2487 len = strnlen(bcc_ptr, 1024);
2488 kfree(ses->serverNOS);
2489 ses->serverNOS = kzalloc(len + 1,
2491 if (ses->serverNOS == NULL)
2492 goto sesssetup_nomem;
2493 strncpy(ses->serverNOS, bcc_ptr, len);
2498 len = strnlen(bcc_ptr, 1024);
2499 if (ses->serverDomain)
2500 kfree(ses->serverDomain);
2501 ses->serverDomain = kzalloc(len + 1,
2503 if (ses->serverDomain == NULL)
2504 goto sesssetup_nomem;
2505 strncpy(ses->serverDomain, bcc_ptr,
2512 ("Variable field of length %d "
2513 "extends beyond end of smb ",
2518 (" Security Blob Length extends beyond "
2523 (" Invalid Word count %d: ",
2524 smb_buffer_response->WordCount));
2527 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2528 since that could make reconnection harder, and
2529 reconnection might be needed to free memory */
2531 cifs_buf_release(smb_buffer);
2537 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2538 struct cifsSesInfo *ses, int *pNTLMv2_flag,
2539 const struct nls_table *nls_codepage)
2541 struct smb_hdr *smb_buffer;
2542 struct smb_hdr *smb_buffer_response;
2543 SESSION_SETUP_ANDX *pSMB;
2544 SESSION_SETUP_ANDX *pSMBr;
2548 int remaining_words = 0;
2549 int bytes_returned = 0;
2551 int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
2552 PNEGOTIATE_MESSAGE SecurityBlob;
2553 PCHALLENGE_MESSAGE SecurityBlob2;
2554 __u32 negotiate_flags, capabilities;
2557 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2560 domain = ses->domainName;
2561 *pNTLMv2_flag = FALSE;
2562 smb_buffer = cifs_buf_get();
2563 if (smb_buffer == NULL) {
2566 smb_buffer_response = smb_buffer;
2567 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2568 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2570 /* send SMBsessionSetup here */
2571 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2572 NULL /* no tCon exists yet */ , 12 /* wct */ );
2574 smb_buffer->Mid = GetNextMid(ses->server);
2575 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2576 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2578 pSMB->req.AndXCommand = 0xFF;
2579 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2580 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2582 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2583 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2585 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2586 CAP_EXTENDED_SECURITY;
2587 if (ses->capabilities & CAP_UNICODE) {
2588 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2589 capabilities |= CAP_UNICODE;
2591 if (ses->capabilities & CAP_STATUS32) {
2592 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2593 capabilities |= CAP_STATUS32;
2595 if (ses->capabilities & CAP_DFS) {
2596 smb_buffer->Flags2 |= SMBFLG2_DFS;
2597 capabilities |= CAP_DFS;
2599 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2601 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2602 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2603 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2604 SecurityBlob->MessageType = NtLmNegotiate;
2606 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2607 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2608 NTLMSSP_NEGOTIATE_56 |
2609 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2611 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2612 /* if (ntlmv2_support)
2613 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2614 /* setup pointers to domain name and workstation name */
2615 bcc_ptr += SecurityBlobLength;
2617 SecurityBlob->WorkstationName.Buffer = 0;
2618 SecurityBlob->WorkstationName.Length = 0;
2619 SecurityBlob->WorkstationName.MaximumLength = 0;
2621 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2622 along with username on auth request (ie the response to challenge) */
2623 SecurityBlob->DomainName.Buffer = 0;
2624 SecurityBlob->DomainName.Length = 0;
2625 SecurityBlob->DomainName.MaximumLength = 0;
2626 if (ses->capabilities & CAP_UNICODE) {
2627 if ((long) bcc_ptr % 2) {
2633 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2635 bcc_ptr += 2 * bytes_returned;
2637 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2639 bcc_ptr += 2 * bytes_returned;
2640 bcc_ptr += 2; /* null terminate Linux version */
2642 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2644 bcc_ptr += 2 * bytes_returned;
2647 bcc_ptr += 2; /* null terminate network opsys string */
2650 bcc_ptr += 2; /* null domain */
2651 } else { /* ASCII */
2652 strcpy(bcc_ptr, "Linux version ");
2653 bcc_ptr += strlen("Linux version ");
2654 strcpy(bcc_ptr, utsname()->release);
2655 bcc_ptr += strlen(utsname()->release) + 1;
2656 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2657 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2658 bcc_ptr++; /* empty domain field */
2661 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2662 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2663 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2664 smb_buffer->smb_buf_length += count;
2665 pSMB->req.ByteCount = cpu_to_le16(count);
2667 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2668 &bytes_returned, 1);
2670 if (smb_buffer_response->Status.CifsError ==
2671 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2675 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2676 } else if ((smb_buffer_response->WordCount == 3)
2677 || (smb_buffer_response->WordCount == 4)) {
2678 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2679 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2681 if (action & GUEST_LOGIN)
2682 cFYI(1, (" Guest login"));
2683 /* Do we want to set anything in SesInfo struct when guest login? */
2685 bcc_ptr = pByteArea(smb_buffer_response);
2686 /* response can have either 3 or 4 word count - Samba sends 3 */
2688 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2689 if (SecurityBlob2->MessageType != NtLmChallenge) {
2691 ("Unexpected NTLMSSP message type received %d",
2692 SecurityBlob2->MessageType));
2694 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2695 cFYI(1, ("UID = %d", ses->Suid));
2696 if ((pSMBr->resp.hdr.WordCount == 3)
2697 || ((pSMBr->resp.hdr.WordCount == 4)
2699 pSMBr->resp.ByteCount))) {
2701 if (pSMBr->resp.hdr.WordCount == 4) {
2702 bcc_ptr += blob_len;
2703 cFYI(1, ("Security Blob Length %d",
2707 cFYI(1, ("NTLMSSP Challenge rcvd"));
2709 memcpy(ses->server->cryptKey,
2710 SecurityBlob2->Challenge,
2711 CIFS_CRYPTO_KEY_SIZE);
2712 if (SecurityBlob2->NegotiateFlags &
2713 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2714 *pNTLMv2_flag = TRUE;
2716 if ((SecurityBlob2->NegotiateFlags &
2717 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2718 || (sign_CIFS_PDUs > 1))
2719 ses->server->secMode |=
2720 SECMODE_SIGN_REQUIRED;
2721 if ((SecurityBlob2->NegotiateFlags &
2722 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2723 ses->server->secMode |=
2724 SECMODE_SIGN_ENABLED;
2726 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2727 if ((long) (bcc_ptr) % 2) {
2729 (BCC(smb_buffer_response)
2731 /* Must word align unicode strings */
2736 (smb_buffer_response) / 2;
2739 UniStrnlen((wchar_t *) bcc_ptr,
2740 remaining_words - 1);
2741 /* We look for obvious messed up bcc or strings in response so we do not go off
2742 the end since (at least) WIN2K and Windows XP have a major bug in not null
2743 terminating last Unicode string in response */
2745 kfree(ses->serverOS);
2747 kzalloc(2 * (len + 1), GFP_KERNEL);
2748 cifs_strfromUCS_le(ses->serverOS,
2752 bcc_ptr += 2 * (len + 1);
2753 remaining_words -= len + 1;
2754 ses->serverOS[2 * len] = 0;
2755 ses->serverOS[1 + (2 * len)] = 0;
2756 if (remaining_words > 0) {
2757 len = UniStrnlen((wchar_t *)
2761 kfree(ses->serverNOS);
2763 kzalloc(2 * (len + 1),
2765 cifs_strfromUCS_le(ses->
2771 bcc_ptr += 2 * (len + 1);
2772 ses->serverNOS[2 * len] = 0;
2775 remaining_words -= len + 1;
2776 if (remaining_words > 0) {
2777 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2778 /* last string not always null terminated
2779 (for e.g. for Windows XP & 2000) */
2780 kfree(ses->serverDomain);
2792 ses->serverDomain[2*len]
2797 } /* else no more room so create dummy domain string */
2799 kfree(ses->serverDomain);
2804 } else { /* no room so create dummy domain and NOS string */
2805 kfree(ses->serverDomain);
2807 kzalloc(2, GFP_KERNEL);
2808 kfree(ses->serverNOS);
2810 kzalloc(2, GFP_KERNEL);
2812 } else { /* ASCII */
2813 len = strnlen(bcc_ptr, 1024);
2814 if (((long) bcc_ptr + len) - (long)
2815 pByteArea(smb_buffer_response)
2816 <= BCC(smb_buffer_response)) {
2818 kfree(ses->serverOS);
2822 strncpy(ses->serverOS,
2826 bcc_ptr[0] = 0; /* null terminate string */
2829 len = strnlen(bcc_ptr, 1024);
2830 kfree(ses->serverNOS);
2834 strncpy(ses->serverNOS, bcc_ptr, len);
2839 len = strnlen(bcc_ptr, 1024);
2840 kfree(ses->serverDomain);
2844 strncpy(ses->serverDomain,
2851 ("field of length %d "
2852 "extends beyond end of smb",
2856 cERROR(1, ("Security Blob Length extends beyond"
2860 cERROR(1, ("No session structure passed in."));
2864 (" Invalid Word count %d:",
2865 smb_buffer_response->WordCount));
2870 cifs_buf_release(smb_buffer);
2875 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2876 char *ntlm_session_key, int ntlmv2_flag,
2877 const struct nls_table *nls_codepage)
2879 struct smb_hdr *smb_buffer;
2880 struct smb_hdr *smb_buffer_response;
2881 SESSION_SETUP_ANDX *pSMB;
2882 SESSION_SETUP_ANDX *pSMBr;
2887 int remaining_words = 0;
2888 int bytes_returned = 0;
2890 int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
2891 PAUTHENTICATE_MESSAGE SecurityBlob;
2892 __u32 negotiate_flags, capabilities;
2895 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2898 user = ses->userName;
2899 domain = ses->domainName;
2900 smb_buffer = cifs_buf_get();
2901 if (smb_buffer == NULL) {
2904 smb_buffer_response = smb_buffer;
2905 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2906 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2908 /* send SMBsessionSetup here */
2909 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2910 NULL /* no tCon exists yet */ , 12 /* wct */ );
2912 smb_buffer->Mid = GetNextMid(ses->server);
2913 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2914 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2915 pSMB->req.AndXCommand = 0xFF;
2916 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2917 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2919 pSMB->req.hdr.Uid = ses->Suid;
2921 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2922 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2924 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2925 CAP_EXTENDED_SECURITY;
2926 if (ses->capabilities & CAP_UNICODE) {
2927 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2928 capabilities |= CAP_UNICODE;
2930 if (ses->capabilities & CAP_STATUS32) {
2931 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2932 capabilities |= CAP_STATUS32;
2934 if (ses->capabilities & CAP_DFS) {
2935 smb_buffer->Flags2 |= SMBFLG2_DFS;
2936 capabilities |= CAP_DFS;
2938 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2940 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2941 SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
2942 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2943 SecurityBlob->MessageType = NtLmAuthenticate;
2944 bcc_ptr += SecurityBlobLength;
2946 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
2947 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
2948 0x80000000 | NTLMSSP_NEGOTIATE_128;
2950 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
2952 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2954 /* setup pointers to domain name and workstation name */
2956 SecurityBlob->WorkstationName.Buffer = 0;
2957 SecurityBlob->WorkstationName.Length = 0;
2958 SecurityBlob->WorkstationName.MaximumLength = 0;
2959 SecurityBlob->SessionKey.Length = 0;
2960 SecurityBlob->SessionKey.MaximumLength = 0;
2961 SecurityBlob->SessionKey.Buffer = 0;
2963 SecurityBlob->LmChallengeResponse.Length = 0;
2964 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
2965 SecurityBlob->LmChallengeResponse.Buffer = 0;
2967 SecurityBlob->NtChallengeResponse.Length =
2968 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2969 SecurityBlob->NtChallengeResponse.MaximumLength =
2970 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2971 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
2972 SecurityBlob->NtChallengeResponse.Buffer =
2973 cpu_to_le32(SecurityBlobLength);
2974 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
2975 bcc_ptr += CIFS_SESS_KEY_SIZE;
2977 if (ses->capabilities & CAP_UNICODE) {
2978 if (domain == NULL) {
2979 SecurityBlob->DomainName.Buffer = 0;
2980 SecurityBlob->DomainName.Length = 0;
2981 SecurityBlob->DomainName.MaximumLength = 0;
2984 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2987 SecurityBlob->DomainName.MaximumLength =
2989 SecurityBlob->DomainName.Buffer =
2990 cpu_to_le32(SecurityBlobLength);
2992 SecurityBlobLength += len;
2993 SecurityBlob->DomainName.Length =
2997 SecurityBlob->UserName.Buffer = 0;
2998 SecurityBlob->UserName.Length = 0;
2999 SecurityBlob->UserName.MaximumLength = 0;
3002 cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
3005 SecurityBlob->UserName.MaximumLength =
3007 SecurityBlob->UserName.Buffer =
3008 cpu_to_le32(SecurityBlobLength);
3010 SecurityBlobLength += len;
3011 SecurityBlob->UserName.Length =
3015 /* SecurityBlob->WorkstationName.Length =
3016 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3017 SecurityBlob->WorkstationName.Length *= 2;
3018 SecurityBlob->WorkstationName.MaximumLength =
3019 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3020 SecurityBlob->WorkstationName.Buffer =
3021 cpu_to_le32(SecurityBlobLength);
3022 bcc_ptr += SecurityBlob->WorkstationName.Length;
3023 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3024 SecurityBlob->WorkstationName.Length =
3025 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3027 if ((long) bcc_ptr % 2) {
3032 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3034 bcc_ptr += 2 * bytes_returned;
3036 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3038 bcc_ptr += 2 * bytes_returned;
3039 bcc_ptr += 2; /* null term version string */
3041 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3043 bcc_ptr += 2 * bytes_returned;
3046 bcc_ptr += 2; /* null terminate network opsys string */
3049 bcc_ptr += 2; /* null domain */
3050 } else { /* ASCII */
3051 if (domain == NULL) {
3052 SecurityBlob->DomainName.Buffer = 0;
3053 SecurityBlob->DomainName.Length = 0;
3054 SecurityBlob->DomainName.MaximumLength = 0;
3057 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3058 strncpy(bcc_ptr, domain, 63);
3059 len = strnlen(domain, 64);
3060 SecurityBlob->DomainName.MaximumLength =
3062 SecurityBlob->DomainName.Buffer =
3063 cpu_to_le32(SecurityBlobLength);
3065 SecurityBlobLength += len;
3066 SecurityBlob->DomainName.Length = cpu_to_le16(len);
3069 SecurityBlob->UserName.Buffer = 0;
3070 SecurityBlob->UserName.Length = 0;
3071 SecurityBlob->UserName.MaximumLength = 0;
3074 strncpy(bcc_ptr, user, 63);
3075 len = strnlen(user, 64);
3076 SecurityBlob->UserName.MaximumLength =
3078 SecurityBlob->UserName.Buffer =
3079 cpu_to_le32(SecurityBlobLength);
3081 SecurityBlobLength += len;
3082 SecurityBlob->UserName.Length = cpu_to_le16(len);
3084 /* BB fill in our workstation name if known BB */
3086 strcpy(bcc_ptr, "Linux version ");
3087 bcc_ptr += strlen("Linux version ");
3088 strcpy(bcc_ptr, utsname()->release);
3089 bcc_ptr += strlen(utsname()->release) + 1;
3090 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3091 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3092 bcc_ptr++; /* null domain */
3095 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3096 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3097 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3098 smb_buffer->smb_buf_length += count;
3099 pSMB->req.ByteCount = cpu_to_le16(count);
3101 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3102 &bytes_returned, 1);
3104 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
3105 } else if ((smb_buffer_response->WordCount == 3)
3106 || (smb_buffer_response->WordCount == 4)) {
3107 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3109 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3110 if (action & GUEST_LOGIN)
3111 cFYI(1, (" Guest login")); /* BB Should we set anything
3112 in SesInfo struct ? */
3113 /* if (SecurityBlob2->MessageType != NtLm??) {
3114 cFYI("Unexpected message type on auth response is %d"));
3119 ("Check challenge UID %d vs auth response UID %d",
3120 ses->Suid, smb_buffer_response->Uid));
3121 /* UID left in wire format */
3122 ses->Suid = smb_buffer_response->Uid;
3123 bcc_ptr = pByteArea(smb_buffer_response);
3124 /* response can have either 3 or 4 word count - Samba sends 3 */
3125 if ((pSMBr->resp.hdr.WordCount == 3)
3126 || ((pSMBr->resp.hdr.WordCount == 4)
3128 pSMBr->resp.ByteCount))) {
3129 if (pSMBr->resp.hdr.WordCount == 4) {
3133 ("Security Blob Length %d ",
3138 ("NTLMSSP response to Authenticate "));
3140 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3141 if ((long) (bcc_ptr) % 2) {
3143 (BCC(smb_buffer_response)
3145 bcc_ptr++; /* Unicode strings must be word aligned */
3147 remaining_words = BCC(smb_buffer_response) / 2;
3150 UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
3151 /* We look for obvious messed up bcc or strings in response so we do not go off
3152 the end since (at least) WIN2K and Windows XP have a major bug in not null
3153 terminating last Unicode string in response */
3155 kfree(ses->serverOS);
3157 kzalloc(2 * (len + 1), GFP_KERNEL);
3158 cifs_strfromUCS_le(ses->serverOS,
3162 bcc_ptr += 2 * (len + 1);
3163 remaining_words -= len + 1;
3164 ses->serverOS[2 * len] = 0;
3165 ses->serverOS[1 + (2 * len)] = 0;
3166 if (remaining_words > 0) {
3167 len = UniStrnlen((wchar_t *)
3171 kfree(ses->serverNOS);
3173 kzalloc(2 * (len + 1),
3175 cifs_strfromUCS_le(ses->
3181 bcc_ptr += 2 * (len + 1);
3182 ses->serverNOS[2 * len] = 0;
3183 ses->serverNOS[1+(2*len)] = 0;
3184 remaining_words -= len + 1;
3185 if (remaining_words > 0) {
3186 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3187 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3188 if (ses->serverDomain)
3189 kfree(ses->serverDomain);
3214 } /* else no more room so create dummy domain string */
3216 if (ses->serverDomain)
3217 kfree(ses->serverDomain);
3218 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3220 } else { /* no room so create dummy domain and NOS string */
3221 if (ses->serverDomain)
3222 kfree(ses->serverDomain);
3223 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3224 kfree(ses->serverNOS);
3225 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3227 } else { /* ASCII */
3228 len = strnlen(bcc_ptr, 1024);
3229 if (((long) bcc_ptr + len) -
3230 (long) pByteArea(smb_buffer_response)
3231 <= BCC(smb_buffer_response)) {
3233 kfree(ses->serverOS);
3234 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
3235 strncpy(ses->serverOS,bcc_ptr, len);
3238 bcc_ptr[0] = 0; /* null terminate the string */
3241 len = strnlen(bcc_ptr, 1024);
3242 kfree(ses->serverNOS);
3243 ses->serverNOS = kzalloc(len+1,
3245 strncpy(ses->serverNOS,
3251 len = strnlen(bcc_ptr, 1024);
3252 if (ses->serverDomain)
3253 kfree(ses->serverDomain);
3257 strncpy(ses->serverDomain,
3264 ("field of length %d "
3265 "extends beyond end of smb ",
3270 (" Security Blob extends beyond end "
3274 cERROR(1, ("No session structure passed in."));
3278 (" Invalid Word count %d: ",
3279 smb_buffer_response->WordCount));
3284 cifs_buf_release(smb_buffer);
3290 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3291 const char *tree, struct cifsTconInfo *tcon,
3292 const struct nls_table *nls_codepage)
3294 struct smb_hdr *smb_buffer;
3295 struct smb_hdr *smb_buffer_response;
3298 unsigned char *bcc_ptr;
3306 smb_buffer = cifs_buf_get();
3307 if (smb_buffer == NULL) {
3310 smb_buffer_response = smb_buffer;
3312 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3313 NULL /*no tid */ , 4 /*wct */ );
3315 smb_buffer->Mid = GetNextMid(ses->server);
3316 smb_buffer->Uid = ses->Suid;
3317 pSMB = (TCONX_REQ *) smb_buffer;
3318 pSMBr = (TCONX_RSP *) smb_buffer_response;
3320 pSMB->AndXCommand = 0xFF;
3321 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3322 bcc_ptr = &pSMB->Password[0];
3323 if ((ses->server->secMode) & SECMODE_USER) {
3324 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3325 *bcc_ptr = 0; /* password is null byte */
3326 bcc_ptr++; /* skip password */
3327 /* already aligned so no need to do it below */
3329 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3330 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3331 specified as required (when that support is added to
3332 the vfs in the future) as only NTLM or the much
3333 weaker LANMAN (which we do not send by default) is accepted
3334 by Samba (not sure whether other servers allow
3335 NTLMv2 password here) */
3336 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3337 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3338 (ses->server->secType == LANMAN))
3339 calc_lanman_hash(ses, bcc_ptr);
3341 #endif /* CIFS_WEAK_PW_HASH */
3342 SMBNTencrypt(ses->password,
3343 ses->server->cryptKey,
3346 bcc_ptr += CIFS_SESS_KEY_SIZE;
3347 if (ses->capabilities & CAP_UNICODE) {
3348 /* must align unicode strings */
3349 *bcc_ptr = 0; /* null byte password */
3354 if (ses->server->secMode &
3355 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3356 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3358 if (ses->capabilities & CAP_STATUS32) {
3359 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3361 if (ses->capabilities & CAP_DFS) {
3362 smb_buffer->Flags2 |= SMBFLG2_DFS;
3364 if (ses->capabilities & CAP_UNICODE) {
3365 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3367 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3368 6 /* max utf8 char length in bytes */ *
3369 (/* server len*/ + 256 /* share len */), nls_codepage);
3370 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3371 bcc_ptr += 2; /* skip trailing null */
3372 } else { /* ASCII */
3373 strcpy(bcc_ptr, tree);
3374 bcc_ptr += strlen(tree) + 1;
3376 strcpy(bcc_ptr, "?????");
3377 bcc_ptr += strlen("?????");
3379 count = bcc_ptr - &pSMB->Password[0];
3380 pSMB->hdr.smb_buf_length += count;
3381 pSMB->ByteCount = cpu_to_le16(count);
3383 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
3385 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3386 /* above now done in SendReceive */
3387 if ((rc == 0) && (tcon != NULL)) {
3388 tcon->tidStatus = CifsGood;
3389 tcon->tid = smb_buffer_response->Tid;
3390 bcc_ptr = pByteArea(smb_buffer_response);
3391 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3392 /* skip service field (NB: this field is always ASCII) */
3393 bcc_ptr += length + 1;
3394 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3395 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3396 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3397 if ((bcc_ptr + (2 * length)) -
3398 pByteArea(smb_buffer_response) <=
3399 BCC(smb_buffer_response)) {
3400 kfree(tcon->nativeFileSystem);
3401 tcon->nativeFileSystem =
3402 kzalloc(length + 2, GFP_KERNEL);
3403 cifs_strfromUCS_le(tcon->nativeFileSystem,
3405 length, nls_codepage);
3406 bcc_ptr += 2 * length;
3407 bcc_ptr[0] = 0; /* null terminate the string */
3411 /* else do not bother copying these information fields*/
3413 length = strnlen(bcc_ptr, 1024);
3414 if ((bcc_ptr + length) -
3415 pByteArea(smb_buffer_response) <=
3416 BCC(smb_buffer_response)) {
3417 kfree(tcon->nativeFileSystem);
3418 tcon->nativeFileSystem =
3419 kzalloc(length + 1, GFP_KERNEL);
3420 strncpy(tcon->nativeFileSystem, bcc_ptr,
3423 /* else do not bother copying these information fields*/
3425 if ((smb_buffer_response->WordCount == 3) ||
3426 (smb_buffer_response->WordCount == 7))
3427 /* field is in same location */
3428 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3431 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3432 } else if ((rc == 0) && tcon == NULL) {
3433 /* all we need to save for IPC$ connection */
3434 ses->ipc_tid = smb_buffer_response->Tid;
3438 cifs_buf_release(smb_buffer);
3443 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3447 struct cifsSesInfo *ses = NULL;
3448 struct task_struct *cifsd_task;
3453 if (cifs_sb->tcon) {
3454 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3455 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3460 tconInfoFree(cifs_sb->tcon);
3461 if ((ses) && (ses->server)) {
3462 /* save off task so we do not refer to ses later */
3463 cifsd_task = ses->server->tsk;
3464 cFYI(1, ("About to do SMBLogoff "));
3465 rc = CIFSSMBLogoff(xid, ses);
3469 } else if (rc == -ESHUTDOWN) {
3470 cFYI(1, ("Waking up socket by sending signal"));
3472 force_sig(SIGKILL, cifsd_task);
3473 kthread_stop(cifsd_task);
3476 } /* else - we have an smb session
3477 left on this socket do not kill cifsd */
3479 cFYI(1, ("No session or bad tcon"));
3482 cifs_sb->tcon = NULL;
3483 tmp = cifs_sb->prepath;
3484 cifs_sb->prepathlen = 0;
3485 cifs_sb->prepath = NULL;
3488 schedule_timeout_interruptible(msecs_to_jiffies(500));
3493 return rc; /* BB check if we should always return zero here */
3496 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3497 struct nls_table *nls_info)
3500 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3501 int ntlmv2_flag = FALSE;
3504 /* what if server changes its buffer size after dropping the session? */
3505 if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
3506 rc = CIFSSMBNegotiate(xid, pSesInfo);
3507 if (rc == -EAGAIN) /* retry only once on 1st time connection */ {
3508 rc = CIFSSMBNegotiate(xid, pSesInfo);
3513 spin_lock(&GlobalMid_Lock);
3514 if (pSesInfo->server->tcpStatus != CifsExiting)
3515 pSesInfo->server->tcpStatus = CifsGood;
3518 spin_unlock(&GlobalMid_Lock);
3524 pSesInfo->flags = 0;
3525 pSesInfo->capabilities = pSesInfo->server->capabilities;
3526 if (linuxExtEnabled == 0)
3527 pSesInfo->capabilities &= (~CAP_UNIX);
3528 /* pSesInfo->sequence_number = 0;*/
3530 ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3531 pSesInfo->server->secMode,
3532 pSesInfo->server->capabilities,
3533 pSesInfo->server->timeAdj));
3534 if (experimEnabled < 2)
3535 rc = CIFS_SessSetup(xid, pSesInfo,
3536 first_time, nls_info);
3537 else if (extended_security
3538 && (pSesInfo->capabilities
3539 & CAP_EXTENDED_SECURITY)
3540 && (pSesInfo->server->secType == NTLMSSP)) {
3542 } else if (extended_security
3543 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3544 && (pSesInfo->server->secType == RawNTLMSSP)) {
3545 cFYI(1, ("NTLMSSP sesssetup"));
3546 rc = CIFSNTLMSSPNegotiateSessSetup(xid,
3553 cFYI(1, ("more secure NTLM ver2 hash"));
3554 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3559 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
3561 CalcNTLMv2_response(pSesInfo,
3564 cifs_calculate_ntlmv2_mac_key(
3565 pSesInfo->server->mac_signing_key,
3566 response, ntlm_session_key,*/
3568 /* BB Put dummy sig in SessSetup PDU? */
3575 SMBNTencrypt(pSesInfo->password,
3576 pSesInfo->server->cryptKey,
3580 cifs_calculate_mac_key(
3581 &pSesInfo->server->mac_signing_key,
3583 pSesInfo->password);
3585 /* for better security the weaker lanman hash not sent
3586 in AuthSessSetup so we no longer calculate it */
3588 rc = CIFSNTLMSSPAuthSessSetup(xid,
3594 } else { /* old style NTLM 0.12 session setup */
3595 SMBNTencrypt(pSesInfo->password,
3596 pSesInfo->server->cryptKey,
3600 cifs_calculate_mac_key(
3601 &pSesInfo->server->mac_signing_key,
3602 ntlm_session_key, pSesInfo->password);
3604 rc = CIFSSessSetup(xid, pSesInfo,
3605 ntlm_session_key, nls_info);
3608 cERROR(1, ("Send error in SessSetup = %d", rc));
3610 cFYI(1, ("CIFS Session Established successfully"));
3611 pSesInfo->status = CifsGood;