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 if (vol_info == NULL)
1746 cFYI(1, ("resetting capabilities failed"));
1748 cERROR(1, ("Negotiating Unix capabilities "
1749 "with the server failed. Consider "
1750 "mounting with the Unix Extensions\n"
1751 "disabled, if problems are found, "
1752 "by specifying the nounix mount "
1760 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1761 char *mount_data, const char *devname)
1765 int address_type = AF_INET;
1766 struct socket *csocket = NULL;
1767 struct sockaddr_in sin_server;
1768 struct sockaddr_in6 sin_server6;
1769 struct smb_vol volume_info;
1770 struct cifsSesInfo *pSesInfo = NULL;
1771 struct cifsSesInfo *existingCifsSes = NULL;
1772 struct cifsTconInfo *tcon = NULL;
1773 struct TCP_Server_Info *srvTcp = NULL;
1777 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1779 memset(&volume_info, 0, sizeof(struct smb_vol));
1780 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1781 kfree(volume_info.UNC);
1782 kfree(volume_info.password);
1783 kfree(volume_info.prepath);
1788 if (volume_info.nullauth) {
1789 cFYI(1, ("null user"));
1790 volume_info.username = NULL;
1791 } else if (volume_info.username) {
1792 /* BB fixme parse for domain name here */
1793 cFYI(1, ("Username: %s", volume_info.username));
1795 cifserror("No username specified");
1796 /* In userspace mount helper we can get user name from alternate
1797 locations such as env variables and files on disk */
1798 kfree(volume_info.UNC);
1799 kfree(volume_info.password);
1800 kfree(volume_info.prepath);
1805 if (volume_info.UNCip && volume_info.UNC) {
1806 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
1807 &sin_server.sin_addr.s_addr);
1810 /* not ipv4 address, try ipv6 */
1811 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
1812 &sin_server6.sin6_addr.in6_u);
1814 address_type = AF_INET6;
1816 address_type = AF_INET;
1820 /* we failed translating address */
1821 kfree(volume_info.UNC);
1822 kfree(volume_info.password);
1823 kfree(volume_info.prepath);
1828 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1831 } else if (volume_info.UNCip) {
1832 /* BB using ip addr as server name to connect to the
1834 cERROR(1, ("Connecting to DFS root not implemented yet"));
1835 kfree(volume_info.UNC);
1836 kfree(volume_info.password);
1837 kfree(volume_info.prepath);
1840 } else /* which servers DFS root would we conect to */ {
1842 ("CIFS mount error: No UNC path (e.g. -o "
1843 "unc=//192.168.1.100/public) specified"));
1844 kfree(volume_info.UNC);
1845 kfree(volume_info.password);
1846 kfree(volume_info.prepath);
1851 /* this is needed for ASCII cp to Unicode converts */
1852 if (volume_info.iocharset == NULL) {
1853 cifs_sb->local_nls = load_nls_default();
1854 /* load_nls_default can not return null */
1856 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1857 if (cifs_sb->local_nls == NULL) {
1858 cERROR(1, ("CIFS mount error: iocharset %s not found",
1859 volume_info.iocharset));
1860 kfree(volume_info.UNC);
1861 kfree(volume_info.password);
1862 kfree(volume_info.prepath);
1868 if (address_type == AF_INET)
1869 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1870 NULL /* no ipv6 addr */,
1871 volume_info.username, &srvTcp);
1872 else if (address_type == AF_INET6) {
1873 cFYI(1, ("looking for ipv6 address"));
1874 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1875 &sin_server6.sin6_addr,
1876 volume_info.username, &srvTcp);
1878 kfree(volume_info.UNC);
1879 kfree(volume_info.password);
1880 kfree(volume_info.prepath);
1886 cFYI(1, ("Existing tcp session with server found"));
1887 } else { /* create socket */
1888 if (volume_info.port)
1889 sin_server.sin_port = htons(volume_info.port);
1891 sin_server.sin_port = 0;
1892 if (address_type == AF_INET6) {
1893 cFYI(1, ("attempting ipv6 connect"));
1894 /* BB should we allow ipv6 on port 139? */
1895 /* other OS never observed in Wild doing 139 with v6 */
1896 rc = ipv6_connect(&sin_server6, &csocket);
1898 rc = ipv4_connect(&sin_server, &csocket,
1899 volume_info.source_rfc1001_name,
1900 volume_info.target_rfc1001_name);
1902 cERROR(1, ("Error connecting to IPv4 socket. "
1903 "Aborting operation"));
1904 if (csocket != NULL)
1905 sock_release(csocket);
1906 kfree(volume_info.UNC);
1907 kfree(volume_info.password);
1908 kfree(volume_info.prepath);
1913 srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
1914 if (srvTcp == NULL) {
1916 sock_release(csocket);
1917 kfree(volume_info.UNC);
1918 kfree(volume_info.password);
1919 kfree(volume_info.prepath);
1923 memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
1924 memcpy(&srvTcp->addr.sockAddr, &sin_server,
1925 sizeof (struct sockaddr_in));
1926 atomic_set(&srvTcp->inFlight, 0);
1927 /* BB Add code for ipv6 case too */
1928 srvTcp->ssocket = csocket;
1929 srvTcp->protocolType = IPV4;
1930 init_waitqueue_head(&srvTcp->response_q);
1931 init_waitqueue_head(&srvTcp->request_q);
1932 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
1933 /* at this point we are the only ones with the pointer
1934 to the struct since the kernel thread not created yet
1935 so no need to spinlock this init of tcpStatus */
1936 srvTcp->tcpStatus = CifsNew;
1937 init_MUTEX(&srvTcp->tcpSem);
1938 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
1939 if ( IS_ERR(srvTcp->tsk) ) {
1940 rc = PTR_ERR(srvTcp->tsk);
1941 cERROR(1, ("error %d create cifsd thread", rc));
1943 sock_release(csocket);
1944 kfree(volume_info.UNC);
1945 kfree(volume_info.password);
1946 kfree(volume_info.prepath);
1950 wait_for_completion(&cifsd_complete);
1952 memcpy(srvTcp->workstation_RFC1001_name,
1953 volume_info.source_rfc1001_name, 16);
1954 memcpy(srvTcp->server_RFC1001_name,
1955 volume_info.target_rfc1001_name, 16);
1956 srvTcp->sequence_number = 0;
1960 if (existingCifsSes) {
1961 pSesInfo = existingCifsSes;
1962 cFYI(1, ("Existing smb sess found"));
1963 kfree(volume_info.password);
1964 /* volume_info.UNC freed at end of function */
1966 cFYI(1, ("Existing smb sess not found"));
1967 pSesInfo = sesInfoAlloc();
1968 if (pSesInfo == NULL)
1971 pSesInfo->server = srvTcp;
1972 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
1973 NIPQUAD(sin_server.sin_addr.s_addr));
1977 /* volume_info.password freed at unmount */
1978 if (volume_info.password)
1979 pSesInfo->password = volume_info.password;
1980 if (volume_info.username)
1981 strncpy(pSesInfo->userName,
1982 volume_info.username,
1984 if (volume_info.domainname) {
1985 int len = strlen(volume_info.domainname);
1986 pSesInfo->domainName =
1987 kmalloc(len + 1, GFP_KERNEL);
1988 if (pSesInfo->domainName)
1989 strcpy(pSesInfo->domainName,
1990 volume_info.domainname);
1992 pSesInfo->linux_uid = volume_info.linux_uid;
1993 pSesInfo->overrideSecFlg = volume_info.secFlg;
1994 down(&pSesInfo->sesSem);
1995 /* BB FIXME need to pass vol->secFlgs BB */
1996 rc = cifs_setup_session(xid, pSesInfo,
1997 cifs_sb->local_nls);
1998 up(&pSesInfo->sesSem);
2000 atomic_inc(&srvTcp->socketUseCount);
2002 kfree(volume_info.password);
2005 /* search for existing tcon to this server share */
2007 if (volume_info.rsize > CIFSMaxBufSize) {
2008 cERROR(1, ("rsize %d too large, using MaxBufSize",
2009 volume_info.rsize));
2010 cifs_sb->rsize = CIFSMaxBufSize;
2011 } else if ((volume_info.rsize) &&
2012 (volume_info.rsize <= CIFSMaxBufSize))
2013 cifs_sb->rsize = volume_info.rsize;
2015 cifs_sb->rsize = CIFSMaxBufSize;
2017 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2018 cERROR(1, ("wsize %d too large, using 4096 instead",
2019 volume_info.wsize));
2020 cifs_sb->wsize = 4096;
2021 } else if (volume_info.wsize)
2022 cifs_sb->wsize = volume_info.wsize;
2025 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2027 /* old default of CIFSMaxBufSize was too small now
2028 that SMB Write2 can send multiple pages in kvec.
2029 RFC1001 does not describe what happens when frame
2030 bigger than 128K is sent so use that as max in
2031 conjunction with 52K kvec constraint on arch with 4K
2034 if (cifs_sb->rsize < 2048) {
2035 cifs_sb->rsize = 2048;
2036 /* Windows ME may prefer this */
2037 cFYI(1, ("readsize set to minimum: 2048"));
2039 /* calculate prepath */
2040 cifs_sb->prepath = volume_info.prepath;
2041 if (cifs_sb->prepath) {
2042 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2043 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
2044 volume_info.prepath = NULL;
2046 cifs_sb->prepathlen = 0;
2047 cifs_sb->mnt_uid = volume_info.linux_uid;
2048 cifs_sb->mnt_gid = volume_info.linux_gid;
2049 cifs_sb->mnt_file_mode = volume_info.file_mode;
2050 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
2051 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2052 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2054 if (volume_info.noperm)
2055 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2056 if (volume_info.setuids)
2057 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2058 if (volume_info.server_ino)
2059 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2060 if (volume_info.remap)
2061 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2062 if (volume_info.no_xattr)
2063 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2064 if (volume_info.sfu_emul)
2065 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2066 if (volume_info.nobrl)
2067 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2068 if (volume_info.cifs_acl)
2069 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2070 if (volume_info.override_uid)
2071 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2072 if (volume_info.override_gid)
2073 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2074 if (volume_info.direct_io) {
2075 cFYI(1, ("mounting share using direct i/o"));
2076 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2080 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
2081 volume_info.username);
2083 cFYI(1, ("Found match on UNC path"));
2084 /* we can have only one retry value for a connection
2085 to a share so for resources mounted more than once
2086 to the same server share the last value passed in
2087 for the retry flag is used */
2088 tcon->retry = volume_info.retry;
2089 tcon->nocase = volume_info.nocase;
2091 tcon = tconInfoAlloc();
2095 /* check for null share name ie connecting to
2098 /* BB check if this works for exactly length
2100 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2101 && (strchr(volume_info.UNC + 3, '/') ==
2103 rc = connect_to_dfs_path(xid, pSesInfo,
2104 "", cifs_sb->local_nls,
2105 cifs_sb->mnt_cifs_flags &
2106 CIFS_MOUNT_MAP_SPECIAL_CHR);
2107 kfree(volume_info.UNC);
2111 /* BB Do we need to wrap sesSem around
2112 * this TCon call and Unix SetFS as
2113 * we do on SessSetup and reconnect? */
2114 rc = CIFSTCon(xid, pSesInfo,
2116 tcon, cifs_sb->local_nls);
2117 cFYI(1, ("CIFS Tcon rc = %d", rc));
2120 atomic_inc(&pSesInfo->inUse);
2121 tcon->retry = volume_info.retry;
2122 tcon->nocase = volume_info.nocase;
2128 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2129 sb->s_maxbytes = (u64) 1 << 63;
2131 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2134 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2135 sb->s_time_gran = 100;
2137 /* on error free sesinfo and tcon struct if needed */
2139 /* if session setup failed, use count is zero but
2140 we still need to free cifsd thread */
2141 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2142 spin_lock(&GlobalMid_Lock);
2143 srvTcp->tcpStatus = CifsExiting;
2144 spin_unlock(&GlobalMid_Lock);
2146 struct task_struct *tsk;
2147 /* If we could verify that kthread_stop would
2148 always wake up processes blocked in
2149 tcp in recv_mesg then we could remove the
2151 force_sig(SIGKILL, srvTcp->tsk);
2157 /* If find_unc succeeded then rc == 0 so we can not end */
2158 if (tcon) /* up accidently freeing someone elses tcon struct */
2160 if (existingCifsSes == NULL) {
2162 if ((pSesInfo->server) &&
2163 (pSesInfo->status == CifsGood)) {
2165 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2166 /* if the socketUseCount is now zero */
2167 if ((temp_rc == -ESHUTDOWN) &&
2168 (pSesInfo->server) &&
2169 (pSesInfo->server->tsk)) {
2170 struct task_struct *tsk;
2172 pSesInfo->server->tsk);
2173 tsk = pSesInfo->server->tsk;
2178 cFYI(1, ("No session or bad tcon"));
2179 sesInfoFree(pSesInfo);
2180 /* pSesInfo = NULL; */
2184 atomic_inc(&tcon->useCount);
2185 cifs_sb->tcon = tcon;
2186 tcon->ses = pSesInfo;
2188 /* do not care if following two calls succeed - informational */
2189 CIFSSMBQFSDeviceInfo(xid, tcon);
2190 CIFSSMBQFSAttributeInfo(xid, tcon);
2192 /* tell server which Unix caps we support */
2193 if (tcon->ses->capabilities & CAP_UNIX)
2194 /* reset of caps checks mount to see if unix extensions
2195 disabled for just this mount */
2196 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2198 tcon->unix_ext = 0; /* server does not support them */
2200 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2201 cifs_sb->rsize = 1024 * 127;
2202 #ifdef CONFIG_CIFS_DEBUG2
2203 cFYI(1, ("no very large read support, rsize now 127K"));
2206 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2207 cifs_sb->wsize = min(cifs_sb->wsize,
2208 (tcon->ses->server->maxBuf -
2209 MAX_CIFS_HDR_SIZE));
2210 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2211 cifs_sb->rsize = min(cifs_sb->rsize,
2212 (tcon->ses->server->maxBuf -
2213 MAX_CIFS_HDR_SIZE));
2216 /* volume_info.password is freed above when existing session found
2217 (in which case it is not needed anymore) but when new sesion is created
2218 the password ptr is put in the new session structure (in which case the
2219 password will be freed at unmount time) */
2220 kfree(volume_info.UNC);
2221 kfree(volume_info.prepath);
2227 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2228 char session_key[CIFS_SESS_KEY_SIZE],
2229 const struct nls_table *nls_codepage)
2231 struct smb_hdr *smb_buffer;
2232 struct smb_hdr *smb_buffer_response;
2233 SESSION_SETUP_ANDX *pSMB;
2234 SESSION_SETUP_ANDX *pSMBr;
2239 int remaining_words = 0;
2240 int bytes_returned = 0;
2245 cFYI(1, ("In sesssetup"));
2248 user = ses->userName;
2249 domain = ses->domainName;
2250 smb_buffer = cifs_buf_get();
2251 if (smb_buffer == NULL) {
2254 smb_buffer_response = smb_buffer;
2255 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2257 /* send SMBsessionSetup here */
2258 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2259 NULL /* no tCon exists yet */ , 13 /* wct */ );
2261 smb_buffer->Mid = GetNextMid(ses->server);
2262 pSMB->req_no_secext.AndXCommand = 0xFF;
2263 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2264 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2266 if (ses->server->secMode &
2267 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2268 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2270 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2271 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2272 if (ses->capabilities & CAP_UNICODE) {
2273 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2274 capabilities |= CAP_UNICODE;
2276 if (ses->capabilities & CAP_STATUS32) {
2277 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2278 capabilities |= CAP_STATUS32;
2280 if (ses->capabilities & CAP_DFS) {
2281 smb_buffer->Flags2 |= SMBFLG2_DFS;
2282 capabilities |= CAP_DFS;
2284 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2286 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2287 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2289 pSMB->req_no_secext.CaseSensitivePasswordLength =
2290 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2291 bcc_ptr = pByteArea(smb_buffer);
2292 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2293 bcc_ptr += CIFS_SESS_KEY_SIZE;
2294 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2295 bcc_ptr += CIFS_SESS_KEY_SIZE;
2297 if (ses->capabilities & CAP_UNICODE) {
2298 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2303 bytes_returned = 0; /* skip null user */
2306 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2308 /* convert number of 16 bit words to bytes */
2309 bcc_ptr += 2 * bytes_returned;
2310 bcc_ptr += 2; /* trailing null */
2313 cifs_strtoUCS((__le16 *) bcc_ptr,
2314 "CIFS_LINUX_DOM", 32, nls_codepage);
2317 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2319 bcc_ptr += 2 * bytes_returned;
2322 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2324 bcc_ptr += 2 * bytes_returned;
2326 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2328 bcc_ptr += 2 * bytes_returned;
2331 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2333 bcc_ptr += 2 * bytes_returned;
2337 strncpy(bcc_ptr, user, 200);
2338 bcc_ptr += strnlen(user, 200);
2342 if (domain == NULL) {
2343 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2344 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2346 strncpy(bcc_ptr, domain, 64);
2347 bcc_ptr += strnlen(domain, 64);
2351 strcpy(bcc_ptr, "Linux version ");
2352 bcc_ptr += strlen("Linux version ");
2353 strcpy(bcc_ptr, utsname()->release);
2354 bcc_ptr += strlen(utsname()->release) + 1;
2355 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2356 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2358 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2359 smb_buffer->smb_buf_length += count;
2360 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2362 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2363 &bytes_returned, 1);
2365 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2366 } else if ((smb_buffer_response->WordCount == 3)
2367 || (smb_buffer_response->WordCount == 4)) {
2368 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2369 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2370 if (action & GUEST_LOGIN)
2371 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2372 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2374 cFYI(1, ("UID = %d ", ses->Suid));
2375 /* response can have either 3 or 4 word count - Samba sends 3 */
2376 bcc_ptr = pByteArea(smb_buffer_response);
2377 if ((pSMBr->resp.hdr.WordCount == 3)
2378 || ((pSMBr->resp.hdr.WordCount == 4)
2379 && (blob_len < pSMBr->resp.ByteCount))) {
2380 if (pSMBr->resp.hdr.WordCount == 4)
2381 bcc_ptr += blob_len;
2383 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2384 if ((long) (bcc_ptr) % 2) {
2386 (BCC(smb_buffer_response) - 1) / 2;
2387 /* Unicode strings must be word
2392 BCC(smb_buffer_response) / 2;
2395 UniStrnlen((wchar_t *) bcc_ptr,
2396 remaining_words - 1);
2397 /* We look for obvious messed up bcc or strings in response so we do not go off
2398 the end since (at least) WIN2K and Windows XP have a major bug in not null
2399 terminating last Unicode string in response */
2401 kfree(ses->serverOS);
2402 ses->serverOS = kzalloc(2 * (len + 1),
2404 if (ses->serverOS == NULL)
2405 goto sesssetup_nomem;
2406 cifs_strfromUCS_le(ses->serverOS,
2409 bcc_ptr += 2 * (len + 1);
2410 remaining_words -= len + 1;
2411 ses->serverOS[2 * len] = 0;
2412 ses->serverOS[1 + (2 * len)] = 0;
2413 if (remaining_words > 0) {
2414 len = UniStrnlen((wchar_t *)bcc_ptr,
2416 kfree(ses->serverNOS);
2417 ses->serverNOS = kzalloc(2 * (len + 1),
2419 if (ses->serverNOS == NULL)
2420 goto sesssetup_nomem;
2421 cifs_strfromUCS_le(ses->serverNOS,
2424 bcc_ptr += 2 * (len + 1);
2425 ses->serverNOS[2 * len] = 0;
2426 ses->serverNOS[1 + (2 * len)] = 0;
2427 if (strncmp(ses->serverNOS,
2428 "NT LAN Manager 4", 16) == 0) {
2429 cFYI(1, ("NT4 server"));
2430 ses->flags |= CIFS_SES_NT4;
2432 remaining_words -= len + 1;
2433 if (remaining_words > 0) {
2434 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2435 /* last string is not always null terminated
2436 (for e.g. for Windows XP & 2000) */
2437 if (ses->serverDomain)
2438 kfree(ses->serverDomain);
2442 if (ses->serverDomain == NULL)
2443 goto sesssetup_nomem;
2444 cifs_strfromUCS_le(ses->serverDomain,
2447 bcc_ptr += 2 * (len + 1);
2448 ses->serverDomain[2*len] = 0;
2449 ses->serverDomain[1+(2*len)] = 0;
2450 } else { /* else no more room so create
2451 dummy domain string */
2452 if (ses->serverDomain)
2453 kfree(ses->serverDomain);
2455 kzalloc(2, GFP_KERNEL);
2457 } else { /* no room so create dummy domain
2460 /* if these kcallocs fail not much we
2461 can do, but better to not fail the
2463 kfree(ses->serverDomain);
2465 kzalloc(2, GFP_KERNEL);
2466 kfree(ses->serverNOS);
2468 kzalloc(2, GFP_KERNEL);
2470 } else { /* ASCII */
2471 len = strnlen(bcc_ptr, 1024);
2472 if (((long) bcc_ptr + len) - (long)
2473 pByteArea(smb_buffer_response)
2474 <= BCC(smb_buffer_response)) {
2475 kfree(ses->serverOS);
2476 ses->serverOS = kzalloc(len + 1,
2478 if (ses->serverOS == NULL)
2479 goto sesssetup_nomem;
2480 strncpy(ses->serverOS, bcc_ptr, len);
2483 /* null terminate the string */
2487 len = strnlen(bcc_ptr, 1024);
2488 kfree(ses->serverNOS);
2489 ses->serverNOS = kzalloc(len + 1,
2491 if (ses->serverNOS == NULL)
2492 goto sesssetup_nomem;
2493 strncpy(ses->serverNOS, bcc_ptr, len);
2498 len = strnlen(bcc_ptr, 1024);
2499 if (ses->serverDomain)
2500 kfree(ses->serverDomain);
2501 ses->serverDomain = kzalloc(len + 1,
2503 if (ses->serverDomain == NULL)
2504 goto sesssetup_nomem;
2505 strncpy(ses->serverDomain, bcc_ptr,
2512 ("Variable field of length %d "
2513 "extends beyond end of smb ",
2518 (" Security Blob Length extends beyond "
2523 (" Invalid Word count %d: ",
2524 smb_buffer_response->WordCount));
2527 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2528 since that could make reconnection harder, and
2529 reconnection might be needed to free memory */
2531 cifs_buf_release(smb_buffer);
2537 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2538 struct cifsSesInfo *ses, int *pNTLMv2_flag,
2539 const struct nls_table *nls_codepage)
2541 struct smb_hdr *smb_buffer;
2542 struct smb_hdr *smb_buffer_response;
2543 SESSION_SETUP_ANDX *pSMB;
2544 SESSION_SETUP_ANDX *pSMBr;
2548 int remaining_words = 0;
2549 int bytes_returned = 0;
2551 int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
2552 PNEGOTIATE_MESSAGE SecurityBlob;
2553 PCHALLENGE_MESSAGE SecurityBlob2;
2554 __u32 negotiate_flags, capabilities;
2557 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2560 domain = ses->domainName;
2561 *pNTLMv2_flag = FALSE;
2562 smb_buffer = cifs_buf_get();
2563 if (smb_buffer == NULL) {
2566 smb_buffer_response = smb_buffer;
2567 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2568 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2570 /* send SMBsessionSetup here */
2571 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2572 NULL /* no tCon exists yet */ , 12 /* wct */ );
2574 smb_buffer->Mid = GetNextMid(ses->server);
2575 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2576 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2578 pSMB->req.AndXCommand = 0xFF;
2579 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2580 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2582 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2583 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2585 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2586 CAP_EXTENDED_SECURITY;
2587 if (ses->capabilities & CAP_UNICODE) {
2588 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2589 capabilities |= CAP_UNICODE;
2591 if (ses->capabilities & CAP_STATUS32) {
2592 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2593 capabilities |= CAP_STATUS32;
2595 if (ses->capabilities & CAP_DFS) {
2596 smb_buffer->Flags2 |= SMBFLG2_DFS;
2597 capabilities |= CAP_DFS;
2599 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2601 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2602 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2603 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2604 SecurityBlob->MessageType = NtLmNegotiate;
2606 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2607 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2608 NTLMSSP_NEGOTIATE_56 |
2609 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2611 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2612 /* if (ntlmv2_support)
2613 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2614 /* setup pointers to domain name and workstation name */
2615 bcc_ptr += SecurityBlobLength;
2617 SecurityBlob->WorkstationName.Buffer = 0;
2618 SecurityBlob->WorkstationName.Length = 0;
2619 SecurityBlob->WorkstationName.MaximumLength = 0;
2621 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2622 along with username on auth request (ie the response to challenge) */
2623 SecurityBlob->DomainName.Buffer = 0;
2624 SecurityBlob->DomainName.Length = 0;
2625 SecurityBlob->DomainName.MaximumLength = 0;
2626 if (ses->capabilities & CAP_UNICODE) {
2627 if ((long) bcc_ptr % 2) {
2633 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2635 bcc_ptr += 2 * bytes_returned;
2637 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2639 bcc_ptr += 2 * bytes_returned;
2640 bcc_ptr += 2; /* null terminate Linux version */
2642 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2644 bcc_ptr += 2 * bytes_returned;
2647 bcc_ptr += 2; /* null terminate network opsys string */
2650 bcc_ptr += 2; /* null domain */
2651 } else { /* ASCII */
2652 strcpy(bcc_ptr, "Linux version ");
2653 bcc_ptr += strlen("Linux version ");
2654 strcpy(bcc_ptr, utsname()->release);
2655 bcc_ptr += strlen(utsname()->release) + 1;
2656 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2657 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2658 bcc_ptr++; /* empty domain field */
2661 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2662 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2663 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2664 smb_buffer->smb_buf_length += count;
2665 pSMB->req.ByteCount = cpu_to_le16(count);
2667 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2668 &bytes_returned, 1);
2670 if (smb_buffer_response->Status.CifsError ==
2671 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2675 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2676 } else if ((smb_buffer_response->WordCount == 3)
2677 || (smb_buffer_response->WordCount == 4)) {
2678 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2679 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2681 if (action & GUEST_LOGIN)
2682 cFYI(1, (" Guest login"));
2683 /* Do we want to set anything in SesInfo struct when guest login? */
2685 bcc_ptr = pByteArea(smb_buffer_response);
2686 /* response can have either 3 or 4 word count - Samba sends 3 */
2688 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2689 if (SecurityBlob2->MessageType != NtLmChallenge) {
2691 ("Unexpected NTLMSSP message type received %d",
2692 SecurityBlob2->MessageType));
2694 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2695 cFYI(1, ("UID = %d", ses->Suid));
2696 if ((pSMBr->resp.hdr.WordCount == 3)
2697 || ((pSMBr->resp.hdr.WordCount == 4)
2699 pSMBr->resp.ByteCount))) {
2701 if (pSMBr->resp.hdr.WordCount == 4) {
2702 bcc_ptr += blob_len;
2703 cFYI(1, ("Security Blob Length %d",
2707 cFYI(1, ("NTLMSSP Challenge rcvd"));
2709 memcpy(ses->server->cryptKey,
2710 SecurityBlob2->Challenge,
2711 CIFS_CRYPTO_KEY_SIZE);
2712 if (SecurityBlob2->NegotiateFlags &
2713 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2714 *pNTLMv2_flag = TRUE;
2716 if ((SecurityBlob2->NegotiateFlags &
2717 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2718 || (sign_CIFS_PDUs > 1))
2719 ses->server->secMode |=
2720 SECMODE_SIGN_REQUIRED;
2721 if ((SecurityBlob2->NegotiateFlags &
2722 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2723 ses->server->secMode |=
2724 SECMODE_SIGN_ENABLED;
2726 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2727 if ((long) (bcc_ptr) % 2) {
2729 (BCC(smb_buffer_response)
2731 /* Must word align unicode strings */
2736 (smb_buffer_response) / 2;
2739 UniStrnlen((wchar_t *) bcc_ptr,
2740 remaining_words - 1);
2741 /* We look for obvious messed up bcc or strings in response so we do not go off
2742 the end since (at least) WIN2K and Windows XP have a major bug in not null
2743 terminating last Unicode string in response */
2745 kfree(ses->serverOS);
2747 kzalloc(2 * (len + 1), GFP_KERNEL);
2748 cifs_strfromUCS_le(ses->serverOS,
2752 bcc_ptr += 2 * (len + 1);
2753 remaining_words -= len + 1;
2754 ses->serverOS[2 * len] = 0;
2755 ses->serverOS[1 + (2 * len)] = 0;
2756 if (remaining_words > 0) {
2757 len = UniStrnlen((wchar_t *)
2761 kfree(ses->serverNOS);
2763 kzalloc(2 * (len + 1),
2765 cifs_strfromUCS_le(ses->
2771 bcc_ptr += 2 * (len + 1);
2772 ses->serverNOS[2 * len] = 0;
2775 remaining_words -= len + 1;
2776 if (remaining_words > 0) {
2777 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2778 /* last string not always null terminated
2779 (for e.g. for Windows XP & 2000) */
2780 kfree(ses->serverDomain);
2792 ses->serverDomain[2*len]
2797 } /* else no more room so create dummy domain string */
2799 kfree(ses->serverDomain);
2804 } else { /* no room so create dummy domain and NOS string */
2805 kfree(ses->serverDomain);
2807 kzalloc(2, GFP_KERNEL);
2808 kfree(ses->serverNOS);
2810 kzalloc(2, GFP_KERNEL);
2812 } else { /* ASCII */
2813 len = strnlen(bcc_ptr, 1024);
2814 if (((long) bcc_ptr + len) - (long)
2815 pByteArea(smb_buffer_response)
2816 <= BCC(smb_buffer_response)) {
2818 kfree(ses->serverOS);
2822 strncpy(ses->serverOS,
2826 bcc_ptr[0] = 0; /* null terminate string */
2829 len = strnlen(bcc_ptr, 1024);
2830 kfree(ses->serverNOS);
2834 strncpy(ses->serverNOS, bcc_ptr, len);
2839 len = strnlen(bcc_ptr, 1024);
2840 kfree(ses->serverDomain);
2844 strncpy(ses->serverDomain,
2851 ("field of length %d "
2852 "extends beyond end of smb",
2856 cERROR(1, ("Security Blob Length extends beyond"
2860 cERROR(1, ("No session structure passed in."));
2864 (" Invalid Word count %d:",
2865 smb_buffer_response->WordCount));
2870 cifs_buf_release(smb_buffer);
2875 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2876 char *ntlm_session_key, int ntlmv2_flag,
2877 const struct nls_table *nls_codepage)
2879 struct smb_hdr *smb_buffer;
2880 struct smb_hdr *smb_buffer_response;
2881 SESSION_SETUP_ANDX *pSMB;
2882 SESSION_SETUP_ANDX *pSMBr;
2887 int remaining_words = 0;
2888 int bytes_returned = 0;
2890 int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
2891 PAUTHENTICATE_MESSAGE SecurityBlob;
2892 __u32 negotiate_flags, capabilities;
2895 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2898 user = ses->userName;
2899 domain = ses->domainName;
2900 smb_buffer = cifs_buf_get();
2901 if (smb_buffer == NULL) {
2904 smb_buffer_response = smb_buffer;
2905 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2906 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2908 /* send SMBsessionSetup here */
2909 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2910 NULL /* no tCon exists yet */ , 12 /* wct */ );
2912 smb_buffer->Mid = GetNextMid(ses->server);
2913 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2914 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2915 pSMB->req.AndXCommand = 0xFF;
2916 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2917 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2919 pSMB->req.hdr.Uid = ses->Suid;
2921 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2922 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2924 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2925 CAP_EXTENDED_SECURITY;
2926 if (ses->capabilities & CAP_UNICODE) {
2927 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2928 capabilities |= CAP_UNICODE;
2930 if (ses->capabilities & CAP_STATUS32) {
2931 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2932 capabilities |= CAP_STATUS32;
2934 if (ses->capabilities & CAP_DFS) {
2935 smb_buffer->Flags2 |= SMBFLG2_DFS;
2936 capabilities |= CAP_DFS;
2938 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2940 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2941 SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
2942 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2943 SecurityBlob->MessageType = NtLmAuthenticate;
2944 bcc_ptr += SecurityBlobLength;
2946 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
2947 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
2948 0x80000000 | NTLMSSP_NEGOTIATE_128;
2950 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
2952 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2954 /* setup pointers to domain name and workstation name */
2956 SecurityBlob->WorkstationName.Buffer = 0;
2957 SecurityBlob->WorkstationName.Length = 0;
2958 SecurityBlob->WorkstationName.MaximumLength = 0;
2959 SecurityBlob->SessionKey.Length = 0;
2960 SecurityBlob->SessionKey.MaximumLength = 0;
2961 SecurityBlob->SessionKey.Buffer = 0;
2963 SecurityBlob->LmChallengeResponse.Length = 0;
2964 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
2965 SecurityBlob->LmChallengeResponse.Buffer = 0;
2967 SecurityBlob->NtChallengeResponse.Length =
2968 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2969 SecurityBlob->NtChallengeResponse.MaximumLength =
2970 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2971 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
2972 SecurityBlob->NtChallengeResponse.Buffer =
2973 cpu_to_le32(SecurityBlobLength);
2974 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
2975 bcc_ptr += CIFS_SESS_KEY_SIZE;
2977 if (ses->capabilities & CAP_UNICODE) {
2978 if (domain == NULL) {
2979 SecurityBlob->DomainName.Buffer = 0;
2980 SecurityBlob->DomainName.Length = 0;
2981 SecurityBlob->DomainName.MaximumLength = 0;
2983 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2986 SecurityBlob->DomainName.MaximumLength =
2988 SecurityBlob->DomainName.Buffer =
2989 cpu_to_le32(SecurityBlobLength);
2991 SecurityBlobLength += ln;
2992 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
2995 SecurityBlob->UserName.Buffer = 0;
2996 SecurityBlob->UserName.Length = 0;
2997 SecurityBlob->UserName.MaximumLength = 0;
2999 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
3002 SecurityBlob->UserName.MaximumLength =
3004 SecurityBlob->UserName.Buffer =
3005 cpu_to_le32(SecurityBlobLength);
3007 SecurityBlobLength += ln;
3008 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3011 /* SecurityBlob->WorkstationName.Length =
3012 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3013 SecurityBlob->WorkstationName.Length *= 2;
3014 SecurityBlob->WorkstationName.MaximumLength =
3015 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3016 SecurityBlob->WorkstationName.Buffer =
3017 cpu_to_le32(SecurityBlobLength);
3018 bcc_ptr += SecurityBlob->WorkstationName.Length;
3019 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3020 SecurityBlob->WorkstationName.Length =
3021 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3023 if ((long) bcc_ptr % 2) {
3028 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3030 bcc_ptr += 2 * bytes_returned;
3032 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3034 bcc_ptr += 2 * bytes_returned;
3035 bcc_ptr += 2; /* null term version string */
3037 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3039 bcc_ptr += 2 * bytes_returned;
3042 bcc_ptr += 2; /* null terminate network opsys string */
3045 bcc_ptr += 2; /* null domain */
3046 } else { /* ASCII */
3047 if (domain == NULL) {
3048 SecurityBlob->DomainName.Buffer = 0;
3049 SecurityBlob->DomainName.Length = 0;
3050 SecurityBlob->DomainName.MaximumLength = 0;
3053 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3054 strncpy(bcc_ptr, domain, 63);
3055 ln = strnlen(domain, 64);
3056 SecurityBlob->DomainName.MaximumLength =
3058 SecurityBlob->DomainName.Buffer =
3059 cpu_to_le32(SecurityBlobLength);
3061 SecurityBlobLength += ln;
3062 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3065 SecurityBlob->UserName.Buffer = 0;
3066 SecurityBlob->UserName.Length = 0;
3067 SecurityBlob->UserName.MaximumLength = 0;
3070 strncpy(bcc_ptr, user, 63);
3071 ln = strnlen(user, 64);
3072 SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
3073 SecurityBlob->UserName.Buffer =
3074 cpu_to_le32(SecurityBlobLength);
3076 SecurityBlobLength += ln;
3077 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3079 /* BB fill in our workstation name if known BB */
3081 strcpy(bcc_ptr, "Linux version ");
3082 bcc_ptr += strlen("Linux version ");
3083 strcpy(bcc_ptr, utsname()->release);
3084 bcc_ptr += strlen(utsname()->release) + 1;
3085 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3086 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3087 bcc_ptr++; /* null domain */
3090 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3091 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3092 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3093 smb_buffer->smb_buf_length += count;
3094 pSMB->req.ByteCount = cpu_to_le16(count);
3096 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3097 &bytes_returned, 1);
3099 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
3100 } else if ((smb_buffer_response->WordCount == 3)
3101 || (smb_buffer_response->WordCount == 4)) {
3102 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3104 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3105 if (action & GUEST_LOGIN)
3106 cFYI(1, (" Guest login")); /* BB Should we set anything
3107 in SesInfo struct ? */
3108 /* if (SecurityBlob2->MessageType != NtLm??) {
3109 cFYI("Unexpected message type on auth response is %d"));
3114 ("Check challenge UID %d vs auth response UID %d",
3115 ses->Suid, smb_buffer_response->Uid));
3116 /* UID left in wire format */
3117 ses->Suid = smb_buffer_response->Uid;
3118 bcc_ptr = pByteArea(smb_buffer_response);
3119 /* response can have either 3 or 4 word count - Samba sends 3 */
3120 if ((pSMBr->resp.hdr.WordCount == 3)
3121 || ((pSMBr->resp.hdr.WordCount == 4)
3123 pSMBr->resp.ByteCount))) {
3124 if (pSMBr->resp.hdr.WordCount == 4) {
3128 ("Security Blob Length %d ",
3133 ("NTLMSSP response to Authenticate "));
3135 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3136 if ((long) (bcc_ptr) % 2) {
3138 (BCC(smb_buffer_response)
3140 bcc_ptr++; /* Unicode strings must be word aligned */
3142 remaining_words = BCC(smb_buffer_response) / 2;
3144 len = UniStrnlen((wchar_t *) bcc_ptr,
3145 remaining_words - 1);
3146 /* We look for obvious messed up bcc or strings in response so we do not go off
3147 the end since (at least) WIN2K and Windows XP have a major bug in not null
3148 terminating last Unicode string in response */
3150 kfree(ses->serverOS);
3152 kzalloc(2 * (len + 1), GFP_KERNEL);
3153 cifs_strfromUCS_le(ses->serverOS,
3157 bcc_ptr += 2 * (len + 1);
3158 remaining_words -= len + 1;
3159 ses->serverOS[2 * len] = 0;
3160 ses->serverOS[1 + (2 * len)] = 0;
3161 if (remaining_words > 0) {
3162 len = UniStrnlen((wchar_t *)
3166 kfree(ses->serverNOS);
3168 kzalloc(2 * (len + 1),
3170 cifs_strfromUCS_le(ses->
3176 bcc_ptr += 2 * (len + 1);
3177 ses->serverNOS[2 * len] = 0;
3178 ses->serverNOS[1+(2*len)] = 0;
3179 remaining_words -= len + 1;
3180 if (remaining_words > 0) {
3181 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3182 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3183 if (ses->serverDomain)
3184 kfree(ses->serverDomain);
3209 } /* else no more room so create dummy domain string */
3211 if (ses->serverDomain)
3212 kfree(ses->serverDomain);
3213 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3215 } else { /* no room so create dummy domain and NOS string */
3216 if (ses->serverDomain)
3217 kfree(ses->serverDomain);
3218 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3219 kfree(ses->serverNOS);
3220 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3222 } else { /* ASCII */
3223 len = strnlen(bcc_ptr, 1024);
3224 if (((long) bcc_ptr + len) -
3225 (long) pByteArea(smb_buffer_response)
3226 <= BCC(smb_buffer_response)) {
3228 kfree(ses->serverOS);
3229 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
3230 strncpy(ses->serverOS,bcc_ptr, len);
3233 bcc_ptr[0] = 0; /* null terminate the string */
3236 len = strnlen(bcc_ptr, 1024);
3237 kfree(ses->serverNOS);
3238 ses->serverNOS = kzalloc(len+1,
3240 strncpy(ses->serverNOS,
3246 len = strnlen(bcc_ptr, 1024);
3247 if (ses->serverDomain)
3248 kfree(ses->serverDomain);
3252 strncpy(ses->serverDomain,
3259 ("field of length %d "
3260 "extends beyond end of smb ",
3265 (" Security Blob extends beyond end "
3269 cERROR(1, ("No session structure passed in."));
3273 (" Invalid Word count %d: ",
3274 smb_buffer_response->WordCount));
3279 cifs_buf_release(smb_buffer);
3285 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3286 const char *tree, struct cifsTconInfo *tcon,
3287 const struct nls_table *nls_codepage)
3289 struct smb_hdr *smb_buffer;
3290 struct smb_hdr *smb_buffer_response;
3293 unsigned char *bcc_ptr;
3301 smb_buffer = cifs_buf_get();
3302 if (smb_buffer == NULL) {
3305 smb_buffer_response = smb_buffer;
3307 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3308 NULL /*no tid */ , 4 /*wct */ );
3310 smb_buffer->Mid = GetNextMid(ses->server);
3311 smb_buffer->Uid = ses->Suid;
3312 pSMB = (TCONX_REQ *) smb_buffer;
3313 pSMBr = (TCONX_RSP *) smb_buffer_response;
3315 pSMB->AndXCommand = 0xFF;
3316 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3317 bcc_ptr = &pSMB->Password[0];
3318 if ((ses->server->secMode) & SECMODE_USER) {
3319 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3320 *bcc_ptr = 0; /* password is null byte */
3321 bcc_ptr++; /* skip password */
3322 /* already aligned so no need to do it below */
3324 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3325 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3326 specified as required (when that support is added to
3327 the vfs in the future) as only NTLM or the much
3328 weaker LANMAN (which we do not send by default) is accepted
3329 by Samba (not sure whether other servers allow
3330 NTLMv2 password here) */
3331 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3332 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3333 (ses->server->secType == LANMAN))
3334 calc_lanman_hash(ses, bcc_ptr);
3336 #endif /* CIFS_WEAK_PW_HASH */
3337 SMBNTencrypt(ses->password,
3338 ses->server->cryptKey,
3341 bcc_ptr += CIFS_SESS_KEY_SIZE;
3342 if (ses->capabilities & CAP_UNICODE) {
3343 /* must align unicode strings */
3344 *bcc_ptr = 0; /* null byte password */
3349 if (ses->server->secMode &
3350 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3351 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3353 if (ses->capabilities & CAP_STATUS32) {
3354 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3356 if (ses->capabilities & CAP_DFS) {
3357 smb_buffer->Flags2 |= SMBFLG2_DFS;
3359 if (ses->capabilities & CAP_UNICODE) {
3360 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3362 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3363 6 /* max utf8 char length in bytes */ *
3364 (/* server len*/ + 256 /* share len */), nls_codepage);
3365 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3366 bcc_ptr += 2; /* skip trailing null */
3367 } else { /* ASCII */
3368 strcpy(bcc_ptr, tree);
3369 bcc_ptr += strlen(tree) + 1;
3371 strcpy(bcc_ptr, "?????");
3372 bcc_ptr += strlen("?????");
3374 count = bcc_ptr - &pSMB->Password[0];
3375 pSMB->hdr.smb_buf_length += count;
3376 pSMB->ByteCount = cpu_to_le16(count);
3378 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
3380 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3381 /* above now done in SendReceive */
3382 if ((rc == 0) && (tcon != NULL)) {
3383 tcon->tidStatus = CifsGood;
3384 tcon->tid = smb_buffer_response->Tid;
3385 bcc_ptr = pByteArea(smb_buffer_response);
3386 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3387 /* skip service field (NB: this field is always ASCII) */
3388 bcc_ptr += length + 1;
3389 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3390 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3391 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3392 if ((bcc_ptr + (2 * length)) -
3393 pByteArea(smb_buffer_response) <=
3394 BCC(smb_buffer_response)) {
3395 kfree(tcon->nativeFileSystem);
3396 tcon->nativeFileSystem =
3397 kzalloc(length + 2, GFP_KERNEL);
3398 if (tcon->nativeFileSystem)
3400 tcon->nativeFileSystem,
3402 length, nls_codepage);
3403 bcc_ptr += 2 * length;
3404 bcc_ptr[0] = 0; /* null terminate the string */
3408 /* else do not bother copying these information fields*/
3410 length = strnlen(bcc_ptr, 1024);
3411 if ((bcc_ptr + length) -
3412 pByteArea(smb_buffer_response) <=
3413 BCC(smb_buffer_response)) {
3414 kfree(tcon->nativeFileSystem);
3415 tcon->nativeFileSystem =
3416 kzalloc(length + 1, GFP_KERNEL);
3417 if (tcon->nativeFileSystem)
3418 strncpy(tcon->nativeFileSystem, bcc_ptr,
3421 /* else do not bother copying these information fields*/
3423 if ((smb_buffer_response->WordCount == 3) ||
3424 (smb_buffer_response->WordCount == 7))
3425 /* field is in same location */
3426 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3429 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3430 } else if ((rc == 0) && tcon == NULL) {
3431 /* all we need to save for IPC$ connection */
3432 ses->ipc_tid = smb_buffer_response->Tid;
3436 cifs_buf_release(smb_buffer);
3441 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3445 struct cifsSesInfo *ses = NULL;
3446 struct task_struct *cifsd_task;
3451 if (cifs_sb->tcon) {
3452 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3453 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3458 tconInfoFree(cifs_sb->tcon);
3459 if ((ses) && (ses->server)) {
3460 /* save off task so we do not refer to ses later */
3461 cifsd_task = ses->server->tsk;
3462 cFYI(1, ("About to do SMBLogoff "));
3463 rc = CIFSSMBLogoff(xid, ses);
3467 } else if (rc == -ESHUTDOWN) {
3468 cFYI(1, ("Waking up socket by sending signal"));
3470 force_sig(SIGKILL, cifsd_task);
3471 kthread_stop(cifsd_task);
3474 } /* else - we have an smb session
3475 left on this socket do not kill cifsd */
3477 cFYI(1, ("No session or bad tcon"));
3480 cifs_sb->tcon = NULL;
3481 tmp = cifs_sb->prepath;
3482 cifs_sb->prepathlen = 0;
3483 cifs_sb->prepath = NULL;
3486 schedule_timeout_interruptible(msecs_to_jiffies(500));
3491 return rc; /* BB check if we should always return zero here */
3494 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3495 struct nls_table *nls_info)
3498 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3499 int ntlmv2_flag = FALSE;
3502 /* what if server changes its buffer size after dropping the session? */
3503 if (pSesInfo->server->maxBuf == 0) /* no need to send on reconnect */ {
3504 rc = CIFSSMBNegotiate(xid, pSesInfo);
3505 if (rc == -EAGAIN) /* retry only once on 1st time connection */ {
3506 rc = CIFSSMBNegotiate(xid, pSesInfo);
3511 spin_lock(&GlobalMid_Lock);
3512 if (pSesInfo->server->tcpStatus != CifsExiting)
3513 pSesInfo->server->tcpStatus = CifsGood;
3516 spin_unlock(&GlobalMid_Lock);
3522 pSesInfo->flags = 0;
3523 pSesInfo->capabilities = pSesInfo->server->capabilities;
3524 if (linuxExtEnabled == 0)
3525 pSesInfo->capabilities &= (~CAP_UNIX);
3526 /* pSesInfo->sequence_number = 0;*/
3528 ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3529 pSesInfo->server->secMode,
3530 pSesInfo->server->capabilities,
3531 pSesInfo->server->timeAdj));
3532 if (experimEnabled < 2)
3533 rc = CIFS_SessSetup(xid, pSesInfo,
3534 first_time, nls_info);
3535 else if (extended_security
3536 && (pSesInfo->capabilities
3537 & CAP_EXTENDED_SECURITY)
3538 && (pSesInfo->server->secType == NTLMSSP)) {
3540 } else if (extended_security
3541 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3542 && (pSesInfo->server->secType == RawNTLMSSP)) {
3543 cFYI(1, ("NTLMSSP sesssetup"));
3544 rc = CIFSNTLMSSPNegotiateSessSetup(xid,
3551 cFYI(1, ("more secure NTLM ver2 hash"));
3552 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3557 v2_response = kmalloc(16 + 64 /* blob */, GFP_KERNEL);
3559 CalcNTLMv2_response(pSesInfo,
3562 cifs_calculate_ntlmv2_mac_key(
3563 pSesInfo->server->mac_signing_key,
3564 response, ntlm_session_key,*/
3566 /* BB Put dummy sig in SessSetup PDU? */
3573 SMBNTencrypt(pSesInfo->password,
3574 pSesInfo->server->cryptKey,
3578 cifs_calculate_mac_key(
3579 &pSesInfo->server->mac_signing_key,
3581 pSesInfo->password);
3583 /* for better security the weaker lanman hash not sent
3584 in AuthSessSetup so we no longer calculate it */
3586 rc = CIFSNTLMSSPAuthSessSetup(xid,
3592 } else { /* old style NTLM 0.12 session setup */
3593 SMBNTencrypt(pSesInfo->password,
3594 pSesInfo->server->cryptKey,
3598 cifs_calculate_mac_key(
3599 &pSesInfo->server->mac_signing_key,
3600 ntlm_session_key, pSesInfo->password);
3602 rc = CIFSSessSetup(xid, pSesInfo,
3603 ntlm_session_key, nls_info);
3606 cERROR(1, ("Send error in SessSetup = %d", rc));
3608 cFYI(1, ("CIFS Session Established successfully"));
3609 pSesInfo->status = CifsGood;