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;
157 read_unlock(&GlobalSMBSeslock);
158 /* do not want to be sending data on a socket we are freeing */
159 down(&server->tcpSem);
160 if (server->ssocket) {
161 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
162 server->ssocket->flags));
163 server->ssocket->ops->shutdown(server->ssocket, SEND_SHUTDOWN);
164 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
165 server->ssocket->state,
166 server->ssocket->flags));
167 sock_release(server->ssocket);
168 server->ssocket = NULL;
171 spin_lock(&GlobalMid_Lock);
172 list_for_each(tmp, &server->pending_mid_q) {
173 mid_entry = list_entry(tmp, struct
177 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
178 /* Mark other intransit requests as needing
179 retry so we do not immediately mark the
180 session bad again (ie after we reconnect
181 below) as they timeout too */
182 mid_entry->midState = MID_RETRY_NEEDED;
186 spin_unlock(&GlobalMid_Lock);
189 while ((!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
191 if (server->protocolType == IPV6) {
192 rc = ipv6_connect(&server->addr.sockAddr6,
195 rc = ipv4_connect(&server->addr.sockAddr,
197 server->workstation_RFC1001_name,
198 server->server_RFC1001_name);
201 cFYI(1, ("reconnect error %d", rc));
204 atomic_inc(&tcpSesReconnectCount);
205 spin_lock(&GlobalMid_Lock);
206 if (!kthread_should_stop())
207 server->tcpStatus = CifsGood;
208 server->sequence_number = 0;
209 spin_unlock(&GlobalMid_Lock);
210 /* atomic_set(&server->inFlight,0);*/
211 wake_up(&server->response_q);
219 0 not a transact2, or all data present
220 >0 transact2 with that much data missing
221 -EINVAL = invalid transact2
224 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
226 struct smb_t2_rsp *pSMBt;
228 int data_in_this_rsp;
231 if (pSMB->Command != SMB_COM_TRANSACTION2)
234 /* check for plausible wct, bcc and t2 data and parm sizes */
235 /* check for parm and data offset going beyond end of smb */
236 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
237 cFYI(1, ("invalid transact2 word count"));
241 pSMBt = (struct smb_t2_rsp *)pSMB;
243 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
244 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
246 remaining = total_data_size - data_in_this_rsp;
250 else if (remaining < 0) {
251 cFYI(1, ("total data %d smaller than data in frame %d",
252 total_data_size, data_in_this_rsp));
255 cFYI(1, ("missing %d bytes from transact2, check next response",
257 if (total_data_size > maxBufSize) {
258 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
259 total_data_size, maxBufSize));
266 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
268 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
269 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
274 char *data_area_of_target;
275 char *data_area_of_buf2;
278 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
280 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
281 cFYI(1, ("total data size of primary and secondary t2 differ"));
284 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
286 remaining = total_data_size - total_in_buf;
291 if (remaining == 0) /* nothing to do, ignore */
294 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
295 if (remaining < total_in_buf2) {
296 cFYI(1, ("transact2 2nd response contains too much data"));
299 /* find end of first SMB data area */
300 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
301 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
302 /* validate target area */
304 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
305 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
307 data_area_of_target += total_in_buf;
309 /* copy second buffer into end of first buffer */
310 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
311 total_in_buf += total_in_buf2;
312 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
313 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
314 byte_count += total_in_buf2;
315 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
317 byte_count = pTargetSMB->smb_buf_length;
318 byte_count += total_in_buf2;
320 /* BB also add check that we are not beyond maximum buffer size */
322 pTargetSMB->smb_buf_length = byte_count;
324 if (remaining == total_in_buf2) {
325 cFYI(1, ("found the last secondary response"));
326 return 0; /* we are done */
327 } else /* more responses to go */
333 cifs_demultiplex_thread(struct TCP_Server_Info *server)
336 unsigned int pdu_length, total_read;
337 struct smb_hdr *smb_buffer = NULL;
338 struct smb_hdr *bigbuf = NULL;
339 struct smb_hdr *smallbuf = NULL;
340 struct msghdr smb_msg;
342 struct socket *csocket = server->ssocket;
343 struct list_head *tmp;
344 struct cifsSesInfo *ses;
345 struct task_struct *task_to_wake = NULL;
346 struct mid_q_entry *mid_entry;
348 int isLargeBuf = FALSE;
352 current->flags |= PF_MEMALLOC;
353 server->tsk = current; /* save process info to wake at shutdown */
354 cFYI(1, ("Demultiplex PID: %d", current->pid));
355 write_lock(&GlobalSMBSeslock);
356 atomic_inc(&tcpSesAllocCount);
357 length = tcpSesAllocCount.counter;
358 write_unlock(&GlobalSMBSeslock);
359 complete(&cifsd_complete);
361 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
365 while (!kthread_should_stop()) {
368 if (bigbuf == NULL) {
369 bigbuf = cifs_buf_get();
371 cERROR(1, ("No memory for large SMB response"));
373 /* retry will check if exiting */
376 } else if (isLargeBuf) {
377 /* we are reusing a dirty large buf, clear its start */
378 memset(bigbuf, 0, sizeof(struct smb_hdr));
381 if (smallbuf == NULL) {
382 smallbuf = cifs_small_buf_get();
384 cERROR(1, ("No memory for SMB response"));
386 /* retry will check if exiting */
389 /* beginning of smb buffer is cleared in our buf_get */
390 } else /* if existing small buf clear beginning */
391 memset(smallbuf, 0, sizeof(struct smb_hdr));
395 smb_buffer = smallbuf;
396 iov.iov_base = smb_buffer;
398 smb_msg.msg_control = NULL;
399 smb_msg.msg_controllen = 0;
400 pdu_length = 4; /* enough to get RFC1001 header */
403 kernel_recvmsg(csocket, &smb_msg,
404 &iov, 1, pdu_length, 0 /* BB other flags? */);
406 if (kthread_should_stop()) {
408 } else if (server->tcpStatus == CifsNeedReconnect) {
409 cFYI(1, ("Reconnect after server stopped responding"));
410 cifs_reconnect(server);
411 cFYI(1, ("call to reconnect done"));
412 csocket = server->ssocket;
414 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
415 msleep(1); /* minimum sleep to prevent looping
416 allowing socket to clear and app threads to set
417 tcpStatus CifsNeedReconnect if server hung */
419 } else if (length <= 0) {
420 if (server->tcpStatus == CifsNew) {
421 cFYI(1, ("tcp session abend after SMBnegprot"));
422 /* some servers kill the TCP session rather than
423 returning an SMB negprot error, in which
424 case reconnecting here is not going to help,
425 and so simply return error to mount */
428 if (!try_to_freeze() && (length == -EINTR)) {
429 cFYI(1, ("cifsd thread killed"));
432 cFYI(1, ("Reconnect after unexpected peek error %d",
434 cifs_reconnect(server);
435 csocket = server->ssocket;
436 wake_up(&server->response_q);
438 } else if (length < 4) {
439 cFYI(1, ("less than four bytes received (%d bytes)",
441 pdu_length -= length;
446 /* The right amount was read from socket - 4 bytes */
447 /* so we can now interpret the length field */
449 /* the first byte big endian of the length field,
450 is actually not part of the length but the type
451 with the most common, zero, as regular data */
452 temp = *((char *) smb_buffer);
454 /* Note that FC 1001 length is big endian on the wire,
455 but we convert it here so it is always manipulated
456 as host byte order */
457 pdu_length = ntohl(smb_buffer->smb_buf_length);
458 smb_buffer->smb_buf_length = pdu_length;
460 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
462 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
464 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
465 cFYI(1, ("Good RFC 1002 session rsp"));
467 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
468 /* we get this from Windows 98 instead of
469 an error on SMB negprot response */
470 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
472 if (server->tcpStatus == CifsNew) {
473 /* if nack on negprot (rather than
474 ret of smb negprot error) reconnecting
475 not going to help, ret error to mount */
478 /* give server a second to
479 clean up before reconnect attempt */
481 /* always try 445 first on reconnect
482 since we get NACK on some if we ever
483 connected to port 139 (the NACK is
484 since we do not begin with RFC1001
485 session initialize frame) */
486 server->addr.sockAddr.sin_port =
488 cifs_reconnect(server);
489 csocket = server->ssocket;
490 wake_up(&server->response_q);
493 } else if (temp != (char) 0) {
494 cERROR(1, ("Unknown RFC 1002 frame"));
495 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
497 cifs_reconnect(server);
498 csocket = server->ssocket;
502 /* else we have an SMB response */
503 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
504 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
505 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
506 length, pdu_length+4));
507 cifs_reconnect(server);
508 csocket = server->ssocket;
509 wake_up(&server->response_q);
516 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
518 memcpy(bigbuf, smallbuf, 4);
522 iov.iov_base = 4 + (char *)smb_buffer;
523 iov.iov_len = pdu_length;
524 for (total_read = 0; total_read < pdu_length;
525 total_read += length) {
526 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
527 pdu_length - total_read, 0);
528 if (kthread_should_stop() ||
529 (length == -EINTR)) {
533 } else if (server->tcpStatus == CifsNeedReconnect) {
534 cifs_reconnect(server);
535 csocket = server->ssocket;
536 /* Reconnect wakes up rspns q */
537 /* Now we will reread sock */
540 } else if ((length == -ERESTARTSYS) ||
541 (length == -EAGAIN)) {
542 msleep(1); /* minimum sleep to prevent looping,
543 allowing socket to clear and app
544 threads to set tcpStatus
545 CifsNeedReconnect if server hung*/
547 } else if (length <= 0) {
548 cERROR(1, ("Received no data, expecting %d",
549 pdu_length - total_read));
550 cifs_reconnect(server);
551 csocket = server->ssocket;
558 else if (reconnect == 1)
561 length += 4; /* account for rfc1002 hdr */
564 dump_smb(smb_buffer, length);
565 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
566 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
572 spin_lock(&GlobalMid_Lock);
573 list_for_each(tmp, &server->pending_mid_q) {
574 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
576 if ((mid_entry->mid == smb_buffer->Mid) &&
577 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
578 (mid_entry->command == smb_buffer->Command)) {
579 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
580 /* We have a multipart transact2 resp */
582 if (mid_entry->resp_buf) {
583 /* merge response - fix up 1st*/
584 if (coalesce_t2(smb_buffer,
585 mid_entry->resp_buf)) {
586 mid_entry->multiRsp = 1;
589 /* all parts received */
590 mid_entry->multiEnd = 1;
595 cERROR(1,("1st trans2 resp needs bigbuf"));
596 /* BB maybe we can fix this up, switch
597 to already allocated large buffer? */
599 /* Have first buffer */
600 mid_entry->resp_buf =
602 mid_entry->largeBuf = 1;
608 mid_entry->resp_buf = smb_buffer;
610 mid_entry->largeBuf = 1;
612 mid_entry->largeBuf = 0;
614 task_to_wake = mid_entry->tsk;
615 mid_entry->midState = MID_RESPONSE_RECEIVED;
616 #ifdef CONFIG_CIFS_STATS2
617 mid_entry->when_received = jiffies;
619 /* so we do not time out requests to server
620 which is still responding (since server could
621 be busy but not dead) */
622 server->lstrp = jiffies;
626 spin_unlock(&GlobalMid_Lock);
628 /* Was previous buf put in mpx struct for multi-rsp? */
630 /* smb buffer will be freed by user thread */
636 wake_up_process(task_to_wake);
637 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE)
638 && (isMultiRsp == FALSE)) {
639 cERROR(1, ("No task to wake, unknown frame received! "
640 "NumMids %d", midCount.counter));
641 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
642 sizeof(struct smb_hdr));
643 #ifdef CONFIG_CIFS_DEBUG2
644 cifs_dump_detail(smb_buffer);
645 cifs_dump_mids(server);
646 #endif /* CIFS_DEBUG2 */
649 } /* end while !EXITING */
651 spin_lock(&GlobalMid_Lock);
652 server->tcpStatus = CifsExiting;
654 /* check if we have blocked requests that need to free */
655 /* Note that cifs_max_pending is normally 50, but
656 can be set at module install time to as little as two */
657 if (atomic_read(&server->inFlight) >= cifs_max_pending)
658 atomic_set(&server->inFlight, cifs_max_pending - 1);
659 /* We do not want to set the max_pending too low or we
660 could end up with the counter going negative */
661 spin_unlock(&GlobalMid_Lock);
662 /* Although there should not be any requests blocked on
663 this queue it can not hurt to be paranoid and try to wake up requests
664 that may haven been blocked when more than 50 at time were on the wire
665 to the same server - they now will see the session is in exit state
666 and get out of SendReceive. */
667 wake_up_all(&server->request_q);
668 /* give those requests time to exit */
671 if (server->ssocket) {
672 sock_release(csocket);
673 server->ssocket = NULL;
675 /* buffer usuallly freed in free_mid - need to free it here on exit */
677 cifs_buf_release(bigbuf);
678 if (smallbuf != NULL)
679 cifs_small_buf_release(smallbuf);
681 read_lock(&GlobalSMBSeslock);
682 if (list_empty(&server->pending_mid_q)) {
683 /* loop through server session structures attached to this and
685 list_for_each(tmp, &GlobalSMBSessionList) {
687 list_entry(tmp, struct cifsSesInfo,
689 if (ses->server == server) {
690 ses->status = CifsExiting;
694 read_unlock(&GlobalSMBSeslock);
696 /* although we can not zero the server struct pointer yet,
697 since there are active requests which may depnd on them,
698 mark the corresponding SMB sessions as exiting too */
699 list_for_each(tmp, &GlobalSMBSessionList) {
700 ses = list_entry(tmp, struct cifsSesInfo,
702 if (ses->server == server)
703 ses->status = CifsExiting;
706 spin_lock(&GlobalMid_Lock);
707 list_for_each(tmp, &server->pending_mid_q) {
708 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
709 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
710 cFYI(1, ("Clearing Mid 0x%x - waking up ",
712 task_to_wake = mid_entry->tsk;
714 wake_up_process(task_to_wake);
717 spin_unlock(&GlobalMid_Lock);
718 read_unlock(&GlobalSMBSeslock);
719 /* 1/8th of sec is more than enough time for them to exit */
723 if (!list_empty(&server->pending_mid_q)) {
724 /* mpx threads have not exited yet give them
725 at least the smb send timeout time for long ops */
726 /* due to delays on oplock break requests, we need
727 to wait at least 45 seconds before giving up
728 on a request getting a response and going ahead
730 cFYI(1, ("Wait for exit from demultiplex thread"));
732 /* if threads still have not exited they are probably never
733 coming home not much else we can do but free the memory */
736 write_lock(&GlobalSMBSeslock);
737 atomic_dec(&tcpSesAllocCount);
738 length = tcpSesAllocCount.counter;
740 /* last chance to mark ses pointers invalid
741 if there are any pointing to this (e.g
742 if a crazy root user tried to kill cifsd
743 kernel thread explicitly this might happen) */
744 list_for_each(tmp, &GlobalSMBSessionList) {
745 ses = list_entry(tmp, struct cifsSesInfo,
747 if (ses->server == server)
750 write_unlock(&GlobalSMBSeslock);
754 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
761 cifs_parse_mount_options(char *options, const char *devname,
766 unsigned int temp_len, i, j;
772 if (Local_System_Name[0] != 0)
773 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
775 char *nodename = utsname()->nodename;
776 int n = strnlen(nodename, 15);
777 memset(vol->source_rfc1001_name, 0x20, 15);
778 for (i = 0; i < n; i++) {
779 /* does not have to be perfect mapping since field is
780 informational, only used for servers that do not support
781 port 445 and it can be overridden at mount time */
782 vol->source_rfc1001_name[i] = toupper(nodename[i]);
785 vol->source_rfc1001_name[15] = 0;
786 /* null target name indicates to use *SMBSERVR default called name
787 if we end up sending RFC1001 session initialize */
788 vol->target_rfc1001_name[0] = 0;
789 vol->linux_uid = current->uid; /* current->euid instead? */
790 vol->linux_gid = current->gid;
791 vol->dir_mode = S_IRWXUGO;
792 /* 2767 perms indicate mandatory locking support */
793 vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
795 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
797 /* default is always to request posix paths. */
798 vol->posix_paths = 1;
803 if (strncmp(options, "sep=", 4) == 0) {
804 if (options[4] != 0) {
805 separator[0] = options[4];
808 cFYI(1, ("Null separator not allowed"));
812 while ((data = strsep(&options, separator)) != NULL) {
815 if ((value = strchr(data, '=')) != NULL)
818 /* Have to parse this before we parse for "user" */
819 if (strnicmp(data, "user_xattr", 10) == 0) {
821 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
823 } else if (strnicmp(data, "user", 4) == 0) {
826 "CIFS: invalid or missing username\n");
827 return 1; /* needs_arg; */
828 } else if (!*value) {
829 /* null user, ie anonymous, authentication */
832 if (strnlen(value, 200) < 200) {
833 vol->username = value;
835 printk(KERN_WARNING "CIFS: username too long\n");
838 } else if (strnicmp(data, "pass", 4) == 0) {
840 vol->password = NULL;
842 } else if (value[0] == 0) {
843 /* check if string begins with double comma
844 since that would mean the password really
845 does start with a comma, and would not
846 indicate an empty string */
847 if (value[1] != separator[0]) {
848 vol->password = NULL;
852 temp_len = strlen(value);
853 /* removed password length check, NTLM passwords
854 can be arbitrarily long */
856 /* if comma in password, the string will be
857 prematurely null terminated. Commas in password are
858 specified across the cifs mount interface by a double
859 comma ie ,, and a comma used as in other cases ie ','
860 as a parameter delimiter/separator is single and due
861 to the strsep above is temporarily zeroed. */
863 /* NB: password legally can have multiple commas and
864 the only illegal character in a password is null */
866 if ((value[temp_len] == 0) &&
867 (value[temp_len+1] == separator[0])) {
869 value[temp_len] = separator[0];
870 temp_len += 2; /* move after second comma */
871 while (value[temp_len] != 0) {
872 if (value[temp_len] == separator[0]) {
873 if (value[temp_len+1] ==
875 /* skip second comma */
878 /* single comma indicating start
885 if (value[temp_len] == 0) {
889 /* point option to start of next parm */
890 options = value + temp_len + 1;
892 /* go from value to value + temp_len condensing
893 double commas to singles. Note that this ends up
894 allocating a few bytes too many, which is ok */
895 vol->password = kzalloc(temp_len, GFP_KERNEL);
896 if (vol->password == NULL) {
897 printk(KERN_WARNING "CIFS: no memory "
901 for (i = 0, j = 0; i < temp_len; i++, j++) {
902 vol->password[j] = value[i];
903 if (value[i] == separator[0]
904 && value[i+1] == separator[0]) {
905 /* skip second comma */
909 vol->password[j] = 0;
911 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
912 if (vol->password == NULL) {
913 printk(KERN_WARNING "CIFS: no memory "
917 strcpy(vol->password, value);
919 } else if (strnicmp(data, "ip", 2) == 0) {
920 if (!value || !*value) {
922 } else if (strnlen(value, 35) < 35) {
925 printk(KERN_WARNING "CIFS: ip address "
929 } else if (strnicmp(data, "sec", 3) == 0) {
930 if (!value || !*value) {
931 cERROR(1, ("no security value specified"));
933 } else if (strnicmp(value, "krb5i", 5) == 0) {
934 vol->secFlg |= CIFSSEC_MAY_KRB5 |
936 } else if (strnicmp(value, "krb5p", 5) == 0) {
937 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
939 cERROR(1, ("Krb5 cifs privacy not supported"));
941 } else if (strnicmp(value, "krb5", 4) == 0) {
942 vol->secFlg |= CIFSSEC_MAY_KRB5;
943 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
944 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
946 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
947 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
948 } else if (strnicmp(value, "ntlmi", 5) == 0) {
949 vol->secFlg |= CIFSSEC_MAY_NTLM |
951 } else if (strnicmp(value, "ntlm", 4) == 0) {
952 /* ntlm is default so can be turned off too */
953 vol->secFlg |= CIFSSEC_MAY_NTLM;
954 } else if (strnicmp(value, "nontlm", 6) == 0) {
955 /* BB is there a better way to do this? */
956 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
957 #ifdef CONFIG_CIFS_WEAK_PW_HASH
958 } else if (strnicmp(value, "lanman", 6) == 0) {
959 vol->secFlg |= CIFSSEC_MAY_LANMAN;
961 } else if (strnicmp(value, "none", 4) == 0) {
964 cERROR(1, ("bad security option: %s", value));
967 } else if ((strnicmp(data, "unc", 3) == 0)
968 || (strnicmp(data, "target", 6) == 0)
969 || (strnicmp(data, "path", 4) == 0)) {
970 if (!value || !*value) {
971 printk(KERN_WARNING "CIFS: invalid path to "
972 "network resource\n");
973 return 1; /* needs_arg; */
975 if ((temp_len = strnlen(value, 300)) < 300) {
976 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
977 if (vol->UNC == NULL)
979 strcpy(vol->UNC, value);
980 if (strncmp(vol->UNC, "//", 2) == 0) {
983 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
985 "CIFS: UNC Path does not begin "
986 "with // or \\\\ \n");
990 printk(KERN_WARNING "CIFS: UNC name too long\n");
993 } else if ((strnicmp(data, "domain", 3) == 0)
994 || (strnicmp(data, "workgroup", 5) == 0)) {
995 if (!value || !*value) {
996 printk(KERN_WARNING "CIFS: invalid domain name\n");
997 return 1; /* needs_arg; */
999 /* BB are there cases in which a comma can be valid in
1000 a domain name and need special handling? */
1001 if (strnlen(value, 256) < 256) {
1002 vol->domainname = value;
1003 cFYI(1, ("Domain name set"));
1005 printk(KERN_WARNING "CIFS: domain name too "
1009 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1010 if (!value || !*value) {
1012 "CIFS: invalid path prefix\n");
1013 return 1; /* needs_argument */
1015 if ((temp_len = strnlen(value, 1024)) < 1024) {
1016 if (value[0] != '/')
1017 temp_len++; /* missing leading slash */
1018 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1019 if (vol->prepath == NULL)
1021 if (value[0] != '/') {
1022 vol->prepath[0] = '/';
1023 strcpy(vol->prepath+1, value);
1025 strcpy(vol->prepath, value);
1026 cFYI(1, ("prefix path %s", vol->prepath));
1028 printk(KERN_WARNING "CIFS: prefix too long\n");
1031 } else if (strnicmp(data, "iocharset", 9) == 0) {
1032 if (!value || !*value) {
1033 printk(KERN_WARNING "CIFS: invalid iocharset "
1035 return 1; /* needs_arg; */
1037 if (strnlen(value, 65) < 65) {
1038 if (strnicmp(value, "default", 7))
1039 vol->iocharset = value;
1040 /* if iocharset not set then load_nls_default
1041 is used by caller */
1042 cFYI(1, ("iocharset set to %s", value));
1044 printk(KERN_WARNING "CIFS: iocharset name "
1048 } else if (strnicmp(data, "uid", 3) == 0) {
1049 if (value && *value) {
1051 simple_strtoul(value, &value, 0);
1052 vol->override_uid = 1;
1054 } else if (strnicmp(data, "gid", 3) == 0) {
1055 if (value && *value) {
1057 simple_strtoul(value, &value, 0);
1058 vol->override_gid = 1;
1060 } else if (strnicmp(data, "file_mode", 4) == 0) {
1061 if (value && *value) {
1063 simple_strtoul(value, &value, 0);
1065 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1066 if (value && *value) {
1068 simple_strtoul(value, &value, 0);
1070 } else if (strnicmp(data, "dirmode", 4) == 0) {
1071 if (value && *value) {
1073 simple_strtoul(value, &value, 0);
1075 } else if (strnicmp(data, "port", 4) == 0) {
1076 if (value && *value) {
1078 simple_strtoul(value, &value, 0);
1080 } else if (strnicmp(data, "rsize", 5) == 0) {
1081 if (value && *value) {
1083 simple_strtoul(value, &value, 0);
1085 } else if (strnicmp(data, "wsize", 5) == 0) {
1086 if (value && *value) {
1088 simple_strtoul(value, &value, 0);
1090 } else if (strnicmp(data, "sockopt", 5) == 0) {
1091 if (value && *value) {
1093 simple_strtoul(value, &value, 0);
1095 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1096 if (!value || !*value || (*value == ' ')) {
1097 cFYI(1, ("invalid (empty) netbiosname"));
1099 memset(vol->source_rfc1001_name, 0x20, 15);
1100 for (i = 0; i < 15; i++) {
1101 /* BB are there cases in which a comma can be
1102 valid in this workstation netbios name (and need
1103 special handling)? */
1105 /* We do not uppercase netbiosname for user */
1109 vol->source_rfc1001_name[i] =
1112 /* The string has 16th byte zero still from
1113 set at top of the function */
1114 if ((i == 15) && (value[i] != 0))
1115 printk(KERN_WARNING "CIFS: netbiosname"
1116 " longer than 15 truncated.\n");
1118 } else if (strnicmp(data, "servern", 7) == 0) {
1119 /* servernetbiosname specified override *SMBSERVER */
1120 if (!value || !*value || (*value == ' ')) {
1121 cFYI(1, ("empty server netbiosname specified"));
1123 /* last byte, type, is 0x20 for servr type */
1124 memset(vol->target_rfc1001_name, 0x20, 16);
1126 for (i = 0; i < 15; i++) {
1127 /* BB are there cases in which a comma can be
1128 valid in this workstation netbios name
1129 (and need special handling)? */
1131 /* user or mount helper must uppercase
1136 vol->target_rfc1001_name[i] =
1139 /* The string has 16th byte zero still from
1140 set at top of the function */
1141 if ((i == 15) && (value[i] != 0))
1142 printk(KERN_WARNING "CIFS: server net"
1143 "biosname longer than 15 truncated.\n");
1145 } else if (strnicmp(data, "credentials", 4) == 0) {
1147 } else if (strnicmp(data, "version", 3) == 0) {
1149 } else if (strnicmp(data, "guest", 5) == 0) {
1151 } else if (strnicmp(data, "rw", 2) == 0) {
1153 } else if ((strnicmp(data, "suid", 4) == 0) ||
1154 (strnicmp(data, "nosuid", 6) == 0) ||
1155 (strnicmp(data, "exec", 4) == 0) ||
1156 (strnicmp(data, "noexec", 6) == 0) ||
1157 (strnicmp(data, "nodev", 5) == 0) ||
1158 (strnicmp(data, "noauto", 6) == 0) ||
1159 (strnicmp(data, "dev", 3) == 0)) {
1160 /* The mount tool or mount.cifs helper (if present)
1161 uses these opts to set flags, and the flags are read
1162 by the kernel vfs layer before we get here (ie
1163 before read super) so there is no point trying to
1164 parse these options again and set anything and it
1165 is ok to just ignore them */
1167 } else if (strnicmp(data, "ro", 2) == 0) {
1169 } else if (strnicmp(data, "hard", 4) == 0) {
1171 } else if (strnicmp(data, "soft", 4) == 0) {
1173 } else if (strnicmp(data, "perm", 4) == 0) {
1175 } else if (strnicmp(data, "noperm", 6) == 0) {
1177 } else if (strnicmp(data, "mapchars", 8) == 0) {
1179 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1181 } else if (strnicmp(data, "sfu", 3) == 0) {
1183 } else if (strnicmp(data, "nosfu", 5) == 0) {
1185 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1186 vol->posix_paths = 1;
1187 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1188 vol->posix_paths = 0;
1189 } else if (strnicmp(data, "nounix", 6) == 0) {
1190 vol->no_linux_ext = 1;
1191 } else if (strnicmp(data, "nolinux", 7) == 0) {
1192 vol->no_linux_ext = 1;
1193 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1194 (strnicmp(data, "ignorecase", 10) == 0)) {
1196 } else if (strnicmp(data, "brl", 3) == 0) {
1198 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1199 (strnicmp(data, "nolock", 6) == 0)) {
1201 /* turn off mandatory locking in mode
1202 if remote locking is turned off since the
1203 local vfs will do advisory */
1204 if (vol->file_mode ==
1205 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1206 vol->file_mode = S_IALLUGO;
1207 } else if (strnicmp(data, "setuids", 7) == 0) {
1209 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1211 } else if (strnicmp(data, "nohard", 6) == 0) {
1213 } else if (strnicmp(data, "nosoft", 6) == 0) {
1215 } else if (strnicmp(data, "nointr", 6) == 0) {
1217 } else if (strnicmp(data, "intr", 4) == 0) {
1219 } else if (strnicmp(data, "serverino", 7) == 0) {
1220 vol->server_ino = 1;
1221 } else if (strnicmp(data, "noserverino", 9) == 0) {
1222 vol->server_ino = 0;
1223 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1225 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1227 } else if (strnicmp(data, "acl", 3) == 0) {
1228 vol->no_psx_acl = 0;
1229 } else if (strnicmp(data, "noacl", 5) == 0) {
1230 vol->no_psx_acl = 1;
1231 } else if (strnicmp(data, "sign", 4) == 0) {
1232 vol->secFlg |= CIFSSEC_MUST_SIGN;
1233 /* } else if (strnicmp(data, "seal",4) == 0) {
1234 vol->secFlg |= CIFSSEC_MUST_SEAL; */
1235 } else if (strnicmp(data, "direct", 6) == 0) {
1237 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1239 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1240 if (!value || !*value) {
1241 vol->in6_addr = NULL;
1242 } else if (strnlen(value, 49) == 48) {
1243 vol->in6_addr = value;
1245 printk(KERN_WARNING "CIFS: ip v6 address not "
1246 "48 characters long\n");
1249 } else if (strnicmp(data, "noac", 4) == 0) {
1250 printk(KERN_WARNING "CIFS: Mount option noac not "
1251 "supported. Instead set "
1252 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1254 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1257 if (vol->UNC == NULL) {
1258 if (devname == NULL) {
1259 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1263 if ((temp_len = strnlen(devname, 300)) < 300) {
1264 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1265 if (vol->UNC == NULL)
1267 strcpy(vol->UNC, devname);
1268 if (strncmp(vol->UNC, "//", 2) == 0) {
1271 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1272 printk(KERN_WARNING "CIFS: UNC Path does not "
1273 "begin with // or \\\\ \n");
1277 printk(KERN_WARNING "CIFS: UNC name too long\n");
1281 if (vol->UNCip == NULL)
1282 vol->UNCip = &vol->UNC[2];
1287 static struct cifsSesInfo *
1288 cifs_find_tcp_session(struct in_addr *target_ip_addr,
1289 struct in6_addr *target_ip6_addr,
1290 char *userName, struct TCP_Server_Info **psrvTcp)
1292 struct list_head *tmp;
1293 struct cifsSesInfo *ses;
1295 read_lock(&GlobalSMBSeslock);
1297 list_for_each(tmp, &GlobalSMBSessionList) {
1298 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1300 if ((target_ip_addr &&
1301 (ses->server->addr.sockAddr.sin_addr.s_addr
1302 == target_ip_addr->s_addr)) || (target_ip6_addr
1303 && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1304 target_ip6_addr, sizeof(*target_ip6_addr)))) {
1305 /* BB lock server and tcp session and increment
1308 /* found a match on the TCP session */
1309 *psrvTcp = ses->server;
1311 /* BB check if reconnection needed */
1313 (ses->userName, userName,
1314 MAX_USERNAME_SIZE) == 0){
1315 read_unlock(&GlobalSMBSeslock);
1316 /* Found exact match on both TCP and
1322 /* else tcp and smb sessions need reconnection */
1324 read_unlock(&GlobalSMBSeslock);
1328 static struct cifsTconInfo *
1329 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1331 struct list_head *tmp;
1332 struct cifsTconInfo *tcon;
1334 read_lock(&GlobalSMBSeslock);
1335 list_for_each(tmp, &GlobalTreeConnectionList) {
1336 cFYI(1, ("Next tcon"));
1337 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1339 if (tcon->ses->server) {
1341 ("old ip addr: %x == new ip %x ?",
1342 tcon->ses->server->addr.sockAddr.sin_addr.
1343 s_addr, new_target_ip_addr));
1344 if (tcon->ses->server->addr.sockAddr.sin_addr.
1345 s_addr == new_target_ip_addr) {
1346 /* BB lock tcon, server and tcp session and increment use count here? */
1347 /* found a match on the TCP session */
1348 /* BB check if reconnection needed */
1350 ("IP match, old UNC: %s new: %s",
1351 tcon->treeName, uncName));
1353 (tcon->treeName, uncName,
1354 MAX_TREE_SIZE) == 0) {
1356 ("and old usr: %s new: %s",
1357 tcon->treeName, uncName));
1359 (tcon->ses->userName,
1361 MAX_USERNAME_SIZE) == 0) {
1362 read_unlock(&GlobalSMBSeslock);
1363 /* matched smb session
1372 read_unlock(&GlobalSMBSeslock);
1377 connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1378 const char *old_path, const struct nls_table *nls_codepage,
1381 unsigned char *referrals = NULL;
1382 unsigned int num_referrals;
1385 rc = get_dfs_path(xid, pSesInfo, old_path, nls_codepage,
1386 &num_referrals, &referrals, remap);
1388 /* BB Add in code to: if valid refrl, if not ip address contact
1389 the helper that resolves tcp names, mount to it, try to
1390 tcon to it unmount it if fail */
1398 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1399 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1400 unsigned char **preferrals, int remap)
1405 *pnum_referrals = 0;
1407 if (pSesInfo->ipc_tid == 0) {
1408 temp_unc = kmalloc(2 /* for slashes */ +
1409 strnlen(pSesInfo->serverName,
1410 SERVER_NAME_LEN_WITH_NULL * 2)
1411 + 1 + 4 /* slash IPC$ */ + 2,
1413 if (temp_unc == NULL)
1417 strcpy(temp_unc + 2, pSesInfo->serverName);
1418 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1419 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1421 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1425 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1426 pnum_referrals, nls_codepage, remap);
1431 /* See RFC1001 section 14 on representation of Netbios names */
1432 static void rfc1002mangle(char *target, char *source, unsigned int length)
1436 for (i = 0, j = 0; i < (length); i++) {
1437 /* mask a nibble at a time and encode */
1438 target[j] = 'A' + (0x0F & (source[i] >> 4));
1439 target[j+1] = 'A' + (0x0F & source[i]);
1447 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1448 char *netbios_name, char *target_name)
1452 __be16 orig_port = 0;
1454 if (*csocket == NULL) {
1455 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1456 IPPROTO_TCP, csocket);
1458 cERROR(1, ("Error %d creating socket", rc));
1462 /* BB other socket options to set KEEPALIVE, NODELAY? */
1463 cFYI(1, ("Socket created"));
1464 (*csocket)->sk->sk_allocation = GFP_NOFS;
1468 psin_server->sin_family = AF_INET;
1469 if (psin_server->sin_port) { /* user overrode default port */
1470 rc = (*csocket)->ops->connect(*csocket,
1471 (struct sockaddr *) psin_server,
1472 sizeof (struct sockaddr_in), 0);
1478 /* save original port so we can retry user specified port
1479 later if fall back ports fail this time */
1480 orig_port = psin_server->sin_port;
1482 /* do not retry on the same port we just failed on */
1483 if (psin_server->sin_port != htons(CIFS_PORT)) {
1484 psin_server->sin_port = htons(CIFS_PORT);
1486 rc = (*csocket)->ops->connect(*csocket,
1487 (struct sockaddr *) psin_server,
1488 sizeof (struct sockaddr_in), 0);
1494 psin_server->sin_port = htons(RFC1001_PORT);
1495 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1497 sizeof (struct sockaddr_in), 0);
1502 /* give up here - unless we want to retry on different
1503 protocol families some day */
1506 psin_server->sin_port = orig_port;
1507 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1508 sock_release(*csocket);
1512 /* Eventually check for other socket options to change from
1513 the default. sock_setsockopt not used because it expects
1514 user space buffer */
1515 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1516 (*csocket)->sk->sk_sndbuf,
1517 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1518 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1519 /* make the bufsizes depend on wsize/rsize and max requests */
1520 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1521 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1522 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1523 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1525 /* send RFC1001 sessinit */
1526 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1527 /* some servers require RFC1001 sessinit before sending
1528 negprot - BB check reconnection in case where second
1529 sessinit is sent but no second negprot */
1530 struct rfc1002_session_packet *ses_init_buf;
1531 struct smb_hdr *smb_buf;
1532 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1535 ses_init_buf->trailer.session_req.called_len = 32;
1536 if (target_name && (target_name[0] != 0)) {
1537 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1540 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1541 DEFAULT_CIFS_CALLED_NAME, 16);
1544 ses_init_buf->trailer.session_req.calling_len = 32;
1545 /* calling name ends in null (byte 16) from old smb
1547 if (netbios_name && (netbios_name[0] != 0)) {
1548 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1551 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1552 "LINUX_CIFS_CLNT", 16);
1554 ses_init_buf->trailer.session_req.scope1 = 0;
1555 ses_init_buf->trailer.session_req.scope2 = 0;
1556 smb_buf = (struct smb_hdr *)ses_init_buf;
1557 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1558 smb_buf->smb_buf_length = 0x81000044;
1559 rc = smb_send(*csocket, smb_buf, 0x44,
1560 (struct sockaddr *)psin_server);
1561 kfree(ses_init_buf);
1562 msleep(1); /* RFC1001 layer in at least one server
1563 requires very short break before negprot
1564 presumably because not expecting negprot
1565 to follow so fast. This is a simple
1566 solution that works without
1567 complicating the code and causes no
1568 significant slowing down on mount
1569 for everyone else */
1571 /* else the negprot may still work without this
1572 even though malloc failed */
1580 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1584 __be16 orig_port = 0;
1586 if (*csocket == NULL) {
1587 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1588 IPPROTO_TCP, csocket);
1590 cERROR(1, ("Error %d creating ipv6 socket", rc));
1594 /* BB other socket options to set KEEPALIVE, NODELAY? */
1595 cFYI(1, ("ipv6 Socket created"));
1596 (*csocket)->sk->sk_allocation = GFP_NOFS;
1600 psin_server->sin6_family = AF_INET6;
1602 if (psin_server->sin6_port) { /* user overrode default port */
1603 rc = (*csocket)->ops->connect(*csocket,
1604 (struct sockaddr *) psin_server,
1605 sizeof (struct sockaddr_in6), 0);
1611 /* save original port so we can retry user specified port
1612 later if fall back ports fail this time */
1614 orig_port = psin_server->sin6_port;
1615 /* do not retry on the same port we just failed on */
1616 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1617 psin_server->sin6_port = htons(CIFS_PORT);
1619 rc = (*csocket)->ops->connect(*csocket,
1620 (struct sockaddr *) psin_server,
1621 sizeof (struct sockaddr_in6), 0);
1627 psin_server->sin6_port = htons(RFC1001_PORT);
1628 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1629 psin_server, sizeof (struct sockaddr_in6), 0);
1634 /* give up here - unless we want to retry on different
1635 protocol families some day */
1638 psin_server->sin6_port = orig_port;
1639 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1640 sock_release(*csocket);
1644 /* Eventually check for other socket options to change from
1645 the default. sock_setsockopt not used because it expects
1646 user space buffer */
1647 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1652 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1653 struct super_block *sb, struct smb_vol *vol_info)
1655 /* if we are reconnecting then should we check to see if
1656 * any requested capabilities changed locally e.g. via
1657 * remount but we can not do much about it here
1658 * if they have (even if we could detect it by the following)
1659 * Perhaps we could add a backpointer to array of sb from tcon
1660 * or if we change to make all sb to same share the same
1661 * sb as NFS - then we only have one backpointer to sb.
1662 * What if we wanted to mount the server share twice once with
1663 * and once without posixacls or posix paths? */
1664 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1666 if (vol_info && vol_info->no_linux_ext) {
1667 tcon->fsUnixInfo.Capability = 0;
1668 tcon->unix_ext = 0; /* Unix Extensions disabled */
1669 cFYI(1, ("Linux protocol extensions disabled"));
1671 } else if (vol_info)
1672 tcon->unix_ext = 1; /* Unix Extensions supported */
1674 if (tcon->unix_ext == 0) {
1675 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1679 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1680 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1682 /* check for reconnect case in which we do not
1683 want to change the mount behavior if we can avoid it */
1684 if (vol_info == NULL) {
1685 /* turn off POSIX ACL and PATHNAMES if not set
1686 originally at mount time */
1687 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1688 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1689 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0)
1690 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1693 cap &= CIFS_UNIX_CAP_MASK;
1694 if (vol_info && vol_info->no_psx_acl)
1695 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1696 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
1697 cFYI(1, ("negotiated posix acl support"));
1699 sb->s_flags |= MS_POSIXACL;
1702 if (vol_info && vol_info->posix_paths == 0)
1703 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1704 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1705 cFYI(1, ("negotiate posix pathnames"));
1707 CIFS_SB(sb)->mnt_cifs_flags |=
1708 CIFS_MOUNT_POSIX_PATHS;
1711 /* We might be setting the path sep back to a different
1712 form if we are reconnecting and the server switched its
1713 posix path capability for this share */
1714 if (sb && (CIFS_SB(sb)->prepathlen > 0))
1715 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1717 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
1718 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
1719 CIFS_SB(sb)->rsize = 127 * 1024;
1720 #ifdef CONFIG_CIFS_DEBUG2
1721 cFYI(1, ("larger reads not supported by srv"));
1727 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
1728 #ifdef CONFIG_CIFS_DEBUG2
1729 if (cap & CIFS_UNIX_FCNTL_CAP)
1730 cFYI(1, ("FCNTL cap"));
1731 if (cap & CIFS_UNIX_EXTATTR_CAP)
1732 cFYI(1, ("EXTATTR cap"));
1733 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1734 cFYI(1, ("POSIX path cap"));
1735 if (cap & CIFS_UNIX_XATTR_CAP)
1736 cFYI(1, ("XATTR cap"));
1737 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
1738 cFYI(1, ("POSIX ACL cap"));
1739 if (cap & CIFS_UNIX_LARGE_READ_CAP)
1740 cFYI(1, ("very large read cap"));
1741 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
1742 cFYI(1, ("very large write cap"));
1743 #endif /* CIFS_DEBUG2 */
1744 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1745 cFYI(1, ("setting capabilities failed"));
1751 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1752 char *mount_data, const char *devname)
1756 int address_type = AF_INET;
1757 struct socket *csocket = NULL;
1758 struct sockaddr_in sin_server;
1759 struct sockaddr_in6 sin_server6;
1760 struct smb_vol volume_info;
1761 struct cifsSesInfo *pSesInfo = NULL;
1762 struct cifsSesInfo *existingCifsSes = NULL;
1763 struct cifsTconInfo *tcon = NULL;
1764 struct TCP_Server_Info *srvTcp = NULL;
1768 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1770 memset(&volume_info, 0, sizeof(struct smb_vol));
1771 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1772 kfree(volume_info.UNC);
1773 kfree(volume_info.password);
1774 kfree(volume_info.prepath);
1779 if (volume_info.nullauth) {
1780 cFYI(1, ("null user"));
1781 volume_info.username = NULL;
1782 } else if (volume_info.username) {
1783 /* BB fixme parse for domain name here */
1784 cFYI(1, ("Username: %s", volume_info.username));
1786 cifserror("No username specified");
1787 /* In userspace mount helper we can get user name from alternate
1788 locations such as env variables and files on disk */
1789 kfree(volume_info.UNC);
1790 kfree(volume_info.password);
1791 kfree(volume_info.prepath);
1796 if (volume_info.UNCip && volume_info.UNC) {
1797 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
1798 &sin_server.sin_addr.s_addr);
1801 /* not ipv4 address, try ipv6 */
1802 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
1803 &sin_server6.sin6_addr.in6_u);
1805 address_type = AF_INET6;
1807 address_type = AF_INET;
1811 /* we failed translating address */
1812 kfree(volume_info.UNC);
1813 kfree(volume_info.password);
1814 kfree(volume_info.prepath);
1819 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1822 } else if (volume_info.UNCip) {
1823 /* BB using ip addr as server name to connect to the
1825 cERROR(1, ("Connecting to DFS root not implemented yet"));
1826 kfree(volume_info.UNC);
1827 kfree(volume_info.password);
1828 kfree(volume_info.prepath);
1831 } else /* which servers DFS root would we conect to */ {
1833 ("CIFS mount error: No UNC path (e.g. -o "
1834 "unc=//192.168.1.100/public) specified"));
1835 kfree(volume_info.UNC);
1836 kfree(volume_info.password);
1837 kfree(volume_info.prepath);
1842 /* this is needed for ASCII cp to Unicode converts */
1843 if (volume_info.iocharset == NULL) {
1844 cifs_sb->local_nls = load_nls_default();
1845 /* load_nls_default can not return null */
1847 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1848 if (cifs_sb->local_nls == NULL) {
1849 cERROR(1, ("CIFS mount error: iocharset %s not found",
1850 volume_info.iocharset));
1851 kfree(volume_info.UNC);
1852 kfree(volume_info.password);
1853 kfree(volume_info.prepath);
1859 if (address_type == AF_INET)
1860 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1861 NULL /* no ipv6 addr */,
1862 volume_info.username, &srvTcp);
1863 else if (address_type == AF_INET6) {
1864 cFYI(1, ("looking for ipv6 address"));
1865 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1866 &sin_server6.sin6_addr,
1867 volume_info.username, &srvTcp);
1869 kfree(volume_info.UNC);
1870 kfree(volume_info.password);
1871 kfree(volume_info.prepath);
1877 cFYI(1, ("Existing tcp session with server found"));
1878 } else { /* create socket */
1879 if (volume_info.port)
1880 sin_server.sin_port = htons(volume_info.port);
1882 sin_server.sin_port = 0;
1883 if (address_type == AF_INET6) {
1884 cFYI(1, ("attempting ipv6 connect"));
1885 /* BB should we allow ipv6 on port 139? */
1886 /* other OS never observed in Wild doing 139 with v6 */
1887 rc = ipv6_connect(&sin_server6, &csocket);
1889 rc = ipv4_connect(&sin_server, &csocket,
1890 volume_info.source_rfc1001_name,
1891 volume_info.target_rfc1001_name);
1893 cERROR(1, ("Error connecting to IPv4 socket. "
1894 "Aborting operation"));
1895 if (csocket != NULL)
1896 sock_release(csocket);
1897 kfree(volume_info.UNC);
1898 kfree(volume_info.password);
1899 kfree(volume_info.prepath);
1904 srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
1905 if (srvTcp == NULL) {
1907 sock_release(csocket);
1908 kfree(volume_info.UNC);
1909 kfree(volume_info.password);
1910 kfree(volume_info.prepath);
1914 memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
1915 memcpy(&srvTcp->addr.sockAddr, &sin_server,
1916 sizeof (struct sockaddr_in));
1917 atomic_set(&srvTcp->inFlight, 0);
1918 /* BB Add code for ipv6 case too */
1919 srvTcp->ssocket = csocket;
1920 srvTcp->protocolType = IPV4;
1921 init_waitqueue_head(&srvTcp->response_q);
1922 init_waitqueue_head(&srvTcp->request_q);
1923 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
1924 /* at this point we are the only ones with the pointer
1925 to the struct since the kernel thread not created yet
1926 so no need to spinlock this init of tcpStatus */
1927 srvTcp->tcpStatus = CifsNew;
1928 init_MUTEX(&srvTcp->tcpSem);
1929 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
1930 if ( IS_ERR(srvTcp->tsk) ) {
1931 rc = PTR_ERR(srvTcp->tsk);
1932 cERROR(1, ("error %d create cifsd thread", rc));
1934 sock_release(csocket);
1935 kfree(volume_info.UNC);
1936 kfree(volume_info.password);
1937 kfree(volume_info.prepath);
1941 wait_for_completion(&cifsd_complete);
1943 memcpy(srvTcp->workstation_RFC1001_name,
1944 volume_info.source_rfc1001_name, 16);
1945 memcpy(srvTcp->server_RFC1001_name,
1946 volume_info.target_rfc1001_name, 16);
1947 srvTcp->sequence_number = 0;
1951 if (existingCifsSes) {
1952 pSesInfo = existingCifsSes;
1953 cFYI(1, ("Existing smb sess found"));
1954 kfree(volume_info.password);
1955 /* volume_info.UNC freed at end of function */
1957 cFYI(1, ("Existing smb sess not found"));
1958 pSesInfo = sesInfoAlloc();
1959 if (pSesInfo == NULL)
1962 pSesInfo->server = srvTcp;
1963 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
1964 NIPQUAD(sin_server.sin_addr.s_addr));
1968 /* volume_info.password freed at unmount */
1969 if (volume_info.password)
1970 pSesInfo->password = volume_info.password;
1971 if (volume_info.username)
1972 strncpy(pSesInfo->userName,
1973 volume_info.username,
1975 if (volume_info.domainname) {
1976 int len = strlen(volume_info.domainname);
1977 pSesInfo->domainName =
1978 kmalloc(len + 1, GFP_KERNEL);
1979 if (pSesInfo->domainName)
1980 strcpy(pSesInfo->domainName,
1981 volume_info.domainname);
1983 pSesInfo->linux_uid = volume_info.linux_uid;
1984 pSesInfo->overrideSecFlg = volume_info.secFlg;
1985 down(&pSesInfo->sesSem);
1986 /* BB FIXME need to pass vol->secFlgs BB */
1987 rc = cifs_setup_session(xid, pSesInfo,
1988 cifs_sb->local_nls);
1989 up(&pSesInfo->sesSem);
1991 atomic_inc(&srvTcp->socketUseCount);
1993 kfree(volume_info.password);
1996 /* search for existing tcon to this server share */
1998 if (volume_info.rsize > CIFSMaxBufSize) {
1999 cERROR(1, ("rsize %d too large, using MaxBufSize",
2000 volume_info.rsize));
2001 cifs_sb->rsize = CIFSMaxBufSize;
2002 } else if ((volume_info.rsize) &&
2003 (volume_info.rsize <= CIFSMaxBufSize))
2004 cifs_sb->rsize = volume_info.rsize;
2006 cifs_sb->rsize = CIFSMaxBufSize;
2008 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2009 cERROR(1, ("wsize %d too large, using 4096 instead",
2010 volume_info.wsize));
2011 cifs_sb->wsize = 4096;
2012 } else if (volume_info.wsize)
2013 cifs_sb->wsize = volume_info.wsize;
2016 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2018 /* old default of CIFSMaxBufSize was too small now
2019 that SMB Write2 can send multiple pages in kvec.
2020 RFC1001 does not describe what happens when frame
2021 bigger than 128K is sent so use that as max in
2022 conjunction with 52K kvec constraint on arch with 4K
2025 if (cifs_sb->rsize < 2048) {
2026 cifs_sb->rsize = 2048;
2027 /* Windows ME may prefer this */
2028 cFYI(1, ("readsize set to minimum: 2048"));
2030 /* calculate prepath */
2031 cifs_sb->prepath = volume_info.prepath;
2032 if (cifs_sb->prepath) {
2033 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2034 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
2035 volume_info.prepath = NULL;
2037 cifs_sb->prepathlen = 0;
2038 cifs_sb->mnt_uid = volume_info.linux_uid;
2039 cifs_sb->mnt_gid = volume_info.linux_gid;
2040 cifs_sb->mnt_file_mode = volume_info.file_mode;
2041 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
2042 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2043 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2045 if (volume_info.noperm)
2046 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2047 if (volume_info.setuids)
2048 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2049 if (volume_info.server_ino)
2050 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2051 if (volume_info.remap)
2052 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2053 if (volume_info.no_xattr)
2054 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2055 if (volume_info.sfu_emul)
2056 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2057 if (volume_info.nobrl)
2058 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2059 if (volume_info.cifs_acl)
2060 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2061 if (volume_info.override_uid)
2062 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2063 if (volume_info.override_gid)
2064 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2065 if (volume_info.direct_io) {
2066 cFYI(1, ("mounting share using direct i/o"));
2067 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2071 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
2072 volume_info.username);
2074 cFYI(1, ("Found match on UNC path"));
2075 /* we can have only one retry value for a connection
2076 to a share so for resources mounted more than once
2077 to the same server share the last value passed in
2078 for the retry flag is used */
2079 tcon->retry = volume_info.retry;
2080 tcon->nocase = volume_info.nocase;
2082 tcon = tconInfoAlloc();
2086 /* check for null share name ie connecting to
2089 /* BB check if this works for exactly length
2091 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2092 && (strchr(volume_info.UNC + 3, '/') ==
2094 rc = connect_to_dfs_path(xid, pSesInfo,
2095 "", cifs_sb->local_nls,
2096 cifs_sb->mnt_cifs_flags &
2097 CIFS_MOUNT_MAP_SPECIAL_CHR);
2098 kfree(volume_info.UNC);
2102 /* BB Do we need to wrap sesSem around
2103 * this TCon call and Unix SetFS as
2104 * we do on SessSetup and reconnect? */
2105 rc = CIFSTCon(xid, pSesInfo,
2107 tcon, cifs_sb->local_nls);
2108 cFYI(1, ("CIFS Tcon rc = %d", rc));
2111 atomic_inc(&pSesInfo->inUse);
2112 tcon->retry = volume_info.retry;
2113 tcon->nocase = volume_info.nocase;
2119 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2120 sb->s_maxbytes = (u64) 1 << 63;
2122 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2125 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2126 sb->s_time_gran = 100;
2128 /* on error free sesinfo and tcon struct if needed */
2130 /* if session setup failed, use count is zero but
2131 we still need to free cifsd thread */
2132 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2133 spin_lock(&GlobalMid_Lock);
2134 srvTcp->tcpStatus = CifsExiting;
2135 spin_unlock(&GlobalMid_Lock);
2137 struct task_struct *tsk;
2138 /* If we could verify that kthread_stop would
2139 always wake up processes blocked in
2140 tcp in recv_mesg then we could remove the
2142 force_sig(SIGKILL, srvTcp->tsk);
2148 /* If find_unc succeeded then rc == 0 so we can not end */
2149 if (tcon) /* up accidently freeing someone elses tcon struct */
2151 if (existingCifsSes == NULL) {
2153 if ((pSesInfo->server) &&
2154 (pSesInfo->status == CifsGood)) {
2156 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2157 /* if the socketUseCount is now zero */
2158 if ((temp_rc == -ESHUTDOWN) &&
2159 (pSesInfo->server) &&
2160 (pSesInfo->server->tsk)) {
2161 struct task_struct *tsk;
2163 pSesInfo->server->tsk);
2164 tsk = pSesInfo->server->tsk;
2169 cFYI(1, ("No session or bad tcon"));
2170 sesInfoFree(pSesInfo);
2171 /* pSesInfo = NULL; */
2175 atomic_inc(&tcon->useCount);
2176 cifs_sb->tcon = tcon;
2177 tcon->ses = pSesInfo;
2179 /* do not care if following two calls succeed - informational */
2180 CIFSSMBQFSDeviceInfo(xid, tcon);
2181 CIFSSMBQFSAttributeInfo(xid, tcon);
2183 /* tell server which Unix caps we support */
2184 if (tcon->ses->capabilities & CAP_UNIX)
2185 /* reset of caps checks mount to see if unix extensions
2186 disabled for just this mount */
2187 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2189 tcon->unix_ext = 0; /* server does not support them */
2191 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2192 cifs_sb->rsize = 1024 * 127;
2193 #ifdef CONFIG_CIFS_DEBUG2
2194 cFYI(1, ("no very large read support, rsize now 127K"));
2197 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2198 cifs_sb->wsize = min(cifs_sb->wsize,
2199 (tcon->ses->server->maxBuf -
2200 MAX_CIFS_HDR_SIZE));
2201 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2202 cifs_sb->rsize = min(cifs_sb->rsize,
2203 (tcon->ses->server->maxBuf -
2204 MAX_CIFS_HDR_SIZE));
2207 /* volume_info.password is freed above when existing session found
2208 (in which case it is not needed anymore) but when new sesion is created
2209 the password ptr is put in the new session structure (in which case the
2210 password will be freed at unmount time) */
2211 kfree(volume_info.UNC);
2212 kfree(volume_info.prepath);
2218 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2219 char session_key[CIFS_SESS_KEY_SIZE],
2220 const struct nls_table *nls_codepage)
2222 struct smb_hdr *smb_buffer;
2223 struct smb_hdr *smb_buffer_response;
2224 SESSION_SETUP_ANDX *pSMB;
2225 SESSION_SETUP_ANDX *pSMBr;
2230 int remaining_words = 0;
2231 int bytes_returned = 0;
2236 cFYI(1, ("In sesssetup"));
2239 user = ses->userName;
2240 domain = ses->domainName;
2241 smb_buffer = cifs_buf_get();
2242 if (smb_buffer == NULL) {
2245 smb_buffer_response = smb_buffer;
2246 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2248 /* send SMBsessionSetup here */
2249 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2250 NULL /* no tCon exists yet */ , 13 /* wct */ );
2252 smb_buffer->Mid = GetNextMid(ses->server);
2253 pSMB->req_no_secext.AndXCommand = 0xFF;
2254 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2255 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2257 if (ses->server->secMode &
2258 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2259 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2261 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2262 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2263 if (ses->capabilities & CAP_UNICODE) {
2264 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2265 capabilities |= CAP_UNICODE;
2267 if (ses->capabilities & CAP_STATUS32) {
2268 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2269 capabilities |= CAP_STATUS32;
2271 if (ses->capabilities & CAP_DFS) {
2272 smb_buffer->Flags2 |= SMBFLG2_DFS;
2273 capabilities |= CAP_DFS;
2275 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2277 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2278 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2280 pSMB->req_no_secext.CaseSensitivePasswordLength =
2281 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2282 bcc_ptr = pByteArea(smb_buffer);
2283 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2284 bcc_ptr += CIFS_SESS_KEY_SIZE;
2285 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2286 bcc_ptr += CIFS_SESS_KEY_SIZE;
2288 if (ses->capabilities & CAP_UNICODE) {
2289 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2294 bytes_returned = 0; /* skip null user */
2297 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2299 /* convert number of 16 bit words to bytes */
2300 bcc_ptr += 2 * bytes_returned;
2301 bcc_ptr += 2; /* trailing null */
2304 cifs_strtoUCS((__le16 *) bcc_ptr,
2305 "CIFS_LINUX_DOM", 32, nls_codepage);
2308 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2310 bcc_ptr += 2 * bytes_returned;
2313 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2315 bcc_ptr += 2 * bytes_returned;
2317 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2319 bcc_ptr += 2 * bytes_returned;
2322 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2324 bcc_ptr += 2 * bytes_returned;
2328 strncpy(bcc_ptr, user, 200);
2329 bcc_ptr += strnlen(user, 200);
2333 if (domain == NULL) {
2334 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2335 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2337 strncpy(bcc_ptr, domain, 64);
2338 bcc_ptr += strnlen(domain, 64);
2342 strcpy(bcc_ptr, "Linux version ");
2343 bcc_ptr += strlen("Linux version ");
2344 strcpy(bcc_ptr, utsname()->release);
2345 bcc_ptr += strlen(utsname()->release) + 1;
2346 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2347 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2349 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2350 smb_buffer->smb_buf_length += count;
2351 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2353 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2354 &bytes_returned, 1);
2356 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2357 } else if ((smb_buffer_response->WordCount == 3)
2358 || (smb_buffer_response->WordCount == 4)) {
2359 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2360 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2361 if (action & GUEST_LOGIN)
2362 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2363 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2365 cFYI(1, ("UID = %d ", ses->Suid));
2366 /* response can have either 3 or 4 word count - Samba sends 3 */
2367 bcc_ptr = pByteArea(smb_buffer_response);
2368 if ((pSMBr->resp.hdr.WordCount == 3)
2369 || ((pSMBr->resp.hdr.WordCount == 4)
2370 && (blob_len < pSMBr->resp.ByteCount))) {
2371 if (pSMBr->resp.hdr.WordCount == 4)
2372 bcc_ptr += blob_len;
2374 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2375 if ((long) (bcc_ptr) % 2) {
2377 (BCC(smb_buffer_response) - 1) / 2;
2378 /* Unicode strings must be word
2383 BCC(smb_buffer_response) / 2;
2386 UniStrnlen((wchar_t *) bcc_ptr,
2387 remaining_words - 1);
2388 /* We look for obvious messed up bcc or strings in response so we do not go off
2389 the end since (at least) WIN2K and Windows XP have a major bug in not null
2390 terminating last Unicode string in response */
2392 kfree(ses->serverOS);
2393 ses->serverOS = kzalloc(2 * (len + 1),
2395 if (ses->serverOS == NULL)
2396 goto sesssetup_nomem;
2397 cifs_strfromUCS_le(ses->serverOS,
2400 bcc_ptr += 2 * (len + 1);
2401 remaining_words -= len + 1;
2402 ses->serverOS[2 * len] = 0;
2403 ses->serverOS[1 + (2 * len)] = 0;
2404 if (remaining_words > 0) {
2405 len = UniStrnlen((wchar_t *)bcc_ptr,
2407 kfree(ses->serverNOS);
2408 ses->serverNOS = kzalloc(2 * (len + 1),
2410 if (ses->serverNOS == NULL)
2411 goto sesssetup_nomem;
2412 cifs_strfromUCS_le(ses->serverNOS,
2415 bcc_ptr += 2 * (len + 1);
2416 ses->serverNOS[2 * len] = 0;
2417 ses->serverNOS[1 + (2 * len)] = 0;
2418 if (strncmp(ses->serverNOS,
2419 "NT LAN Manager 4", 16) == 0) {
2420 cFYI(1, ("NT4 server"));
2421 ses->flags |= CIFS_SES_NT4;
2423 remaining_words -= len + 1;
2424 if (remaining_words > 0) {
2425 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2426 /* last string is not always null terminated
2427 (for e.g. for Windows XP & 2000) */
2428 if (ses->serverDomain)
2429 kfree(ses->serverDomain);
2433 if (ses->serverDomain == NULL)
2434 goto sesssetup_nomem;
2435 cifs_strfromUCS_le(ses->serverDomain,
2438 bcc_ptr += 2 * (len + 1);
2439 ses->serverDomain[2*len] = 0;
2440 ses->serverDomain[1+(2*len)] = 0;
2441 } else { /* else no more room so create
2442 dummy domain string */
2443 if (ses->serverDomain)
2444 kfree(ses->serverDomain);
2446 kzalloc(2, GFP_KERNEL);
2448 } else { /* no room so create dummy domain
2451 /* if these kcallocs fail not much we
2452 can do, but better to not fail the
2454 kfree(ses->serverDomain);
2456 kzalloc(2, GFP_KERNEL);
2457 kfree(ses->serverNOS);
2459 kzalloc(2, GFP_KERNEL);
2461 } else { /* ASCII */
2462 len = strnlen(bcc_ptr, 1024);
2463 if (((long) bcc_ptr + len) - (long)
2464 pByteArea(smb_buffer_response)
2465 <= BCC(smb_buffer_response)) {
2466 kfree(ses->serverOS);
2467 ses->serverOS = kzalloc(len + 1,
2469 if (ses->serverOS == NULL)
2470 goto sesssetup_nomem;
2471 strncpy(ses->serverOS, bcc_ptr, len);
2474 /* null terminate the string */
2478 len = strnlen(bcc_ptr, 1024);
2479 kfree(ses->serverNOS);
2480 ses->serverNOS = kzalloc(len + 1,
2482 if (ses->serverNOS == NULL)
2483 goto sesssetup_nomem;
2484 strncpy(ses->serverNOS, bcc_ptr, len);
2489 len = strnlen(bcc_ptr, 1024);
2490 if (ses->serverDomain)
2491 kfree(ses->serverDomain);
2492 ses->serverDomain = kzalloc(len + 1,
2494 if (ses->serverDomain == NULL)
2495 goto sesssetup_nomem;
2496 strncpy(ses->serverDomain, bcc_ptr,
2503 ("Variable field of length %d "
2504 "extends beyond end of smb ",
2509 (" Security Blob Length extends beyond "
2514 (" Invalid Word count %d: ",
2515 smb_buffer_response->WordCount));
2518 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2519 since that could make reconnection harder, and
2520 reconnection might be needed to free memory */
2522 cifs_buf_release(smb_buffer);
2528 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2529 struct cifsSesInfo *ses, int *pNTLMv2_flag,
2530 const struct nls_table *nls_codepage)
2532 struct smb_hdr *smb_buffer;
2533 struct smb_hdr *smb_buffer_response;
2534 SESSION_SETUP_ANDX *pSMB;
2535 SESSION_SETUP_ANDX *pSMBr;
2539 int remaining_words = 0;
2540 int bytes_returned = 0;
2542 int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
2543 PNEGOTIATE_MESSAGE SecurityBlob;
2544 PCHALLENGE_MESSAGE SecurityBlob2;
2545 __u32 negotiate_flags, capabilities;
2548 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2551 domain = ses->domainName;
2552 *pNTLMv2_flag = FALSE;
2553 smb_buffer = cifs_buf_get();
2554 if (smb_buffer == NULL) {
2557 smb_buffer_response = smb_buffer;
2558 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2559 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2561 /* send SMBsessionSetup here */
2562 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2563 NULL /* no tCon exists yet */ , 12 /* wct */ );
2565 smb_buffer->Mid = GetNextMid(ses->server);
2566 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2567 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2569 pSMB->req.AndXCommand = 0xFF;
2570 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2571 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2573 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2574 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2576 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2577 CAP_EXTENDED_SECURITY;
2578 if (ses->capabilities & CAP_UNICODE) {
2579 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2580 capabilities |= CAP_UNICODE;
2582 if (ses->capabilities & CAP_STATUS32) {
2583 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2584 capabilities |= CAP_STATUS32;
2586 if (ses->capabilities & CAP_DFS) {
2587 smb_buffer->Flags2 |= SMBFLG2_DFS;
2588 capabilities |= CAP_DFS;
2590 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2592 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2593 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2594 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2595 SecurityBlob->MessageType = NtLmNegotiate;
2597 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2598 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2599 NTLMSSP_NEGOTIATE_56 |
2600 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2602 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2603 /* if (ntlmv2_support)
2604 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2605 /* setup pointers to domain name and workstation name */
2606 bcc_ptr += SecurityBlobLength;
2608 SecurityBlob->WorkstationName.Buffer = 0;
2609 SecurityBlob->WorkstationName.Length = 0;
2610 SecurityBlob->WorkstationName.MaximumLength = 0;
2612 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2613 along with username on auth request (ie the response to challenge) */
2614 SecurityBlob->DomainName.Buffer = 0;
2615 SecurityBlob->DomainName.Length = 0;
2616 SecurityBlob->DomainName.MaximumLength = 0;
2617 if (ses->capabilities & CAP_UNICODE) {
2618 if ((long) bcc_ptr % 2) {
2624 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2626 bcc_ptr += 2 * bytes_returned;
2628 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2630 bcc_ptr += 2 * bytes_returned;
2631 bcc_ptr += 2; /* null terminate Linux version */
2633 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2635 bcc_ptr += 2 * bytes_returned;
2638 bcc_ptr += 2; /* null terminate network opsys string */
2641 bcc_ptr += 2; /* null domain */
2642 } else { /* ASCII */
2643 strcpy(bcc_ptr, "Linux version ");
2644 bcc_ptr += strlen("Linux version ");
2645 strcpy(bcc_ptr, utsname()->release);
2646 bcc_ptr += strlen(utsname()->release) + 1;
2647 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2648 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2649 bcc_ptr++; /* empty domain field */
2652 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2653 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2654 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2655 smb_buffer->smb_buf_length += count;
2656 pSMB->req.ByteCount = cpu_to_le16(count);
2658 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2659 &bytes_returned, 1);
2661 if (smb_buffer_response->Status.CifsError ==
2662 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2666 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2667 } else if ((smb_buffer_response->WordCount == 3)
2668 || (smb_buffer_response->WordCount == 4)) {
2669 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2670 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2672 if (action & GUEST_LOGIN)
2673 cFYI(1, (" Guest login"));
2674 /* Do we want to set anything in SesInfo struct when guest login? */
2676 bcc_ptr = pByteArea(smb_buffer_response);
2677 /* response can have either 3 or 4 word count - Samba sends 3 */
2679 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2680 if (SecurityBlob2->MessageType != NtLmChallenge) {
2682 ("Unexpected NTLMSSP message type received %d",
2683 SecurityBlob2->MessageType));
2685 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2686 cFYI(1, ("UID = %d", ses->Suid));
2687 if ((pSMBr->resp.hdr.WordCount == 3)
2688 || ((pSMBr->resp.hdr.WordCount == 4)
2690 pSMBr->resp.ByteCount))) {
2692 if (pSMBr->resp.hdr.WordCount == 4) {
2693 bcc_ptr += blob_len;
2694 cFYI(1, ("Security Blob Length %d",
2698 cFYI(1, ("NTLMSSP Challenge rcvd"));
2700 memcpy(ses->server->cryptKey,
2701 SecurityBlob2->Challenge,
2702 CIFS_CRYPTO_KEY_SIZE);
2703 if (SecurityBlob2->NegotiateFlags &
2704 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2705 *pNTLMv2_flag = TRUE;
2707 if ((SecurityBlob2->NegotiateFlags &
2708 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2709 || (sign_CIFS_PDUs > 1))
2710 ses->server->secMode |=
2711 SECMODE_SIGN_REQUIRED;
2712 if ((SecurityBlob2->NegotiateFlags &
2713 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2714 ses->server->secMode |=
2715 SECMODE_SIGN_ENABLED;
2717 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2718 if ((long) (bcc_ptr) % 2) {
2720 (BCC(smb_buffer_response)
2722 /* Must word align unicode strings */
2727 (smb_buffer_response) / 2;
2730 UniStrnlen((wchar_t *) bcc_ptr,
2731 remaining_words - 1);
2732 /* We look for obvious messed up bcc or strings in response so we do not go off
2733 the end since (at least) WIN2K and Windows XP have a major bug in not null
2734 terminating last Unicode string in response */
2736 kfree(ses->serverOS);
2738 kzalloc(2 * (len + 1), GFP_KERNEL);
2739 cifs_strfromUCS_le(ses->serverOS,
2743 bcc_ptr += 2 * (len + 1);
2744 remaining_words -= len + 1;
2745 ses->serverOS[2 * len] = 0;
2746 ses->serverOS[1 + (2 * len)] = 0;
2747 if (remaining_words > 0) {
2748 len = UniStrnlen((wchar_t *)
2752 kfree(ses->serverNOS);
2754 kzalloc(2 * (len + 1),
2756 cifs_strfromUCS_le(ses->
2762 bcc_ptr += 2 * (len + 1);
2763 ses->serverNOS[2 * len] = 0;
2766 remaining_words -= len + 1;
2767 if (remaining_words > 0) {
2768 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2769 /* last string not always null terminated
2770 (for e.g. for Windows XP & 2000) */
2771 kfree(ses->serverDomain);
2783 ses->serverDomain[2*len]
2788 } /* else no more room so create dummy domain string */
2790 kfree(ses->serverDomain);
2795 } else { /* no room so create dummy domain and NOS string */
2796 kfree(ses->serverDomain);
2798 kzalloc(2, GFP_KERNEL);
2799 kfree(ses->serverNOS);
2801 kzalloc(2, GFP_KERNEL);
2803 } else { /* ASCII */
2804 len = strnlen(bcc_ptr, 1024);
2805 if (((long) bcc_ptr + len) - (long)
2806 pByteArea(smb_buffer_response)
2807 <= BCC(smb_buffer_response)) {
2809 kfree(ses->serverOS);
2813 strncpy(ses->serverOS,
2817 bcc_ptr[0] = 0; /* null terminate string */
2820 len = strnlen(bcc_ptr, 1024);
2821 kfree(ses->serverNOS);
2825 strncpy(ses->serverNOS, bcc_ptr, len);
2830 len = strnlen(bcc_ptr, 1024);
2831 kfree(ses->serverDomain);
2835 strncpy(ses->serverDomain,
2842 ("field of length %d "
2843 "extends beyond end of smb",
2847 cERROR(1, ("Security Blob Length extends beyond"
2851 cERROR(1, ("No session structure passed in."));
2855 (" Invalid Word count %d:",
2856 smb_buffer_response->WordCount));
2861 cifs_buf_release(smb_buffer);
2866 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2867 char *ntlm_session_key, int ntlmv2_flag,
2868 const struct nls_table *nls_codepage)
2870 struct smb_hdr *smb_buffer;
2871 struct smb_hdr *smb_buffer_response;
2872 SESSION_SETUP_ANDX *pSMB;
2873 SESSION_SETUP_ANDX *pSMBr;
2878 int remaining_words = 0;
2879 int bytes_returned = 0;
2881 int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
2882 PAUTHENTICATE_MESSAGE SecurityBlob;
2883 __u32 negotiate_flags, capabilities;
2886 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2889 user = ses->userName;
2890 domain = ses->domainName;
2891 smb_buffer = cifs_buf_get();
2892 if (smb_buffer == NULL) {
2895 smb_buffer_response = smb_buffer;
2896 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2897 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2899 /* send SMBsessionSetup here */
2900 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2901 NULL /* no tCon exists yet */ , 12 /* wct */ );
2903 smb_buffer->Mid = GetNextMid(ses->server);
2904 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2905 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2906 pSMB->req.AndXCommand = 0xFF;
2907 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2908 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2910 pSMB->req.hdr.Uid = ses->Suid;
2912 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2913 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2915 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2916 CAP_EXTENDED_SECURITY;
2917 if (ses->capabilities & CAP_UNICODE) {
2918 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2919 capabilities |= CAP_UNICODE;
2921 if (ses->capabilities & CAP_STATUS32) {
2922 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2923 capabilities |= CAP_STATUS32;
2925 if (ses->capabilities & CAP_DFS) {
2926 smb_buffer->Flags2 |= SMBFLG2_DFS;
2927 capabilities |= CAP_DFS;
2929 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2931 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2932 SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
2933 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2934 SecurityBlob->MessageType = NtLmAuthenticate;
2935 bcc_ptr += SecurityBlobLength;
2937 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
2938 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
2939 0x80000000 | NTLMSSP_NEGOTIATE_128;
2941 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
2943 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2945 /* setup pointers to domain name and workstation name */
2947 SecurityBlob->WorkstationName.Buffer = 0;
2948 SecurityBlob->WorkstationName.Length = 0;
2949 SecurityBlob->WorkstationName.MaximumLength = 0;
2950 SecurityBlob->SessionKey.Length = 0;
2951 SecurityBlob->SessionKey.MaximumLength = 0;
2952 SecurityBlob->SessionKey.Buffer = 0;
2954 SecurityBlob->LmChallengeResponse.Length = 0;
2955 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
2956 SecurityBlob->LmChallengeResponse.Buffer = 0;
2958 SecurityBlob->NtChallengeResponse.Length =
2959 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2960 SecurityBlob->NtChallengeResponse.MaximumLength =
2961 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2962 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
2963 SecurityBlob->NtChallengeResponse.Buffer =
2964 cpu_to_le32(SecurityBlobLength);
2965 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
2966 bcc_ptr += CIFS_SESS_KEY_SIZE;
2968 if (ses->capabilities & CAP_UNICODE) {
2969 if (domain == NULL) {
2970 SecurityBlob->DomainName.Buffer = 0;
2971 SecurityBlob->DomainName.Length = 0;
2972 SecurityBlob->DomainName.MaximumLength = 0;
2974 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2977 SecurityBlob->DomainName.MaximumLength =
2979 SecurityBlob->DomainName.Buffer =
2980 cpu_to_le32(SecurityBlobLength);
2982 SecurityBlobLength += ln;
2983 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
2986 SecurityBlob->UserName.Buffer = 0;
2987 SecurityBlob->UserName.Length = 0;
2988 SecurityBlob->UserName.MaximumLength = 0;
2990 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
2993 SecurityBlob->UserName.MaximumLength =
2995 SecurityBlob->UserName.Buffer =
2996 cpu_to_le32(SecurityBlobLength);
2998 SecurityBlobLength += ln;
2999 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3002 /* SecurityBlob->WorkstationName.Length =
3003 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3004 SecurityBlob->WorkstationName.Length *= 2;
3005 SecurityBlob->WorkstationName.MaximumLength =
3006 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3007 SecurityBlob->WorkstationName.Buffer =
3008 cpu_to_le32(SecurityBlobLength);
3009 bcc_ptr += SecurityBlob->WorkstationName.Length;
3010 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3011 SecurityBlob->WorkstationName.Length =
3012 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3014 if ((long) bcc_ptr % 2) {
3019 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3021 bcc_ptr += 2 * bytes_returned;
3023 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3025 bcc_ptr += 2 * bytes_returned;
3026 bcc_ptr += 2; /* null term version string */
3028 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3030 bcc_ptr += 2 * bytes_returned;
3033 bcc_ptr += 2; /* null terminate network opsys string */
3036 bcc_ptr += 2; /* null domain */
3037 } else { /* ASCII */
3038 if (domain == NULL) {
3039 SecurityBlob->DomainName.Buffer = 0;
3040 SecurityBlob->DomainName.Length = 0;
3041 SecurityBlob->DomainName.MaximumLength = 0;
3044 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3045 strncpy(bcc_ptr, domain, 63);
3046 ln = strnlen(domain, 64);
3047 SecurityBlob->DomainName.MaximumLength =
3049 SecurityBlob->DomainName.Buffer =
3050 cpu_to_le32(SecurityBlobLength);
3052 SecurityBlobLength += ln;
3053 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3056 SecurityBlob->UserName.Buffer = 0;
3057 SecurityBlob->UserName.Length = 0;
3058 SecurityBlob->UserName.MaximumLength = 0;
3061 strncpy(bcc_ptr, user, 63);
3062 ln = strnlen(user, 64);
3063 SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
3064 SecurityBlob->UserName.Buffer =
3065 cpu_to_le32(SecurityBlobLength);
3067 SecurityBlobLength += ln;
3068 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3070 /* BB fill in our workstation name if known BB */
3072 strcpy(bcc_ptr, "Linux version ");
3073 bcc_ptr += strlen("Linux version ");
3074 strcpy(bcc_ptr, utsname()->release);
3075 bcc_ptr += strlen(utsname()->release) + 1;
3076 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3077 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3078 bcc_ptr++; /* null domain */
3081 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3082 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3083 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3084 smb_buffer->smb_buf_length += count;
3085 pSMB->req.ByteCount = cpu_to_le16(count);
3087 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3088 &bytes_returned, 1);
3090 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
3091 } else if ((smb_buffer_response->WordCount == 3)
3092 || (smb_buffer_response->WordCount == 4)) {
3093 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3095 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3096 if (action & GUEST_LOGIN)
3097 cFYI(1, (" Guest login")); /* BB Should we set anything
3098 in SesInfo struct ? */
3099 /* if (SecurityBlob2->MessageType != NtLm??) {
3100 cFYI("Unexpected message type on auth response is %d"));
3105 ("Check challenge UID %d vs auth response UID %d",
3106 ses->Suid, smb_buffer_response->Uid));
3107 /* UID left in wire format */
3108 ses->Suid = smb_buffer_response->Uid;
3109 bcc_ptr = pByteArea(smb_buffer_response);
3110 /* response can have either 3 or 4 word count - Samba sends 3 */
3111 if ((pSMBr->resp.hdr.WordCount == 3)
3112 || ((pSMBr->resp.hdr.WordCount == 4)
3114 pSMBr->resp.ByteCount))) {
3115 if (pSMBr->resp.hdr.WordCount == 4) {
3119 ("Security Blob Length %d ",
3124 ("NTLMSSP response to Authenticate "));
3126 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3127 if ((long) (bcc_ptr) % 2) {
3129 (BCC(smb_buffer_response)
3131 bcc_ptr++; /* Unicode strings must be word aligned */
3133 remaining_words = BCC(smb_buffer_response) / 2;
3135 len = UniStrnlen((wchar_t *) bcc_ptr,
3136 remaining_words - 1);
3137 /* We look for obvious messed up bcc or strings in response so we do not go off
3138 the end since (at least) WIN2K and Windows XP have a major bug in not null
3139 terminating last Unicode string in response */
3141 kfree(ses->serverOS);
3143 kzalloc(2 * (len + 1), GFP_KERNEL);
3144 cifs_strfromUCS_le(ses->serverOS,
3148 bcc_ptr += 2 * (len + 1);
3149 remaining_words -= len + 1;
3150 ses->serverOS[2 * len] = 0;
3151 ses->serverOS[1 + (2 * len)] = 0;
3152 if (remaining_words > 0) {
3153 len = UniStrnlen((wchar_t *)
3157 kfree(ses->serverNOS);
3159 kzalloc(2 * (len + 1),
3161 cifs_strfromUCS_le(ses->
3167 bcc_ptr += 2 * (len + 1);
3168 ses->serverNOS[2 * len] = 0;
3169 ses->serverNOS[1+(2*len)] = 0;
3170 remaining_words -= len + 1;
3171 if (remaining_words > 0) {
3172 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3173 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3174 if (ses->serverDomain)
3175 kfree(ses->serverDomain);
3200 } /* else no more room so create dummy domain string */
3202 if (ses->serverDomain)
3203 kfree(ses->serverDomain);
3204 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3206 } else { /* no room so create dummy domain and NOS string */
3207 if (ses->serverDomain)
3208 kfree(ses->serverDomain);
3209 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3210 kfree(ses->serverNOS);
3211 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3213 } else { /* ASCII */
3214 len = strnlen(bcc_ptr, 1024);
3215 if (((long) bcc_ptr + len) -
3216 (long) pByteArea(smb_buffer_response)
3217 <= BCC(smb_buffer_response)) {
3219 kfree(ses->serverOS);
3220 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
3221 strncpy(ses->serverOS,bcc_ptr, len);
3224 bcc_ptr[0] = 0; /* null terminate the string */
3227 len = strnlen(bcc_ptr, 1024);
3228 kfree(ses->serverNOS);
3229 ses->serverNOS = kzalloc(len+1,
3231 strncpy(ses->serverNOS,
3237 len = strnlen(bcc_ptr, 1024);
3238 if (ses->serverDomain)
3239 kfree(ses->serverDomain);
3243 strncpy(ses->serverDomain,
3250 ("field of length %d "
3251 "extends beyond end of smb ",
3256 (" Security Blob extends beyond end "
3260 cERROR(1, ("No session structure passed in."));
3264 (" Invalid Word count %d: ",
3265 smb_buffer_response->WordCount));
3270 cifs_buf_release(smb_buffer);
3276 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3277 const char *tree, struct cifsTconInfo *tcon,
3278 const struct nls_table *nls_codepage)
3280 struct smb_hdr *smb_buffer;
3281 struct smb_hdr *smb_buffer_response;
3284 unsigned char *bcc_ptr;
3292 smb_buffer = cifs_buf_get();
3293 if (smb_buffer == NULL) {
3296 smb_buffer_response = smb_buffer;
3298 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3299 NULL /*no tid */ , 4 /*wct */ );
3301 smb_buffer->Mid = GetNextMid(ses->server);
3302 smb_buffer->Uid = ses->Suid;
3303 pSMB = (TCONX_REQ *) smb_buffer;
3304 pSMBr = (TCONX_RSP *) smb_buffer_response;
3306 pSMB->AndXCommand = 0xFF;
3307 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3308 bcc_ptr = &pSMB->Password[0];
3309 if ((ses->server->secMode) & SECMODE_USER) {
3310 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3311 *bcc_ptr = 0; /* password is null byte */
3312 bcc_ptr++; /* skip password */
3313 /* already aligned so no need to do it below */
3315 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3316 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3317 specified as required (when that support is added to
3318 the vfs in the future) as only NTLM or the much
3319 weaker LANMAN (which we do not send by default) is accepted
3320 by Samba (not sure whether other servers allow
3321 NTLMv2 password here) */
3322 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3323 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3324 (ses->server->secType == LANMAN))
3325 calc_lanman_hash(ses, bcc_ptr);
3327 #endif /* CIFS_WEAK_PW_HASH */
3328 SMBNTencrypt(ses->password,
3329 ses->server->cryptKey,
3332 bcc_ptr += CIFS_SESS_KEY_SIZE;
3333 if (ses->capabilities & CAP_UNICODE) {
3334 /* must align unicode strings */
3335 *bcc_ptr = 0; /* null byte password */
3340 if (ses->server->secMode &
3341 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3342 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3344 if (ses->capabilities & CAP_STATUS32) {
3345 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3347 if (ses->capabilities & CAP_DFS) {
3348 smb_buffer->Flags2 |= SMBFLG2_DFS;
3350 if (ses->capabilities & CAP_UNICODE) {
3351 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3353 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3354 6 /* max utf8 char length in bytes */ *
3355 (/* server len*/ + 256 /* share len */), nls_codepage);
3356 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3357 bcc_ptr += 2; /* skip trailing null */
3358 } else { /* ASCII */
3359 strcpy(bcc_ptr, tree);
3360 bcc_ptr += strlen(tree) + 1;
3362 strcpy(bcc_ptr, "?????");
3363 bcc_ptr += strlen("?????");
3365 count = bcc_ptr - &pSMB->Password[0];
3366 pSMB->hdr.smb_buf_length += count;
3367 pSMB->ByteCount = cpu_to_le16(count);
3369 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
3371 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3372 /* above now done in SendReceive */
3373 if ((rc == 0) && (tcon != NULL)) {
3374 tcon->tidStatus = CifsGood;
3375 tcon->tid = smb_buffer_response->Tid;
3376 bcc_ptr = pByteArea(smb_buffer_response);
3377 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3378 /* skip service field (NB: this field is always ASCII) */
3379 bcc_ptr += length + 1;
3380 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3381 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3382 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3383 if ((bcc_ptr + (2 * length)) -
3384 pByteArea(smb_buffer_response) <=
3385 BCC(smb_buffer_response)) {
3386 kfree(tcon->nativeFileSystem);
3387 tcon->nativeFileSystem =
3388 kzalloc(length + 2, GFP_KERNEL);
3389 if (tcon->nativeFileSystem)
3391 tcon->nativeFileSystem,
3393 length, nls_codepage);
3394 bcc_ptr += 2 * length;
3395 bcc_ptr[0] = 0; /* null terminate the string */
3399 /* else do not bother copying these information fields*/
3401 length = strnlen(bcc_ptr, 1024);
3402 if ((bcc_ptr + length) -
3403 pByteArea(smb_buffer_response) <=
3404 BCC(smb_buffer_response)) {
3405 kfree(tcon->nativeFileSystem);
3406 tcon->nativeFileSystem =
3407 kzalloc(length + 1, GFP_KERNEL);
3408 if (tcon->nativeFileSystem)
3409 strncpy(tcon->nativeFileSystem, bcc_ptr,
3412 /* else do not bother copying these information fields*/
3414 if ((smb_buffer_response->WordCount == 3) ||
3415 (smb_buffer_response->WordCount == 7))
3416 /* field is in same location */
3417 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3420 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3421 } else if ((rc == 0) && tcon == NULL) {
3422 /* all we need to save for IPC$ connection */
3423 ses->ipc_tid = smb_buffer_response->Tid;
3427 cifs_buf_release(smb_buffer);
3432 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3436 struct cifsSesInfo *ses = NULL;
3437 struct task_struct *cifsd_task;
3442 if (cifs_sb->tcon) {
3443 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3444 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3449 tconInfoFree(cifs_sb->tcon);
3450 if ((ses) && (ses->server)) {
3451 /* save off task so we do not refer to ses later */
3452 cifsd_task = ses->server->tsk;
3453 cFYI(1, ("About to do SMBLogoff "));
3454 rc = CIFSSMBLogoff(xid, ses);
3458 } else if (rc == -ESHUTDOWN) {
3459 cFYI(1, ("Waking up socket by sending signal"));
3461 force_sig(SIGKILL, cifsd_task);
3462 kthread_stop(cifsd_task);
3465 } /* else - we have an smb session
3466 left on this socket do not kill cifsd */
3468 cFYI(1, ("No session or bad tcon"));
3471 cifs_sb->tcon = NULL;
3472 tmp = cifs_sb->prepath;
3473 cifs_sb->prepathlen = 0;
3474 cifs_sb->prepath = NULL;
3477 schedule_timeout_interruptible(msecs_to_jiffies(500));
3482 return rc; /* BB check if we should always return zero here */
3485 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3486 struct nls_table *nls_info)
3489 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3490 int ntlmv2_flag = FALSE;
3493 /* what if server changes its buffer size after dropping the session? */
3494 if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
3495 rc = CIFSSMBNegotiate(xid, pSesInfo);
3496 if (rc == -EAGAIN) /* retry only once on 1st time connection */ {
3497 rc = CIFSSMBNegotiate(xid, pSesInfo);
3502 spin_lock(&GlobalMid_Lock);
3503 if (pSesInfo->server->tcpStatus != CifsExiting)
3504 pSesInfo->server->tcpStatus = CifsGood;
3507 spin_unlock(&GlobalMid_Lock);
3513 pSesInfo->flags = 0;
3514 pSesInfo->capabilities = pSesInfo->server->capabilities;
3515 if (linuxExtEnabled == 0)
3516 pSesInfo->capabilities &= (~CAP_UNIX);
3517 /* pSesInfo->sequence_number = 0;*/
3519 ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3520 pSesInfo->server->secMode,
3521 pSesInfo->server->capabilities,
3522 pSesInfo->server->timeAdj));
3523 if (experimEnabled < 2)
3524 rc = CIFS_SessSetup(xid, pSesInfo,
3525 first_time, nls_info);
3526 else if (extended_security
3527 && (pSesInfo->capabilities
3528 & CAP_EXTENDED_SECURITY)
3529 && (pSesInfo->server->secType == NTLMSSP)) {
3531 } else if (extended_security
3532 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3533 && (pSesInfo->server->secType == RawNTLMSSP)) {
3534 cFYI(1, ("NTLMSSP sesssetup"));
3535 rc = CIFSNTLMSSPNegotiateSessSetup(xid,
3542 cFYI(1, ("more secure NTLM ver2 hash"));
3543 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3548 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
3550 CalcNTLMv2_response(pSesInfo,
3553 cifs_calculate_ntlmv2_mac_key(
3554 pSesInfo->server->mac_signing_key,
3555 response, ntlm_session_key,*/
3557 /* BB Put dummy sig in SessSetup PDU? */
3564 SMBNTencrypt(pSesInfo->password,
3565 pSesInfo->server->cryptKey,
3569 cifs_calculate_mac_key(
3570 &pSesInfo->server->mac_signing_key,
3572 pSesInfo->password);
3574 /* for better security the weaker lanman hash not sent
3575 in AuthSessSetup so we no longer calculate it */
3577 rc = CIFSNTLMSSPAuthSessSetup(xid,
3583 } else { /* old style NTLM 0.12 session setup */
3584 SMBNTencrypt(pSesInfo->password,
3585 pSesInfo->server->cryptKey,
3589 cifs_calculate_mac_key(
3590 &pSesInfo->server->mac_signing_key,
3591 ntlm_session_key, pSesInfo->password);
3593 rc = CIFSSessSetup(xid, pSesInfo,
3594 ntlm_session_key, nls_info);
3597 cERROR(1, ("Send error in SessSetup = %d", rc));
3599 cFYI(1, ("CIFS Session Established successfully"));
3600 pSesInfo->status = CifsGood;