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;
404 kernel_recvmsg(csocket, &smb_msg,
405 &iov, 1, 4, 0 /* BB see socket.h flags */);
407 if ( kthread_should_stop() ) {
409 } else if (server->tcpStatus == CifsNeedReconnect) {
410 cFYI(1, ("Reconnect after server stopped responding"));
411 cifs_reconnect(server);
412 cFYI(1, ("call to reconnect done"));
413 csocket = server->ssocket;
415 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
416 msleep(1); /* minimum sleep to prevent looping
417 allowing socket to clear and app threads to set
418 tcpStatus CifsNeedReconnect if server hung */
420 } else if (length <= 0) {
421 if (server->tcpStatus == CifsNew) {
422 cFYI(1, ("tcp session abend after SMBnegprot"));
423 /* some servers kill the TCP session rather than
424 returning an SMB negprot error, in which
425 case reconnecting here is not going to help,
426 and so simply return error to mount */
429 if (!try_to_freeze() && (length == -EINTR)) {
430 cFYI(1, ("cifsd thread killed"));
433 cFYI(1, ("Reconnect after unexpected peek error %d",
435 cifs_reconnect(server);
436 csocket = server->ssocket;
437 wake_up(&server->response_q);
439 } else if (length < 4) {
441 ("Frame under four bytes received (%d bytes long)",
443 cifs_reconnect(server);
444 csocket = server->ssocket;
445 wake_up(&server->response_q);
449 /* The right amount was read from socket - 4 bytes */
450 /* so we can now interpret the length field */
452 /* the first byte big endian of the length field,
453 is actually not part of the length but the type
454 with the most common, zero, as regular data */
455 temp = *((char *) smb_buffer);
457 /* Note that FC 1001 length is big endian on the wire,
458 but we convert it here so it is always manipulated
459 as host byte order */
460 pdu_length = ntohl(smb_buffer->smb_buf_length);
461 smb_buffer->smb_buf_length = pdu_length;
463 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
465 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
467 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
468 cFYI(1, ("Good RFC 1002 session rsp"));
470 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
471 /* we get this from Windows 98 instead of
472 an error on SMB negprot response */
473 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
475 if (server->tcpStatus == CifsNew) {
476 /* if nack on negprot (rather than
477 ret of smb negprot error) reconnecting
478 not going to help, ret error to mount */
481 /* give server a second to
482 clean up before reconnect attempt */
484 /* always try 445 first on reconnect
485 since we get NACK on some if we ever
486 connected to port 139 (the NACK is
487 since we do not begin with RFC1001
488 session initialize frame) */
489 server->addr.sockAddr.sin_port =
491 cifs_reconnect(server);
492 csocket = server->ssocket;
493 wake_up(&server->response_q);
496 } else if (temp != (char) 0) {
497 cERROR(1, ("Unknown RFC 1002 frame"));
498 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
500 cifs_reconnect(server);
501 csocket = server->ssocket;
505 /* else we have an SMB response */
506 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
507 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
508 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
509 length, pdu_length+4));
510 cifs_reconnect(server);
511 csocket = server->ssocket;
512 wake_up(&server->response_q);
519 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
521 memcpy(bigbuf, smallbuf, 4);
525 iov.iov_base = 4 + (char *)smb_buffer;
526 iov.iov_len = pdu_length;
527 for (total_read = 0; total_read < pdu_length;
528 total_read += length) {
529 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
530 pdu_length - total_read, 0);
531 if ( kthread_should_stop() ||
532 (length == -EINTR)) {
536 } else if (server->tcpStatus == CifsNeedReconnect) {
537 cifs_reconnect(server);
538 csocket = server->ssocket;
539 /* Reconnect wakes up rspns q */
540 /* Now we will reread sock */
543 } else if ((length == -ERESTARTSYS) ||
544 (length == -EAGAIN)) {
545 msleep(1); /* minimum sleep to prevent looping,
546 allowing socket to clear and app
547 threads to set tcpStatus
548 CifsNeedReconnect if server hung*/
550 } else if (length <= 0) {
551 cERROR(1, ("Received no data, expecting %d",
552 pdu_length - total_read));
553 cifs_reconnect(server);
554 csocket = server->ssocket;
561 else if (reconnect == 1)
564 length += 4; /* account for rfc1002 hdr */
567 dump_smb(smb_buffer, length);
568 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
569 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
575 spin_lock(&GlobalMid_Lock);
576 list_for_each(tmp, &server->pending_mid_q) {
577 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
579 if ((mid_entry->mid == smb_buffer->Mid) &&
580 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
581 (mid_entry->command == smb_buffer->Command)) {
582 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
583 /* We have a multipart transact2 resp */
585 if (mid_entry->resp_buf) {
586 /* merge response - fix up 1st*/
587 if (coalesce_t2(smb_buffer,
588 mid_entry->resp_buf)) {
589 mid_entry->multiRsp = 1;
592 /* all parts received */
593 mid_entry->multiEnd = 1;
598 cERROR(1,("1st trans2 resp needs bigbuf"));
599 /* BB maybe we can fix this up, switch
600 to already allocated large buffer? */
602 /* Have first buffer */
603 mid_entry->resp_buf =
605 mid_entry->largeBuf = 1;
611 mid_entry->resp_buf = smb_buffer;
613 mid_entry->largeBuf = 1;
615 mid_entry->largeBuf = 0;
617 task_to_wake = mid_entry->tsk;
618 mid_entry->midState = MID_RESPONSE_RECEIVED;
619 #ifdef CONFIG_CIFS_STATS2
620 mid_entry->when_received = jiffies;
622 /* so we do not time out requests to server
623 which is still responding (since server could
624 be busy but not dead) */
625 server->lstrp = jiffies;
629 spin_unlock(&GlobalMid_Lock);
631 /* Was previous buf put in mpx struct for multi-rsp? */
633 /* smb buffer will be freed by user thread */
639 wake_up_process(task_to_wake);
640 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE)
641 && (isMultiRsp == FALSE)) {
642 cERROR(1, ("No task to wake, unknown frame received! "
643 "NumMids %d", midCount.counter));
644 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
645 sizeof(struct smb_hdr));
646 #ifdef CONFIG_CIFS_DEBUG2
647 cifs_dump_detail(smb_buffer);
648 cifs_dump_mids(server);
649 #endif /* CIFS_DEBUG2 */
652 } /* end while !EXITING */
654 spin_lock(&GlobalMid_Lock);
655 server->tcpStatus = CifsExiting;
657 /* check if we have blocked requests that need to free */
658 /* Note that cifs_max_pending is normally 50, but
659 can be set at module install time to as little as two */
660 if (atomic_read(&server->inFlight) >= cifs_max_pending)
661 atomic_set(&server->inFlight, cifs_max_pending - 1);
662 /* We do not want to set the max_pending too low or we
663 could end up with the counter going negative */
664 spin_unlock(&GlobalMid_Lock);
665 /* Although there should not be any requests blocked on
666 this queue it can not hurt to be paranoid and try to wake up requests
667 that may haven been blocked when more than 50 at time were on the wire
668 to the same server - they now will see the session is in exit state
669 and get out of SendReceive. */
670 wake_up_all(&server->request_q);
671 /* give those requests time to exit */
674 if (server->ssocket) {
675 sock_release(csocket);
676 server->ssocket = NULL;
678 /* buffer usuallly freed in free_mid - need to free it here on exit */
680 cifs_buf_release(bigbuf);
681 if (smallbuf != NULL)
682 cifs_small_buf_release(smallbuf);
684 read_lock(&GlobalSMBSeslock);
685 if (list_empty(&server->pending_mid_q)) {
686 /* loop through server session structures attached to this and
688 list_for_each(tmp, &GlobalSMBSessionList) {
690 list_entry(tmp, struct cifsSesInfo,
692 if (ses->server == server) {
693 ses->status = CifsExiting;
697 read_unlock(&GlobalSMBSeslock);
699 /* although we can not zero the server struct pointer yet,
700 since there are active requests which may depnd on them,
701 mark the corresponding SMB sessions as exiting too */
702 list_for_each(tmp, &GlobalSMBSessionList) {
703 ses = list_entry(tmp, struct cifsSesInfo,
705 if (ses->server == server) {
706 ses->status = CifsExiting;
710 spin_lock(&GlobalMid_Lock);
711 list_for_each(tmp, &server->pending_mid_q) {
712 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
713 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
714 cFYI(1, ("Clearing Mid 0x%x - waking up ",
716 task_to_wake = mid_entry->tsk;
718 wake_up_process(task_to_wake);
722 spin_unlock(&GlobalMid_Lock);
723 read_unlock(&GlobalSMBSeslock);
724 /* 1/8th of sec is more than enough time for them to exit */
728 if (!list_empty(&server->pending_mid_q)) {
729 /* mpx threads have not exited yet give them
730 at least the smb send timeout time for long ops */
731 /* due to delays on oplock break requests, we need
732 to wait at least 45 seconds before giving up
733 on a request getting a response and going ahead
735 cFYI(1, ("Wait for exit from demultiplex thread"));
737 /* if threads still have not exited they are probably never
738 coming home not much else we can do but free the memory */
741 write_lock(&GlobalSMBSeslock);
742 atomic_dec(&tcpSesAllocCount);
743 length = tcpSesAllocCount.counter;
745 /* last chance to mark ses pointers invalid
746 if there are any pointing to this (e.g
747 if a crazy root user tried to kill cifsd
748 kernel thread explicitly this might happen) */
749 list_for_each(tmp, &GlobalSMBSessionList) {
750 ses = list_entry(tmp, struct cifsSesInfo,
752 if (ses->server == server) {
756 write_unlock(&GlobalSMBSeslock);
760 mempool_resize(cifs_req_poolp,
761 length + cifs_min_rcv,
769 cifs_parse_mount_options(char *options, const char *devname,
774 unsigned int temp_len, i, j;
780 if (Local_System_Name[0] != 0)
781 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
783 char *nodename = utsname()->nodename;
784 int n = strnlen(nodename, 15);
785 memset(vol->source_rfc1001_name, 0x20, 15);
786 for (i = 0; i < n; i++) {
787 /* does not have to be perfect mapping since field is
788 informational, only used for servers that do not support
789 port 445 and it can be overridden at mount time */
790 vol->source_rfc1001_name[i] = toupper(nodename[i]);
793 vol->source_rfc1001_name[15] = 0;
794 /* null target name indicates to use *SMBSERVR default called name
795 if we end up sending RFC1001 session initialize */
796 vol->target_rfc1001_name[0] = 0;
797 vol->linux_uid = current->uid; /* current->euid instead? */
798 vol->linux_gid = current->gid;
799 vol->dir_mode = S_IRWXUGO;
800 /* 2767 perms indicate mandatory locking support */
801 vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
803 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
805 /* default is always to request posix paths. */
806 vol->posix_paths = 1;
811 if (strncmp(options, "sep=", 4) == 0) {
812 if (options[4] != 0) {
813 separator[0] = options[4];
816 cFYI(1, ("Null separator not allowed"));
820 while ((data = strsep(&options, separator)) != NULL) {
823 if ((value = strchr(data, '=')) != NULL)
826 /* Have to parse this before we parse for "user" */
827 if (strnicmp(data, "user_xattr", 10) == 0) {
829 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
831 } else if (strnicmp(data, "user", 4) == 0) {
834 "CIFS: invalid or missing username\n");
835 return 1; /* needs_arg; */
836 } else if (!*value) {
837 /* null user, ie anonymous, authentication */
840 if (strnlen(value, 200) < 200) {
841 vol->username = value;
843 printk(KERN_WARNING "CIFS: username too long\n");
846 } else if (strnicmp(data, "pass", 4) == 0) {
848 vol->password = NULL;
850 } else if (value[0] == 0) {
851 /* check if string begins with double comma
852 since that would mean the password really
853 does start with a comma, and would not
854 indicate an empty string */
855 if (value[1] != separator[0]) {
856 vol->password = NULL;
860 temp_len = strlen(value);
861 /* removed password length check, NTLM passwords
862 can be arbitrarily long */
864 /* if comma in password, the string will be
865 prematurely null terminated. Commas in password are
866 specified across the cifs mount interface by a double
867 comma ie ,, and a comma used as in other cases ie ','
868 as a parameter delimiter/separator is single and due
869 to the strsep above is temporarily zeroed. */
871 /* NB: password legally can have multiple commas and
872 the only illegal character in a password is null */
874 if ((value[temp_len] == 0) &&
875 (value[temp_len+1] == separator[0])) {
877 value[temp_len] = separator[0];
878 temp_len += 2; /* move after second comma */
879 while (value[temp_len] != 0) {
880 if (value[temp_len] == separator[0]) {
881 if (value[temp_len+1] ==
883 /* skip second comma */
886 /* single comma indicating start
893 if (value[temp_len] == 0) {
897 /* point option to start of next parm */
898 options = value + temp_len + 1;
900 /* go from value to value + temp_len condensing
901 double commas to singles. Note that this ends up
902 allocating a few bytes too many, which is ok */
903 vol->password = kzalloc(temp_len, GFP_KERNEL);
904 if (vol->password == NULL) {
905 printk(KERN_WARNING "CIFS: no memory "
909 for (i = 0, j = 0; i < temp_len; i++, j++) {
910 vol->password[j] = value[i];
911 if (value[i] == separator[0]
912 && value[i+1] == separator[0]) {
913 /* skip second comma */
917 vol->password[j] = 0;
919 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
920 if (vol->password == NULL) {
921 printk(KERN_WARNING "CIFS: no memory "
925 strcpy(vol->password, value);
927 } else if (strnicmp(data, "ip", 2) == 0) {
928 if (!value || !*value) {
930 } else if (strnlen(value, 35) < 35) {
933 printk(KERN_WARNING "CIFS: ip address "
937 } else if (strnicmp(data, "sec", 3) == 0) {
938 if (!value || !*value) {
939 cERROR(1, ("no security value specified"));
941 } else if (strnicmp(value, "krb5i", 5) == 0) {
942 vol->secFlg |= CIFSSEC_MAY_KRB5 |
944 } else if (strnicmp(value, "krb5p", 5) == 0) {
945 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
947 cERROR(1, ("Krb5 cifs privacy not supported"));
949 } else if (strnicmp(value, "krb5", 4) == 0) {
950 vol->secFlg |= CIFSSEC_MAY_KRB5;
951 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
952 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
954 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
955 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
956 } else if (strnicmp(value, "ntlmi", 5) == 0) {
957 vol->secFlg |= CIFSSEC_MAY_NTLM |
959 } else if (strnicmp(value, "ntlm", 4) == 0) {
960 /* ntlm is default so can be turned off too */
961 vol->secFlg |= CIFSSEC_MAY_NTLM;
962 } else if (strnicmp(value, "nontlm", 6) == 0) {
963 /* BB is there a better way to do this? */
964 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
965 #ifdef CONFIG_CIFS_WEAK_PW_HASH
966 } else if (strnicmp(value, "lanman", 6) == 0) {
967 vol->secFlg |= CIFSSEC_MAY_LANMAN;
969 } else if (strnicmp(value, "none", 4) == 0) {
972 cERROR(1, ("bad security option: %s", value));
975 } else if ((strnicmp(data, "unc", 3) == 0)
976 || (strnicmp(data, "target", 6) == 0)
977 || (strnicmp(data, "path", 4) == 0)) {
978 if (!value || !*value) {
979 printk(KERN_WARNING "CIFS: invalid path to "
980 "network resource\n");
981 return 1; /* needs_arg; */
983 if ((temp_len = strnlen(value, 300)) < 300) {
984 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
985 if (vol->UNC == NULL)
987 strcpy(vol->UNC, value);
988 if (strncmp(vol->UNC, "//", 2) == 0) {
991 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
993 "CIFS: UNC Path does not begin "
994 "with // or \\\\ \n");
998 printk(KERN_WARNING "CIFS: UNC name too long\n");
1001 } else if ((strnicmp(data, "domain", 3) == 0)
1002 || (strnicmp(data, "workgroup", 5) == 0)) {
1003 if (!value || !*value) {
1004 printk(KERN_WARNING "CIFS: invalid domain name\n");
1005 return 1; /* needs_arg; */
1007 /* BB are there cases in which a comma can be valid in
1008 a domain name and need special handling? */
1009 if (strnlen(value, 256) < 256) {
1010 vol->domainname = value;
1011 cFYI(1, ("Domain name set"));
1013 printk(KERN_WARNING "CIFS: domain name too "
1017 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1018 if (!value || !*value) {
1020 "CIFS: invalid path prefix\n");
1021 return 1; /* needs_argument */
1023 if ((temp_len = strnlen(value, 1024)) < 1024) {
1024 if (value[0] != '/')
1025 temp_len++; /* missing leading slash */
1026 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1027 if (vol->prepath == NULL)
1029 if (value[0] != '/') {
1030 vol->prepath[0] = '/';
1031 strcpy(vol->prepath+1, value);
1033 strcpy(vol->prepath, value);
1034 cFYI(1, ("prefix path %s", vol->prepath));
1036 printk(KERN_WARNING "CIFS: prefix too long\n");
1039 } else if (strnicmp(data, "iocharset", 9) == 0) {
1040 if (!value || !*value) {
1041 printk(KERN_WARNING "CIFS: invalid iocharset "
1043 return 1; /* needs_arg; */
1045 if (strnlen(value, 65) < 65) {
1046 if (strnicmp(value, "default", 7))
1047 vol->iocharset = value;
1048 /* if iocharset not set then load_nls_default
1049 is used by caller */
1050 cFYI(1, ("iocharset set to %s", value));
1052 printk(KERN_WARNING "CIFS: iocharset name "
1056 } else if (strnicmp(data, "uid", 3) == 0) {
1057 if (value && *value) {
1059 simple_strtoul(value, &value, 0);
1060 vol->override_uid = 1;
1062 } else if (strnicmp(data, "gid", 3) == 0) {
1063 if (value && *value) {
1065 simple_strtoul(value, &value, 0);
1066 vol->override_gid = 1;
1068 } else if (strnicmp(data, "file_mode", 4) == 0) {
1069 if (value && *value) {
1071 simple_strtoul(value, &value, 0);
1073 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1074 if (value && *value) {
1076 simple_strtoul(value, &value, 0);
1078 } else if (strnicmp(data, "dirmode", 4) == 0) {
1079 if (value && *value) {
1081 simple_strtoul(value, &value, 0);
1083 } else if (strnicmp(data, "port", 4) == 0) {
1084 if (value && *value) {
1086 simple_strtoul(value, &value, 0);
1088 } else if (strnicmp(data, "rsize", 5) == 0) {
1089 if (value && *value) {
1091 simple_strtoul(value, &value, 0);
1093 } else if (strnicmp(data, "wsize", 5) == 0) {
1094 if (value && *value) {
1096 simple_strtoul(value, &value, 0);
1098 } else if (strnicmp(data, "sockopt", 5) == 0) {
1099 if (value && *value) {
1101 simple_strtoul(value, &value, 0);
1103 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1104 if (!value || !*value || (*value == ' ')) {
1105 cFYI(1, ("invalid (empty) netbiosname"));
1107 memset(vol->source_rfc1001_name, 0x20, 15);
1108 for (i = 0; i < 15; i++) {
1109 /* BB are there cases in which a comma can be
1110 valid in this workstation netbios name (and need
1111 special handling)? */
1113 /* We do not uppercase netbiosname for user */
1117 vol->source_rfc1001_name[i] =
1120 /* The string has 16th byte zero still from
1121 set at top of the function */
1122 if ((i == 15) && (value[i] != 0))
1123 printk(KERN_WARNING "CIFS: netbiosname"
1124 " longer than 15 truncated.\n");
1126 } else if (strnicmp(data, "servern", 7) == 0) {
1127 /* servernetbiosname specified override *SMBSERVER */
1128 if (!value || !*value || (*value == ' ')) {
1129 cFYI(1, ("empty server netbiosname specified"));
1131 /* last byte, type, is 0x20 for servr type */
1132 memset(vol->target_rfc1001_name, 0x20, 16);
1134 for (i = 0; i < 15; i++) {
1135 /* BB are there cases in which a comma can be
1136 valid in this workstation netbios name
1137 (and need special handling)? */
1139 /* user or mount helper must uppercase
1144 vol->target_rfc1001_name[i] =
1147 /* The string has 16th byte zero still from
1148 set at top of the function */
1149 if ((i == 15) && (value[i] != 0))
1150 printk(KERN_WARNING "CIFS: server net"
1151 "biosname longer than 15 truncated.\n");
1153 } else if (strnicmp(data, "credentials", 4) == 0) {
1155 } else if (strnicmp(data, "version", 3) == 0) {
1157 } else if (strnicmp(data, "guest", 5) == 0) {
1159 } else if (strnicmp(data, "rw", 2) == 0) {
1161 } else if ((strnicmp(data, "suid", 4) == 0) ||
1162 (strnicmp(data, "nosuid", 6) == 0) ||
1163 (strnicmp(data, "exec", 4) == 0) ||
1164 (strnicmp(data, "noexec", 6) == 0) ||
1165 (strnicmp(data, "nodev", 5) == 0) ||
1166 (strnicmp(data, "noauto", 6) == 0) ||
1167 (strnicmp(data, "dev", 3) == 0)) {
1168 /* The mount tool or mount.cifs helper (if present)
1169 uses these opts to set flags, and the flags are read
1170 by the kernel vfs layer before we get here (ie
1171 before read super) so there is no point trying to
1172 parse these options again and set anything and it
1173 is ok to just ignore them */
1175 } else if (strnicmp(data, "ro", 2) == 0) {
1177 } else if (strnicmp(data, "hard", 4) == 0) {
1179 } else if (strnicmp(data, "soft", 4) == 0) {
1181 } else if (strnicmp(data, "perm", 4) == 0) {
1183 } else if (strnicmp(data, "noperm", 6) == 0) {
1185 } else if (strnicmp(data, "mapchars", 8) == 0) {
1187 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1189 } else if (strnicmp(data, "sfu", 3) == 0) {
1191 } else if (strnicmp(data, "nosfu", 5) == 0) {
1193 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1194 vol->posix_paths = 1;
1195 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1196 vol->posix_paths = 0;
1197 } else if (strnicmp(data, "nounix", 6) == 0) {
1198 vol->no_linux_ext = 1;
1199 } else if (strnicmp(data, "nolinux", 7) == 0) {
1200 vol->no_linux_ext = 1;
1201 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1202 (strnicmp(data, "ignorecase", 10) == 0)) {
1204 } else if (strnicmp(data, "brl", 3) == 0) {
1206 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1207 (strnicmp(data, "nolock", 6) == 0)) {
1209 /* turn off mandatory locking in mode
1210 if remote locking is turned off since the
1211 local vfs will do advisory */
1212 if (vol->file_mode ==
1213 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1214 vol->file_mode = S_IALLUGO;
1215 } else if (strnicmp(data, "setuids", 7) == 0) {
1217 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1219 } else if (strnicmp(data, "nohard", 6) == 0) {
1221 } else if (strnicmp(data, "nosoft", 6) == 0) {
1223 } else if (strnicmp(data, "nointr", 6) == 0) {
1225 } else if (strnicmp(data, "intr", 4) == 0) {
1227 } else if (strnicmp(data, "serverino", 7) == 0) {
1228 vol->server_ino = 1;
1229 } else if (strnicmp(data, "noserverino", 9) == 0) {
1230 vol->server_ino = 0;
1231 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1233 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1235 } else if (strnicmp(data, "acl", 3) == 0) {
1236 vol->no_psx_acl = 0;
1237 } else if (strnicmp(data, "noacl", 5) == 0) {
1238 vol->no_psx_acl = 1;
1239 } else if (strnicmp(data, "sign", 4) == 0) {
1240 vol->secFlg |= CIFSSEC_MUST_SIGN;
1241 /* } else if (strnicmp(data, "seal",4) == 0) {
1242 vol->secFlg |= CIFSSEC_MUST_SEAL; */
1243 } else if (strnicmp(data, "direct", 6) == 0) {
1245 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1247 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1248 if (!value || !*value) {
1249 vol->in6_addr = NULL;
1250 } else if (strnlen(value, 49) == 48) {
1251 vol->in6_addr = value;
1253 printk(KERN_WARNING "CIFS: ip v6 address not "
1254 "48 characters long\n");
1257 } else if (strnicmp(data, "noac", 4) == 0) {
1258 printk(KERN_WARNING "CIFS: Mount option noac not "
1259 "supported. Instead set "
1260 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1262 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1265 if (vol->UNC == NULL) {
1266 if (devname == NULL) {
1267 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1271 if ((temp_len = strnlen(devname, 300)) < 300) {
1272 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1273 if (vol->UNC == NULL)
1275 strcpy(vol->UNC, devname);
1276 if (strncmp(vol->UNC, "//", 2) == 0) {
1279 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1280 printk(KERN_WARNING "CIFS: UNC Path does not "
1281 "begin with // or \\\\ \n");
1285 printk(KERN_WARNING "CIFS: UNC name too long\n");
1289 if (vol->UNCip == NULL)
1290 vol->UNCip = &vol->UNC[2];
1295 static struct cifsSesInfo *
1296 cifs_find_tcp_session(struct in_addr *target_ip_addr,
1297 struct in6_addr *target_ip6_addr,
1298 char *userName, struct TCP_Server_Info **psrvTcp)
1300 struct list_head *tmp;
1301 struct cifsSesInfo *ses;
1303 read_lock(&GlobalSMBSeslock);
1305 list_for_each(tmp, &GlobalSMBSessionList) {
1306 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1308 if ((target_ip_addr &&
1309 (ses->server->addr.sockAddr.sin_addr.s_addr
1310 == target_ip_addr->s_addr)) || (target_ip6_addr
1311 && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1312 target_ip6_addr, sizeof(*target_ip6_addr)))) {
1313 /* BB lock server and tcp session and increment
1316 /* found a match on the TCP session */
1317 *psrvTcp = ses->server;
1319 /* BB check if reconnection needed */
1321 (ses->userName, userName,
1322 MAX_USERNAME_SIZE) == 0){
1323 read_unlock(&GlobalSMBSeslock);
1324 /* Found exact match on both TCP and
1330 /* else tcp and smb sessions need reconnection */
1332 read_unlock(&GlobalSMBSeslock);
1336 static struct cifsTconInfo *
1337 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1339 struct list_head *tmp;
1340 struct cifsTconInfo *tcon;
1342 read_lock(&GlobalSMBSeslock);
1343 list_for_each(tmp, &GlobalTreeConnectionList) {
1344 cFYI(1, ("Next tcon"));
1345 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1347 if (tcon->ses->server) {
1349 ("old ip addr: %x == new ip %x ?",
1350 tcon->ses->server->addr.sockAddr.sin_addr.
1351 s_addr, new_target_ip_addr));
1352 if (tcon->ses->server->addr.sockAddr.sin_addr.
1353 s_addr == new_target_ip_addr) {
1354 /* BB lock tcon, server and tcp session and increment use count here? */
1355 /* found a match on the TCP session */
1356 /* BB check if reconnection needed */
1358 ("IP match, old UNC: %s new: %s",
1359 tcon->treeName, uncName));
1361 (tcon->treeName, uncName,
1362 MAX_TREE_SIZE) == 0) {
1364 ("and old usr: %s new: %s",
1365 tcon->treeName, uncName));
1367 (tcon->ses->userName,
1369 MAX_USERNAME_SIZE) == 0) {
1370 read_unlock(&GlobalSMBSeslock);
1371 /* matched smb session
1380 read_unlock(&GlobalSMBSeslock);
1385 connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1386 const char *old_path, const struct nls_table *nls_codepage,
1389 unsigned char *referrals = NULL;
1390 unsigned int num_referrals;
1393 rc = get_dfs_path(xid, pSesInfo, old_path, nls_codepage,
1394 &num_referrals, &referrals, remap);
1396 /* BB Add in code to: if valid refrl, if not ip address contact
1397 the helper that resolves tcp names, mount to it, try to
1398 tcon to it unmount it if fail */
1406 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1407 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1408 unsigned char **preferrals, int remap)
1413 *pnum_referrals = 0;
1415 if (pSesInfo->ipc_tid == 0) {
1416 temp_unc = kmalloc(2 /* for slashes */ +
1417 strnlen(pSesInfo->serverName,
1418 SERVER_NAME_LEN_WITH_NULL * 2)
1419 + 1 + 4 /* slash IPC$ */ + 2,
1421 if (temp_unc == NULL)
1425 strcpy(temp_unc + 2, pSesInfo->serverName);
1426 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1427 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1429 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1433 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1434 pnum_referrals, nls_codepage, remap);
1439 /* See RFC1001 section 14 on representation of Netbios names */
1440 static void rfc1002mangle(char *target, char *source, unsigned int length)
1444 for (i = 0, j = 0; i < (length); i++) {
1445 /* mask a nibble at a time and encode */
1446 target[j] = 'A' + (0x0F & (source[i] >> 4));
1447 target[j+1] = 'A' + (0x0F & source[i]);
1455 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1456 char *netbios_name, char *target_name)
1460 __be16 orig_port = 0;
1462 if (*csocket == NULL) {
1463 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1464 IPPROTO_TCP, csocket);
1466 cERROR(1, ("Error %d creating socket", rc));
1470 /* BB other socket options to set KEEPALIVE, NODELAY? */
1471 cFYI(1, ("Socket created"));
1472 (*csocket)->sk->sk_allocation = GFP_NOFS;
1476 psin_server->sin_family = AF_INET;
1477 if (psin_server->sin_port) { /* user overrode default port */
1478 rc = (*csocket)->ops->connect(*csocket,
1479 (struct sockaddr *) psin_server,
1480 sizeof (struct sockaddr_in), 0);
1486 /* save original port so we can retry user specified port
1487 later if fall back ports fail this time */
1488 orig_port = psin_server->sin_port;
1490 /* do not retry on the same port we just failed on */
1491 if (psin_server->sin_port != htons(CIFS_PORT)) {
1492 psin_server->sin_port = htons(CIFS_PORT);
1494 rc = (*csocket)->ops->connect(*csocket,
1495 (struct sockaddr *) psin_server,
1496 sizeof (struct sockaddr_in), 0);
1502 psin_server->sin_port = htons(RFC1001_PORT);
1503 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1505 sizeof (struct sockaddr_in), 0);
1510 /* give up here - unless we want to retry on different
1511 protocol families some day */
1514 psin_server->sin_port = orig_port;
1515 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1516 sock_release(*csocket);
1520 /* Eventually check for other socket options to change from
1521 the default. sock_setsockopt not used because it expects
1522 user space buffer */
1523 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1524 (*csocket)->sk->sk_sndbuf,
1525 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1526 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1527 /* make the bufsizes depend on wsize/rsize and max requests */
1528 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1529 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1530 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1531 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1533 /* send RFC1001 sessinit */
1534 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1535 /* some servers require RFC1001 sessinit before sending
1536 negprot - BB check reconnection in case where second
1537 sessinit is sent but no second negprot */
1538 struct rfc1002_session_packet *ses_init_buf;
1539 struct smb_hdr *smb_buf;
1540 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1543 ses_init_buf->trailer.session_req.called_len = 32;
1544 if (target_name && (target_name[0] != 0)) {
1545 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1548 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1549 DEFAULT_CIFS_CALLED_NAME, 16);
1552 ses_init_buf->trailer.session_req.calling_len = 32;
1553 /* calling name ends in null (byte 16) from old smb
1555 if (netbios_name && (netbios_name[0] != 0)) {
1556 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1559 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1560 "LINUX_CIFS_CLNT", 16);
1562 ses_init_buf->trailer.session_req.scope1 = 0;
1563 ses_init_buf->trailer.session_req.scope2 = 0;
1564 smb_buf = (struct smb_hdr *)ses_init_buf;
1565 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1566 smb_buf->smb_buf_length = 0x81000044;
1567 rc = smb_send(*csocket, smb_buf, 0x44,
1568 (struct sockaddr *)psin_server);
1569 kfree(ses_init_buf);
1570 msleep(1); /* RFC1001 layer in at least one server
1571 requires very short break before negprot
1572 presumably because not expecting negprot
1573 to follow so fast. This is a simple
1574 solution that works without
1575 complicating the code and causes no
1576 significant slowing down on mount
1577 for everyone else */
1579 /* else the negprot may still work without this
1580 even though malloc failed */
1588 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1592 __be16 orig_port = 0;
1594 if (*csocket == NULL) {
1595 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1596 IPPROTO_TCP, csocket);
1598 cERROR(1, ("Error %d creating ipv6 socket", rc));
1602 /* BB other socket options to set KEEPALIVE, NODELAY? */
1603 cFYI(1, ("ipv6 Socket created"));
1604 (*csocket)->sk->sk_allocation = GFP_NOFS;
1608 psin_server->sin6_family = AF_INET6;
1610 if (psin_server->sin6_port) { /* user overrode default port */
1611 rc = (*csocket)->ops->connect(*csocket,
1612 (struct sockaddr *) psin_server,
1613 sizeof (struct sockaddr_in6), 0);
1619 /* save original port so we can retry user specified port
1620 later if fall back ports fail this time */
1622 orig_port = psin_server->sin6_port;
1623 /* do not retry on the same port we just failed on */
1624 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1625 psin_server->sin6_port = htons(CIFS_PORT);
1627 rc = (*csocket)->ops->connect(*csocket,
1628 (struct sockaddr *) psin_server,
1629 sizeof (struct sockaddr_in6), 0);
1635 psin_server->sin6_port = htons(RFC1001_PORT);
1636 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1637 psin_server, sizeof (struct sockaddr_in6), 0);
1642 /* give up here - unless we want to retry on different
1643 protocol families some day */
1646 psin_server->sin6_port = orig_port;
1647 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1648 sock_release(*csocket);
1652 /* Eventually check for other socket options to change from
1653 the default. sock_setsockopt not used because it expects
1654 user space buffer */
1655 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1660 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1661 struct super_block *sb, struct smb_vol *vol_info)
1663 /* if we are reconnecting then should we check to see if
1664 * any requested capabilities changed locally e.g. via
1665 * remount but we can not do much about it here
1666 * if they have (even if we could detect it by the following)
1667 * Perhaps we could add a backpointer to array of sb from tcon
1668 * or if we change to make all sb to same share the same
1669 * sb as NFS - then we only have one backpointer to sb.
1670 * What if we wanted to mount the server share twice once with
1671 * and once without posixacls or posix paths? */
1672 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1674 if (vol_info && vol_info->no_linux_ext) {
1675 tcon->fsUnixInfo.Capability = 0;
1676 tcon->unix_ext = 0; /* Unix Extensions disabled */
1677 cFYI(1, ("Linux protocol extensions disabled"));
1679 } else if (vol_info)
1680 tcon->unix_ext = 1; /* Unix Extensions supported */
1682 if (tcon->unix_ext == 0) {
1683 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1687 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1688 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1690 /* check for reconnect case in which we do not
1691 want to change the mount behavior if we can avoid it */
1692 if (vol_info == NULL) {
1693 /* turn off POSIX ACL and PATHNAMES if not set
1694 originally at mount time */
1695 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1696 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1697 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0)
1698 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1701 cap &= CIFS_UNIX_CAP_MASK;
1702 if (vol_info && vol_info->no_psx_acl)
1703 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1704 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
1705 cFYI(1, ("negotiated posix acl support"));
1707 sb->s_flags |= MS_POSIXACL;
1710 if (vol_info && vol_info->posix_paths == 0)
1711 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1712 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1713 cFYI(1, ("negotiate posix pathnames"));
1715 CIFS_SB(sb)->mnt_cifs_flags |=
1716 CIFS_MOUNT_POSIX_PATHS;
1719 /* We might be setting the path sep back to a different
1720 form if we are reconnecting and the server switched its
1721 posix path capability for this share */
1722 if (sb && (CIFS_SB(sb)->prepathlen > 0))
1723 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1725 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
1726 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
1727 CIFS_SB(sb)->rsize = 127 * 1024;
1728 #ifdef CONFIG_CIFS_DEBUG2
1729 cFYI(1, ("larger reads not supported by srv"));
1735 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
1736 #ifdef CONFIG_CIFS_DEBUG2
1737 if (cap & CIFS_UNIX_FCNTL_CAP)
1738 cFYI(1, ("FCNTL cap"));
1739 if (cap & CIFS_UNIX_EXTATTR_CAP)
1740 cFYI(1, ("EXTATTR cap"));
1741 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1742 cFYI(1, ("POSIX path cap"));
1743 if (cap & CIFS_UNIX_XATTR_CAP)
1744 cFYI(1, ("XATTR cap"));
1745 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
1746 cFYI(1, ("POSIX ACL cap"));
1747 if (cap & CIFS_UNIX_LARGE_READ_CAP)
1748 cFYI(1, ("very large read cap"));
1749 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
1750 cFYI(1, ("very large write cap"));
1751 #endif /* CIFS_DEBUG2 */
1752 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1753 cFYI(1, ("setting capabilities failed"));
1759 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1760 char *mount_data, const char *devname)
1764 int address_type = AF_INET;
1765 struct socket *csocket = NULL;
1766 struct sockaddr_in sin_server;
1767 struct sockaddr_in6 sin_server6;
1768 struct smb_vol volume_info;
1769 struct cifsSesInfo *pSesInfo = NULL;
1770 struct cifsSesInfo *existingCifsSes = NULL;
1771 struct cifsTconInfo *tcon = NULL;
1772 struct TCP_Server_Info *srvTcp = NULL;
1776 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1778 memset(&volume_info, 0, sizeof(struct smb_vol));
1779 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1780 kfree(volume_info.UNC);
1781 kfree(volume_info.password);
1782 kfree(volume_info.prepath);
1787 if (volume_info.nullauth) {
1788 cFYI(1, ("null user"));
1789 volume_info.username = NULL;
1790 } else if (volume_info.username) {
1791 /* BB fixme parse for domain name here */
1792 cFYI(1, ("Username: %s", volume_info.username));
1794 cifserror("No username specified");
1795 /* In userspace mount helper we can get user name from alternate
1796 locations such as env variables and files on disk */
1797 kfree(volume_info.UNC);
1798 kfree(volume_info.password);
1799 kfree(volume_info.prepath);
1804 if (volume_info.UNCip && volume_info.UNC) {
1805 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
1806 &sin_server.sin_addr.s_addr);
1809 /* not ipv4 address, try ipv6 */
1810 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
1811 &sin_server6.sin6_addr.in6_u);
1813 address_type = AF_INET6;
1815 address_type = AF_INET;
1819 /* we failed translating address */
1820 kfree(volume_info.UNC);
1821 kfree(volume_info.password);
1822 kfree(volume_info.prepath);
1827 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1830 } else if (volume_info.UNCip) {
1831 /* BB using ip addr as server name to connect to the
1833 cERROR(1, ("Connecting to DFS root not implemented yet"));
1834 kfree(volume_info.UNC);
1835 kfree(volume_info.password);
1836 kfree(volume_info.prepath);
1839 } else /* which servers DFS root would we conect to */ {
1841 ("CIFS mount error: No UNC path (e.g. -o "
1842 "unc=//192.168.1.100/public) specified"));
1843 kfree(volume_info.UNC);
1844 kfree(volume_info.password);
1845 kfree(volume_info.prepath);
1850 /* this is needed for ASCII cp to Unicode converts */
1851 if (volume_info.iocharset == NULL) {
1852 cifs_sb->local_nls = load_nls_default();
1853 /* load_nls_default can not return null */
1855 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1856 if (cifs_sb->local_nls == NULL) {
1857 cERROR(1, ("CIFS mount error: iocharset %s not found",
1858 volume_info.iocharset));
1859 kfree(volume_info.UNC);
1860 kfree(volume_info.password);
1861 kfree(volume_info.prepath);
1867 if (address_type == AF_INET)
1868 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1869 NULL /* no ipv6 addr */,
1870 volume_info.username, &srvTcp);
1871 else if (address_type == AF_INET6) {
1872 cFYI(1, ("looking for ipv6 address"));
1873 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1874 &sin_server6.sin6_addr,
1875 volume_info.username, &srvTcp);
1877 kfree(volume_info.UNC);
1878 kfree(volume_info.password);
1879 kfree(volume_info.prepath);
1885 cFYI(1, ("Existing tcp session with server found"));
1886 } else { /* create socket */
1887 if (volume_info.port)
1888 sin_server.sin_port = htons(volume_info.port);
1890 sin_server.sin_port = 0;
1891 if (address_type == AF_INET6) {
1892 cFYI(1, ("attempting ipv6 connect"));
1893 /* BB should we allow ipv6 on port 139? */
1894 /* other OS never observed in Wild doing 139 with v6 */
1895 rc = ipv6_connect(&sin_server6, &csocket);
1897 rc = ipv4_connect(&sin_server, &csocket,
1898 volume_info.source_rfc1001_name,
1899 volume_info.target_rfc1001_name);
1901 cERROR(1, ("Error connecting to IPv4 socket. "
1902 "Aborting operation"));
1903 if (csocket != NULL)
1904 sock_release(csocket);
1905 kfree(volume_info.UNC);
1906 kfree(volume_info.password);
1907 kfree(volume_info.prepath);
1912 srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
1913 if (srvTcp == NULL) {
1915 sock_release(csocket);
1916 kfree(volume_info.UNC);
1917 kfree(volume_info.password);
1918 kfree(volume_info.prepath);
1922 memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
1923 memcpy(&srvTcp->addr.sockAddr, &sin_server,
1924 sizeof (struct sockaddr_in));
1925 atomic_set(&srvTcp->inFlight, 0);
1926 /* BB Add code for ipv6 case too */
1927 srvTcp->ssocket = csocket;
1928 srvTcp->protocolType = IPV4;
1929 init_waitqueue_head(&srvTcp->response_q);
1930 init_waitqueue_head(&srvTcp->request_q);
1931 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
1932 /* at this point we are the only ones with the pointer
1933 to the struct since the kernel thread not created yet
1934 so no need to spinlock this init of tcpStatus */
1935 srvTcp->tcpStatus = CifsNew;
1936 init_MUTEX(&srvTcp->tcpSem);
1937 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
1938 if ( IS_ERR(srvTcp->tsk) ) {
1939 rc = PTR_ERR(srvTcp->tsk);
1940 cERROR(1, ("error %d create cifsd thread", rc));
1942 sock_release(csocket);
1943 kfree(volume_info.UNC);
1944 kfree(volume_info.password);
1945 kfree(volume_info.prepath);
1949 wait_for_completion(&cifsd_complete);
1951 memcpy(srvTcp->workstation_RFC1001_name,
1952 volume_info.source_rfc1001_name, 16);
1953 memcpy(srvTcp->server_RFC1001_name,
1954 volume_info.target_rfc1001_name, 16);
1955 srvTcp->sequence_number = 0;
1959 if (existingCifsSes) {
1960 pSesInfo = existingCifsSes;
1961 cFYI(1, ("Existing smb sess found"));
1962 kfree(volume_info.password);
1963 /* volume_info.UNC freed at end of function */
1965 cFYI(1, ("Existing smb sess not found"));
1966 pSesInfo = sesInfoAlloc();
1967 if (pSesInfo == NULL)
1970 pSesInfo->server = srvTcp;
1971 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
1972 NIPQUAD(sin_server.sin_addr.s_addr));
1976 /* volume_info.password freed at unmount */
1977 if (volume_info.password)
1978 pSesInfo->password = volume_info.password;
1979 if (volume_info.username)
1980 strncpy(pSesInfo->userName,
1981 volume_info.username,
1983 if (volume_info.domainname) {
1984 int len = strlen(volume_info.domainname);
1985 pSesInfo->domainName =
1986 kmalloc(len + 1, GFP_KERNEL);
1987 if (pSesInfo->domainName)
1988 strcpy(pSesInfo->domainName,
1989 volume_info.domainname);
1991 pSesInfo->linux_uid = volume_info.linux_uid;
1992 pSesInfo->overrideSecFlg = volume_info.secFlg;
1993 down(&pSesInfo->sesSem);
1994 /* BB FIXME need to pass vol->secFlgs BB */
1995 rc = cifs_setup_session(xid, pSesInfo,
1996 cifs_sb->local_nls);
1997 up(&pSesInfo->sesSem);
1999 atomic_inc(&srvTcp->socketUseCount);
2001 kfree(volume_info.password);
2004 /* search for existing tcon to this server share */
2006 if (volume_info.rsize > CIFSMaxBufSize) {
2007 cERROR(1, ("rsize %d too large, using MaxBufSize",
2008 volume_info.rsize));
2009 cifs_sb->rsize = CIFSMaxBufSize;
2010 } else if ((volume_info.rsize) &&
2011 (volume_info.rsize <= CIFSMaxBufSize))
2012 cifs_sb->rsize = volume_info.rsize;
2014 cifs_sb->rsize = CIFSMaxBufSize;
2016 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2017 cERROR(1, ("wsize %d too large, using 4096 instead",
2018 volume_info.wsize));
2019 cifs_sb->wsize = 4096;
2020 } else if (volume_info.wsize)
2021 cifs_sb->wsize = volume_info.wsize;
2024 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2026 /* old default of CIFSMaxBufSize was too small now
2027 that SMB Write2 can send multiple pages in kvec.
2028 RFC1001 does not describe what happens when frame
2029 bigger than 128K is sent so use that as max in
2030 conjunction with 52K kvec constraint on arch with 4K
2033 if (cifs_sb->rsize < 2048) {
2034 cifs_sb->rsize = 2048;
2035 /* Windows ME may prefer this */
2036 cFYI(1, ("readsize set to minimum: 2048"));
2038 /* calculate prepath */
2039 cifs_sb->prepath = volume_info.prepath;
2040 if (cifs_sb->prepath) {
2041 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2042 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
2043 volume_info.prepath = NULL;
2045 cifs_sb->prepathlen = 0;
2046 cifs_sb->mnt_uid = volume_info.linux_uid;
2047 cifs_sb->mnt_gid = volume_info.linux_gid;
2048 cifs_sb->mnt_file_mode = volume_info.file_mode;
2049 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
2050 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2051 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2053 if (volume_info.noperm)
2054 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2055 if (volume_info.setuids)
2056 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2057 if (volume_info.server_ino)
2058 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2059 if (volume_info.remap)
2060 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2061 if (volume_info.no_xattr)
2062 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2063 if (volume_info.sfu_emul)
2064 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2065 if (volume_info.nobrl)
2066 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2067 if (volume_info.cifs_acl)
2068 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2069 if (volume_info.override_uid)
2070 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2071 if (volume_info.override_gid)
2072 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2073 if (volume_info.direct_io) {
2074 cFYI(1, ("mounting share using direct i/o"));
2075 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2079 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
2080 volume_info.username);
2082 cFYI(1, ("Found match on UNC path"));
2083 /* we can have only one retry value for a connection
2084 to a share so for resources mounted more than once
2085 to the same server share the last value passed in
2086 for the retry flag is used */
2087 tcon->retry = volume_info.retry;
2088 tcon->nocase = volume_info.nocase;
2090 tcon = tconInfoAlloc();
2094 /* check for null share name ie connecting to
2097 /* BB check if this works for exactly length
2099 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2100 && (strchr(volume_info.UNC + 3, '/') ==
2102 rc = connect_to_dfs_path(xid, pSesInfo,
2103 "", cifs_sb->local_nls,
2104 cifs_sb->mnt_cifs_flags &
2105 CIFS_MOUNT_MAP_SPECIAL_CHR);
2106 kfree(volume_info.UNC);
2110 /* BB Do we need to wrap sesSem around
2111 * this TCon call and Unix SetFS as
2112 * we do on SessSetup and reconnect? */
2113 rc = CIFSTCon(xid, pSesInfo,
2115 tcon, cifs_sb->local_nls);
2116 cFYI(1, ("CIFS Tcon rc = %d", rc));
2119 atomic_inc(&pSesInfo->inUse);
2120 tcon->retry = volume_info.retry;
2121 tcon->nocase = volume_info.nocase;
2127 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2128 sb->s_maxbytes = (u64) 1 << 63;
2130 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2133 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2134 sb->s_time_gran = 100;
2136 /* on error free sesinfo and tcon struct if needed */
2138 /* if session setup failed, use count is zero but
2139 we still need to free cifsd thread */
2140 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2141 spin_lock(&GlobalMid_Lock);
2142 srvTcp->tcpStatus = CifsExiting;
2143 spin_unlock(&GlobalMid_Lock);
2145 struct task_struct *tsk;
2146 /* If we could verify that kthread_stop would
2147 always wake up processes blocked in
2148 tcp in recv_mesg then we could remove the
2150 force_sig(SIGKILL, srvTcp->tsk);
2156 /* If find_unc succeeded then rc == 0 so we can not end */
2157 if (tcon) /* up accidently freeing someone elses tcon struct */
2159 if (existingCifsSes == NULL) {
2161 if ((pSesInfo->server) &&
2162 (pSesInfo->status == CifsGood)) {
2164 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2165 /* if the socketUseCount is now zero */
2166 if ((temp_rc == -ESHUTDOWN) &&
2167 (pSesInfo->server) &&
2168 (pSesInfo->server->tsk)) {
2169 struct task_struct *tsk;
2171 pSesInfo->server->tsk);
2172 tsk = pSesInfo->server->tsk;
2177 cFYI(1, ("No session or bad tcon"));
2178 sesInfoFree(pSesInfo);
2179 /* pSesInfo = NULL; */
2183 atomic_inc(&tcon->useCount);
2184 cifs_sb->tcon = tcon;
2185 tcon->ses = pSesInfo;
2187 /* do not care if following two calls succeed - informational */
2188 CIFSSMBQFSDeviceInfo(xid, tcon);
2189 CIFSSMBQFSAttributeInfo(xid, tcon);
2191 /* tell server which Unix caps we support */
2192 if (tcon->ses->capabilities & CAP_UNIX)
2193 /* reset of caps checks mount to see if unix extensions
2194 disabled for just this mount */
2195 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2197 tcon->unix_ext = 0; /* server does not support them */
2199 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2200 cifs_sb->rsize = 1024 * 127;
2201 #ifdef CONFIG_CIFS_DEBUG2
2202 cFYI(1, ("no very large read support, rsize now 127K"));
2205 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2206 cifs_sb->wsize = min(cifs_sb->wsize,
2207 (tcon->ses->server->maxBuf -
2208 MAX_CIFS_HDR_SIZE));
2209 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2210 cifs_sb->rsize = min(cifs_sb->rsize,
2211 (tcon->ses->server->maxBuf -
2212 MAX_CIFS_HDR_SIZE));
2215 /* volume_info.password is freed above when existing session found
2216 (in which case it is not needed anymore) but when new sesion is created
2217 the password ptr is put in the new session structure (in which case the
2218 password will be freed at unmount time) */
2219 kfree(volume_info.UNC);
2220 kfree(volume_info.prepath);
2226 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2227 char session_key[CIFS_SESS_KEY_SIZE],
2228 const struct nls_table *nls_codepage)
2230 struct smb_hdr *smb_buffer;
2231 struct smb_hdr *smb_buffer_response;
2232 SESSION_SETUP_ANDX *pSMB;
2233 SESSION_SETUP_ANDX *pSMBr;
2238 int remaining_words = 0;
2239 int bytes_returned = 0;
2244 cFYI(1, ("In sesssetup"));
2247 user = ses->userName;
2248 domain = ses->domainName;
2249 smb_buffer = cifs_buf_get();
2250 if (smb_buffer == NULL) {
2253 smb_buffer_response = smb_buffer;
2254 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2256 /* send SMBsessionSetup here */
2257 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2258 NULL /* no tCon exists yet */ , 13 /* wct */ );
2260 smb_buffer->Mid = GetNextMid(ses->server);
2261 pSMB->req_no_secext.AndXCommand = 0xFF;
2262 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2263 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2265 if (ses->server->secMode &
2266 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2267 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2269 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2270 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2271 if (ses->capabilities & CAP_UNICODE) {
2272 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2273 capabilities |= CAP_UNICODE;
2275 if (ses->capabilities & CAP_STATUS32) {
2276 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2277 capabilities |= CAP_STATUS32;
2279 if (ses->capabilities & CAP_DFS) {
2280 smb_buffer->Flags2 |= SMBFLG2_DFS;
2281 capabilities |= CAP_DFS;
2283 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2285 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2286 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2288 pSMB->req_no_secext.CaseSensitivePasswordLength =
2289 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2290 bcc_ptr = pByteArea(smb_buffer);
2291 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2292 bcc_ptr += CIFS_SESS_KEY_SIZE;
2293 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2294 bcc_ptr += CIFS_SESS_KEY_SIZE;
2296 if (ses->capabilities & CAP_UNICODE) {
2297 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2302 bytes_returned = 0; /* skip null user */
2305 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2307 /* convert number of 16 bit words to bytes */
2308 bcc_ptr += 2 * bytes_returned;
2309 bcc_ptr += 2; /* trailing null */
2312 cifs_strtoUCS((__le16 *) bcc_ptr,
2313 "CIFS_LINUX_DOM", 32, nls_codepage);
2316 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2318 bcc_ptr += 2 * bytes_returned;
2321 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2323 bcc_ptr += 2 * bytes_returned;
2325 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2327 bcc_ptr += 2 * bytes_returned;
2330 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2332 bcc_ptr += 2 * bytes_returned;
2336 strncpy(bcc_ptr, user, 200);
2337 bcc_ptr += strnlen(user, 200);
2341 if (domain == NULL) {
2342 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2343 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2345 strncpy(bcc_ptr, domain, 64);
2346 bcc_ptr += strnlen(domain, 64);
2350 strcpy(bcc_ptr, "Linux version ");
2351 bcc_ptr += strlen("Linux version ");
2352 strcpy(bcc_ptr, utsname()->release);
2353 bcc_ptr += strlen(utsname()->release) + 1;
2354 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2355 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2357 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2358 smb_buffer->smb_buf_length += count;
2359 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2361 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2362 &bytes_returned, 1);
2364 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2365 } else if ((smb_buffer_response->WordCount == 3)
2366 || (smb_buffer_response->WordCount == 4)) {
2367 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2368 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2369 if (action & GUEST_LOGIN)
2370 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2371 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2373 cFYI(1, ("UID = %d ", ses->Suid));
2374 /* response can have either 3 or 4 word count - Samba sends 3 */
2375 bcc_ptr = pByteArea(smb_buffer_response);
2376 if ((pSMBr->resp.hdr.WordCount == 3)
2377 || ((pSMBr->resp.hdr.WordCount == 4)
2378 && (blob_len < pSMBr->resp.ByteCount))) {
2379 if (pSMBr->resp.hdr.WordCount == 4)
2380 bcc_ptr += blob_len;
2382 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2383 if ((long) (bcc_ptr) % 2) {
2385 (BCC(smb_buffer_response) - 1) / 2;
2386 /* Unicode strings must be word
2391 BCC(smb_buffer_response) / 2;
2394 UniStrnlen((wchar_t *) bcc_ptr,
2395 remaining_words - 1);
2396 /* We look for obvious messed up bcc or strings in response so we do not go off
2397 the end since (at least) WIN2K and Windows XP have a major bug in not null
2398 terminating last Unicode string in response */
2400 kfree(ses->serverOS);
2401 ses->serverOS = kzalloc(2 * (len + 1),
2403 if (ses->serverOS == NULL)
2404 goto sesssetup_nomem;
2405 cifs_strfromUCS_le(ses->serverOS,
2408 bcc_ptr += 2 * (len + 1);
2409 remaining_words -= len + 1;
2410 ses->serverOS[2 * len] = 0;
2411 ses->serverOS[1 + (2 * len)] = 0;
2412 if (remaining_words > 0) {
2413 len = UniStrnlen((wchar_t *)bcc_ptr,
2415 kfree(ses->serverNOS);
2416 ses->serverNOS = kzalloc(2 * (len + 1),
2418 if (ses->serverNOS == NULL)
2419 goto sesssetup_nomem;
2420 cifs_strfromUCS_le(ses->serverNOS,
2423 bcc_ptr += 2 * (len + 1);
2424 ses->serverNOS[2 * len] = 0;
2425 ses->serverNOS[1 + (2 * len)] = 0;
2426 if (strncmp(ses->serverNOS,
2427 "NT LAN Manager 4", 16) == 0) {
2428 cFYI(1, ("NT4 server"));
2429 ses->flags |= CIFS_SES_NT4;
2431 remaining_words -= len + 1;
2432 if (remaining_words > 0) {
2433 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2434 /* last string is not always null terminated
2435 (for e.g. for Windows XP & 2000) */
2436 if (ses->serverDomain)
2437 kfree(ses->serverDomain);
2441 if (ses->serverDomain == NULL)
2442 goto sesssetup_nomem;
2443 cifs_strfromUCS_le(ses->serverDomain,
2446 bcc_ptr += 2 * (len + 1);
2447 ses->serverDomain[2*len] = 0;
2448 ses->serverDomain[1+(2*len)] = 0;
2449 } else { /* else no more room so create
2450 dummy domain string */
2451 if (ses->serverDomain)
2452 kfree(ses->serverDomain);
2454 kzalloc(2, GFP_KERNEL);
2456 } else { /* no room so create dummy domain
2459 /* if these kcallocs fail not much we
2460 can do, but better to not fail the
2462 kfree(ses->serverDomain);
2464 kzalloc(2, GFP_KERNEL);
2465 kfree(ses->serverNOS);
2467 kzalloc(2, GFP_KERNEL);
2469 } else { /* ASCII */
2470 len = strnlen(bcc_ptr, 1024);
2471 if (((long) bcc_ptr + len) - (long)
2472 pByteArea(smb_buffer_response)
2473 <= BCC(smb_buffer_response)) {
2474 kfree(ses->serverOS);
2475 ses->serverOS = kzalloc(len + 1,
2477 if (ses->serverOS == NULL)
2478 goto sesssetup_nomem;
2479 strncpy(ses->serverOS, bcc_ptr, len);
2482 /* null terminate the string */
2486 len = strnlen(bcc_ptr, 1024);
2487 kfree(ses->serverNOS);
2488 ses->serverNOS = kzalloc(len + 1,
2490 if (ses->serverNOS == NULL)
2491 goto sesssetup_nomem;
2492 strncpy(ses->serverNOS, bcc_ptr, len);
2497 len = strnlen(bcc_ptr, 1024);
2498 if (ses->serverDomain)
2499 kfree(ses->serverDomain);
2500 ses->serverDomain = kzalloc(len + 1,
2502 if (ses->serverDomain == NULL)
2503 goto sesssetup_nomem;
2504 strncpy(ses->serverDomain, bcc_ptr,
2511 ("Variable field of length %d "
2512 "extends beyond end of smb ",
2517 (" Security Blob Length extends beyond "
2522 (" Invalid Word count %d: ",
2523 smb_buffer_response->WordCount));
2526 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2527 since that could make reconnection harder, and
2528 reconnection might be needed to free memory */
2530 cifs_buf_release(smb_buffer);
2536 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2537 struct cifsSesInfo *ses, int *pNTLMv2_flag,
2538 const struct nls_table *nls_codepage)
2540 struct smb_hdr *smb_buffer;
2541 struct smb_hdr *smb_buffer_response;
2542 SESSION_SETUP_ANDX *pSMB;
2543 SESSION_SETUP_ANDX *pSMBr;
2547 int remaining_words = 0;
2548 int bytes_returned = 0;
2550 int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
2551 PNEGOTIATE_MESSAGE SecurityBlob;
2552 PCHALLENGE_MESSAGE SecurityBlob2;
2553 __u32 negotiate_flags, capabilities;
2556 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2559 domain = ses->domainName;
2560 *pNTLMv2_flag = FALSE;
2561 smb_buffer = cifs_buf_get();
2562 if (smb_buffer == NULL) {
2565 smb_buffer_response = smb_buffer;
2566 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2567 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2569 /* send SMBsessionSetup here */
2570 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2571 NULL /* no tCon exists yet */ , 12 /* wct */ );
2573 smb_buffer->Mid = GetNextMid(ses->server);
2574 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2575 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2577 pSMB->req.AndXCommand = 0xFF;
2578 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2579 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2581 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2582 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2584 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2585 CAP_EXTENDED_SECURITY;
2586 if (ses->capabilities & CAP_UNICODE) {
2587 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2588 capabilities |= CAP_UNICODE;
2590 if (ses->capabilities & CAP_STATUS32) {
2591 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2592 capabilities |= CAP_STATUS32;
2594 if (ses->capabilities & CAP_DFS) {
2595 smb_buffer->Flags2 |= SMBFLG2_DFS;
2596 capabilities |= CAP_DFS;
2598 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2600 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2601 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2602 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2603 SecurityBlob->MessageType = NtLmNegotiate;
2605 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2606 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2607 NTLMSSP_NEGOTIATE_56 |
2608 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2610 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2611 /* if (ntlmv2_support)
2612 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2613 /* setup pointers to domain name and workstation name */
2614 bcc_ptr += SecurityBlobLength;
2616 SecurityBlob->WorkstationName.Buffer = 0;
2617 SecurityBlob->WorkstationName.Length = 0;
2618 SecurityBlob->WorkstationName.MaximumLength = 0;
2620 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2621 along with username on auth request (ie the response to challenge) */
2622 SecurityBlob->DomainName.Buffer = 0;
2623 SecurityBlob->DomainName.Length = 0;
2624 SecurityBlob->DomainName.MaximumLength = 0;
2625 if (ses->capabilities & CAP_UNICODE) {
2626 if ((long) bcc_ptr % 2) {
2632 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2634 bcc_ptr += 2 * bytes_returned;
2636 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2638 bcc_ptr += 2 * bytes_returned;
2639 bcc_ptr += 2; /* null terminate Linux version */
2641 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2643 bcc_ptr += 2 * bytes_returned;
2646 bcc_ptr += 2; /* null terminate network opsys string */
2649 bcc_ptr += 2; /* null domain */
2650 } else { /* ASCII */
2651 strcpy(bcc_ptr, "Linux version ");
2652 bcc_ptr += strlen("Linux version ");
2653 strcpy(bcc_ptr, utsname()->release);
2654 bcc_ptr += strlen(utsname()->release) + 1;
2655 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2656 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2657 bcc_ptr++; /* empty domain field */
2660 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2661 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2662 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2663 smb_buffer->smb_buf_length += count;
2664 pSMB->req.ByteCount = cpu_to_le16(count);
2666 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2667 &bytes_returned, 1);
2669 if (smb_buffer_response->Status.CifsError ==
2670 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2674 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2675 } else if ((smb_buffer_response->WordCount == 3)
2676 || (smb_buffer_response->WordCount == 4)) {
2677 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2678 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2680 if (action & GUEST_LOGIN)
2681 cFYI(1, (" Guest login"));
2682 /* Do we want to set anything in SesInfo struct when guest login? */
2684 bcc_ptr = pByteArea(smb_buffer_response);
2685 /* response can have either 3 or 4 word count - Samba sends 3 */
2687 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2688 if (SecurityBlob2->MessageType != NtLmChallenge) {
2690 ("Unexpected NTLMSSP message type received %d",
2691 SecurityBlob2->MessageType));
2693 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2694 cFYI(1, ("UID = %d", ses->Suid));
2695 if ((pSMBr->resp.hdr.WordCount == 3)
2696 || ((pSMBr->resp.hdr.WordCount == 4)
2698 pSMBr->resp.ByteCount))) {
2700 if (pSMBr->resp.hdr.WordCount == 4) {
2701 bcc_ptr += blob_len;
2702 cFYI(1, ("Security Blob Length %d",
2706 cFYI(1, ("NTLMSSP Challenge rcvd"));
2708 memcpy(ses->server->cryptKey,
2709 SecurityBlob2->Challenge,
2710 CIFS_CRYPTO_KEY_SIZE);
2711 if (SecurityBlob2->NegotiateFlags &
2712 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2713 *pNTLMv2_flag = TRUE;
2715 if ((SecurityBlob2->NegotiateFlags &
2716 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2717 || (sign_CIFS_PDUs > 1))
2718 ses->server->secMode |=
2719 SECMODE_SIGN_REQUIRED;
2720 if ((SecurityBlob2->NegotiateFlags &
2721 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2722 ses->server->secMode |=
2723 SECMODE_SIGN_ENABLED;
2725 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2726 if ((long) (bcc_ptr) % 2) {
2728 (BCC(smb_buffer_response)
2730 /* Must word align unicode strings */
2735 (smb_buffer_response) / 2;
2738 UniStrnlen((wchar_t *) bcc_ptr,
2739 remaining_words - 1);
2740 /* We look for obvious messed up bcc or strings in response so we do not go off
2741 the end since (at least) WIN2K and Windows XP have a major bug in not null
2742 terminating last Unicode string in response */
2744 kfree(ses->serverOS);
2746 kzalloc(2 * (len + 1), GFP_KERNEL);
2747 cifs_strfromUCS_le(ses->serverOS,
2751 bcc_ptr += 2 * (len + 1);
2752 remaining_words -= len + 1;
2753 ses->serverOS[2 * len] = 0;
2754 ses->serverOS[1 + (2 * len)] = 0;
2755 if (remaining_words > 0) {
2756 len = UniStrnlen((wchar_t *)
2760 kfree(ses->serverNOS);
2762 kzalloc(2 * (len + 1),
2764 cifs_strfromUCS_le(ses->
2770 bcc_ptr += 2 * (len + 1);
2771 ses->serverNOS[2 * len] = 0;
2774 remaining_words -= len + 1;
2775 if (remaining_words > 0) {
2776 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2777 /* last string not always null terminated
2778 (for e.g. for Windows XP & 2000) */
2779 kfree(ses->serverDomain);
2791 ses->serverDomain[2*len]
2796 } /* else no more room so create dummy domain string */
2798 kfree(ses->serverDomain);
2803 } else { /* no room so create dummy domain and NOS string */
2804 kfree(ses->serverDomain);
2806 kzalloc(2, GFP_KERNEL);
2807 kfree(ses->serverNOS);
2809 kzalloc(2, GFP_KERNEL);
2811 } else { /* ASCII */
2812 len = strnlen(bcc_ptr, 1024);
2813 if (((long) bcc_ptr + len) - (long)
2814 pByteArea(smb_buffer_response)
2815 <= BCC(smb_buffer_response)) {
2817 kfree(ses->serverOS);
2821 strncpy(ses->serverOS,
2825 bcc_ptr[0] = 0; /* null terminate string */
2828 len = strnlen(bcc_ptr, 1024);
2829 kfree(ses->serverNOS);
2833 strncpy(ses->serverNOS, bcc_ptr, len);
2838 len = strnlen(bcc_ptr, 1024);
2839 kfree(ses->serverDomain);
2843 strncpy(ses->serverDomain,
2850 ("field of length %d "
2851 "extends beyond end of smb",
2855 cERROR(1, ("Security Blob Length extends beyond"
2859 cERROR(1, ("No session structure passed in."));
2863 (" Invalid Word count %d:",
2864 smb_buffer_response->WordCount));
2869 cifs_buf_release(smb_buffer);
2874 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2875 char *ntlm_session_key, int ntlmv2_flag,
2876 const struct nls_table *nls_codepage)
2878 struct smb_hdr *smb_buffer;
2879 struct smb_hdr *smb_buffer_response;
2880 SESSION_SETUP_ANDX *pSMB;
2881 SESSION_SETUP_ANDX *pSMBr;
2886 int remaining_words = 0;
2887 int bytes_returned = 0;
2889 int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
2890 PAUTHENTICATE_MESSAGE SecurityBlob;
2891 __u32 negotiate_flags, capabilities;
2894 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2897 user = ses->userName;
2898 domain = ses->domainName;
2899 smb_buffer = cifs_buf_get();
2900 if (smb_buffer == NULL) {
2903 smb_buffer_response = smb_buffer;
2904 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2905 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2907 /* send SMBsessionSetup here */
2908 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2909 NULL /* no tCon exists yet */ , 12 /* wct */ );
2911 smb_buffer->Mid = GetNextMid(ses->server);
2912 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2913 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2914 pSMB->req.AndXCommand = 0xFF;
2915 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2916 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2918 pSMB->req.hdr.Uid = ses->Suid;
2920 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2921 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2923 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2924 CAP_EXTENDED_SECURITY;
2925 if (ses->capabilities & CAP_UNICODE) {
2926 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2927 capabilities |= CAP_UNICODE;
2929 if (ses->capabilities & CAP_STATUS32) {
2930 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2931 capabilities |= CAP_STATUS32;
2933 if (ses->capabilities & CAP_DFS) {
2934 smb_buffer->Flags2 |= SMBFLG2_DFS;
2935 capabilities |= CAP_DFS;
2937 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2939 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2940 SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
2941 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2942 SecurityBlob->MessageType = NtLmAuthenticate;
2943 bcc_ptr += SecurityBlobLength;
2945 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
2946 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
2947 0x80000000 | NTLMSSP_NEGOTIATE_128;
2949 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
2951 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2953 /* setup pointers to domain name and workstation name */
2955 SecurityBlob->WorkstationName.Buffer = 0;
2956 SecurityBlob->WorkstationName.Length = 0;
2957 SecurityBlob->WorkstationName.MaximumLength = 0;
2958 SecurityBlob->SessionKey.Length = 0;
2959 SecurityBlob->SessionKey.MaximumLength = 0;
2960 SecurityBlob->SessionKey.Buffer = 0;
2962 SecurityBlob->LmChallengeResponse.Length = 0;
2963 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
2964 SecurityBlob->LmChallengeResponse.Buffer = 0;
2966 SecurityBlob->NtChallengeResponse.Length =
2967 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2968 SecurityBlob->NtChallengeResponse.MaximumLength =
2969 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2970 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
2971 SecurityBlob->NtChallengeResponse.Buffer =
2972 cpu_to_le32(SecurityBlobLength);
2973 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
2974 bcc_ptr += CIFS_SESS_KEY_SIZE;
2976 if (ses->capabilities & CAP_UNICODE) {
2977 if (domain == NULL) {
2978 SecurityBlob->DomainName.Buffer = 0;
2979 SecurityBlob->DomainName.Length = 0;
2980 SecurityBlob->DomainName.MaximumLength = 0;
2983 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2986 SecurityBlob->DomainName.MaximumLength =
2988 SecurityBlob->DomainName.Buffer =
2989 cpu_to_le32(SecurityBlobLength);
2991 SecurityBlobLength += len;
2992 SecurityBlob->DomainName.Length =
2996 SecurityBlob->UserName.Buffer = 0;
2997 SecurityBlob->UserName.Length = 0;
2998 SecurityBlob->UserName.MaximumLength = 0;
3001 cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
3004 SecurityBlob->UserName.MaximumLength =
3006 SecurityBlob->UserName.Buffer =
3007 cpu_to_le32(SecurityBlobLength);
3009 SecurityBlobLength += len;
3010 SecurityBlob->UserName.Length =
3014 /* SecurityBlob->WorkstationName.Length =
3015 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3016 SecurityBlob->WorkstationName.Length *= 2;
3017 SecurityBlob->WorkstationName.MaximumLength =
3018 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3019 SecurityBlob->WorkstationName.Buffer =
3020 cpu_to_le32(SecurityBlobLength);
3021 bcc_ptr += SecurityBlob->WorkstationName.Length;
3022 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3023 SecurityBlob->WorkstationName.Length =
3024 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3026 if ((long) bcc_ptr % 2) {
3031 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3033 bcc_ptr += 2 * bytes_returned;
3035 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3037 bcc_ptr += 2 * bytes_returned;
3038 bcc_ptr += 2; /* null term version string */
3040 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3042 bcc_ptr += 2 * bytes_returned;
3045 bcc_ptr += 2; /* null terminate network opsys string */
3048 bcc_ptr += 2; /* null domain */
3049 } else { /* ASCII */
3050 if (domain == NULL) {
3051 SecurityBlob->DomainName.Buffer = 0;
3052 SecurityBlob->DomainName.Length = 0;
3053 SecurityBlob->DomainName.MaximumLength = 0;
3056 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3057 strncpy(bcc_ptr, domain, 63);
3058 len = strnlen(domain, 64);
3059 SecurityBlob->DomainName.MaximumLength =
3061 SecurityBlob->DomainName.Buffer =
3062 cpu_to_le32(SecurityBlobLength);
3064 SecurityBlobLength += len;
3065 SecurityBlob->DomainName.Length = cpu_to_le16(len);
3068 SecurityBlob->UserName.Buffer = 0;
3069 SecurityBlob->UserName.Length = 0;
3070 SecurityBlob->UserName.MaximumLength = 0;
3073 strncpy(bcc_ptr, user, 63);
3074 len = strnlen(user, 64);
3075 SecurityBlob->UserName.MaximumLength =
3077 SecurityBlob->UserName.Buffer =
3078 cpu_to_le32(SecurityBlobLength);
3080 SecurityBlobLength += len;
3081 SecurityBlob->UserName.Length = cpu_to_le16(len);
3083 /* BB fill in our workstation name if known BB */
3085 strcpy(bcc_ptr, "Linux version ");
3086 bcc_ptr += strlen("Linux version ");
3087 strcpy(bcc_ptr, utsname()->release);
3088 bcc_ptr += strlen(utsname()->release) + 1;
3089 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3090 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3091 bcc_ptr++; /* null domain */
3094 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3095 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3096 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3097 smb_buffer->smb_buf_length += count;
3098 pSMB->req.ByteCount = cpu_to_le16(count);
3100 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3101 &bytes_returned, 1);
3103 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
3104 } else if ((smb_buffer_response->WordCount == 3)
3105 || (smb_buffer_response->WordCount == 4)) {
3106 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3108 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3109 if (action & GUEST_LOGIN)
3110 cFYI(1, (" Guest login")); /* BB Should we set anything
3111 in SesInfo struct ? */
3112 /* if (SecurityBlob2->MessageType != NtLm??) {
3113 cFYI("Unexpected message type on auth response is %d"));
3118 ("Check challenge UID %d vs auth response UID %d",
3119 ses->Suid, smb_buffer_response->Uid));
3120 /* UID left in wire format */
3121 ses->Suid = smb_buffer_response->Uid;
3122 bcc_ptr = pByteArea(smb_buffer_response);
3123 /* response can have either 3 or 4 word count - Samba sends 3 */
3124 if ((pSMBr->resp.hdr.WordCount == 3)
3125 || ((pSMBr->resp.hdr.WordCount == 4)
3127 pSMBr->resp.ByteCount))) {
3128 if (pSMBr->resp.hdr.WordCount == 4) {
3132 ("Security Blob Length %d ",
3137 ("NTLMSSP response to Authenticate "));
3139 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3140 if ((long) (bcc_ptr) % 2) {
3142 (BCC(smb_buffer_response)
3144 bcc_ptr++; /* Unicode strings must be word aligned */
3146 remaining_words = BCC(smb_buffer_response) / 2;
3149 UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
3150 /* We look for obvious messed up bcc or strings in response so we do not go off
3151 the end since (at least) WIN2K and Windows XP have a major bug in not null
3152 terminating last Unicode string in response */
3154 kfree(ses->serverOS);
3156 kzalloc(2 * (len + 1), GFP_KERNEL);
3157 cifs_strfromUCS_le(ses->serverOS,
3161 bcc_ptr += 2 * (len + 1);
3162 remaining_words -= len + 1;
3163 ses->serverOS[2 * len] = 0;
3164 ses->serverOS[1 + (2 * len)] = 0;
3165 if (remaining_words > 0) {
3166 len = UniStrnlen((wchar_t *)
3170 kfree(ses->serverNOS);
3172 kzalloc(2 * (len + 1),
3174 cifs_strfromUCS_le(ses->
3180 bcc_ptr += 2 * (len + 1);
3181 ses->serverNOS[2 * len] = 0;
3182 ses->serverNOS[1+(2*len)] = 0;
3183 remaining_words -= len + 1;
3184 if (remaining_words > 0) {
3185 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3186 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3187 if (ses->serverDomain)
3188 kfree(ses->serverDomain);
3213 } /* else no more room so create dummy domain string */
3215 if (ses->serverDomain)
3216 kfree(ses->serverDomain);
3217 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3219 } else { /* no room so create dummy domain and NOS string */
3220 if (ses->serverDomain)
3221 kfree(ses->serverDomain);
3222 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3223 kfree(ses->serverNOS);
3224 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3226 } else { /* ASCII */
3227 len = strnlen(bcc_ptr, 1024);
3228 if (((long) bcc_ptr + len) -
3229 (long) pByteArea(smb_buffer_response)
3230 <= BCC(smb_buffer_response)) {
3232 kfree(ses->serverOS);
3233 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
3234 strncpy(ses->serverOS,bcc_ptr, len);
3237 bcc_ptr[0] = 0; /* null terminate the string */
3240 len = strnlen(bcc_ptr, 1024);
3241 kfree(ses->serverNOS);
3242 ses->serverNOS = kzalloc(len+1,
3244 strncpy(ses->serverNOS,
3250 len = strnlen(bcc_ptr, 1024);
3251 if (ses->serverDomain)
3252 kfree(ses->serverDomain);
3256 strncpy(ses->serverDomain,
3263 ("field of length %d "
3264 "extends beyond end of smb ",
3269 (" Security Blob extends beyond end "
3273 cERROR(1, ("No session structure passed in."));
3277 (" Invalid Word count %d: ",
3278 smb_buffer_response->WordCount));
3283 cifs_buf_release(smb_buffer);
3289 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3290 const char *tree, struct cifsTconInfo *tcon,
3291 const struct nls_table *nls_codepage)
3293 struct smb_hdr *smb_buffer;
3294 struct smb_hdr *smb_buffer_response;
3297 unsigned char *bcc_ptr;
3305 smb_buffer = cifs_buf_get();
3306 if (smb_buffer == NULL) {
3309 smb_buffer_response = smb_buffer;
3311 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3312 NULL /*no tid */ , 4 /*wct */ );
3314 smb_buffer->Mid = GetNextMid(ses->server);
3315 smb_buffer->Uid = ses->Suid;
3316 pSMB = (TCONX_REQ *) smb_buffer;
3317 pSMBr = (TCONX_RSP *) smb_buffer_response;
3319 pSMB->AndXCommand = 0xFF;
3320 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3321 bcc_ptr = &pSMB->Password[0];
3322 if ((ses->server->secMode) & SECMODE_USER) {
3323 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3324 *bcc_ptr = 0; /* password is null byte */
3325 bcc_ptr++; /* skip password */
3326 /* already aligned so no need to do it below */
3328 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3329 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3330 specified as required (when that support is added to
3331 the vfs in the future) as only NTLM or the much
3332 weaker LANMAN (which we do not send by default) is accepted
3333 by Samba (not sure whether other servers allow
3334 NTLMv2 password here) */
3335 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3336 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3337 (ses->server->secType == LANMAN))
3338 calc_lanman_hash(ses, bcc_ptr);
3340 #endif /* CIFS_WEAK_PW_HASH */
3341 SMBNTencrypt(ses->password,
3342 ses->server->cryptKey,
3345 bcc_ptr += CIFS_SESS_KEY_SIZE;
3346 if (ses->capabilities & CAP_UNICODE) {
3347 /* must align unicode strings */
3348 *bcc_ptr = 0; /* null byte password */
3353 if (ses->server->secMode &
3354 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3355 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3357 if (ses->capabilities & CAP_STATUS32) {
3358 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3360 if (ses->capabilities & CAP_DFS) {
3361 smb_buffer->Flags2 |= SMBFLG2_DFS;
3363 if (ses->capabilities & CAP_UNICODE) {
3364 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3366 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3367 6 /* max utf8 char length in bytes */ *
3368 (/* server len*/ + 256 /* share len */), nls_codepage);
3369 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3370 bcc_ptr += 2; /* skip trailing null */
3371 } else { /* ASCII */
3372 strcpy(bcc_ptr, tree);
3373 bcc_ptr += strlen(tree) + 1;
3375 strcpy(bcc_ptr, "?????");
3376 bcc_ptr += strlen("?????");
3378 count = bcc_ptr - &pSMB->Password[0];
3379 pSMB->hdr.smb_buf_length += count;
3380 pSMB->ByteCount = cpu_to_le16(count);
3382 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
3384 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3385 /* above now done in SendReceive */
3386 if ((rc == 0) && (tcon != NULL)) {
3387 tcon->tidStatus = CifsGood;
3388 tcon->tid = smb_buffer_response->Tid;
3389 bcc_ptr = pByteArea(smb_buffer_response);
3390 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3391 /* skip service field (NB: this field is always ASCII) */
3392 bcc_ptr += length + 1;
3393 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3394 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3395 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3396 if ((bcc_ptr + (2 * length)) -
3397 pByteArea(smb_buffer_response) <=
3398 BCC(smb_buffer_response)) {
3399 kfree(tcon->nativeFileSystem);
3400 tcon->nativeFileSystem =
3401 kzalloc(length + 2, GFP_KERNEL);
3402 cifs_strfromUCS_le(tcon->nativeFileSystem,
3404 length, nls_codepage);
3405 bcc_ptr += 2 * length;
3406 bcc_ptr[0] = 0; /* null terminate the string */
3410 /* else do not bother copying these information fields*/
3412 length = strnlen(bcc_ptr, 1024);
3413 if ((bcc_ptr + length) -
3414 pByteArea(smb_buffer_response) <=
3415 BCC(smb_buffer_response)) {
3416 kfree(tcon->nativeFileSystem);
3417 tcon->nativeFileSystem =
3418 kzalloc(length + 1, GFP_KERNEL);
3419 strncpy(tcon->nativeFileSystem, bcc_ptr,
3422 /* else do not bother copying these information fields*/
3424 if ((smb_buffer_response->WordCount == 3) ||
3425 (smb_buffer_response->WordCount == 7))
3426 /* field is in same location */
3427 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3430 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3431 } else if ((rc == 0) && tcon == NULL) {
3432 /* all we need to save for IPC$ connection */
3433 ses->ipc_tid = smb_buffer_response->Tid;
3437 cifs_buf_release(smb_buffer);
3442 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3446 struct cifsSesInfo *ses = NULL;
3447 struct task_struct *cifsd_task;
3452 if (cifs_sb->tcon) {
3453 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3454 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3459 tconInfoFree(cifs_sb->tcon);
3460 if ((ses) && (ses->server)) {
3461 /* save off task so we do not refer to ses later */
3462 cifsd_task = ses->server->tsk;
3463 cFYI(1, ("About to do SMBLogoff "));
3464 rc = CIFSSMBLogoff(xid, ses);
3468 } else if (rc == -ESHUTDOWN) {
3469 cFYI(1, ("Waking up socket by sending signal"));
3471 force_sig(SIGKILL, cifsd_task);
3472 kthread_stop(cifsd_task);
3475 } /* else - we have an smb session
3476 left on this socket do not kill cifsd */
3478 cFYI(1, ("No session or bad tcon"));
3481 cifs_sb->tcon = NULL;
3482 tmp = cifs_sb->prepath;
3483 cifs_sb->prepathlen = 0;
3484 cifs_sb->prepath = NULL;
3487 schedule_timeout_interruptible(msecs_to_jiffies(500));
3492 return rc; /* BB check if we should always return zero here */
3495 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3496 struct nls_table *nls_info)
3499 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3500 int ntlmv2_flag = FALSE;
3503 /* what if server changes its buffer size after dropping the session? */
3504 if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
3505 rc = CIFSSMBNegotiate(xid, pSesInfo);
3506 if (rc == -EAGAIN) /* retry only once on 1st time connection */ {
3507 rc = CIFSSMBNegotiate(xid, pSesInfo);
3512 spin_lock(&GlobalMid_Lock);
3513 if (pSesInfo->server->tcpStatus != CifsExiting)
3514 pSesInfo->server->tcpStatus = CifsGood;
3517 spin_unlock(&GlobalMid_Lock);
3523 pSesInfo->flags = 0;
3524 pSesInfo->capabilities = pSesInfo->server->capabilities;
3525 if (linuxExtEnabled == 0)
3526 pSesInfo->capabilities &= (~CAP_UNIX);
3527 /* pSesInfo->sequence_number = 0;*/
3529 ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3530 pSesInfo->server->secMode,
3531 pSesInfo->server->capabilities,
3532 pSesInfo->server->timeAdj));
3533 if (experimEnabled < 2)
3534 rc = CIFS_SessSetup(xid, pSesInfo,
3535 first_time, nls_info);
3536 else if (extended_security
3537 && (pSesInfo->capabilities
3538 & CAP_EXTENDED_SECURITY)
3539 && (pSesInfo->server->secType == NTLMSSP)) {
3541 } else if (extended_security
3542 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3543 && (pSesInfo->server->secType == RawNTLMSSP)) {
3544 cFYI(1, ("NTLMSSP sesssetup"));
3545 rc = CIFSNTLMSSPNegotiateSessSetup(xid,
3552 cFYI(1, ("more secure NTLM ver2 hash"));
3553 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3558 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
3560 CalcNTLMv2_response(pSesInfo,
3563 cifs_calculate_ntlmv2_mac_key(
3564 pSesInfo->server->mac_signing_key,
3565 response, ntlm_session_key,*/
3567 /* BB Put dummy sig in SessSetup PDU? */
3574 SMBNTencrypt(pSesInfo->password,
3575 pSesInfo->server->cryptKey,
3579 cifs_calculate_mac_key(
3580 &pSesInfo->server->mac_signing_key,
3582 pSesInfo->password);
3584 /* for better security the weaker lanman hash not sent
3585 in AuthSessSetup so we no longer calculate it */
3587 rc = CIFSNTLMSSPAuthSessSetup(xid,
3593 } else { /* old style NTLM 0.12 session setup */
3594 SMBNTencrypt(pSesInfo->password,
3595 pSesInfo->server->cryptKey,
3599 cifs_calculate_mac_key(
3600 &pSesInfo->server->mac_signing_key,
3601 ntlm_session_key, pSesInfo->password);
3603 rc = CIFSSessSetup(xid, pSesInfo,
3604 ntlm_session_key, nls_info);
3607 cERROR(1, ("Send error in SessSetup = %d", rc));
3609 cFYI(1, ("CIFS Session Established successfully"));
3610 pSesInfo->status = CifsGood;