4 * Copyright (C) International Business Machines Corp., 2002,2007
5 * Author(s): Steve French (sfrench@us.ibm.com)
7 * This library is free software; you can redistribute it and/or modify
8 * it under the terms of the GNU Lesser General Public License as published
9 * by the Free Software Foundation; either version 2.1 of the License, or
10 * (at your option) any later version.
12 * This library is distributed in the hope that it will be useful,
13 * but WITHOUT ANY WARRANTY; without even the implied warranty of
14 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See
15 * the GNU Lesser General Public License for more details.
17 * You should have received a copy of the GNU Lesser General Public License
18 * along with this library; if not, write to the Free Software
19 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22 #include <linux/net.h>
23 #include <linux/string.h>
24 #include <linux/list.h>
25 #include <linux/wait.h>
26 #include <linux/ipv6.h>
27 #include <linux/pagemap.h>
28 #include <linux/ctype.h>
29 #include <linux/utsname.h>
30 #include <linux/mempool.h>
31 #include <linux/delay.h>
32 #include <linux/completion.h>
33 #include <linux/kthread.h>
34 #include <linux/pagevec.h>
35 #include <linux/freezer.h>
36 #include <asm/uaccess.h>
37 #include <asm/processor.h>
40 #include "cifsproto.h"
41 #include "cifs_unicode.h"
42 #include "cifs_debug.h"
43 #include "cifs_fs_sb.h"
46 #include "rfc1002pdu.h"
50 #define RFC1001_PORT 139
52 static DECLARE_COMPLETION(cifsd_complete);
54 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
57 extern mempool_t *cifs_req_poolp;
65 char *in6_addr; /* ipv6 address as human readable form of in6_addr */
66 char *iocharset; /* local code page for mapping to and from Unicode */
67 char source_rfc1001_name[16]; /* netbios name of client */
68 char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
78 unsigned override_uid:1;
79 unsigned override_gid:1;
81 unsigned no_psx_acl:1; /* set if posix acl support should be disabled */
83 unsigned no_xattr:1; /* set if xattr (EA) support should be disabled*/
84 unsigned server_ino:1; /* use inode numbers from server ie UniqueId */
86 unsigned remap:1; /* set to remap seven reserved chars in filenames */
87 unsigned posix_paths:1; /* unset to not ask for posix pathnames. */
88 unsigned no_linux_ext:1;
90 unsigned nullauth:1; /* attempt to authenticate with null user */
91 unsigned nocase; /* request case insensitive filenames */
92 unsigned nobrl; /* disable sending byte range locks to srv */
96 unsigned short int port;
100 static int ipv4_connect(struct sockaddr_in *psin_server,
101 struct socket **csocket,
103 char *server_netb_name);
104 static int ipv6_connect(struct sockaddr_in6 *psin_server,
105 struct socket **csocket);
109 * cifs tcp session reconnection
111 * mark tcp session as reconnecting so temporarily locked
112 * mark all smb sessions as reconnecting for tcp session
113 * reconnect tcp session
114 * wake up waiters on reconnection? - (not needed currently)
118 cifs_reconnect(struct TCP_Server_Info *server)
121 struct list_head *tmp;
122 struct cifsSesInfo *ses;
123 struct cifsTconInfo *tcon;
124 struct mid_q_entry *mid_entry;
126 spin_lock(&GlobalMid_Lock);
127 if ( kthread_should_stop() ) {
128 /* the demux thread will exit normally
129 next time through the loop */
130 spin_unlock(&GlobalMid_Lock);
133 server->tcpStatus = CifsNeedReconnect;
134 spin_unlock(&GlobalMid_Lock);
137 cFYI(1, ("Reconnecting tcp session"));
139 /* before reconnecting the tcp session, mark the smb session (uid)
140 and the tid bad so they are not used until reconnected */
141 read_lock(&GlobalSMBSeslock);
142 list_for_each(tmp, &GlobalSMBSessionList) {
143 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
145 if (ses->server == server) {
146 ses->status = CifsNeedReconnect;
150 /* else tcp and smb sessions need reconnection */
152 list_for_each(tmp, &GlobalTreeConnectionList) {
153 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
154 if ((tcon) && (tcon->ses) && (tcon->ses->server == server)) {
155 tcon->tidStatus = CifsNeedReconnect;
158 read_unlock(&GlobalSMBSeslock);
159 /* do not want to be sending data on a socket we are freeing */
160 down(&server->tcpSem);
161 if (server->ssocket) {
162 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
163 server->ssocket->flags));
164 server->ssocket->ops->shutdown(server->ssocket, SEND_SHUTDOWN);
165 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
166 server->ssocket->state,
167 server->ssocket->flags));
168 sock_release(server->ssocket);
169 server->ssocket = NULL;
172 spin_lock(&GlobalMid_Lock);
173 list_for_each(tmp, &server->pending_mid_q) {
174 mid_entry = list_entry(tmp, struct
178 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
179 /* Mark other intransit requests as needing
180 retry so we do not immediately mark the
181 session bad again (ie after we reconnect
182 below) as they timeout too */
183 mid_entry->midState = MID_RETRY_NEEDED;
187 spin_unlock(&GlobalMid_Lock);
190 while ( (!kthread_should_stop()) && (server->tcpStatus != CifsGood)) {
192 if (server->protocolType == IPV6) {
193 rc = ipv6_connect(&server->addr.sockAddr6,
196 rc = ipv4_connect(&server->addr.sockAddr,
198 server->workstation_RFC1001_name,
199 server->server_RFC1001_name);
202 cFYI(1, ("reconnect error %d", rc));
205 atomic_inc(&tcpSesReconnectCount);
206 spin_lock(&GlobalMid_Lock);
207 if ( !kthread_should_stop() )
208 server->tcpStatus = CifsGood;
209 server->sequence_number = 0;
210 spin_unlock(&GlobalMid_Lock);
211 /* atomic_set(&server->inFlight,0);*/
212 wake_up(&server->response_q);
220 0 not a transact2, or all data present
221 >0 transact2 with that much data missing
222 -EINVAL = invalid transact2
225 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
227 struct smb_t2_rsp *pSMBt;
229 int data_in_this_rsp;
232 if (pSMB->Command != SMB_COM_TRANSACTION2)
235 /* check for plausible wct, bcc and t2 data and parm sizes */
236 /* check for parm and data offset going beyond end of smb */
237 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
238 cFYI(1, ("invalid transact2 word count"));
242 pSMBt = (struct smb_t2_rsp *)pSMB;
244 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
245 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
247 remaining = total_data_size - data_in_this_rsp;
251 else if (remaining < 0) {
252 cFYI(1, ("total data %d smaller than data in frame %d",
253 total_data_size, data_in_this_rsp));
256 cFYI(1, ("missing %d bytes from transact2, check next response",
258 if (total_data_size > maxBufSize) {
259 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
260 total_data_size, maxBufSize));
267 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
269 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
270 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
275 char *data_area_of_target;
276 char *data_area_of_buf2;
279 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
281 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
282 cFYI(1, ("total data size of primary and secondary t2 differ"));
285 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
287 remaining = total_data_size - total_in_buf;
292 if (remaining == 0) /* nothing to do, ignore */
295 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
296 if (remaining < total_in_buf2) {
297 cFYI(1, ("transact2 2nd response contains too much data"));
300 /* find end of first SMB data area */
301 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
302 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
303 /* validate target area */
305 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
306 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
308 data_area_of_target += total_in_buf;
310 /* copy second buffer into end of first buffer */
311 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
312 total_in_buf += total_in_buf2;
313 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
314 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
315 byte_count += total_in_buf2;
316 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
318 byte_count = pTargetSMB->smb_buf_length;
319 byte_count += total_in_buf2;
321 /* BB also add check that we are not beyond maximum buffer size */
323 pTargetSMB->smb_buf_length = byte_count;
325 if (remaining == total_in_buf2) {
326 cFYI(1, ("found the last secondary response"));
327 return 0; /* we are done */
328 } else /* more responses to go */
334 cifs_demultiplex_thread(struct TCP_Server_Info *server)
337 unsigned int pdu_length, total_read;
338 struct smb_hdr *smb_buffer = NULL;
339 struct smb_hdr *bigbuf = NULL;
340 struct smb_hdr *smallbuf = NULL;
341 struct msghdr smb_msg;
343 struct socket *csocket = server->ssocket;
344 struct list_head *tmp;
345 struct cifsSesInfo *ses;
346 struct task_struct *task_to_wake = NULL;
347 struct mid_q_entry *mid_entry;
349 int isLargeBuf = FALSE;
353 current->flags |= PF_MEMALLOC;
354 server->tsk = current; /* save process info to wake at shutdown */
355 cFYI(1, ("Demultiplex PID: %d", current->pid));
356 write_lock(&GlobalSMBSeslock);
357 atomic_inc(&tcpSesAllocCount);
358 length = tcpSesAllocCount.counter;
359 write_unlock(&GlobalSMBSeslock);
360 complete(&cifsd_complete);
362 mempool_resize(cifs_req_poolp,
363 length + cifs_min_rcv,
367 while (!kthread_should_stop()) {
370 if (bigbuf == NULL) {
371 bigbuf = cifs_buf_get();
373 cERROR(1, ("No memory for large SMB response"));
375 /* retry will check if exiting */
378 } else if (isLargeBuf) {
379 /* we are reusing a dirty large buf, clear its start */
380 memset(bigbuf, 0, sizeof (struct smb_hdr));
383 if (smallbuf == NULL) {
384 smallbuf = cifs_small_buf_get();
386 cERROR(1, ("No memory for SMB response"));
388 /* retry will check if exiting */
391 /* beginning of smb buffer is cleared in our buf_get */
392 } else /* if existing small buf clear beginning */
393 memset(smallbuf, 0, sizeof (struct smb_hdr));
397 smb_buffer = smallbuf;
398 iov.iov_base = smb_buffer;
400 smb_msg.msg_control = NULL;
401 smb_msg.msg_controllen = 0;
403 kernel_recvmsg(csocket, &smb_msg,
404 &iov, 1, 4, 0 /* BB see socket.h 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) {
440 ("Frame under four bytes received (%d bytes long)",
442 cifs_reconnect(server);
443 csocket = server->ssocket;
444 wake_up(&server->response_q);
448 /* The right amount was read from socket - 4 bytes */
449 /* so we can now interpret the length field */
451 /* the first byte big endian of the length field,
452 is actually not part of the length but the type
453 with the most common, zero, as regular data */
454 temp = *((char *) smb_buffer);
456 /* Note that FC 1001 length is big endian on the wire,
457 but we convert it here so it is always manipulated
458 as host byte order */
459 pdu_length = ntohl(smb_buffer->smb_buf_length);
460 smb_buffer->smb_buf_length = pdu_length;
462 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
464 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
466 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
467 cFYI(1, ("Good RFC 1002 session rsp"));
469 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
470 /* we get this from Windows 98 instead of
471 an error on SMB negprot response */
472 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
474 if (server->tcpStatus == CifsNew) {
475 /* if nack on negprot (rather than
476 ret of smb negprot error) reconnecting
477 not going to help, ret error to mount */
480 /* give server a second to
481 clean up before reconnect attempt */
483 /* always try 445 first on reconnect
484 since we get NACK on some if we ever
485 connected to port 139 (the NACK is
486 since we do not begin with RFC1001
487 session initialize frame) */
488 server->addr.sockAddr.sin_port =
490 cifs_reconnect(server);
491 csocket = server->ssocket;
492 wake_up(&server->response_q);
495 } else if (temp != (char) 0) {
496 cERROR(1, ("Unknown RFC 1002 frame"));
497 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
499 cifs_reconnect(server);
500 csocket = server->ssocket;
504 /* else we have an SMB response */
505 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
506 (pdu_length < sizeof (struct smb_hdr) - 1 - 4)) {
507 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
508 length, pdu_length+4));
509 cifs_reconnect(server);
510 csocket = server->ssocket;
511 wake_up(&server->response_q);
518 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
520 memcpy(bigbuf, smallbuf, 4);
524 iov.iov_base = 4 + (char *)smb_buffer;
525 iov.iov_len = pdu_length;
526 for (total_read = 0; total_read < pdu_length;
527 total_read += length) {
528 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
529 pdu_length - total_read, 0);
530 if ( kthread_should_stop() ||
531 (length == -EINTR)) {
535 } else if (server->tcpStatus == CifsNeedReconnect) {
536 cifs_reconnect(server);
537 csocket = server->ssocket;
538 /* Reconnect wakes up rspns q */
539 /* Now we will reread sock */
542 } else if ((length == -ERESTARTSYS) ||
543 (length == -EAGAIN)) {
544 msleep(1); /* minimum sleep to prevent looping,
545 allowing socket to clear and app
546 threads to set tcpStatus
547 CifsNeedReconnect if server hung*/
549 } else if (length <= 0) {
550 cERROR(1, ("Received no data, expecting %d",
551 pdu_length - total_read));
552 cifs_reconnect(server);
553 csocket = server->ssocket;
560 else if (reconnect == 1)
563 length += 4; /* account for rfc1002 hdr */
566 dump_smb(smb_buffer, length);
567 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
568 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
574 spin_lock(&GlobalMid_Lock);
575 list_for_each(tmp, &server->pending_mid_q) {
576 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
578 if ((mid_entry->mid == smb_buffer->Mid) &&
579 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
580 (mid_entry->command == smb_buffer->Command)) {
581 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
582 /* We have a multipart transact2 resp */
584 if (mid_entry->resp_buf) {
585 /* merge response - fix up 1st*/
586 if (coalesce_t2(smb_buffer,
587 mid_entry->resp_buf)) {
588 mid_entry->multiRsp = 1;
591 /* all parts received */
592 mid_entry->multiEnd = 1;
597 cERROR(1,("1st trans2 resp needs bigbuf"));
598 /* BB maybe we can fix this up, switch
599 to already allocated large buffer? */
601 /* Have first buffer */
602 mid_entry->resp_buf =
604 mid_entry->largeBuf = 1;
610 mid_entry->resp_buf = smb_buffer;
612 mid_entry->largeBuf = 1;
614 mid_entry->largeBuf = 0;
616 task_to_wake = mid_entry->tsk;
617 mid_entry->midState = MID_RESPONSE_RECEIVED;
618 #ifdef CONFIG_CIFS_STATS2
619 mid_entry->when_received = jiffies;
621 /* so we do not time out requests to server
622 which is still responding (since server could
623 be busy but not dead) */
624 server->lstrp = jiffies;
628 spin_unlock(&GlobalMid_Lock);
630 /* Was previous buf put in mpx struct for multi-rsp? */
632 /* smb buffer will be freed by user thread */
638 wake_up_process(task_to_wake);
639 } else if ((is_valid_oplock_break(smb_buffer, server) == FALSE)
640 && (isMultiRsp == FALSE)) {
641 cERROR(1, ("No task to wake, unknown frame received! "
642 "NumMids %d", midCount.counter));
643 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
644 sizeof(struct smb_hdr));
645 #ifdef CONFIG_CIFS_DEBUG2
646 cifs_dump_detail(smb_buffer);
647 cifs_dump_mids(server);
648 #endif /* CIFS_DEBUG2 */
651 } /* end while !EXITING */
653 spin_lock(&GlobalMid_Lock);
654 server->tcpStatus = CifsExiting;
656 /* check if we have blocked requests that need to free */
657 /* Note that cifs_max_pending is normally 50, but
658 can be set at module install time to as little as two */
659 if (atomic_read(&server->inFlight) >= cifs_max_pending)
660 atomic_set(&server->inFlight, cifs_max_pending - 1);
661 /* We do not want to set the max_pending too low or we
662 could end up with the counter going negative */
663 spin_unlock(&GlobalMid_Lock);
664 /* Although there should not be any requests blocked on
665 this queue it can not hurt to be paranoid and try to wake up requests
666 that may haven been blocked when more than 50 at time were on the wire
667 to the same server - they now will see the session is in exit state
668 and get out of SendReceive. */
669 wake_up_all(&server->request_q);
670 /* give those requests time to exit */
673 if (server->ssocket) {
674 sock_release(csocket);
675 server->ssocket = NULL;
677 /* buffer usuallly freed in free_mid - need to free it here on exit */
679 cifs_buf_release(bigbuf);
680 if (smallbuf != NULL)
681 cifs_small_buf_release(smallbuf);
683 read_lock(&GlobalSMBSeslock);
684 if (list_empty(&server->pending_mid_q)) {
685 /* loop through server session structures attached to this and
687 list_for_each(tmp, &GlobalSMBSessionList) {
689 list_entry(tmp, struct cifsSesInfo,
691 if (ses->server == server) {
692 ses->status = CifsExiting;
696 read_unlock(&GlobalSMBSeslock);
698 /* although we can not zero the server struct pointer yet,
699 since there are active requests which may depnd on them,
700 mark the corresponding SMB sessions as exiting too */
701 list_for_each(tmp, &GlobalSMBSessionList) {
702 ses = list_entry(tmp, struct cifsSesInfo,
704 if (ses->server == server) {
705 ses->status = CifsExiting;
709 spin_lock(&GlobalMid_Lock);
710 list_for_each(tmp, &server->pending_mid_q) {
711 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
712 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
713 cFYI(1, ("Clearing Mid 0x%x - waking up ",
715 task_to_wake = mid_entry->tsk;
717 wake_up_process(task_to_wake);
721 spin_unlock(&GlobalMid_Lock);
722 read_unlock(&GlobalSMBSeslock);
723 /* 1/8th of sec is more than enough time for them to exit */
727 if (!list_empty(&server->pending_mid_q)) {
728 /* mpx threads have not exited yet give them
729 at least the smb send timeout time for long ops */
730 /* due to delays on oplock break requests, we need
731 to wait at least 45 seconds before giving up
732 on a request getting a response and going ahead
734 cFYI(1, ("Wait for exit from demultiplex thread"));
736 /* if threads still have not exited they are probably never
737 coming home not much else we can do but free the memory */
740 write_lock(&GlobalSMBSeslock);
741 atomic_dec(&tcpSesAllocCount);
742 length = tcpSesAllocCount.counter;
744 /* last chance to mark ses pointers invalid
745 if there are any pointing to this (e.g
746 if a crazy root user tried to kill cifsd
747 kernel thread explicitly this might happen) */
748 list_for_each(tmp, &GlobalSMBSessionList) {
749 ses = list_entry(tmp, struct cifsSesInfo,
751 if (ses->server == server) {
755 write_unlock(&GlobalSMBSeslock);
759 mempool_resize(cifs_req_poolp,
760 length + cifs_min_rcv,
768 cifs_parse_mount_options(char *options, const char *devname,
773 unsigned int temp_len, i, j;
779 if (Local_System_Name[0] != 0)
780 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
782 char *nodename = utsname()->nodename;
783 int n = strnlen(nodename, 15);
784 memset(vol->source_rfc1001_name, 0x20, 15);
785 for (i = 0; i < n; i++) {
786 /* does not have to be perfect mapping since field is
787 informational, only used for servers that do not support
788 port 445 and it can be overridden at mount time */
789 vol->source_rfc1001_name[i] = toupper(nodename[i]);
792 vol->source_rfc1001_name[15] = 0;
793 /* null target name indicates to use *SMBSERVR default called name
794 if we end up sending RFC1001 session initialize */
795 vol->target_rfc1001_name[0] = 0;
796 vol->linux_uid = current->uid; /* current->euid instead? */
797 vol->linux_gid = current->gid;
798 vol->dir_mode = S_IRWXUGO;
799 /* 2767 perms indicate mandatory locking support */
800 vol->file_mode = S_IALLUGO & ~(S_ISUID | S_IXGRP);
802 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
804 /* default is always to request posix paths. */
805 vol->posix_paths = 1;
810 if (strncmp(options, "sep=", 4) == 0) {
811 if (options[4] != 0) {
812 separator[0] = options[4];
815 cFYI(1, ("Null separator not allowed"));
819 while ((data = strsep(&options, separator)) != NULL) {
822 if ((value = strchr(data, '=')) != NULL)
825 /* Have to parse this before we parse for "user" */
826 if (strnicmp(data, "user_xattr", 10) == 0) {
828 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
830 } else if (strnicmp(data, "user", 4) == 0) {
833 "CIFS: invalid or missing username\n");
834 return 1; /* needs_arg; */
835 } else if (!*value) {
836 /* null user, ie anonymous, authentication */
839 if (strnlen(value, 200) < 200) {
840 vol->username = value;
842 printk(KERN_WARNING "CIFS: username too long\n");
845 } else if (strnicmp(data, "pass", 4) == 0) {
847 vol->password = NULL;
849 } else if (value[0] == 0) {
850 /* check if string begins with double comma
851 since that would mean the password really
852 does start with a comma, and would not
853 indicate an empty string */
854 if (value[1] != separator[0]) {
855 vol->password = NULL;
859 temp_len = strlen(value);
860 /* removed password length check, NTLM passwords
861 can be arbitrarily long */
863 /* if comma in password, the string will be
864 prematurely null terminated. Commas in password are
865 specified across the cifs mount interface by a double
866 comma ie ,, and a comma used as in other cases ie ','
867 as a parameter delimiter/separator is single and due
868 to the strsep above is temporarily zeroed. */
870 /* NB: password legally can have multiple commas and
871 the only illegal character in a password is null */
873 if ((value[temp_len] == 0) &&
874 (value[temp_len+1] == separator[0])) {
876 value[temp_len] = separator[0];
877 temp_len += 2; /* move after second comma */
878 while (value[temp_len] != 0) {
879 if (value[temp_len] == separator[0]) {
880 if (value[temp_len+1] ==
882 /* skip second comma */
885 /* single comma indicating start
892 if (value[temp_len] == 0) {
896 /* point option to start of next parm */
897 options = value + temp_len + 1;
899 /* go from value to value + temp_len condensing
900 double commas to singles. Note that this ends up
901 allocating a few bytes too many, which is ok */
902 vol->password = kzalloc(temp_len, GFP_KERNEL);
903 if (vol->password == NULL) {
904 printk(KERN_WARNING "CIFS: no memory "
908 for (i = 0, j = 0; i < temp_len; i++, j++) {
909 vol->password[j] = value[i];
910 if (value[i] == separator[0]
911 && value[i+1] == separator[0]) {
912 /* skip second comma */
916 vol->password[j] = 0;
918 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
919 if (vol->password == NULL) {
920 printk(KERN_WARNING "CIFS: no memory "
924 strcpy(vol->password, value);
926 } else if (strnicmp(data, "ip", 2) == 0) {
927 if (!value || !*value) {
929 } else if (strnlen(value, 35) < 35) {
932 printk(KERN_WARNING "CIFS: ip address "
936 } else if (strnicmp(data, "sec", 3) == 0) {
937 if (!value || !*value) {
938 cERROR(1, ("no security value specified"));
940 } else if (strnicmp(value, "krb5i", 5) == 0) {
941 vol->secFlg |= CIFSSEC_MAY_KRB5 |
943 } else if (strnicmp(value, "krb5p", 5) == 0) {
944 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
946 cERROR(1, ("Krb5 cifs privacy not supported"));
948 } else if (strnicmp(value, "krb5", 4) == 0) {
949 vol->secFlg |= CIFSSEC_MAY_KRB5;
950 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
951 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
953 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
954 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
955 } else if (strnicmp(value, "ntlmi", 5) == 0) {
956 vol->secFlg |= CIFSSEC_MAY_NTLM |
958 } else if (strnicmp(value, "ntlm", 4) == 0) {
959 /* ntlm is default so can be turned off too */
960 vol->secFlg |= CIFSSEC_MAY_NTLM;
961 } else if (strnicmp(value, "nontlm", 6) == 0) {
962 /* BB is there a better way to do this? */
963 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
964 #ifdef CONFIG_CIFS_WEAK_PW_HASH
965 } else if (strnicmp(value, "lanman", 6) == 0) {
966 vol->secFlg |= CIFSSEC_MAY_LANMAN;
968 } else if (strnicmp(value, "none", 4) == 0) {
971 cERROR(1, ("bad security option: %s", value));
974 } else if ((strnicmp(data, "unc", 3) == 0)
975 || (strnicmp(data, "target", 6) == 0)
976 || (strnicmp(data, "path", 4) == 0)) {
977 if (!value || !*value) {
978 printk(KERN_WARNING "CIFS: invalid path to "
979 "network resource\n");
980 return 1; /* needs_arg; */
982 if ((temp_len = strnlen(value, 300)) < 300) {
983 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
984 if (vol->UNC == NULL)
986 strcpy(vol->UNC, value);
987 if (strncmp(vol->UNC, "//", 2) == 0) {
990 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
992 "CIFS: UNC Path does not begin "
993 "with // or \\\\ \n");
997 printk(KERN_WARNING "CIFS: UNC name too long\n");
1000 } else if ((strnicmp(data, "domain", 3) == 0)
1001 || (strnicmp(data, "workgroup", 5) == 0)) {
1002 if (!value || !*value) {
1003 printk(KERN_WARNING "CIFS: invalid domain name\n");
1004 return 1; /* needs_arg; */
1006 /* BB are there cases in which a comma can be valid in
1007 a domain name and need special handling? */
1008 if (strnlen(value, 256) < 256) {
1009 vol->domainname = value;
1010 cFYI(1, ("Domain name set"));
1012 printk(KERN_WARNING "CIFS: domain name too "
1016 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1017 if (!value || !*value) {
1019 "CIFS: invalid path prefix\n");
1020 return 1; /* needs_argument */
1022 if ((temp_len = strnlen(value, 1024)) < 1024) {
1023 if (value[0] != '/')
1024 temp_len++; /* missing leading slash */
1025 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1026 if (vol->prepath == NULL)
1028 if (value[0] != '/') {
1029 vol->prepath[0] = '/';
1030 strcpy(vol->prepath+1, value);
1032 strcpy(vol->prepath, value);
1033 cFYI(1, ("prefix path %s", vol->prepath));
1035 printk(KERN_WARNING "CIFS: prefix too long\n");
1038 } else if (strnicmp(data, "iocharset", 9) == 0) {
1039 if (!value || !*value) {
1040 printk(KERN_WARNING "CIFS: invalid iocharset "
1042 return 1; /* needs_arg; */
1044 if (strnlen(value, 65) < 65) {
1045 if (strnicmp(value, "default", 7))
1046 vol->iocharset = value;
1047 /* if iocharset not set then load_nls_default
1048 is used by caller */
1049 cFYI(1, ("iocharset set to %s", value));
1051 printk(KERN_WARNING "CIFS: iocharset name "
1055 } else if (strnicmp(data, "uid", 3) == 0) {
1056 if (value && *value) {
1058 simple_strtoul(value, &value, 0);
1059 vol->override_uid = 1;
1061 } else if (strnicmp(data, "gid", 3) == 0) {
1062 if (value && *value) {
1064 simple_strtoul(value, &value, 0);
1065 vol->override_gid = 1;
1067 } else if (strnicmp(data, "file_mode", 4) == 0) {
1068 if (value && *value) {
1070 simple_strtoul(value, &value, 0);
1072 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1073 if (value && *value) {
1075 simple_strtoul(value, &value, 0);
1077 } else if (strnicmp(data, "dirmode", 4) == 0) {
1078 if (value && *value) {
1080 simple_strtoul(value, &value, 0);
1082 } else if (strnicmp(data, "port", 4) == 0) {
1083 if (value && *value) {
1085 simple_strtoul(value, &value, 0);
1087 } else if (strnicmp(data, "rsize", 5) == 0) {
1088 if (value && *value) {
1090 simple_strtoul(value, &value, 0);
1092 } else if (strnicmp(data, "wsize", 5) == 0) {
1093 if (value && *value) {
1095 simple_strtoul(value, &value, 0);
1097 } else if (strnicmp(data, "sockopt", 5) == 0) {
1098 if (value && *value) {
1100 simple_strtoul(value, &value, 0);
1102 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1103 if (!value || !*value || (*value == ' ')) {
1104 cFYI(1, ("invalid (empty) netbiosname"));
1106 memset(vol->source_rfc1001_name, 0x20, 15);
1107 for (i = 0; i < 15; i++) {
1108 /* BB are there cases in which a comma can be
1109 valid in this workstation netbios name (and need
1110 special handling)? */
1112 /* We do not uppercase netbiosname for user */
1116 vol->source_rfc1001_name[i] =
1119 /* The string has 16th byte zero still from
1120 set at top of the function */
1121 if ((i == 15) && (value[i] != 0))
1122 printk(KERN_WARNING "CIFS: netbiosname"
1123 " longer than 15 truncated.\n");
1125 } else if (strnicmp(data, "servern", 7) == 0) {
1126 /* servernetbiosname specified override *SMBSERVER */
1127 if (!value || !*value || (*value == ' ')) {
1128 cFYI(1, ("empty server netbiosname specified"));
1130 /* last byte, type, is 0x20 for servr type */
1131 memset(vol->target_rfc1001_name, 0x20, 16);
1133 for (i = 0; i < 15; i++) {
1134 /* BB are there cases in which a comma can be
1135 valid in this workstation netbios name
1136 (and need special handling)? */
1138 /* user or mount helper must uppercase
1143 vol->target_rfc1001_name[i] =
1146 /* The string has 16th byte zero still from
1147 set at top of the function */
1148 if ((i == 15) && (value[i] != 0))
1149 printk(KERN_WARNING "CIFS: server net"
1150 "biosname longer than 15 truncated.\n");
1152 } else if (strnicmp(data, "credentials", 4) == 0) {
1154 } else if (strnicmp(data, "version", 3) == 0) {
1156 } else if (strnicmp(data, "guest", 5) == 0) {
1158 } else if (strnicmp(data, "rw", 2) == 0) {
1160 } else if ((strnicmp(data, "suid", 4) == 0) ||
1161 (strnicmp(data, "nosuid", 6) == 0) ||
1162 (strnicmp(data, "exec", 4) == 0) ||
1163 (strnicmp(data, "noexec", 6) == 0) ||
1164 (strnicmp(data, "nodev", 5) == 0) ||
1165 (strnicmp(data, "noauto", 6) == 0) ||
1166 (strnicmp(data, "dev", 3) == 0)) {
1167 /* The mount tool or mount.cifs helper (if present)
1168 uses these opts to set flags, and the flags are read
1169 by the kernel vfs layer before we get here (ie
1170 before read super) so there is no point trying to
1171 parse these options again and set anything and it
1172 is ok to just ignore them */
1174 } else if (strnicmp(data, "ro", 2) == 0) {
1176 } else if (strnicmp(data, "hard", 4) == 0) {
1178 } else if (strnicmp(data, "soft", 4) == 0) {
1180 } else if (strnicmp(data, "perm", 4) == 0) {
1182 } else if (strnicmp(data, "noperm", 6) == 0) {
1184 } else if (strnicmp(data, "mapchars", 8) == 0) {
1186 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1188 } else if (strnicmp(data, "sfu", 3) == 0) {
1190 } else if (strnicmp(data, "nosfu", 5) == 0) {
1192 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1193 vol->posix_paths = 1;
1194 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1195 vol->posix_paths = 0;
1196 } else if (strnicmp(data, "nounix", 6) == 0) {
1197 vol->no_linux_ext = 1;
1198 } else if (strnicmp(data, "nolinux", 7) == 0) {
1199 vol->no_linux_ext = 1;
1200 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1201 (strnicmp(data, "ignorecase", 10) == 0)) {
1203 } else if (strnicmp(data, "brl", 3) == 0) {
1205 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1206 (strnicmp(data, "nolock", 6) == 0)) {
1208 /* turn off mandatory locking in mode
1209 if remote locking is turned off since the
1210 local vfs will do advisory */
1211 if (vol->file_mode ==
1212 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1213 vol->file_mode = S_IALLUGO;
1214 } else if (strnicmp(data, "setuids", 7) == 0) {
1216 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1218 } else if (strnicmp(data, "nohard", 6) == 0) {
1220 } else if (strnicmp(data, "nosoft", 6) == 0) {
1222 } else if (strnicmp(data, "nointr", 6) == 0) {
1224 } else if (strnicmp(data, "intr", 4) == 0) {
1226 } else if (strnicmp(data, "serverino", 7) == 0) {
1227 vol->server_ino = 1;
1228 } else if (strnicmp(data, "noserverino", 9) == 0) {
1229 vol->server_ino = 0;
1230 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1232 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1234 } else if (strnicmp(data, "acl", 3) == 0) {
1235 vol->no_psx_acl = 0;
1236 } else if (strnicmp(data, "noacl", 5) == 0) {
1237 vol->no_psx_acl = 1;
1238 } else if (strnicmp(data, "sign", 4) == 0) {
1239 vol->secFlg |= CIFSSEC_MUST_SIGN;
1240 /* } else if (strnicmp(data, "seal",4) == 0) {
1241 vol->secFlg |= CIFSSEC_MUST_SEAL; */
1242 } else if (strnicmp(data, "direct", 6) == 0) {
1244 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1246 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1247 if (!value || !*value) {
1248 vol->in6_addr = NULL;
1249 } else if (strnlen(value, 49) == 48) {
1250 vol->in6_addr = value;
1252 printk(KERN_WARNING "CIFS: ip v6 address not "
1253 "48 characters long\n");
1256 } else if (strnicmp(data, "noac", 4) == 0) {
1257 printk(KERN_WARNING "CIFS: Mount option noac not "
1258 "supported. Instead set "
1259 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1261 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1264 if (vol->UNC == NULL) {
1265 if (devname == NULL) {
1266 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1270 if ((temp_len = strnlen(devname, 300)) < 300) {
1271 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1272 if (vol->UNC == NULL)
1274 strcpy(vol->UNC, devname);
1275 if (strncmp(vol->UNC, "//", 2) == 0) {
1278 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1279 printk(KERN_WARNING "CIFS: UNC Path does not "
1280 "begin with // or \\\\ \n");
1284 printk(KERN_WARNING "CIFS: UNC name too long\n");
1288 if (vol->UNCip == NULL)
1289 vol->UNCip = &vol->UNC[2];
1294 static struct cifsSesInfo *
1295 cifs_find_tcp_session(struct in_addr *target_ip_addr,
1296 struct in6_addr *target_ip6_addr,
1297 char *userName, struct TCP_Server_Info **psrvTcp)
1299 struct list_head *tmp;
1300 struct cifsSesInfo *ses;
1302 read_lock(&GlobalSMBSeslock);
1304 list_for_each(tmp, &GlobalSMBSessionList) {
1305 ses = list_entry(tmp, struct cifsSesInfo, cifsSessionList);
1307 if ((target_ip_addr &&
1308 (ses->server->addr.sockAddr.sin_addr.s_addr
1309 == target_ip_addr->s_addr)) || (target_ip6_addr
1310 && memcmp(&ses->server->addr.sockAddr6.sin6_addr,
1311 target_ip6_addr, sizeof(*target_ip6_addr)))) {
1312 /* BB lock server and tcp session and increment
1315 /* found a match on the TCP session */
1316 *psrvTcp = ses->server;
1318 /* BB check if reconnection needed */
1320 (ses->userName, userName,
1321 MAX_USERNAME_SIZE) == 0){
1322 read_unlock(&GlobalSMBSeslock);
1323 /* Found exact match on both TCP and
1329 /* else tcp and smb sessions need reconnection */
1331 read_unlock(&GlobalSMBSeslock);
1335 static struct cifsTconInfo *
1336 find_unc(__be32 new_target_ip_addr, char *uncName, char *userName)
1338 struct list_head *tmp;
1339 struct cifsTconInfo *tcon;
1341 read_lock(&GlobalSMBSeslock);
1342 list_for_each(tmp, &GlobalTreeConnectionList) {
1343 cFYI(1, ("Next tcon"));
1344 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
1346 if (tcon->ses->server) {
1348 ("old ip addr: %x == new ip %x ?",
1349 tcon->ses->server->addr.sockAddr.sin_addr.
1350 s_addr, new_target_ip_addr));
1351 if (tcon->ses->server->addr.sockAddr.sin_addr.
1352 s_addr == new_target_ip_addr) {
1353 /* BB lock tcon, server and tcp session and increment use count here? */
1354 /* found a match on the TCP session */
1355 /* BB check if reconnection needed */
1357 ("IP match, old UNC: %s new: %s",
1358 tcon->treeName, uncName));
1360 (tcon->treeName, uncName,
1361 MAX_TREE_SIZE) == 0) {
1363 ("and old usr: %s new: %s",
1364 tcon->treeName, uncName));
1366 (tcon->ses->userName,
1368 MAX_USERNAME_SIZE) == 0) {
1369 read_unlock(&GlobalSMBSeslock);
1370 /* matched smb session
1379 read_unlock(&GlobalSMBSeslock);
1384 connect_to_dfs_path(int xid, struct cifsSesInfo *pSesInfo,
1385 const char *old_path, const struct nls_table *nls_codepage,
1388 unsigned char *referrals = NULL;
1389 unsigned int num_referrals;
1392 rc = get_dfs_path(xid, pSesInfo, old_path, nls_codepage,
1393 &num_referrals, &referrals, remap);
1395 /* BB Add in code to: if valid refrl, if not ip address contact
1396 the helper that resolves tcp names, mount to it, try to
1397 tcon to it unmount it if fail */
1405 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1406 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1407 unsigned char **preferrals, int remap)
1412 *pnum_referrals = 0;
1414 if (pSesInfo->ipc_tid == 0) {
1415 temp_unc = kmalloc(2 /* for slashes */ +
1416 strnlen(pSesInfo->serverName,
1417 SERVER_NAME_LEN_WITH_NULL * 2)
1418 + 1 + 4 /* slash IPC$ */ + 2,
1420 if (temp_unc == NULL)
1424 strcpy(temp_unc + 2, pSesInfo->serverName);
1425 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1426 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1428 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1432 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1433 pnum_referrals, nls_codepage, remap);
1438 /* See RFC1001 section 14 on representation of Netbios names */
1439 static void rfc1002mangle(char *target, char *source, unsigned int length)
1443 for (i = 0, j = 0; i < (length); i++) {
1444 /* mask a nibble at a time and encode */
1445 target[j] = 'A' + (0x0F & (source[i] >> 4));
1446 target[j+1] = 'A' + (0x0F & source[i]);
1454 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1455 char *netbios_name, char *target_name)
1459 __be16 orig_port = 0;
1461 if (*csocket == NULL) {
1462 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1463 IPPROTO_TCP, csocket);
1465 cERROR(1, ("Error %d creating socket", rc));
1469 /* BB other socket options to set KEEPALIVE, NODELAY? */
1470 cFYI(1, ("Socket created"));
1471 (*csocket)->sk->sk_allocation = GFP_NOFS;
1475 psin_server->sin_family = AF_INET;
1476 if (psin_server->sin_port) { /* user overrode default port */
1477 rc = (*csocket)->ops->connect(*csocket,
1478 (struct sockaddr *) psin_server,
1479 sizeof (struct sockaddr_in), 0);
1485 /* save original port so we can retry user specified port
1486 later if fall back ports fail this time */
1487 orig_port = psin_server->sin_port;
1489 /* do not retry on the same port we just failed on */
1490 if (psin_server->sin_port != htons(CIFS_PORT)) {
1491 psin_server->sin_port = htons(CIFS_PORT);
1493 rc = (*csocket)->ops->connect(*csocket,
1494 (struct sockaddr *) psin_server,
1495 sizeof (struct sockaddr_in), 0);
1501 psin_server->sin_port = htons(RFC1001_PORT);
1502 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1504 sizeof (struct sockaddr_in), 0);
1509 /* give up here - unless we want to retry on different
1510 protocol families some day */
1513 psin_server->sin_port = orig_port;
1514 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1515 sock_release(*csocket);
1519 /* Eventually check for other socket options to change from
1520 the default. sock_setsockopt not used because it expects
1521 user space buffer */
1522 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1523 (*csocket)->sk->sk_sndbuf,
1524 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1525 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1526 /* make the bufsizes depend on wsize/rsize and max requests */
1527 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1528 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1529 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1530 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1532 /* send RFC1001 sessinit */
1533 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1534 /* some servers require RFC1001 sessinit before sending
1535 negprot - BB check reconnection in case where second
1536 sessinit is sent but no second negprot */
1537 struct rfc1002_session_packet *ses_init_buf;
1538 struct smb_hdr *smb_buf;
1539 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1542 ses_init_buf->trailer.session_req.called_len = 32;
1543 if (target_name && (target_name[0] != 0)) {
1544 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1547 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1548 DEFAULT_CIFS_CALLED_NAME, 16);
1551 ses_init_buf->trailer.session_req.calling_len = 32;
1552 /* calling name ends in null (byte 16) from old smb
1554 if (netbios_name && (netbios_name[0] != 0)) {
1555 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1558 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1559 "LINUX_CIFS_CLNT", 16);
1561 ses_init_buf->trailer.session_req.scope1 = 0;
1562 ses_init_buf->trailer.session_req.scope2 = 0;
1563 smb_buf = (struct smb_hdr *)ses_init_buf;
1564 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1565 smb_buf->smb_buf_length = 0x81000044;
1566 rc = smb_send(*csocket, smb_buf, 0x44,
1567 (struct sockaddr *)psin_server);
1568 kfree(ses_init_buf);
1569 msleep(1); /* RFC1001 layer in at least one server
1570 requires very short break before negprot
1571 presumably because not expecting negprot
1572 to follow so fast. This is a simple
1573 solution that works without
1574 complicating the code and causes no
1575 significant slowing down on mount
1576 for everyone else */
1578 /* else the negprot may still work without this
1579 even though malloc failed */
1587 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket)
1591 __be16 orig_port = 0;
1593 if (*csocket == NULL) {
1594 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1595 IPPROTO_TCP, csocket);
1597 cERROR(1, ("Error %d creating ipv6 socket", rc));
1601 /* BB other socket options to set KEEPALIVE, NODELAY? */
1602 cFYI(1, ("ipv6 Socket created"));
1603 (*csocket)->sk->sk_allocation = GFP_NOFS;
1607 psin_server->sin6_family = AF_INET6;
1609 if (psin_server->sin6_port) { /* user overrode default port */
1610 rc = (*csocket)->ops->connect(*csocket,
1611 (struct sockaddr *) psin_server,
1612 sizeof (struct sockaddr_in6), 0);
1618 /* save original port so we can retry user specified port
1619 later if fall back ports fail this time */
1621 orig_port = psin_server->sin6_port;
1622 /* do not retry on the same port we just failed on */
1623 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1624 psin_server->sin6_port = htons(CIFS_PORT);
1626 rc = (*csocket)->ops->connect(*csocket,
1627 (struct sockaddr *) psin_server,
1628 sizeof (struct sockaddr_in6), 0);
1634 psin_server->sin6_port = htons(RFC1001_PORT);
1635 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1636 psin_server, sizeof (struct sockaddr_in6), 0);
1641 /* give up here - unless we want to retry on different
1642 protocol families some day */
1645 psin_server->sin6_port = orig_port;
1646 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1647 sock_release(*csocket);
1651 /* Eventually check for other socket options to change from
1652 the default. sock_setsockopt not used because it expects
1653 user space buffer */
1654 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1659 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1660 struct super_block *sb, struct smb_vol *vol_info)
1662 /* if we are reconnecting then should we check to see if
1663 * any requested capabilities changed locally e.g. via
1664 * remount but we can not do much about it here
1665 * if they have (even if we could detect it by the following)
1666 * Perhaps we could add a backpointer to array of sb from tcon
1667 * or if we change to make all sb to same share the same
1668 * sb as NFS - then we only have one backpointer to sb.
1669 * What if we wanted to mount the server share twice once with
1670 * and once without posixacls or posix paths? */
1671 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1673 if (vol_info && vol_info->no_linux_ext) {
1674 tcon->fsUnixInfo.Capability = 0;
1675 tcon->unix_ext = 0; /* Unix Extensions disabled */
1676 cFYI(1, ("Linux protocol extensions disabled"));
1678 } else if (vol_info)
1679 tcon->unix_ext = 1; /* Unix Extensions supported */
1681 if (tcon->unix_ext == 0) {
1682 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1686 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1687 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1689 /* check for reconnect case in which we do not
1690 want to change the mount behavior if we can avoid it */
1691 if (vol_info == NULL) {
1692 /* turn off POSIX ACL and PATHNAMES if not set
1693 originally at mount time */
1694 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1695 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1696 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0)
1697 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1700 cap &= CIFS_UNIX_CAP_MASK;
1701 if (vol_info && vol_info->no_psx_acl)
1702 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1703 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
1704 cFYI(1, ("negotiated posix acl support"));
1706 sb->s_flags |= MS_POSIXACL;
1709 if (vol_info && vol_info->posix_paths == 0)
1710 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1711 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1712 cFYI(1, ("negotiate posix pathnames"));
1714 CIFS_SB(sb)->mnt_cifs_flags |=
1715 CIFS_MOUNT_POSIX_PATHS;
1718 /* We might be setting the path sep back to a different
1719 form if we are reconnecting and the server switched its
1720 posix path capability for this share */
1721 if (sb && (CIFS_SB(sb)->prepathlen > 0))
1722 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1724 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
1725 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
1726 CIFS_SB(sb)->rsize = 127 * 1024;
1727 #ifdef CONFIG_CIFS_DEBUG2
1728 cFYI(1, ("larger reads not supported by srv"));
1734 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
1735 #ifdef CONFIG_CIFS_DEBUG2
1736 if (cap & CIFS_UNIX_FCNTL_CAP)
1737 cFYI(1, ("FCNTL cap"));
1738 if (cap & CIFS_UNIX_EXTATTR_CAP)
1739 cFYI(1, ("EXTATTR cap"));
1740 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1741 cFYI(1, ("POSIX path cap"));
1742 if (cap & CIFS_UNIX_XATTR_CAP)
1743 cFYI(1, ("XATTR cap"));
1744 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
1745 cFYI(1, ("POSIX ACL cap"));
1746 if (cap & CIFS_UNIX_LARGE_READ_CAP)
1747 cFYI(1, ("very large read cap"));
1748 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
1749 cFYI(1, ("very large write cap"));
1750 #endif /* CIFS_DEBUG2 */
1751 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1752 cFYI(1, ("setting capabilities failed"));
1758 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1759 char *mount_data, const char *devname)
1763 int address_type = AF_INET;
1764 struct socket *csocket = NULL;
1765 struct sockaddr_in sin_server;
1766 struct sockaddr_in6 sin_server6;
1767 struct smb_vol volume_info;
1768 struct cifsSesInfo *pSesInfo = NULL;
1769 struct cifsSesInfo *existingCifsSes = NULL;
1770 struct cifsTconInfo *tcon = NULL;
1771 struct TCP_Server_Info *srvTcp = NULL;
1775 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1777 memset(&volume_info, 0, sizeof(struct smb_vol));
1778 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
1779 kfree(volume_info.UNC);
1780 kfree(volume_info.password);
1781 kfree(volume_info.prepath);
1786 if (volume_info.nullauth) {
1787 cFYI(1, ("null user"));
1788 volume_info.username = NULL;
1789 } else if (volume_info.username) {
1790 /* BB fixme parse for domain name here */
1791 cFYI(1, ("Username: %s", volume_info.username));
1793 cifserror("No username specified");
1794 /* In userspace mount helper we can get user name from alternate
1795 locations such as env variables and files on disk */
1796 kfree(volume_info.UNC);
1797 kfree(volume_info.password);
1798 kfree(volume_info.prepath);
1803 if (volume_info.UNCip && volume_info.UNC) {
1804 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
1805 &sin_server.sin_addr.s_addr);
1808 /* not ipv4 address, try ipv6 */
1809 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
1810 &sin_server6.sin6_addr.in6_u);
1812 address_type = AF_INET6;
1814 address_type = AF_INET;
1818 /* we failed translating address */
1819 kfree(volume_info.UNC);
1820 kfree(volume_info.password);
1821 kfree(volume_info.prepath);
1826 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
1829 } else if (volume_info.UNCip) {
1830 /* BB using ip addr as server name to connect to the
1832 cERROR(1, ("Connecting to DFS root not implemented yet"));
1833 kfree(volume_info.UNC);
1834 kfree(volume_info.password);
1835 kfree(volume_info.prepath);
1838 } else /* which servers DFS root would we conect to */ {
1840 ("CIFS mount error: No UNC path (e.g. -o "
1841 "unc=//192.168.1.100/public) specified"));
1842 kfree(volume_info.UNC);
1843 kfree(volume_info.password);
1844 kfree(volume_info.prepath);
1849 /* this is needed for ASCII cp to Unicode converts */
1850 if (volume_info.iocharset == NULL) {
1851 cifs_sb->local_nls = load_nls_default();
1852 /* load_nls_default can not return null */
1854 cifs_sb->local_nls = load_nls(volume_info.iocharset);
1855 if (cifs_sb->local_nls == NULL) {
1856 cERROR(1, ("CIFS mount error: iocharset %s not found",
1857 volume_info.iocharset));
1858 kfree(volume_info.UNC);
1859 kfree(volume_info.password);
1860 kfree(volume_info.prepath);
1866 if (address_type == AF_INET)
1867 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
1868 NULL /* no ipv6 addr */,
1869 volume_info.username, &srvTcp);
1870 else if (address_type == AF_INET6) {
1871 cFYI(1, ("looking for ipv6 address"));
1872 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
1873 &sin_server6.sin6_addr,
1874 volume_info.username, &srvTcp);
1876 kfree(volume_info.UNC);
1877 kfree(volume_info.password);
1878 kfree(volume_info.prepath);
1884 cFYI(1, ("Existing tcp session with server found"));
1885 } else { /* create socket */
1886 if (volume_info.port)
1887 sin_server.sin_port = htons(volume_info.port);
1889 sin_server.sin_port = 0;
1890 if (address_type == AF_INET6) {
1891 cFYI(1, ("attempting ipv6 connect"));
1892 /* BB should we allow ipv6 on port 139? */
1893 /* other OS never observed in Wild doing 139 with v6 */
1894 rc = ipv6_connect(&sin_server6, &csocket);
1896 rc = ipv4_connect(&sin_server, &csocket,
1897 volume_info.source_rfc1001_name,
1898 volume_info.target_rfc1001_name);
1900 cERROR(1, ("Error connecting to IPv4 socket. "
1901 "Aborting operation"));
1902 if (csocket != NULL)
1903 sock_release(csocket);
1904 kfree(volume_info.UNC);
1905 kfree(volume_info.password);
1906 kfree(volume_info.prepath);
1911 srvTcp = kmalloc(sizeof (struct TCP_Server_Info), GFP_KERNEL);
1912 if (srvTcp == NULL) {
1914 sock_release(csocket);
1915 kfree(volume_info.UNC);
1916 kfree(volume_info.password);
1917 kfree(volume_info.prepath);
1921 memset(srvTcp, 0, sizeof (struct TCP_Server_Info));
1922 memcpy(&srvTcp->addr.sockAddr, &sin_server,
1923 sizeof (struct sockaddr_in));
1924 atomic_set(&srvTcp->inFlight, 0);
1925 /* BB Add code for ipv6 case too */
1926 srvTcp->ssocket = csocket;
1927 srvTcp->protocolType = IPV4;
1928 init_waitqueue_head(&srvTcp->response_q);
1929 init_waitqueue_head(&srvTcp->request_q);
1930 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
1931 /* at this point we are the only ones with the pointer
1932 to the struct since the kernel thread not created yet
1933 so no need to spinlock this init of tcpStatus */
1934 srvTcp->tcpStatus = CifsNew;
1935 init_MUTEX(&srvTcp->tcpSem);
1936 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
1937 if ( IS_ERR(srvTcp->tsk) ) {
1938 rc = PTR_ERR(srvTcp->tsk);
1939 cERROR(1, ("error %d create cifsd thread", rc));
1941 sock_release(csocket);
1942 kfree(volume_info.UNC);
1943 kfree(volume_info.password);
1944 kfree(volume_info.prepath);
1948 wait_for_completion(&cifsd_complete);
1950 memcpy(srvTcp->workstation_RFC1001_name,
1951 volume_info.source_rfc1001_name, 16);
1952 memcpy(srvTcp->server_RFC1001_name,
1953 volume_info.target_rfc1001_name, 16);
1954 srvTcp->sequence_number = 0;
1958 if (existingCifsSes) {
1959 pSesInfo = existingCifsSes;
1960 cFYI(1, ("Existing smb sess found"));
1961 kfree(volume_info.password);
1962 /* volume_info.UNC freed at end of function */
1964 cFYI(1, ("Existing smb sess not found"));
1965 pSesInfo = sesInfoAlloc();
1966 if (pSesInfo == NULL)
1969 pSesInfo->server = srvTcp;
1970 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
1971 NIPQUAD(sin_server.sin_addr.s_addr));
1975 /* volume_info.password freed at unmount */
1976 if (volume_info.password)
1977 pSesInfo->password = volume_info.password;
1978 if (volume_info.username)
1979 strncpy(pSesInfo->userName,
1980 volume_info.username,
1982 if (volume_info.domainname) {
1983 int len = strlen(volume_info.domainname);
1984 pSesInfo->domainName =
1985 kmalloc(len + 1, GFP_KERNEL);
1986 if (pSesInfo->domainName)
1987 strcpy(pSesInfo->domainName,
1988 volume_info.domainname);
1990 pSesInfo->linux_uid = volume_info.linux_uid;
1991 pSesInfo->overrideSecFlg = volume_info.secFlg;
1992 down(&pSesInfo->sesSem);
1993 /* BB FIXME need to pass vol->secFlgs BB */
1994 rc = cifs_setup_session(xid, pSesInfo,
1995 cifs_sb->local_nls);
1996 up(&pSesInfo->sesSem);
1998 atomic_inc(&srvTcp->socketUseCount);
2000 kfree(volume_info.password);
2003 /* search for existing tcon to this server share */
2005 if (volume_info.rsize > CIFSMaxBufSize) {
2006 cERROR(1, ("rsize %d too large, using MaxBufSize",
2007 volume_info.rsize));
2008 cifs_sb->rsize = CIFSMaxBufSize;
2009 } else if ((volume_info.rsize) &&
2010 (volume_info.rsize <= CIFSMaxBufSize))
2011 cifs_sb->rsize = volume_info.rsize;
2013 cifs_sb->rsize = CIFSMaxBufSize;
2015 if (volume_info.wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2016 cERROR(1, ("wsize %d too large, using 4096 instead",
2017 volume_info.wsize));
2018 cifs_sb->wsize = 4096;
2019 } else if (volume_info.wsize)
2020 cifs_sb->wsize = volume_info.wsize;
2023 min_t(const int, PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2025 /* old default of CIFSMaxBufSize was too small now
2026 that SMB Write2 can send multiple pages in kvec.
2027 RFC1001 does not describe what happens when frame
2028 bigger than 128K is sent so use that as max in
2029 conjunction with 52K kvec constraint on arch with 4K
2032 if (cifs_sb->rsize < 2048) {
2033 cifs_sb->rsize = 2048;
2034 /* Windows ME may prefer this */
2035 cFYI(1, ("readsize set to minimum: 2048"));
2037 /* calculate prepath */
2038 cifs_sb->prepath = volume_info.prepath;
2039 if (cifs_sb->prepath) {
2040 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2041 cifs_sb->prepath[0] = CIFS_DIR_SEP(cifs_sb);
2042 volume_info.prepath = NULL;
2044 cifs_sb->prepathlen = 0;
2045 cifs_sb->mnt_uid = volume_info.linux_uid;
2046 cifs_sb->mnt_gid = volume_info.linux_gid;
2047 cifs_sb->mnt_file_mode = volume_info.file_mode;
2048 cifs_sb->mnt_dir_mode = volume_info.dir_mode;
2049 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2050 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2052 if (volume_info.noperm)
2053 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2054 if (volume_info.setuids)
2055 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2056 if (volume_info.server_ino)
2057 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2058 if (volume_info.remap)
2059 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2060 if (volume_info.no_xattr)
2061 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2062 if (volume_info.sfu_emul)
2063 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2064 if (volume_info.nobrl)
2065 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2066 if (volume_info.cifs_acl)
2067 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2068 if (volume_info.override_uid)
2069 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2070 if (volume_info.override_gid)
2071 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2072 if (volume_info.direct_io) {
2073 cFYI(1, ("mounting share using direct i/o"));
2074 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2078 find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
2079 volume_info.username);
2081 cFYI(1, ("Found match on UNC path"));
2082 /* we can have only one retry value for a connection
2083 to a share so for resources mounted more than once
2084 to the same server share the last value passed in
2085 for the retry flag is used */
2086 tcon->retry = volume_info.retry;
2087 tcon->nocase = volume_info.nocase;
2089 tcon = tconInfoAlloc();
2093 /* check for null share name ie connecting to
2096 /* BB check if this works for exactly length
2098 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2099 && (strchr(volume_info.UNC + 3, '/') ==
2101 rc = connect_to_dfs_path(xid, pSesInfo,
2102 "", cifs_sb->local_nls,
2103 cifs_sb->mnt_cifs_flags &
2104 CIFS_MOUNT_MAP_SPECIAL_CHR);
2105 kfree(volume_info.UNC);
2109 /* BB Do we need to wrap sesSem around
2110 * this TCon call and Unix SetFS as
2111 * we do on SessSetup and reconnect? */
2112 rc = CIFSTCon(xid, pSesInfo,
2114 tcon, cifs_sb->local_nls);
2115 cFYI(1, ("CIFS Tcon rc = %d", rc));
2118 atomic_inc(&pSesInfo->inUse);
2119 tcon->retry = volume_info.retry;
2120 tcon->nocase = volume_info.nocase;
2126 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2127 sb->s_maxbytes = (u64) 1 << 63;
2129 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2132 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2133 sb->s_time_gran = 100;
2135 /* on error free sesinfo and tcon struct if needed */
2137 /* if session setup failed, use count is zero but
2138 we still need to free cifsd thread */
2139 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2140 spin_lock(&GlobalMid_Lock);
2141 srvTcp->tcpStatus = CifsExiting;
2142 spin_unlock(&GlobalMid_Lock);
2144 struct task_struct *tsk;
2145 /* If we could verify that kthread_stop would
2146 always wake up processes blocked in
2147 tcp in recv_mesg then we could remove the
2149 force_sig(SIGKILL, srvTcp->tsk);
2155 /* If find_unc succeeded then rc == 0 so we can not end */
2156 if (tcon) /* up accidently freeing someone elses tcon struct */
2158 if (existingCifsSes == NULL) {
2160 if ((pSesInfo->server) &&
2161 (pSesInfo->status == CifsGood)) {
2163 temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2164 /* if the socketUseCount is now zero */
2165 if ((temp_rc == -ESHUTDOWN) &&
2166 (pSesInfo->server) &&
2167 (pSesInfo->server->tsk)) {
2168 struct task_struct *tsk;
2170 pSesInfo->server->tsk);
2171 tsk = pSesInfo->server->tsk;
2176 cFYI(1, ("No session or bad tcon"));
2177 sesInfoFree(pSesInfo);
2178 /* pSesInfo = NULL; */
2182 atomic_inc(&tcon->useCount);
2183 cifs_sb->tcon = tcon;
2184 tcon->ses = pSesInfo;
2186 /* do not care if following two calls succeed - informational */
2187 CIFSSMBQFSDeviceInfo(xid, tcon);
2188 CIFSSMBQFSAttributeInfo(xid, tcon);
2190 /* tell server which Unix caps we support */
2191 if (tcon->ses->capabilities & CAP_UNIX)
2192 /* reset of caps checks mount to see if unix extensions
2193 disabled for just this mount */
2194 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2196 tcon->unix_ext = 0; /* server does not support them */
2198 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2199 cifs_sb->rsize = 1024 * 127;
2200 #ifdef CONFIG_CIFS_DEBUG2
2201 cFYI(1, ("no very large read support, rsize now 127K"));
2204 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2205 cifs_sb->wsize = min(cifs_sb->wsize,
2206 (tcon->ses->server->maxBuf -
2207 MAX_CIFS_HDR_SIZE));
2208 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2209 cifs_sb->rsize = min(cifs_sb->rsize,
2210 (tcon->ses->server->maxBuf -
2211 MAX_CIFS_HDR_SIZE));
2214 /* volume_info.password is freed above when existing session found
2215 (in which case it is not needed anymore) but when new sesion is created
2216 the password ptr is put in the new session structure (in which case the
2217 password will be freed at unmount time) */
2218 kfree(volume_info.UNC);
2219 kfree(volume_info.prepath);
2225 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2226 char session_key[CIFS_SESS_KEY_SIZE],
2227 const struct nls_table *nls_codepage)
2229 struct smb_hdr *smb_buffer;
2230 struct smb_hdr *smb_buffer_response;
2231 SESSION_SETUP_ANDX *pSMB;
2232 SESSION_SETUP_ANDX *pSMBr;
2237 int remaining_words = 0;
2238 int bytes_returned = 0;
2243 cFYI(1, ("In sesssetup"));
2246 user = ses->userName;
2247 domain = ses->domainName;
2248 smb_buffer = cifs_buf_get();
2249 if (smb_buffer == NULL) {
2252 smb_buffer_response = smb_buffer;
2253 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2255 /* send SMBsessionSetup here */
2256 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2257 NULL /* no tCon exists yet */ , 13 /* wct */ );
2259 smb_buffer->Mid = GetNextMid(ses->server);
2260 pSMB->req_no_secext.AndXCommand = 0xFF;
2261 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2262 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2264 if (ses->server->secMode &
2265 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2266 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2268 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2269 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2270 if (ses->capabilities & CAP_UNICODE) {
2271 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2272 capabilities |= CAP_UNICODE;
2274 if (ses->capabilities & CAP_STATUS32) {
2275 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2276 capabilities |= CAP_STATUS32;
2278 if (ses->capabilities & CAP_DFS) {
2279 smb_buffer->Flags2 |= SMBFLG2_DFS;
2280 capabilities |= CAP_DFS;
2282 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2284 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2285 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2287 pSMB->req_no_secext.CaseSensitivePasswordLength =
2288 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2289 bcc_ptr = pByteArea(smb_buffer);
2290 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2291 bcc_ptr += CIFS_SESS_KEY_SIZE;
2292 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2293 bcc_ptr += CIFS_SESS_KEY_SIZE;
2295 if (ses->capabilities & CAP_UNICODE) {
2296 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2301 bytes_returned = 0; /* skip null user */
2304 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2306 /* convert number of 16 bit words to bytes */
2307 bcc_ptr += 2 * bytes_returned;
2308 bcc_ptr += 2; /* trailing null */
2311 cifs_strtoUCS((__le16 *) bcc_ptr,
2312 "CIFS_LINUX_DOM", 32, nls_codepage);
2315 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2317 bcc_ptr += 2 * bytes_returned;
2320 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2322 bcc_ptr += 2 * bytes_returned;
2324 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2326 bcc_ptr += 2 * bytes_returned;
2329 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2331 bcc_ptr += 2 * bytes_returned;
2335 strncpy(bcc_ptr, user, 200);
2336 bcc_ptr += strnlen(user, 200);
2340 if (domain == NULL) {
2341 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2342 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2344 strncpy(bcc_ptr, domain, 64);
2345 bcc_ptr += strnlen(domain, 64);
2349 strcpy(bcc_ptr, "Linux version ");
2350 bcc_ptr += strlen("Linux version ");
2351 strcpy(bcc_ptr, utsname()->release);
2352 bcc_ptr += strlen(utsname()->release) + 1;
2353 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2354 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2356 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2357 smb_buffer->smb_buf_length += count;
2358 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2360 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2361 &bytes_returned, 1);
2363 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2364 } else if ((smb_buffer_response->WordCount == 3)
2365 || (smb_buffer_response->WordCount == 4)) {
2366 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2367 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2368 if (action & GUEST_LOGIN)
2369 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2370 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2372 cFYI(1, ("UID = %d ", ses->Suid));
2373 /* response can have either 3 or 4 word count - Samba sends 3 */
2374 bcc_ptr = pByteArea(smb_buffer_response);
2375 if ((pSMBr->resp.hdr.WordCount == 3)
2376 || ((pSMBr->resp.hdr.WordCount == 4)
2377 && (blob_len < pSMBr->resp.ByteCount))) {
2378 if (pSMBr->resp.hdr.WordCount == 4)
2379 bcc_ptr += blob_len;
2381 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2382 if ((long) (bcc_ptr) % 2) {
2384 (BCC(smb_buffer_response) - 1) / 2;
2385 /* Unicode strings must be word
2390 BCC(smb_buffer_response) / 2;
2393 UniStrnlen((wchar_t *) bcc_ptr,
2394 remaining_words - 1);
2395 /* We look for obvious messed up bcc or strings in response so we do not go off
2396 the end since (at least) WIN2K and Windows XP have a major bug in not null
2397 terminating last Unicode string in response */
2399 kfree(ses->serverOS);
2400 ses->serverOS = kzalloc(2 * (len + 1),
2402 if (ses->serverOS == NULL)
2403 goto sesssetup_nomem;
2404 cifs_strfromUCS_le(ses->serverOS,
2407 bcc_ptr += 2 * (len + 1);
2408 remaining_words -= len + 1;
2409 ses->serverOS[2 * len] = 0;
2410 ses->serverOS[1 + (2 * len)] = 0;
2411 if (remaining_words > 0) {
2412 len = UniStrnlen((wchar_t *)bcc_ptr,
2414 kfree(ses->serverNOS);
2415 ses->serverNOS = kzalloc(2 * (len + 1),
2417 if (ses->serverNOS == NULL)
2418 goto sesssetup_nomem;
2419 cifs_strfromUCS_le(ses->serverNOS,
2422 bcc_ptr += 2 * (len + 1);
2423 ses->serverNOS[2 * len] = 0;
2424 ses->serverNOS[1 + (2 * len)] = 0;
2425 if (strncmp(ses->serverNOS,
2426 "NT LAN Manager 4", 16) == 0) {
2427 cFYI(1, ("NT4 server"));
2428 ses->flags |= CIFS_SES_NT4;
2430 remaining_words -= len + 1;
2431 if (remaining_words > 0) {
2432 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2433 /* last string is not always null terminated
2434 (for e.g. for Windows XP & 2000) */
2435 if (ses->serverDomain)
2436 kfree(ses->serverDomain);
2440 if (ses->serverDomain == NULL)
2441 goto sesssetup_nomem;
2442 cifs_strfromUCS_le(ses->serverDomain,
2445 bcc_ptr += 2 * (len + 1);
2446 ses->serverDomain[2*len] = 0;
2447 ses->serverDomain[1+(2*len)] = 0;
2448 } else { /* else no more room so create
2449 dummy domain string */
2450 if (ses->serverDomain)
2451 kfree(ses->serverDomain);
2453 kzalloc(2, GFP_KERNEL);
2455 } else { /* no room so create dummy domain
2458 /* if these kcallocs fail not much we
2459 can do, but better to not fail the
2461 kfree(ses->serverDomain);
2463 kzalloc(2, GFP_KERNEL);
2464 kfree(ses->serverNOS);
2466 kzalloc(2, GFP_KERNEL);
2468 } else { /* ASCII */
2469 len = strnlen(bcc_ptr, 1024);
2470 if (((long) bcc_ptr + len) - (long)
2471 pByteArea(smb_buffer_response)
2472 <= BCC(smb_buffer_response)) {
2473 kfree(ses->serverOS);
2474 ses->serverOS = kzalloc(len + 1,
2476 if (ses->serverOS == NULL)
2477 goto sesssetup_nomem;
2478 strncpy(ses->serverOS, bcc_ptr, len);
2481 /* null terminate the string */
2485 len = strnlen(bcc_ptr, 1024);
2486 kfree(ses->serverNOS);
2487 ses->serverNOS = kzalloc(len + 1,
2489 if (ses->serverNOS == NULL)
2490 goto sesssetup_nomem;
2491 strncpy(ses->serverNOS, bcc_ptr, len);
2496 len = strnlen(bcc_ptr, 1024);
2497 if (ses->serverDomain)
2498 kfree(ses->serverDomain);
2499 ses->serverDomain = kzalloc(len + 1,
2501 if (ses->serverDomain == NULL)
2502 goto sesssetup_nomem;
2503 strncpy(ses->serverDomain, bcc_ptr,
2510 ("Variable field of length %d "
2511 "extends beyond end of smb ",
2516 (" Security Blob Length extends beyond "
2521 (" Invalid Word count %d: ",
2522 smb_buffer_response->WordCount));
2525 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2526 since that could make reconnection harder, and
2527 reconnection might be needed to free memory */
2529 cifs_buf_release(smb_buffer);
2535 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2536 struct cifsSesInfo *ses, int *pNTLMv2_flag,
2537 const struct nls_table *nls_codepage)
2539 struct smb_hdr *smb_buffer;
2540 struct smb_hdr *smb_buffer_response;
2541 SESSION_SETUP_ANDX *pSMB;
2542 SESSION_SETUP_ANDX *pSMBr;
2546 int remaining_words = 0;
2547 int bytes_returned = 0;
2549 int SecurityBlobLength = sizeof (NEGOTIATE_MESSAGE);
2550 PNEGOTIATE_MESSAGE SecurityBlob;
2551 PCHALLENGE_MESSAGE SecurityBlob2;
2552 __u32 negotiate_flags, capabilities;
2555 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2558 domain = ses->domainName;
2559 *pNTLMv2_flag = FALSE;
2560 smb_buffer = cifs_buf_get();
2561 if (smb_buffer == NULL) {
2564 smb_buffer_response = smb_buffer;
2565 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2566 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2568 /* send SMBsessionSetup here */
2569 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2570 NULL /* no tCon exists yet */ , 12 /* wct */ );
2572 smb_buffer->Mid = GetNextMid(ses->server);
2573 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2574 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2576 pSMB->req.AndXCommand = 0xFF;
2577 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2578 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2580 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2581 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2583 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2584 CAP_EXTENDED_SECURITY;
2585 if (ses->capabilities & CAP_UNICODE) {
2586 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2587 capabilities |= CAP_UNICODE;
2589 if (ses->capabilities & CAP_STATUS32) {
2590 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2591 capabilities |= CAP_STATUS32;
2593 if (ses->capabilities & CAP_DFS) {
2594 smb_buffer->Flags2 |= SMBFLG2_DFS;
2595 capabilities |= CAP_DFS;
2597 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2599 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2600 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2601 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2602 SecurityBlob->MessageType = NtLmNegotiate;
2604 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2605 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2606 NTLMSSP_NEGOTIATE_56 |
2607 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2609 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2610 /* if (ntlmv2_support)
2611 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2612 /* setup pointers to domain name and workstation name */
2613 bcc_ptr += SecurityBlobLength;
2615 SecurityBlob->WorkstationName.Buffer = 0;
2616 SecurityBlob->WorkstationName.Length = 0;
2617 SecurityBlob->WorkstationName.MaximumLength = 0;
2619 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2620 along with username on auth request (ie the response to challenge) */
2621 SecurityBlob->DomainName.Buffer = 0;
2622 SecurityBlob->DomainName.Length = 0;
2623 SecurityBlob->DomainName.MaximumLength = 0;
2624 if (ses->capabilities & CAP_UNICODE) {
2625 if ((long) bcc_ptr % 2) {
2631 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2633 bcc_ptr += 2 * bytes_returned;
2635 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2637 bcc_ptr += 2 * bytes_returned;
2638 bcc_ptr += 2; /* null terminate Linux version */
2640 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2642 bcc_ptr += 2 * bytes_returned;
2645 bcc_ptr += 2; /* null terminate network opsys string */
2648 bcc_ptr += 2; /* null domain */
2649 } else { /* ASCII */
2650 strcpy(bcc_ptr, "Linux version ");
2651 bcc_ptr += strlen("Linux version ");
2652 strcpy(bcc_ptr, utsname()->release);
2653 bcc_ptr += strlen(utsname()->release) + 1;
2654 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2655 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2656 bcc_ptr++; /* empty domain field */
2659 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2660 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2661 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2662 smb_buffer->smb_buf_length += count;
2663 pSMB->req.ByteCount = cpu_to_le16(count);
2665 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2666 &bytes_returned, 1);
2668 if (smb_buffer_response->Status.CifsError ==
2669 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2673 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2674 } else if ((smb_buffer_response->WordCount == 3)
2675 || (smb_buffer_response->WordCount == 4)) {
2676 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2677 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2679 if (action & GUEST_LOGIN)
2680 cFYI(1, (" Guest login"));
2681 /* Do we want to set anything in SesInfo struct when guest login? */
2683 bcc_ptr = pByteArea(smb_buffer_response);
2684 /* response can have either 3 or 4 word count - Samba sends 3 */
2686 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2687 if (SecurityBlob2->MessageType != NtLmChallenge) {
2689 ("Unexpected NTLMSSP message type received %d",
2690 SecurityBlob2->MessageType));
2692 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2693 cFYI(1, ("UID = %d", ses->Suid));
2694 if ((pSMBr->resp.hdr.WordCount == 3)
2695 || ((pSMBr->resp.hdr.WordCount == 4)
2697 pSMBr->resp.ByteCount))) {
2699 if (pSMBr->resp.hdr.WordCount == 4) {
2700 bcc_ptr += blob_len;
2701 cFYI(1, ("Security Blob Length %d",
2705 cFYI(1, ("NTLMSSP Challenge rcvd"));
2707 memcpy(ses->server->cryptKey,
2708 SecurityBlob2->Challenge,
2709 CIFS_CRYPTO_KEY_SIZE);
2710 if (SecurityBlob2->NegotiateFlags &
2711 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2712 *pNTLMv2_flag = TRUE;
2714 if ((SecurityBlob2->NegotiateFlags &
2715 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2716 || (sign_CIFS_PDUs > 1))
2717 ses->server->secMode |=
2718 SECMODE_SIGN_REQUIRED;
2719 if ((SecurityBlob2->NegotiateFlags &
2720 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2721 ses->server->secMode |=
2722 SECMODE_SIGN_ENABLED;
2724 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2725 if ((long) (bcc_ptr) % 2) {
2727 (BCC(smb_buffer_response)
2729 /* Must word align unicode strings */
2734 (smb_buffer_response) / 2;
2737 UniStrnlen((wchar_t *) bcc_ptr,
2738 remaining_words - 1);
2739 /* We look for obvious messed up bcc or strings in response so we do not go off
2740 the end since (at least) WIN2K and Windows XP have a major bug in not null
2741 terminating last Unicode string in response */
2743 kfree(ses->serverOS);
2745 kzalloc(2 * (len + 1), GFP_KERNEL);
2746 cifs_strfromUCS_le(ses->serverOS,
2750 bcc_ptr += 2 * (len + 1);
2751 remaining_words -= len + 1;
2752 ses->serverOS[2 * len] = 0;
2753 ses->serverOS[1 + (2 * len)] = 0;
2754 if (remaining_words > 0) {
2755 len = UniStrnlen((wchar_t *)
2759 kfree(ses->serverNOS);
2761 kzalloc(2 * (len + 1),
2763 cifs_strfromUCS_le(ses->
2769 bcc_ptr += 2 * (len + 1);
2770 ses->serverNOS[2 * len] = 0;
2773 remaining_words -= len + 1;
2774 if (remaining_words > 0) {
2775 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2776 /* last string not always null terminated
2777 (for e.g. for Windows XP & 2000) */
2778 kfree(ses->serverDomain);
2790 ses->serverDomain[2*len]
2795 } /* else no more room so create dummy domain string */
2797 kfree(ses->serverDomain);
2802 } else { /* no room so create dummy domain and NOS string */
2803 kfree(ses->serverDomain);
2805 kzalloc(2, GFP_KERNEL);
2806 kfree(ses->serverNOS);
2808 kzalloc(2, GFP_KERNEL);
2810 } else { /* ASCII */
2811 len = strnlen(bcc_ptr, 1024);
2812 if (((long) bcc_ptr + len) - (long)
2813 pByteArea(smb_buffer_response)
2814 <= BCC(smb_buffer_response)) {
2816 kfree(ses->serverOS);
2820 strncpy(ses->serverOS,
2824 bcc_ptr[0] = 0; /* null terminate string */
2827 len = strnlen(bcc_ptr, 1024);
2828 kfree(ses->serverNOS);
2832 strncpy(ses->serverNOS, bcc_ptr, len);
2837 len = strnlen(bcc_ptr, 1024);
2838 kfree(ses->serverDomain);
2842 strncpy(ses->serverDomain,
2849 ("field of length %d "
2850 "extends beyond end of smb",
2854 cERROR(1, ("Security Blob Length extends beyond"
2858 cERROR(1, ("No session structure passed in."));
2862 (" Invalid Word count %d:",
2863 smb_buffer_response->WordCount));
2868 cifs_buf_release(smb_buffer);
2873 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2874 char *ntlm_session_key, int ntlmv2_flag,
2875 const struct nls_table *nls_codepage)
2877 struct smb_hdr *smb_buffer;
2878 struct smb_hdr *smb_buffer_response;
2879 SESSION_SETUP_ANDX *pSMB;
2880 SESSION_SETUP_ANDX *pSMBr;
2885 int remaining_words = 0;
2886 int bytes_returned = 0;
2888 int SecurityBlobLength = sizeof (AUTHENTICATE_MESSAGE);
2889 PAUTHENTICATE_MESSAGE SecurityBlob;
2890 __u32 negotiate_flags, capabilities;
2893 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
2896 user = ses->userName;
2897 domain = ses->domainName;
2898 smb_buffer = cifs_buf_get();
2899 if (smb_buffer == NULL) {
2902 smb_buffer_response = smb_buffer;
2903 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2904 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2906 /* send SMBsessionSetup here */
2907 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2908 NULL /* no tCon exists yet */ , 12 /* wct */ );
2910 smb_buffer->Mid = GetNextMid(ses->server);
2911 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2912 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2913 pSMB->req.AndXCommand = 0xFF;
2914 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2915 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2917 pSMB->req.hdr.Uid = ses->Suid;
2919 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2920 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2922 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2923 CAP_EXTENDED_SECURITY;
2924 if (ses->capabilities & CAP_UNICODE) {
2925 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2926 capabilities |= CAP_UNICODE;
2928 if (ses->capabilities & CAP_STATUS32) {
2929 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2930 capabilities |= CAP_STATUS32;
2932 if (ses->capabilities & CAP_DFS) {
2933 smb_buffer->Flags2 |= SMBFLG2_DFS;
2934 capabilities |= CAP_DFS;
2936 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2938 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2939 SecurityBlob = (PAUTHENTICATE_MESSAGE) bcc_ptr;
2940 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2941 SecurityBlob->MessageType = NtLmAuthenticate;
2942 bcc_ptr += SecurityBlobLength;
2944 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
2945 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
2946 0x80000000 | NTLMSSP_NEGOTIATE_128;
2948 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
2950 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
2952 /* setup pointers to domain name and workstation name */
2954 SecurityBlob->WorkstationName.Buffer = 0;
2955 SecurityBlob->WorkstationName.Length = 0;
2956 SecurityBlob->WorkstationName.MaximumLength = 0;
2957 SecurityBlob->SessionKey.Length = 0;
2958 SecurityBlob->SessionKey.MaximumLength = 0;
2959 SecurityBlob->SessionKey.Buffer = 0;
2961 SecurityBlob->LmChallengeResponse.Length = 0;
2962 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
2963 SecurityBlob->LmChallengeResponse.Buffer = 0;
2965 SecurityBlob->NtChallengeResponse.Length =
2966 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2967 SecurityBlob->NtChallengeResponse.MaximumLength =
2968 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2969 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
2970 SecurityBlob->NtChallengeResponse.Buffer =
2971 cpu_to_le32(SecurityBlobLength);
2972 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
2973 bcc_ptr += CIFS_SESS_KEY_SIZE;
2975 if (ses->capabilities & CAP_UNICODE) {
2976 if (domain == NULL) {
2977 SecurityBlob->DomainName.Buffer = 0;
2978 SecurityBlob->DomainName.Length = 0;
2979 SecurityBlob->DomainName.MaximumLength = 0;
2982 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2985 SecurityBlob->DomainName.MaximumLength =
2987 SecurityBlob->DomainName.Buffer =
2988 cpu_to_le32(SecurityBlobLength);
2990 SecurityBlobLength += len;
2991 SecurityBlob->DomainName.Length =
2995 SecurityBlob->UserName.Buffer = 0;
2996 SecurityBlob->UserName.Length = 0;
2997 SecurityBlob->UserName.MaximumLength = 0;
3000 cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
3003 SecurityBlob->UserName.MaximumLength =
3005 SecurityBlob->UserName.Buffer =
3006 cpu_to_le32(SecurityBlobLength);
3008 SecurityBlobLength += len;
3009 SecurityBlob->UserName.Length =
3013 /* SecurityBlob->WorkstationName.Length =
3014 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3015 SecurityBlob->WorkstationName.Length *= 2;
3016 SecurityBlob->WorkstationName.MaximumLength =
3017 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3018 SecurityBlob->WorkstationName.Buffer =
3019 cpu_to_le32(SecurityBlobLength);
3020 bcc_ptr += SecurityBlob->WorkstationName.Length;
3021 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3022 SecurityBlob->WorkstationName.Length =
3023 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3025 if ((long) bcc_ptr % 2) {
3030 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3032 bcc_ptr += 2 * bytes_returned;
3034 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3036 bcc_ptr += 2 * bytes_returned;
3037 bcc_ptr += 2; /* null term version string */
3039 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3041 bcc_ptr += 2 * bytes_returned;
3044 bcc_ptr += 2; /* null terminate network opsys string */
3047 bcc_ptr += 2; /* null domain */
3048 } else { /* ASCII */
3049 if (domain == NULL) {
3050 SecurityBlob->DomainName.Buffer = 0;
3051 SecurityBlob->DomainName.Length = 0;
3052 SecurityBlob->DomainName.MaximumLength = 0;
3055 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3056 strncpy(bcc_ptr, domain, 63);
3057 len = strnlen(domain, 64);
3058 SecurityBlob->DomainName.MaximumLength =
3060 SecurityBlob->DomainName.Buffer =
3061 cpu_to_le32(SecurityBlobLength);
3063 SecurityBlobLength += len;
3064 SecurityBlob->DomainName.Length = cpu_to_le16(len);
3067 SecurityBlob->UserName.Buffer = 0;
3068 SecurityBlob->UserName.Length = 0;
3069 SecurityBlob->UserName.MaximumLength = 0;
3072 strncpy(bcc_ptr, user, 63);
3073 len = strnlen(user, 64);
3074 SecurityBlob->UserName.MaximumLength =
3076 SecurityBlob->UserName.Buffer =
3077 cpu_to_le32(SecurityBlobLength);
3079 SecurityBlobLength += len;
3080 SecurityBlob->UserName.Length = cpu_to_le16(len);
3082 /* BB fill in our workstation name if known BB */
3084 strcpy(bcc_ptr, "Linux version ");
3085 bcc_ptr += strlen("Linux version ");
3086 strcpy(bcc_ptr, utsname()->release);
3087 bcc_ptr += strlen(utsname()->release) + 1;
3088 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3089 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3090 bcc_ptr++; /* null domain */
3093 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3094 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3095 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3096 smb_buffer->smb_buf_length += count;
3097 pSMB->req.ByteCount = cpu_to_le16(count);
3099 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3100 &bytes_returned, 1);
3102 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
3103 } else if ((smb_buffer_response->WordCount == 3)
3104 || (smb_buffer_response->WordCount == 4)) {
3105 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3107 le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3108 if (action & GUEST_LOGIN)
3109 cFYI(1, (" Guest login")); /* BB Should we set anything
3110 in SesInfo struct ? */
3111 /* if (SecurityBlob2->MessageType != NtLm??) {
3112 cFYI("Unexpected message type on auth response is %d"));
3117 ("Check challenge UID %d vs auth response UID %d",
3118 ses->Suid, smb_buffer_response->Uid));
3119 /* UID left in wire format */
3120 ses->Suid = smb_buffer_response->Uid;
3121 bcc_ptr = pByteArea(smb_buffer_response);
3122 /* response can have either 3 or 4 word count - Samba sends 3 */
3123 if ((pSMBr->resp.hdr.WordCount == 3)
3124 || ((pSMBr->resp.hdr.WordCount == 4)
3126 pSMBr->resp.ByteCount))) {
3127 if (pSMBr->resp.hdr.WordCount == 4) {
3131 ("Security Blob Length %d ",
3136 ("NTLMSSP response to Authenticate "));
3138 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3139 if ((long) (bcc_ptr) % 2) {
3141 (BCC(smb_buffer_response)
3143 bcc_ptr++; /* Unicode strings must be word aligned */
3145 remaining_words = BCC(smb_buffer_response) / 2;
3148 UniStrnlen((wchar_t *) bcc_ptr,remaining_words - 1);
3149 /* We look for obvious messed up bcc or strings in response so we do not go off
3150 the end since (at least) WIN2K and Windows XP have a major bug in not null
3151 terminating last Unicode string in response */
3153 kfree(ses->serverOS);
3155 kzalloc(2 * (len + 1), GFP_KERNEL);
3156 cifs_strfromUCS_le(ses->serverOS,
3160 bcc_ptr += 2 * (len + 1);
3161 remaining_words -= len + 1;
3162 ses->serverOS[2 * len] = 0;
3163 ses->serverOS[1 + (2 * len)] = 0;
3164 if (remaining_words > 0) {
3165 len = UniStrnlen((wchar_t *)
3169 kfree(ses->serverNOS);
3171 kzalloc(2 * (len + 1),
3173 cifs_strfromUCS_le(ses->
3179 bcc_ptr += 2 * (len + 1);
3180 ses->serverNOS[2 * len] = 0;
3181 ses->serverNOS[1+(2*len)] = 0;
3182 remaining_words -= len + 1;
3183 if (remaining_words > 0) {
3184 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3185 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3186 if (ses->serverDomain)
3187 kfree(ses->serverDomain);
3212 } /* else no more room so create dummy domain string */
3214 if (ses->serverDomain)
3215 kfree(ses->serverDomain);
3216 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3218 } else { /* no room so create dummy domain and NOS string */
3219 if (ses->serverDomain)
3220 kfree(ses->serverDomain);
3221 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3222 kfree(ses->serverNOS);
3223 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3225 } else { /* ASCII */
3226 len = strnlen(bcc_ptr, 1024);
3227 if (((long) bcc_ptr + len) -
3228 (long) pByteArea(smb_buffer_response)
3229 <= BCC(smb_buffer_response)) {
3231 kfree(ses->serverOS);
3232 ses->serverOS = kzalloc(len + 1,GFP_KERNEL);
3233 strncpy(ses->serverOS,bcc_ptr, len);
3236 bcc_ptr[0] = 0; /* null terminate the string */
3239 len = strnlen(bcc_ptr, 1024);
3240 kfree(ses->serverNOS);
3241 ses->serverNOS = kzalloc(len+1,
3243 strncpy(ses->serverNOS,
3249 len = strnlen(bcc_ptr, 1024);
3250 if (ses->serverDomain)
3251 kfree(ses->serverDomain);
3255 strncpy(ses->serverDomain,
3262 ("field of length %d "
3263 "extends beyond end of smb ",
3268 (" Security Blob extends beyond end "
3272 cERROR(1, ("No session structure passed in."));
3276 (" Invalid Word count %d: ",
3277 smb_buffer_response->WordCount));
3282 cifs_buf_release(smb_buffer);
3288 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3289 const char *tree, struct cifsTconInfo *tcon,
3290 const struct nls_table *nls_codepage)
3292 struct smb_hdr *smb_buffer;
3293 struct smb_hdr *smb_buffer_response;
3296 unsigned char *bcc_ptr;
3304 smb_buffer = cifs_buf_get();
3305 if (smb_buffer == NULL) {
3308 smb_buffer_response = smb_buffer;
3310 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3311 NULL /*no tid */ , 4 /*wct */ );
3313 smb_buffer->Mid = GetNextMid(ses->server);
3314 smb_buffer->Uid = ses->Suid;
3315 pSMB = (TCONX_REQ *) smb_buffer;
3316 pSMBr = (TCONX_RSP *) smb_buffer_response;
3318 pSMB->AndXCommand = 0xFF;
3319 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3320 bcc_ptr = &pSMB->Password[0];
3321 if ((ses->server->secMode) & SECMODE_USER) {
3322 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3323 *bcc_ptr = 0; /* password is null byte */
3324 bcc_ptr++; /* skip password */
3325 /* already aligned so no need to do it below */
3327 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3328 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3329 specified as required (when that support is added to
3330 the vfs in the future) as only NTLM or the much
3331 weaker LANMAN (which we do not send by default) is accepted
3332 by Samba (not sure whether other servers allow
3333 NTLMv2 password here) */
3334 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3335 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3336 (ses->server->secType == LANMAN))
3337 calc_lanman_hash(ses, bcc_ptr);
3339 #endif /* CIFS_WEAK_PW_HASH */
3340 SMBNTencrypt(ses->password,
3341 ses->server->cryptKey,
3344 bcc_ptr += CIFS_SESS_KEY_SIZE;
3345 if (ses->capabilities & CAP_UNICODE) {
3346 /* must align unicode strings */
3347 *bcc_ptr = 0; /* null byte password */
3352 if (ses->server->secMode &
3353 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3354 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3356 if (ses->capabilities & CAP_STATUS32) {
3357 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3359 if (ses->capabilities & CAP_DFS) {
3360 smb_buffer->Flags2 |= SMBFLG2_DFS;
3362 if (ses->capabilities & CAP_UNICODE) {
3363 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3365 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3366 6 /* max utf8 char length in bytes */ *
3367 (/* server len*/ + 256 /* share len */), nls_codepage);
3368 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3369 bcc_ptr += 2; /* skip trailing null */
3370 } else { /* ASCII */
3371 strcpy(bcc_ptr, tree);
3372 bcc_ptr += strlen(tree) + 1;
3374 strcpy(bcc_ptr, "?????");
3375 bcc_ptr += strlen("?????");
3377 count = bcc_ptr - &pSMB->Password[0];
3378 pSMB->hdr.smb_buf_length += count;
3379 pSMB->ByteCount = cpu_to_le16(count);
3381 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length, 0);
3383 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3384 /* above now done in SendReceive */
3385 if ((rc == 0) && (tcon != NULL)) {
3386 tcon->tidStatus = CifsGood;
3387 tcon->tid = smb_buffer_response->Tid;
3388 bcc_ptr = pByteArea(smb_buffer_response);
3389 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3390 /* skip service field (NB: this field is always ASCII) */
3391 bcc_ptr += length + 1;
3392 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3393 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3394 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3395 if ((bcc_ptr + (2 * length)) -
3396 pByteArea(smb_buffer_response) <=
3397 BCC(smb_buffer_response)) {
3398 kfree(tcon->nativeFileSystem);
3399 tcon->nativeFileSystem =
3400 kzalloc(length + 2, GFP_KERNEL);
3401 cifs_strfromUCS_le(tcon->nativeFileSystem,
3403 length, nls_codepage);
3404 bcc_ptr += 2 * length;
3405 bcc_ptr[0] = 0; /* null terminate the string */
3409 /* else do not bother copying these information fields*/
3411 length = strnlen(bcc_ptr, 1024);
3412 if ((bcc_ptr + length) -
3413 pByteArea(smb_buffer_response) <=
3414 BCC(smb_buffer_response)) {
3415 kfree(tcon->nativeFileSystem);
3416 tcon->nativeFileSystem =
3417 kzalloc(length + 1, GFP_KERNEL);
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;