4 * Copyright (C) International Business Machines Corp., 2002,2008
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 extern void SMBNTencrypt(unsigned char *passwd
, unsigned char *c8
,
55 extern mempool_t
*cifs_req_poolp
;
63 char *in6_addr
; /* ipv6 address as human readable form of in6_addr */
64 char *iocharset
; /* local code page for mapping to and from Unicode */
65 char source_rfc1001_name
[16]; /* netbios name of client */
66 char target_rfc1001_name
[16]; /* netbios name of server for Win9x/ME */
80 bool no_psx_acl
:1; /* set if posix acl support should be disabled */
82 bool no_xattr
:1; /* set if xattr (EA) support should be disabled*/
83 bool server_ino
:1; /* use inode numbers from server ie UniqueId */
85 bool remap
:1; /* set to remap seven reserved chars in filenames */
86 bool posix_paths
:1; /* unset to not ask for posix pathnames. */
89 bool nullauth
:1; /* attempt to authenticate with null user */
90 bool nocase
:1; /* request case insensitive filenames */
91 bool nobrl
:1; /* disable sending byte range locks to srv */
92 bool seal
:1; /* request transport encryption on share */
97 unsigned short int port
;
101 static int ipv4_connect(struct sockaddr_in
*psin_server
,
102 struct socket
**csocket
,
104 char *server_netb_name
);
105 static int ipv6_connect(struct sockaddr_in6
*psin_server
,
106 struct socket
**csocket
);
110 * cifs tcp session reconnection
112 * mark tcp session as reconnecting so temporarily locked
113 * mark all smb sessions as reconnecting for tcp session
114 * reconnect tcp session
115 * wake up waiters on reconnection? - (not needed currently)
119 cifs_reconnect(struct TCP_Server_Info
*server
)
122 struct list_head
*tmp
;
123 struct cifsSesInfo
*ses
;
124 struct cifsTconInfo
*tcon
;
125 struct mid_q_entry
*mid_entry
;
127 spin_lock(&GlobalMid_Lock
);
128 if (kthread_should_stop()) {
129 /* the demux thread will exit normally
130 next time through the loop */
131 spin_unlock(&GlobalMid_Lock
);
134 server
->tcpStatus
= CifsNeedReconnect
;
135 spin_unlock(&GlobalMid_Lock
);
138 cFYI(1, ("Reconnecting tcp session"));
140 /* before reconnecting the tcp session, mark the smb session (uid)
141 and the tid bad so they are not used until reconnected */
142 read_lock(&GlobalSMBSeslock
);
143 list_for_each(tmp
, &GlobalSMBSessionList
) {
144 ses
= list_entry(tmp
, struct cifsSesInfo
, cifsSessionList
);
146 if (ses
->server
== server
) {
147 ses
->status
= CifsNeedReconnect
;
151 /* else tcp and smb sessions need reconnection */
153 list_for_each(tmp
, &GlobalTreeConnectionList
) {
154 tcon
= list_entry(tmp
, struct cifsTconInfo
, cifsConnectionList
);
155 if ((tcon
->ses
) && (tcon
->ses
->server
== server
))
156 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 kernel_sock_shutdown(server
->ssocket
, SHUT_WR
);
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
177 if (mid_entry
->midState
== MID_REQUEST_SUBMITTED
) {
178 /* Mark other intransit requests as needing
179 retry so we do not immediately mark the
180 session bad again (ie after we reconnect
181 below) as they timeout too */
182 mid_entry
->midState
= MID_RETRY_NEEDED
;
185 spin_unlock(&GlobalMid_Lock
);
188 while ((!kthread_should_stop()) && (server
->tcpStatus
!= CifsGood
)) {
190 if (server
->protocolType
== IPV6
) {
191 rc
= ipv6_connect(&server
->addr
.sockAddr6
,
194 rc
= ipv4_connect(&server
->addr
.sockAddr
,
196 server
->workstation_RFC1001_name
,
197 server
->server_RFC1001_name
);
200 cFYI(1, ("reconnect error %d", rc
));
203 atomic_inc(&tcpSesReconnectCount
);
204 spin_lock(&GlobalMid_Lock
);
205 if (!kthread_should_stop())
206 server
->tcpStatus
= CifsGood
;
207 server
->sequence_number
= 0;
208 spin_unlock(&GlobalMid_Lock
);
209 /* atomic_set(&server->inFlight,0);*/
210 wake_up(&server
->response_q
);
218 0 not a transact2, or all data present
219 >0 transact2 with that much data missing
220 -EINVAL = invalid transact2
223 static int check2ndT2(struct smb_hdr
*pSMB
, unsigned int maxBufSize
)
225 struct smb_t2_rsp
*pSMBt
;
227 int data_in_this_rsp
;
230 if (pSMB
->Command
!= SMB_COM_TRANSACTION2
)
233 /* check for plausible wct, bcc and t2 data and parm sizes */
234 /* check for parm and data offset going beyond end of smb */
235 if (pSMB
->WordCount
!= 10) { /* coalesce_t2 depends on this */
236 cFYI(1, ("invalid transact2 word count"));
240 pSMBt
= (struct smb_t2_rsp
*)pSMB
;
242 total_data_size
= le16_to_cpu(pSMBt
->t2_rsp
.TotalDataCount
);
243 data_in_this_rsp
= le16_to_cpu(pSMBt
->t2_rsp
.DataCount
);
245 remaining
= total_data_size
- data_in_this_rsp
;
249 else if (remaining
< 0) {
250 cFYI(1, ("total data %d smaller than data in frame %d",
251 total_data_size
, data_in_this_rsp
));
254 cFYI(1, ("missing %d bytes from transact2, check next response",
256 if (total_data_size
> maxBufSize
) {
257 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
258 total_data_size
, maxBufSize
));
265 static int coalesce_t2(struct smb_hdr
*psecond
, struct smb_hdr
*pTargetSMB
)
267 struct smb_t2_rsp
*pSMB2
= (struct smb_t2_rsp
*)psecond
;
268 struct smb_t2_rsp
*pSMBt
= (struct smb_t2_rsp
*)pTargetSMB
;
273 char *data_area_of_target
;
274 char *data_area_of_buf2
;
277 total_data_size
= le16_to_cpu(pSMBt
->t2_rsp
.TotalDataCount
);
279 if (total_data_size
!= le16_to_cpu(pSMB2
->t2_rsp
.TotalDataCount
)) {
280 cFYI(1, ("total data size of primary and secondary t2 differ"));
283 total_in_buf
= le16_to_cpu(pSMBt
->t2_rsp
.DataCount
);
285 remaining
= total_data_size
- total_in_buf
;
290 if (remaining
== 0) /* nothing to do, ignore */
293 total_in_buf2
= le16_to_cpu(pSMB2
->t2_rsp
.DataCount
);
294 if (remaining
< total_in_buf2
) {
295 cFYI(1, ("transact2 2nd response contains too much data"));
298 /* find end of first SMB data area */
299 data_area_of_target
= (char *)&pSMBt
->hdr
.Protocol
+
300 le16_to_cpu(pSMBt
->t2_rsp
.DataOffset
);
301 /* validate target area */
303 data_area_of_buf2
= (char *) &pSMB2
->hdr
.Protocol
+
304 le16_to_cpu(pSMB2
->t2_rsp
.DataOffset
);
306 data_area_of_target
+= total_in_buf
;
308 /* copy second buffer into end of first buffer */
309 memcpy(data_area_of_target
, data_area_of_buf2
, total_in_buf2
);
310 total_in_buf
+= total_in_buf2
;
311 pSMBt
->t2_rsp
.DataCount
= cpu_to_le16(total_in_buf
);
312 byte_count
= le16_to_cpu(BCC_LE(pTargetSMB
));
313 byte_count
+= total_in_buf2
;
314 BCC_LE(pTargetSMB
) = cpu_to_le16(byte_count
);
316 byte_count
= pTargetSMB
->smb_buf_length
;
317 byte_count
+= total_in_buf2
;
319 /* BB also add check that we are not beyond maximum buffer size */
321 pTargetSMB
->smb_buf_length
= byte_count
;
323 if (remaining
== total_in_buf2
) {
324 cFYI(1, ("found the last secondary response"));
325 return 0; /* we are done */
326 } else /* more responses to go */
332 cifs_demultiplex_thread(struct TCP_Server_Info
*server
)
335 unsigned int pdu_length
, total_read
;
336 struct smb_hdr
*smb_buffer
= NULL
;
337 struct smb_hdr
*bigbuf
= NULL
;
338 struct smb_hdr
*smallbuf
= NULL
;
339 struct msghdr smb_msg
;
341 struct socket
*csocket
= server
->ssocket
;
342 struct list_head
*tmp
;
343 struct cifsSesInfo
*ses
;
344 struct task_struct
*task_to_wake
= NULL
;
345 struct mid_q_entry
*mid_entry
;
347 bool isLargeBuf
= false;
351 current
->flags
|= PF_MEMALLOC
;
352 cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current
)));
354 length
= atomic_inc_return(&tcpSesAllocCount
);
356 mempool_resize(cifs_req_poolp
, length
+ cifs_min_rcv
,
360 while (!kthread_should_stop()) {
363 if (bigbuf
== NULL
) {
364 bigbuf
= cifs_buf_get();
366 cERROR(1, ("No memory for large SMB response"));
368 /* retry will check if exiting */
371 } else if (isLargeBuf
) {
372 /* we are reusing a dirty large buf, clear its start */
373 memset(bigbuf
, 0, sizeof(struct smb_hdr
));
376 if (smallbuf
== NULL
) {
377 smallbuf
= cifs_small_buf_get();
379 cERROR(1, ("No memory for SMB response"));
381 /* retry will check if exiting */
384 /* beginning of smb buffer is cleared in our buf_get */
385 } else /* if existing small buf clear beginning */
386 memset(smallbuf
, 0, sizeof(struct smb_hdr
));
390 smb_buffer
= smallbuf
;
391 iov
.iov_base
= smb_buffer
;
393 smb_msg
.msg_control
= NULL
;
394 smb_msg
.msg_controllen
= 0;
395 pdu_length
= 4; /* enough to get RFC1001 header */
398 kernel_recvmsg(csocket
, &smb_msg
,
399 &iov
, 1, pdu_length
, 0 /* BB other flags? */);
401 if (kthread_should_stop()) {
403 } else if (server
->tcpStatus
== CifsNeedReconnect
) {
404 cFYI(1, ("Reconnect after server stopped responding"));
405 cifs_reconnect(server
);
406 cFYI(1, ("call to reconnect done"));
407 csocket
= server
->ssocket
;
409 } else if ((length
== -ERESTARTSYS
) || (length
== -EAGAIN
)) {
410 msleep(1); /* minimum sleep to prevent looping
411 allowing socket to clear and app threads to set
412 tcpStatus CifsNeedReconnect if server hung */
417 } else if (length
<= 0) {
418 if (server
->tcpStatus
== CifsNew
) {
419 cFYI(1, ("tcp session abend after SMBnegprot"));
420 /* some servers kill the TCP session rather than
421 returning an SMB negprot error, in which
422 case reconnecting here is not going to help,
423 and so simply return error to mount */
426 if (!try_to_freeze() && (length
== -EINTR
)) {
427 cFYI(1, ("cifsd thread killed"));
430 cFYI(1, ("Reconnect after unexpected peek error %d",
432 cifs_reconnect(server
);
433 csocket
= server
->ssocket
;
434 wake_up(&server
->response_q
);
436 } else if (length
< pdu_length
) {
437 cFYI(1, ("requested %d bytes but only got %d bytes",
438 pdu_length
, length
));
439 pdu_length
-= length
;
444 /* The right amount was read from socket - 4 bytes */
445 /* so we can now interpret the length field */
447 /* the first byte big endian of the length field,
448 is actually not part of the length but the type
449 with the most common, zero, as regular data */
450 temp
= *((char *) smb_buffer
);
452 /* Note that FC 1001 length is big endian on the wire,
453 but we convert it here so it is always manipulated
454 as host byte order */
455 pdu_length
= be32_to_cpu((__force __be32
)smb_buffer
->smb_buf_length
);
456 smb_buffer
->smb_buf_length
= pdu_length
;
458 cFYI(1, ("rfc1002 length 0x%x", pdu_length
+4));
460 if (temp
== (char) RFC1002_SESSION_KEEP_ALIVE
) {
462 } else if (temp
== (char)RFC1002_POSITIVE_SESSION_RESPONSE
) {
463 cFYI(1, ("Good RFC 1002 session rsp"));
465 } else if (temp
== (char)RFC1002_NEGATIVE_SESSION_RESPONSE
) {
466 /* we get this from Windows 98 instead of
467 an error on SMB negprot response */
468 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
470 if (server
->tcpStatus
== CifsNew
) {
471 /* if nack on negprot (rather than
472 ret of smb negprot error) reconnecting
473 not going to help, ret error to mount */
476 /* give server a second to
477 clean up before reconnect attempt */
479 /* always try 445 first on reconnect
480 since we get NACK on some if we ever
481 connected to port 139 (the NACK is
482 since we do not begin with RFC1001
483 session initialize frame) */
484 server
->addr
.sockAddr
.sin_port
=
486 cifs_reconnect(server
);
487 csocket
= server
->ssocket
;
488 wake_up(&server
->response_q
);
491 } else if (temp
!= (char) 0) {
492 cERROR(1, ("Unknown RFC 1002 frame"));
493 cifs_dump_mem(" Received Data: ", (char *)smb_buffer
,
495 cifs_reconnect(server
);
496 csocket
= server
->ssocket
;
500 /* else we have an SMB response */
501 if ((pdu_length
> CIFSMaxBufSize
+ MAX_CIFS_HDR_SIZE
- 4) ||
502 (pdu_length
< sizeof(struct smb_hdr
) - 1 - 4)) {
503 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
504 length
, pdu_length
+4));
505 cifs_reconnect(server
);
506 csocket
= server
->ssocket
;
507 wake_up(&server
->response_q
);
514 if (pdu_length
> MAX_CIFS_SMALL_BUFFER_SIZE
- 4) {
516 memcpy(bigbuf
, smallbuf
, 4);
520 iov
.iov_base
= 4 + (char *)smb_buffer
;
521 iov
.iov_len
= pdu_length
;
522 for (total_read
= 0; total_read
< pdu_length
;
523 total_read
+= length
) {
524 length
= kernel_recvmsg(csocket
, &smb_msg
, &iov
, 1,
525 pdu_length
- total_read
, 0);
526 if (kthread_should_stop() ||
527 (length
== -EINTR
)) {
531 } else if (server
->tcpStatus
== CifsNeedReconnect
) {
532 cifs_reconnect(server
);
533 csocket
= server
->ssocket
;
534 /* Reconnect wakes up rspns q */
535 /* Now we will reread sock */
538 } else if ((length
== -ERESTARTSYS
) ||
539 (length
== -EAGAIN
)) {
540 msleep(1); /* minimum sleep to prevent looping,
541 allowing socket to clear and app
542 threads to set tcpStatus
543 CifsNeedReconnect if server hung*/
546 } else if (length
<= 0) {
547 cERROR(1, ("Received no data, expecting %d",
548 pdu_length
- total_read
));
549 cifs_reconnect(server
);
550 csocket
= server
->ssocket
;
557 else if (reconnect
== 1)
560 length
+= 4; /* account for rfc1002 hdr */
563 dump_smb(smb_buffer
, length
);
564 if (checkSMB(smb_buffer
, smb_buffer
->Mid
, total_read
+4)) {
565 cifs_dump_mem("Bad SMB: ", smb_buffer
, 48);
571 spin_lock(&GlobalMid_Lock
);
572 list_for_each(tmp
, &server
->pending_mid_q
) {
573 mid_entry
= list_entry(tmp
, struct mid_q_entry
, qhead
);
575 if ((mid_entry
->mid
== smb_buffer
->Mid
) &&
576 (mid_entry
->midState
== MID_REQUEST_SUBMITTED
) &&
577 (mid_entry
->command
== smb_buffer
->Command
)) {
578 if (check2ndT2(smb_buffer
,server
->maxBuf
) > 0) {
579 /* We have a multipart transact2 resp */
581 if (mid_entry
->resp_buf
) {
582 /* merge response - fix up 1st*/
583 if (coalesce_t2(smb_buffer
,
584 mid_entry
->resp_buf
)) {
585 mid_entry
->multiRsp
=
589 /* all parts received */
590 mid_entry
->multiEnd
=
596 cERROR(1,("1st trans2 resp needs bigbuf"));
597 /* BB maybe we can fix this up, switch
598 to already allocated large buffer? */
600 /* Have first buffer */
601 mid_entry
->resp_buf
=
603 mid_entry
->largeBuf
=
610 mid_entry
->resp_buf
= smb_buffer
;
611 mid_entry
->largeBuf
= isLargeBuf
;
613 task_to_wake
= mid_entry
->tsk
;
614 mid_entry
->midState
= MID_RESPONSE_RECEIVED
;
615 #ifdef CONFIG_CIFS_STATS2
616 mid_entry
->when_received
= jiffies
;
618 /* so we do not time out requests to server
619 which is still responding (since server could
620 be busy but not dead) */
621 server
->lstrp
= jiffies
;
625 spin_unlock(&GlobalMid_Lock
);
627 /* Was previous buf put in mpx struct for multi-rsp? */
629 /* smb buffer will be freed by user thread */
635 wake_up_process(task_to_wake
);
636 } else if (!is_valid_oplock_break(smb_buffer
, server
) &&
638 cERROR(1, ("No task to wake, unknown frame received! "
639 "NumMids %d", midCount
.counter
));
640 cifs_dump_mem("Received Data is: ", (char *)smb_buffer
,
641 sizeof(struct smb_hdr
));
642 #ifdef CONFIG_CIFS_DEBUG2
643 cifs_dump_detail(smb_buffer
);
644 cifs_dump_mids(server
);
645 #endif /* CIFS_DEBUG2 */
648 } /* end while !EXITING */
650 spin_lock(&GlobalMid_Lock
);
651 server
->tcpStatus
= CifsExiting
;
652 spin_unlock(&GlobalMid_Lock
);
653 wake_up_all(&server
->response_q
);
655 /* don't exit until kthread_stop is called */
656 set_current_state(TASK_UNINTERRUPTIBLE
);
657 while (!kthread_should_stop()) {
659 set_current_state(TASK_UNINTERRUPTIBLE
);
661 set_current_state(TASK_RUNNING
);
663 /* check if we have blocked requests that need to free */
664 /* Note that cifs_max_pending is normally 50, but
665 can be set at module install time to as little as two */
666 spin_lock(&GlobalMid_Lock
);
667 if (atomic_read(&server
->inFlight
) >= cifs_max_pending
)
668 atomic_set(&server
->inFlight
, cifs_max_pending
- 1);
669 /* We do not want to set the max_pending too low or we
670 could end up with the counter going negative */
671 spin_unlock(&GlobalMid_Lock
);
672 /* Although there should not be any requests blocked on
673 this queue it can not hurt to be paranoid and try to wake up requests
674 that may haven been blocked when more than 50 at time were on the wire
675 to the same server - they now will see the session is in exit state
676 and get out of SendReceive. */
677 wake_up_all(&server
->request_q
);
678 /* give those requests time to exit */
681 if (server
->ssocket
) {
682 sock_release(csocket
);
683 server
->ssocket
= NULL
;
685 /* buffer usuallly freed in free_mid - need to free it here on exit */
686 cifs_buf_release(bigbuf
);
687 if (smallbuf
) /* no sense logging a debug message if NULL */
688 cifs_small_buf_release(smallbuf
);
690 read_lock(&GlobalSMBSeslock
);
691 if (list_empty(&server
->pending_mid_q
)) {
692 /* loop through server session structures attached to this and
694 list_for_each(tmp
, &GlobalSMBSessionList
) {
696 list_entry(tmp
, struct cifsSesInfo
,
698 if (ses
->server
== server
) {
699 ses
->status
= CifsExiting
;
703 read_unlock(&GlobalSMBSeslock
);
705 /* although we can not zero the server struct pointer yet,
706 since there are active requests which may depnd on them,
707 mark the corresponding SMB sessions as exiting too */
708 list_for_each(tmp
, &GlobalSMBSessionList
) {
709 ses
= list_entry(tmp
, struct cifsSesInfo
,
711 if (ses
->server
== server
)
712 ses
->status
= CifsExiting
;
715 spin_lock(&GlobalMid_Lock
);
716 list_for_each(tmp
, &server
->pending_mid_q
) {
717 mid_entry
= list_entry(tmp
, struct mid_q_entry
, qhead
);
718 if (mid_entry
->midState
== MID_REQUEST_SUBMITTED
) {
719 cFYI(1, ("Clearing Mid 0x%x - waking up ",
721 task_to_wake
= mid_entry
->tsk
;
723 wake_up_process(task_to_wake
);
726 spin_unlock(&GlobalMid_Lock
);
727 read_unlock(&GlobalSMBSeslock
);
728 /* 1/8th of sec is more than enough time for them to exit */
732 if (!list_empty(&server
->pending_mid_q
)) {
733 /* mpx threads have not exited yet give them
734 at least the smb send timeout time for long ops */
735 /* due to delays on oplock break requests, we need
736 to wait at least 45 seconds before giving up
737 on a request getting a response and going ahead
739 cFYI(1, ("Wait for exit from demultiplex thread"));
741 /* if threads still have not exited they are probably never
742 coming home not much else we can do but free the memory */
745 /* last chance to mark ses pointers invalid
746 if there are any pointing to this (e.g
747 if a crazy root user tried to kill cifsd
748 kernel thread explicitly this might happen) */
749 write_lock(&GlobalSMBSeslock
);
750 list_for_each(tmp
, &GlobalSMBSessionList
) {
751 ses
= list_entry(tmp
, struct cifsSesInfo
,
753 if (ses
->server
== server
)
756 write_unlock(&GlobalSMBSeslock
);
758 kfree(server
->hostname
);
761 length
= atomic_dec_return(&tcpSesAllocCount
);
763 mempool_resize(cifs_req_poolp
, length
+ cifs_min_rcv
,
769 /* extract the host portion of the UNC string */
771 extract_hostname(const char *unc
)
777 /* skip double chars at beginning of string */
778 /* BB: check validity of these bytes? */
781 /* delimiter between hostname and sharename is always '\\' now */
782 delim
= strchr(src
, '\\');
784 return ERR_PTR(-EINVAL
);
787 dst
= kmalloc((len
+ 1), GFP_KERNEL
);
789 return ERR_PTR(-ENOMEM
);
791 memcpy(dst
, src
, len
);
798 cifs_parse_mount_options(char *options
, const char *devname
,
803 unsigned int temp_len
, i
, j
;
809 if (Local_System_Name
[0] != 0)
810 memcpy(vol
->source_rfc1001_name
, Local_System_Name
, 15);
812 char *nodename
= utsname()->nodename
;
813 int n
= strnlen(nodename
, 15);
814 memset(vol
->source_rfc1001_name
, 0x20, 15);
815 for (i
= 0; i
< n
; i
++) {
816 /* does not have to be perfect mapping since field is
817 informational, only used for servers that do not support
818 port 445 and it can be overridden at mount time */
819 vol
->source_rfc1001_name
[i
] = toupper(nodename
[i
]);
822 vol
->source_rfc1001_name
[15] = 0;
823 /* null target name indicates to use *SMBSERVR default called name
824 if we end up sending RFC1001 session initialize */
825 vol
->target_rfc1001_name
[0] = 0;
826 vol
->linux_uid
= current
->uid
; /* current->euid instead? */
827 vol
->linux_gid
= current
->gid
;
828 vol
->dir_mode
= S_IRWXUGO
;
829 /* 2767 perms indicate mandatory locking support */
830 vol
->file_mode
= (S_IRWXUGO
| S_ISGID
) & (~S_IXGRP
);
832 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
834 /* default is always to request posix paths. */
835 vol
->posix_paths
= 1;
840 if (strncmp(options
, "sep=", 4) == 0) {
841 if (options
[4] != 0) {
842 separator
[0] = options
[4];
845 cFYI(1, ("Null separator not allowed"));
849 while ((data
= strsep(&options
, separator
)) != NULL
) {
852 if ((value
= strchr(data
, '=')) != NULL
)
855 /* Have to parse this before we parse for "user" */
856 if (strnicmp(data
, "user_xattr", 10) == 0) {
858 } else if (strnicmp(data
, "nouser_xattr", 12) == 0) {
860 } else if (strnicmp(data
, "user", 4) == 0) {
863 "CIFS: invalid or missing username\n");
864 return 1; /* needs_arg; */
865 } else if (!*value
) {
866 /* null user, ie anonymous, authentication */
869 if (strnlen(value
, 200) < 200) {
870 vol
->username
= value
;
872 printk(KERN_WARNING
"CIFS: username too long\n");
875 } else if (strnicmp(data
, "pass", 4) == 0) {
877 vol
->password
= NULL
;
879 } else if (value
[0] == 0) {
880 /* check if string begins with double comma
881 since that would mean the password really
882 does start with a comma, and would not
883 indicate an empty string */
884 if (value
[1] != separator
[0]) {
885 vol
->password
= NULL
;
889 temp_len
= strlen(value
);
890 /* removed password length check, NTLM passwords
891 can be arbitrarily long */
893 /* if comma in password, the string will be
894 prematurely null terminated. Commas in password are
895 specified across the cifs mount interface by a double
896 comma ie ,, and a comma used as in other cases ie ','
897 as a parameter delimiter/separator is single and due
898 to the strsep above is temporarily zeroed. */
900 /* NB: password legally can have multiple commas and
901 the only illegal character in a password is null */
903 if ((value
[temp_len
] == 0) &&
904 (value
[temp_len
+1] == separator
[0])) {
906 value
[temp_len
] = separator
[0];
907 temp_len
+= 2; /* move after second comma */
908 while (value
[temp_len
] != 0) {
909 if (value
[temp_len
] == separator
[0]) {
910 if (value
[temp_len
+1] ==
912 /* skip second comma */
915 /* single comma indicating start
922 if (value
[temp_len
] == 0) {
926 /* point option to start of next parm */
927 options
= value
+ temp_len
+ 1;
929 /* go from value to value + temp_len condensing
930 double commas to singles. Note that this ends up
931 allocating a few bytes too many, which is ok */
932 vol
->password
= kzalloc(temp_len
, GFP_KERNEL
);
933 if (vol
->password
== NULL
) {
934 printk(KERN_WARNING
"CIFS: no memory "
938 for (i
= 0, j
= 0; i
< temp_len
; i
++, j
++) {
939 vol
->password
[j
] = value
[i
];
940 if (value
[i
] == separator
[0]
941 && value
[i
+1] == separator
[0]) {
942 /* skip second comma */
946 vol
->password
[j
] = 0;
948 vol
->password
= kzalloc(temp_len
+1, GFP_KERNEL
);
949 if (vol
->password
== NULL
) {
950 printk(KERN_WARNING
"CIFS: no memory "
954 strcpy(vol
->password
, value
);
956 } else if (strnicmp(data
, "ip", 2) == 0) {
957 if (!value
|| !*value
) {
959 } else if (strnlen(value
, 35) < 35) {
962 printk(KERN_WARNING
"CIFS: ip address "
966 } else if (strnicmp(data
, "sec", 3) == 0) {
967 if (!value
|| !*value
) {
968 cERROR(1, ("no security value specified"));
970 } else if (strnicmp(value
, "krb5i", 5) == 0) {
971 vol
->secFlg
|= CIFSSEC_MAY_KRB5
|
973 } else if (strnicmp(value
, "krb5p", 5) == 0) {
974 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
976 cERROR(1, ("Krb5 cifs privacy not supported"));
978 } else if (strnicmp(value
, "krb5", 4) == 0) {
979 vol
->secFlg
|= CIFSSEC_MAY_KRB5
;
980 } else if (strnicmp(value
, "ntlmv2i", 7) == 0) {
981 vol
->secFlg
|= CIFSSEC_MAY_NTLMV2
|
983 } else if (strnicmp(value
, "ntlmv2", 6) == 0) {
984 vol
->secFlg
|= CIFSSEC_MAY_NTLMV2
;
985 } else if (strnicmp(value
, "ntlmi", 5) == 0) {
986 vol
->secFlg
|= CIFSSEC_MAY_NTLM
|
988 } else if (strnicmp(value
, "ntlm", 4) == 0) {
989 /* ntlm is default so can be turned off too */
990 vol
->secFlg
|= CIFSSEC_MAY_NTLM
;
991 } else if (strnicmp(value
, "nontlm", 6) == 0) {
992 /* BB is there a better way to do this? */
993 vol
->secFlg
|= CIFSSEC_MAY_NTLMV2
;
994 #ifdef CONFIG_CIFS_WEAK_PW_HASH
995 } else if (strnicmp(value
, "lanman", 6) == 0) {
996 vol
->secFlg
|= CIFSSEC_MAY_LANMAN
;
998 } else if (strnicmp(value
, "none", 4) == 0) {
1001 cERROR(1, ("bad security option: %s", value
));
1004 } else if ((strnicmp(data
, "unc", 3) == 0)
1005 || (strnicmp(data
, "target", 6) == 0)
1006 || (strnicmp(data
, "path", 4) == 0)) {
1007 if (!value
|| !*value
) {
1008 printk(KERN_WARNING
"CIFS: invalid path to "
1009 "network resource\n");
1010 return 1; /* needs_arg; */
1012 if ((temp_len
= strnlen(value
, 300)) < 300) {
1013 vol
->UNC
= kmalloc(temp_len
+1, GFP_KERNEL
);
1014 if (vol
->UNC
== NULL
)
1016 strcpy(vol
->UNC
, value
);
1017 if (strncmp(vol
->UNC
, "//", 2) == 0) {
1020 } else if (strncmp(vol
->UNC
, "\\\\", 2) != 0) {
1022 "CIFS: UNC Path does not begin "
1023 "with // or \\\\ \n");
1027 printk(KERN_WARNING
"CIFS: UNC name too long\n");
1030 } else if ((strnicmp(data
, "domain", 3) == 0)
1031 || (strnicmp(data
, "workgroup", 5) == 0)) {
1032 if (!value
|| !*value
) {
1033 printk(KERN_WARNING
"CIFS: invalid domain name\n");
1034 return 1; /* needs_arg; */
1036 /* BB are there cases in which a comma can be valid in
1037 a domain name and need special handling? */
1038 if (strnlen(value
, 256) < 256) {
1039 vol
->domainname
= value
;
1040 cFYI(1, ("Domain name set"));
1042 printk(KERN_WARNING
"CIFS: domain name too "
1046 } else if (strnicmp(data
, "prefixpath", 10) == 0) {
1047 if (!value
|| !*value
) {
1049 "CIFS: invalid path prefix\n");
1050 return 1; /* needs_argument */
1052 if ((temp_len
= strnlen(value
, 1024)) < 1024) {
1053 if (value
[0] != '/')
1054 temp_len
++; /* missing leading slash */
1055 vol
->prepath
= kmalloc(temp_len
+1, GFP_KERNEL
);
1056 if (vol
->prepath
== NULL
)
1058 if (value
[0] != '/') {
1059 vol
->prepath
[0] = '/';
1060 strcpy(vol
->prepath
+1, value
);
1062 strcpy(vol
->prepath
, value
);
1063 cFYI(1, ("prefix path %s", vol
->prepath
));
1065 printk(KERN_WARNING
"CIFS: prefix too long\n");
1068 } else if (strnicmp(data
, "iocharset", 9) == 0) {
1069 if (!value
|| !*value
) {
1070 printk(KERN_WARNING
"CIFS: invalid iocharset "
1072 return 1; /* needs_arg; */
1074 if (strnlen(value
, 65) < 65) {
1075 if (strnicmp(value
, "default", 7))
1076 vol
->iocharset
= value
;
1077 /* if iocharset not set then load_nls_default
1078 is used by caller */
1079 cFYI(1, ("iocharset set to %s", value
));
1081 printk(KERN_WARNING
"CIFS: iocharset name "
1085 } else if (strnicmp(data
, "uid", 3) == 0) {
1086 if (value
&& *value
) {
1088 simple_strtoul(value
, &value
, 0);
1089 vol
->override_uid
= 1;
1091 } else if (strnicmp(data
, "gid", 3) == 0) {
1092 if (value
&& *value
) {
1094 simple_strtoul(value
, &value
, 0);
1095 vol
->override_gid
= 1;
1097 } else if (strnicmp(data
, "file_mode", 4) == 0) {
1098 if (value
&& *value
) {
1100 simple_strtoul(value
, &value
, 0);
1102 } else if (strnicmp(data
, "dir_mode", 4) == 0) {
1103 if (value
&& *value
) {
1105 simple_strtoul(value
, &value
, 0);
1107 } else if (strnicmp(data
, "dirmode", 4) == 0) {
1108 if (value
&& *value
) {
1110 simple_strtoul(value
, &value
, 0);
1112 } else if (strnicmp(data
, "port", 4) == 0) {
1113 if (value
&& *value
) {
1115 simple_strtoul(value
, &value
, 0);
1117 } else if (strnicmp(data
, "rsize", 5) == 0) {
1118 if (value
&& *value
) {
1120 simple_strtoul(value
, &value
, 0);
1122 } else if (strnicmp(data
, "wsize", 5) == 0) {
1123 if (value
&& *value
) {
1125 simple_strtoul(value
, &value
, 0);
1127 } else if (strnicmp(data
, "sockopt", 5) == 0) {
1128 if (value
&& *value
) {
1130 simple_strtoul(value
, &value
, 0);
1132 } else if (strnicmp(data
, "netbiosname", 4) == 0) {
1133 if (!value
|| !*value
|| (*value
== ' ')) {
1134 cFYI(1, ("invalid (empty) netbiosname"));
1136 memset(vol
->source_rfc1001_name
, 0x20, 15);
1137 for (i
= 0; i
< 15; i
++) {
1138 /* BB are there cases in which a comma can be
1139 valid in this workstation netbios name (and need
1140 special handling)? */
1142 /* We do not uppercase netbiosname for user */
1146 vol
->source_rfc1001_name
[i
] =
1149 /* The string has 16th byte zero still from
1150 set at top of the function */
1151 if ((i
== 15) && (value
[i
] != 0))
1152 printk(KERN_WARNING
"CIFS: netbiosname"
1153 " longer than 15 truncated.\n");
1155 } else if (strnicmp(data
, "servern", 7) == 0) {
1156 /* servernetbiosname specified override *SMBSERVER */
1157 if (!value
|| !*value
|| (*value
== ' ')) {
1158 cFYI(1, ("empty server netbiosname specified"));
1160 /* last byte, type, is 0x20 for servr type */
1161 memset(vol
->target_rfc1001_name
, 0x20, 16);
1163 for (i
= 0; i
< 15; i
++) {
1164 /* BB are there cases in which a comma can be
1165 valid in this workstation netbios name
1166 (and need special handling)? */
1168 /* user or mount helper must uppercase
1173 vol
->target_rfc1001_name
[i
] =
1176 /* The string has 16th byte zero still from
1177 set at top of the function */
1178 if ((i
== 15) && (value
[i
] != 0))
1179 printk(KERN_WARNING
"CIFS: server net"
1180 "biosname longer than 15 truncated.\n");
1182 } else if (strnicmp(data
, "credentials", 4) == 0) {
1184 } else if (strnicmp(data
, "version", 3) == 0) {
1186 } else if (strnicmp(data
, "guest", 5) == 0) {
1188 } else if (strnicmp(data
, "rw", 2) == 0) {
1190 } else if ((strnicmp(data
, "suid", 4) == 0) ||
1191 (strnicmp(data
, "nosuid", 6) == 0) ||
1192 (strnicmp(data
, "exec", 4) == 0) ||
1193 (strnicmp(data
, "noexec", 6) == 0) ||
1194 (strnicmp(data
, "nodev", 5) == 0) ||
1195 (strnicmp(data
, "noauto", 6) == 0) ||
1196 (strnicmp(data
, "dev", 3) == 0)) {
1197 /* The mount tool or mount.cifs helper (if present)
1198 uses these opts to set flags, and the flags are read
1199 by the kernel vfs layer before we get here (ie
1200 before read super) so there is no point trying to
1201 parse these options again and set anything and it
1202 is ok to just ignore them */
1204 } else if (strnicmp(data
, "ro", 2) == 0) {
1206 } else if (strnicmp(data
, "hard", 4) == 0) {
1208 } else if (strnicmp(data
, "soft", 4) == 0) {
1210 } else if (strnicmp(data
, "perm", 4) == 0) {
1212 } else if (strnicmp(data
, "noperm", 6) == 0) {
1214 } else if (strnicmp(data
, "mapchars", 8) == 0) {
1216 } else if (strnicmp(data
, "nomapchars", 10) == 0) {
1218 } else if (strnicmp(data
, "sfu", 3) == 0) {
1220 } else if (strnicmp(data
, "nosfu", 5) == 0) {
1222 } else if (strnicmp(data
, "nodfs", 5) == 0) {
1224 } else if (strnicmp(data
, "posixpaths", 10) == 0) {
1225 vol
->posix_paths
= 1;
1226 } else if (strnicmp(data
, "noposixpaths", 12) == 0) {
1227 vol
->posix_paths
= 0;
1228 } else if (strnicmp(data
, "nounix", 6) == 0) {
1229 vol
->no_linux_ext
= 1;
1230 } else if (strnicmp(data
, "nolinux", 7) == 0) {
1231 vol
->no_linux_ext
= 1;
1232 } else if ((strnicmp(data
, "nocase", 6) == 0) ||
1233 (strnicmp(data
, "ignorecase", 10) == 0)) {
1235 } else if (strnicmp(data
, "brl", 3) == 0) {
1237 } else if ((strnicmp(data
, "nobrl", 5) == 0) ||
1238 (strnicmp(data
, "nolock", 6) == 0)) {
1240 /* turn off mandatory locking in mode
1241 if remote locking is turned off since the
1242 local vfs will do advisory */
1243 if (vol
->file_mode
==
1244 (S_IALLUGO
& ~(S_ISUID
| S_IXGRP
)))
1245 vol
->file_mode
= S_IALLUGO
;
1246 } else if (strnicmp(data
, "setuids", 7) == 0) {
1248 } else if (strnicmp(data
, "nosetuids", 9) == 0) {
1250 } else if (strnicmp(data
, "dynperm", 7) == 0) {
1251 vol
->dynperm
= true;
1252 } else if (strnicmp(data
, "nodynperm", 9) == 0) {
1253 vol
->dynperm
= false;
1254 } else if (strnicmp(data
, "nohard", 6) == 0) {
1256 } else if (strnicmp(data
, "nosoft", 6) == 0) {
1258 } else if (strnicmp(data
, "nointr", 6) == 0) {
1260 } else if (strnicmp(data
, "intr", 4) == 0) {
1262 } else if (strnicmp(data
, "serverino", 7) == 0) {
1263 vol
->server_ino
= 1;
1264 } else if (strnicmp(data
, "noserverino", 9) == 0) {
1265 vol
->server_ino
= 0;
1266 } else if (strnicmp(data
, "cifsacl", 7) == 0) {
1268 } else if (strnicmp(data
, "nocifsacl", 9) == 0) {
1270 } else if (strnicmp(data
, "acl", 3) == 0) {
1271 vol
->no_psx_acl
= 0;
1272 } else if (strnicmp(data
, "noacl", 5) == 0) {
1273 vol
->no_psx_acl
= 1;
1274 } else if (strnicmp(data
, "sign", 4) == 0) {
1275 vol
->secFlg
|= CIFSSEC_MUST_SIGN
;
1276 } else if (strnicmp(data
, "seal", 4) == 0) {
1277 /* we do not do the following in secFlags because seal
1278 is a per tree connection (mount) not a per socket
1279 or per-smb connection option in the protocol */
1280 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1282 } else if (strnicmp(data
, "direct", 6) == 0) {
1284 } else if (strnicmp(data
, "forcedirectio", 13) == 0) {
1286 } else if (strnicmp(data
, "in6_addr", 8) == 0) {
1287 if (!value
|| !*value
) {
1288 vol
->in6_addr
= NULL
;
1289 } else if (strnlen(value
, 49) == 48) {
1290 vol
->in6_addr
= value
;
1292 printk(KERN_WARNING
"CIFS: ip v6 address not "
1293 "48 characters long\n");
1296 } else if (strnicmp(data
, "noac", 4) == 0) {
1297 printk(KERN_WARNING
"CIFS: Mount option noac not "
1298 "supported. Instead set "
1299 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1301 printk(KERN_WARNING
"CIFS: Unknown mount option %s\n",
1304 if (vol
->UNC
== NULL
) {
1305 if (devname
== NULL
) {
1306 printk(KERN_WARNING
"CIFS: Missing UNC name for mount "
1310 if ((temp_len
= strnlen(devname
, 300)) < 300) {
1311 vol
->UNC
= kmalloc(temp_len
+1, GFP_KERNEL
);
1312 if (vol
->UNC
== NULL
)
1314 strcpy(vol
->UNC
, devname
);
1315 if (strncmp(vol
->UNC
, "//", 2) == 0) {
1318 } else if (strncmp(vol
->UNC
, "\\\\", 2) != 0) {
1319 printk(KERN_WARNING
"CIFS: UNC Path does not "
1320 "begin with // or \\\\ \n");
1323 value
= strpbrk(vol
->UNC
+2, "/\\");
1327 printk(KERN_WARNING
"CIFS: UNC name too long\n");
1331 if (vol
->UNCip
== NULL
)
1332 vol
->UNCip
= &vol
->UNC
[2];
1337 static struct cifsSesInfo
*
1338 cifs_find_tcp_session(struct in_addr
*target_ip_addr
,
1339 struct in6_addr
*target_ip6_addr
,
1340 char *userName
, struct TCP_Server_Info
**psrvTcp
)
1342 struct list_head
*tmp
;
1343 struct cifsSesInfo
*ses
;
1347 read_lock(&GlobalSMBSeslock
);
1348 list_for_each(tmp
, &GlobalSMBSessionList
) {
1349 ses
= list_entry(tmp
, struct cifsSesInfo
, cifsSessionList
);
1353 if (target_ip_addr
&&
1354 ses
->server
->addr
.sockAddr
.sin_addr
.s_addr
!= target_ip_addr
->s_addr
)
1356 else if (target_ip6_addr
&&
1357 memcmp(&ses
->server
->addr
.sockAddr6
.sin6_addr
,
1358 target_ip6_addr
, sizeof(*target_ip6_addr
)))
1360 /* BB lock server and tcp session; increment use count here?? */
1362 /* found a match on the TCP session */
1363 *psrvTcp
= ses
->server
;
1365 /* BB check if reconnection needed */
1366 if (strncmp(ses
->userName
, userName
, MAX_USERNAME_SIZE
) == 0) {
1367 read_unlock(&GlobalSMBSeslock
);
1368 /* Found exact match on both TCP and
1372 /* else tcp and smb sessions need reconnection */
1374 read_unlock(&GlobalSMBSeslock
);
1379 static struct cifsTconInfo
*
1380 find_unc(__be32 new_target_ip_addr
, char *uncName
, char *userName
)
1382 struct list_head
*tmp
;
1383 struct cifsTconInfo
*tcon
;
1386 read_lock(&GlobalSMBSeslock
);
1388 list_for_each(tmp
, &GlobalTreeConnectionList
) {
1389 cFYI(1, ("Next tcon"));
1390 tcon
= list_entry(tmp
, struct cifsTconInfo
, cifsConnectionList
);
1391 if (!tcon
->ses
|| !tcon
->ses
->server
)
1394 old_ip
= tcon
->ses
->server
->addr
.sockAddr
.sin_addr
.s_addr
;
1395 cFYI(1, ("old ip addr: %x == new ip %x ?",
1396 old_ip
, new_target_ip_addr
));
1398 if (old_ip
!= new_target_ip_addr
)
1401 /* BB lock tcon, server, tcp session and increment use count? */
1402 /* found a match on the TCP session */
1403 /* BB check if reconnection needed */
1404 cFYI(1, ("IP match, old UNC: %s new: %s",
1405 tcon
->treeName
, uncName
));
1407 if (strncmp(tcon
->treeName
, uncName
, MAX_TREE_SIZE
))
1410 cFYI(1, ("and old usr: %s new: %s",
1411 tcon
->treeName
, uncName
));
1413 if (strncmp(tcon
->ses
->userName
, userName
, MAX_USERNAME_SIZE
))
1416 /* matched smb session (user name) */
1417 read_unlock(&GlobalSMBSeslock
);
1421 read_unlock(&GlobalSMBSeslock
);
1426 get_dfs_path(int xid
, struct cifsSesInfo
*pSesInfo
, const char *old_path
,
1427 const struct nls_table
*nls_codepage
, unsigned int *pnum_referrals
,
1428 struct dfs_info3_param
**preferrals
, int remap
)
1433 *pnum_referrals
= 0;
1436 if (pSesInfo
->ipc_tid
== 0) {
1437 temp_unc
= kmalloc(2 /* for slashes */ +
1438 strnlen(pSesInfo
->serverName
,
1439 SERVER_NAME_LEN_WITH_NULL
* 2)
1440 + 1 + 4 /* slash IPC$ */ + 2,
1442 if (temp_unc
== NULL
)
1446 strcpy(temp_unc
+ 2, pSesInfo
->serverName
);
1447 strcpy(temp_unc
+ 2 + strlen(pSesInfo
->serverName
), "\\IPC$");
1448 rc
= CIFSTCon(xid
, pSesInfo
, temp_unc
, NULL
, nls_codepage
);
1450 ("CIFS Tcon rc = %d ipc_tid = %d", rc
, pSesInfo
->ipc_tid
));
1454 rc
= CIFSGetDFSRefer(xid
, pSesInfo
, old_path
, preferrals
,
1455 pnum_referrals
, nls_codepage
, remap
);
1456 /* BB map targetUNCs to dfs_info3 structures, here or
1457 in CIFSGetDFSRefer BB */
1462 #ifdef CONFIG_DEBUG_LOCK_ALLOC
1463 static struct lock_class_key cifs_key
[2];
1464 static struct lock_class_key cifs_slock_key
[2];
1467 cifs_reclassify_socket4(struct socket
*sock
)
1469 struct sock
*sk
= sock
->sk
;
1470 BUG_ON(sock_owned_by_user(sk
));
1471 sock_lock_init_class_and_name(sk
, "slock-AF_INET-CIFS",
1472 &cifs_slock_key
[0], "sk_lock-AF_INET-CIFS", &cifs_key
[0]);
1476 cifs_reclassify_socket6(struct socket
*sock
)
1478 struct sock
*sk
= sock
->sk
;
1479 BUG_ON(sock_owned_by_user(sk
));
1480 sock_lock_init_class_and_name(sk
, "slock-AF_INET6-CIFS",
1481 &cifs_slock_key
[1], "sk_lock-AF_INET6-CIFS", &cifs_key
[1]);
1485 cifs_reclassify_socket4(struct socket
*sock
)
1490 cifs_reclassify_socket6(struct socket
*sock
)
1495 /* See RFC1001 section 14 on representation of Netbios names */
1496 static void rfc1002mangle(char *target
, char *source
, unsigned int length
)
1500 for (i
= 0, j
= 0; i
< (length
); i
++) {
1501 /* mask a nibble at a time and encode */
1502 target
[j
] = 'A' + (0x0F & (source
[i
] >> 4));
1503 target
[j
+1] = 'A' + (0x0F & source
[i
]);
1511 ipv4_connect(struct sockaddr_in
*psin_server
, struct socket
**csocket
,
1512 char *netbios_name
, char *target_name
)
1516 __be16 orig_port
= 0;
1518 if (*csocket
== NULL
) {
1519 rc
= sock_create_kern(PF_INET
, SOCK_STREAM
,
1520 IPPROTO_TCP
, csocket
);
1522 cERROR(1, ("Error %d creating socket", rc
));
1526 /* BB other socket options to set KEEPALIVE, NODELAY? */
1527 cFYI(1, ("Socket created"));
1528 (*csocket
)->sk
->sk_allocation
= GFP_NOFS
;
1529 cifs_reclassify_socket4(*csocket
);
1533 psin_server
->sin_family
= AF_INET
;
1534 if (psin_server
->sin_port
) { /* user overrode default port */
1535 rc
= (*csocket
)->ops
->connect(*csocket
,
1536 (struct sockaddr
*) psin_server
,
1537 sizeof(struct sockaddr_in
), 0);
1543 /* save original port so we can retry user specified port
1544 later if fall back ports fail this time */
1545 orig_port
= psin_server
->sin_port
;
1547 /* do not retry on the same port we just failed on */
1548 if (psin_server
->sin_port
!= htons(CIFS_PORT
)) {
1549 psin_server
->sin_port
= htons(CIFS_PORT
);
1551 rc
= (*csocket
)->ops
->connect(*csocket
,
1552 (struct sockaddr
*) psin_server
,
1553 sizeof(struct sockaddr_in
), 0);
1559 psin_server
->sin_port
= htons(RFC1001_PORT
);
1560 rc
= (*csocket
)->ops
->connect(*csocket
, (struct sockaddr
*)
1562 sizeof(struct sockaddr_in
), 0);
1567 /* give up here - unless we want to retry on different
1568 protocol families some day */
1571 psin_server
->sin_port
= orig_port
;
1572 cFYI(1, ("Error %d connecting to server via ipv4", rc
));
1573 sock_release(*csocket
);
1577 /* Eventually check for other socket options to change from
1578 the default. sock_setsockopt not used because it expects
1579 user space buffer */
1580 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1581 (*csocket
)->sk
->sk_sndbuf
,
1582 (*csocket
)->sk
->sk_rcvbuf
, (*csocket
)->sk
->sk_rcvtimeo
));
1583 (*csocket
)->sk
->sk_rcvtimeo
= 7 * HZ
;
1584 /* make the bufsizes depend on wsize/rsize and max requests */
1585 if ((*csocket
)->sk
->sk_sndbuf
< (200 * 1024))
1586 (*csocket
)->sk
->sk_sndbuf
= 200 * 1024;
1587 if ((*csocket
)->sk
->sk_rcvbuf
< (140 * 1024))
1588 (*csocket
)->sk
->sk_rcvbuf
= 140 * 1024;
1590 /* send RFC1001 sessinit */
1591 if (psin_server
->sin_port
== htons(RFC1001_PORT
)) {
1592 /* some servers require RFC1001 sessinit before sending
1593 negprot - BB check reconnection in case where second
1594 sessinit is sent but no second negprot */
1595 struct rfc1002_session_packet
*ses_init_buf
;
1596 struct smb_hdr
*smb_buf
;
1597 ses_init_buf
= kzalloc(sizeof(struct rfc1002_session_packet
),
1600 ses_init_buf
->trailer
.session_req
.called_len
= 32;
1601 if (target_name
&& (target_name
[0] != 0)) {
1602 rfc1002mangle(ses_init_buf
->trailer
.session_req
.called_name
,
1605 rfc1002mangle(ses_init_buf
->trailer
.session_req
.called_name
,
1606 DEFAULT_CIFS_CALLED_NAME
, 16);
1609 ses_init_buf
->trailer
.session_req
.calling_len
= 32;
1610 /* calling name ends in null (byte 16) from old smb
1612 if (netbios_name
&& (netbios_name
[0] != 0)) {
1613 rfc1002mangle(ses_init_buf
->trailer
.session_req
.calling_name
,
1616 rfc1002mangle(ses_init_buf
->trailer
.session_req
.calling_name
,
1617 "LINUX_CIFS_CLNT", 16);
1619 ses_init_buf
->trailer
.session_req
.scope1
= 0;
1620 ses_init_buf
->trailer
.session_req
.scope2
= 0;
1621 smb_buf
= (struct smb_hdr
*)ses_init_buf
;
1622 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1623 smb_buf
->smb_buf_length
= 0x81000044;
1624 rc
= smb_send(*csocket
, smb_buf
, 0x44,
1625 (struct sockaddr
*)psin_server
);
1626 kfree(ses_init_buf
);
1627 msleep(1); /* RFC1001 layer in at least one server
1628 requires very short break before negprot
1629 presumably because not expecting negprot
1630 to follow so fast. This is a simple
1631 solution that works without
1632 complicating the code and causes no
1633 significant slowing down on mount
1634 for everyone else */
1636 /* else the negprot may still work without this
1637 even though malloc failed */
1645 ipv6_connect(struct sockaddr_in6
*psin_server
, struct socket
**csocket
)
1649 __be16 orig_port
= 0;
1651 if (*csocket
== NULL
) {
1652 rc
= sock_create_kern(PF_INET6
, SOCK_STREAM
,
1653 IPPROTO_TCP
, csocket
);
1655 cERROR(1, ("Error %d creating ipv6 socket", rc
));
1659 /* BB other socket options to set KEEPALIVE, NODELAY? */
1660 cFYI(1, ("ipv6 Socket created"));
1661 (*csocket
)->sk
->sk_allocation
= GFP_NOFS
;
1662 cifs_reclassify_socket6(*csocket
);
1666 psin_server
->sin6_family
= AF_INET6
;
1668 if (psin_server
->sin6_port
) { /* user overrode default port */
1669 rc
= (*csocket
)->ops
->connect(*csocket
,
1670 (struct sockaddr
*) psin_server
,
1671 sizeof(struct sockaddr_in6
), 0);
1677 /* save original port so we can retry user specified port
1678 later if fall back ports fail this time */
1680 orig_port
= psin_server
->sin6_port
;
1681 /* do not retry on the same port we just failed on */
1682 if (psin_server
->sin6_port
!= htons(CIFS_PORT
)) {
1683 psin_server
->sin6_port
= htons(CIFS_PORT
);
1685 rc
= (*csocket
)->ops
->connect(*csocket
,
1686 (struct sockaddr
*) psin_server
,
1687 sizeof(struct sockaddr_in6
), 0);
1693 psin_server
->sin6_port
= htons(RFC1001_PORT
);
1694 rc
= (*csocket
)->ops
->connect(*csocket
, (struct sockaddr
*)
1695 psin_server
, sizeof(struct sockaddr_in6
), 0);
1700 /* give up here - unless we want to retry on different
1701 protocol families some day */
1704 psin_server
->sin6_port
= orig_port
;
1705 cFYI(1, ("Error %d connecting to server via ipv6", rc
));
1706 sock_release(*csocket
);
1710 /* Eventually check for other socket options to change from
1711 the default. sock_setsockopt not used because it expects
1712 user space buffer */
1713 (*csocket
)->sk
->sk_rcvtimeo
= 7 * HZ
;
1718 void reset_cifs_unix_caps(int xid
, struct cifsTconInfo
*tcon
,
1719 struct super_block
*sb
, struct smb_vol
*vol_info
)
1721 /* if we are reconnecting then should we check to see if
1722 * any requested capabilities changed locally e.g. via
1723 * remount but we can not do much about it here
1724 * if they have (even if we could detect it by the following)
1725 * Perhaps we could add a backpointer to array of sb from tcon
1726 * or if we change to make all sb to same share the same
1727 * sb as NFS - then we only have one backpointer to sb.
1728 * What if we wanted to mount the server share twice once with
1729 * and once without posixacls or posix paths? */
1730 __u64 saved_cap
= le64_to_cpu(tcon
->fsUnixInfo
.Capability
);
1732 if (vol_info
&& vol_info
->no_linux_ext
) {
1733 tcon
->fsUnixInfo
.Capability
= 0;
1734 tcon
->unix_ext
= 0; /* Unix Extensions disabled */
1735 cFYI(1, ("Linux protocol extensions disabled"));
1737 } else if (vol_info
)
1738 tcon
->unix_ext
= 1; /* Unix Extensions supported */
1740 if (tcon
->unix_ext
== 0) {
1741 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1745 if (!CIFSSMBQFSUnixInfo(xid
, tcon
)) {
1746 __u64 cap
= le64_to_cpu(tcon
->fsUnixInfo
.Capability
);
1748 /* check for reconnect case in which we do not
1749 want to change the mount behavior if we can avoid it */
1750 if (vol_info
== NULL
) {
1751 /* turn off POSIX ACL and PATHNAMES if not set
1752 originally at mount time */
1753 if ((saved_cap
& CIFS_UNIX_POSIX_ACL_CAP
) == 0)
1754 cap
&= ~CIFS_UNIX_POSIX_ACL_CAP
;
1755 if ((saved_cap
& CIFS_UNIX_POSIX_PATHNAMES_CAP
) == 0) {
1756 if (cap
& CIFS_UNIX_POSIX_PATHNAMES_CAP
)
1757 cERROR(1, ("POSIXPATH support change"));
1758 cap
&= ~CIFS_UNIX_POSIX_PATHNAMES_CAP
;
1759 } else if ((cap
& CIFS_UNIX_POSIX_PATHNAMES_CAP
) == 0) {
1760 cERROR(1, ("possible reconnect error"));
1762 ("server disabled POSIX path support"));
1766 cap
&= CIFS_UNIX_CAP_MASK
;
1767 if (vol_info
&& vol_info
->no_psx_acl
)
1768 cap
&= ~CIFS_UNIX_POSIX_ACL_CAP
;
1769 else if (CIFS_UNIX_POSIX_ACL_CAP
& cap
) {
1770 cFYI(1, ("negotiated posix acl support"));
1772 sb
->s_flags
|= MS_POSIXACL
;
1775 if (vol_info
&& vol_info
->posix_paths
== 0)
1776 cap
&= ~CIFS_UNIX_POSIX_PATHNAMES_CAP
;
1777 else if (cap
& CIFS_UNIX_POSIX_PATHNAMES_CAP
) {
1778 cFYI(1, ("negotiate posix pathnames"));
1780 CIFS_SB(sb
)->mnt_cifs_flags
|=
1781 CIFS_MOUNT_POSIX_PATHS
;
1784 /* We might be setting the path sep back to a different
1785 form if we are reconnecting and the server switched its
1786 posix path capability for this share */
1787 if (sb
&& (CIFS_SB(sb
)->prepathlen
> 0))
1788 CIFS_SB(sb
)->prepath
[0] = CIFS_DIR_SEP(CIFS_SB(sb
));
1790 if (sb
&& (CIFS_SB(sb
)->rsize
> 127 * 1024)) {
1791 if ((cap
& CIFS_UNIX_LARGE_READ_CAP
) == 0) {
1792 CIFS_SB(sb
)->rsize
= 127 * 1024;
1794 ("larger reads not supported by srv"));
1799 cFYI(1, ("Negotiate caps 0x%x", (int)cap
));
1800 #ifdef CONFIG_CIFS_DEBUG2
1801 if (cap
& CIFS_UNIX_FCNTL_CAP
)
1802 cFYI(1, ("FCNTL cap"));
1803 if (cap
& CIFS_UNIX_EXTATTR_CAP
)
1804 cFYI(1, ("EXTATTR cap"));
1805 if (cap
& CIFS_UNIX_POSIX_PATHNAMES_CAP
)
1806 cFYI(1, ("POSIX path cap"));
1807 if (cap
& CIFS_UNIX_XATTR_CAP
)
1808 cFYI(1, ("XATTR cap"));
1809 if (cap
& CIFS_UNIX_POSIX_ACL_CAP
)
1810 cFYI(1, ("POSIX ACL cap"));
1811 if (cap
& CIFS_UNIX_LARGE_READ_CAP
)
1812 cFYI(1, ("very large read cap"));
1813 if (cap
& CIFS_UNIX_LARGE_WRITE_CAP
)
1814 cFYI(1, ("very large write cap"));
1815 #endif /* CIFS_DEBUG2 */
1816 if (CIFSSMBSetFSUnixInfo(xid
, tcon
, cap
)) {
1817 if (vol_info
== NULL
) {
1818 cFYI(1, ("resetting capabilities failed"));
1820 cERROR(1, ("Negotiating Unix capabilities "
1821 "with the server failed. Consider "
1822 "mounting with the Unix Extensions\n"
1823 "disabled, if problems are found, "
1824 "by specifying the nounix mount "
1832 convert_delimiter(char *path
, char delim
)
1845 for (i
= 0; path
[i
] != '\0'; i
++) {
1846 if (path
[i
] == old_delim
)
1852 cifs_mount(struct super_block
*sb
, struct cifs_sb_info
*cifs_sb
,
1853 char *mount_data
, const char *devname
)
1857 int address_type
= AF_INET
;
1858 struct socket
*csocket
= NULL
;
1859 struct sockaddr_in sin_server
;
1860 struct sockaddr_in6 sin_server6
;
1861 struct smb_vol volume_info
;
1862 struct cifsSesInfo
*pSesInfo
= NULL
;
1863 struct cifsSesInfo
*existingCifsSes
= NULL
;
1864 struct cifsTconInfo
*tcon
= NULL
;
1865 struct TCP_Server_Info
*srvTcp
= NULL
;
1869 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1871 memset(&volume_info
, 0, sizeof(struct smb_vol
));
1872 if (cifs_parse_mount_options(mount_data
, devname
, &volume_info
)) {
1877 if (volume_info
.nullauth
) {
1878 cFYI(1, ("null user"));
1879 volume_info
.username
= "";
1880 } else if (volume_info
.username
) {
1881 /* BB fixme parse for domain name here */
1882 cFYI(1, ("Username: %s", volume_info
.username
));
1884 cifserror("No username specified");
1885 /* In userspace mount helper we can get user name from alternate
1886 locations such as env variables and files on disk */
1891 if (volume_info
.UNCip
&& volume_info
.UNC
) {
1892 rc
= cifs_inet_pton(AF_INET
, volume_info
.UNCip
,
1893 &sin_server
.sin_addr
.s_addr
);
1896 /* not ipv4 address, try ipv6 */
1897 rc
= cifs_inet_pton(AF_INET6
, volume_info
.UNCip
,
1898 &sin_server6
.sin6_addr
.in6_u
);
1900 address_type
= AF_INET6
;
1902 address_type
= AF_INET
;
1906 /* we failed translating address */
1911 cFYI(1, ("UNC: %s ip: %s", volume_info
.UNC
, volume_info
.UNCip
));
1914 } else if (volume_info
.UNCip
) {
1915 /* BB using ip addr as server name to connect to the
1917 cERROR(1, ("Connecting to DFS root not implemented yet"));
1920 } else /* which servers DFS root would we conect to */ {
1922 ("CIFS mount error: No UNC path (e.g. -o "
1923 "unc=//192.168.1.100/public) specified"));
1928 /* this is needed for ASCII cp to Unicode converts */
1929 if (volume_info
.iocharset
== NULL
) {
1930 cifs_sb
->local_nls
= load_nls_default();
1931 /* load_nls_default can not return null */
1933 cifs_sb
->local_nls
= load_nls(volume_info
.iocharset
);
1934 if (cifs_sb
->local_nls
== NULL
) {
1935 cERROR(1, ("CIFS mount error: iocharset %s not found",
1936 volume_info
.iocharset
));
1942 if (address_type
== AF_INET
)
1943 existingCifsSes
= cifs_find_tcp_session(&sin_server
.sin_addr
,
1944 NULL
/* no ipv6 addr */,
1945 volume_info
.username
, &srvTcp
);
1946 else if (address_type
== AF_INET6
) {
1947 cFYI(1, ("looking for ipv6 address"));
1948 existingCifsSes
= cifs_find_tcp_session(NULL
/* no ipv4 addr */,
1949 &sin_server6
.sin6_addr
,
1950 volume_info
.username
, &srvTcp
);
1957 cFYI(1, ("Existing tcp session with server found"));
1958 } else { /* create socket */
1959 if (volume_info
.port
)
1960 sin_server
.sin_port
= htons(volume_info
.port
);
1962 sin_server
.sin_port
= 0;
1963 if (address_type
== AF_INET6
) {
1964 cFYI(1, ("attempting ipv6 connect"));
1965 /* BB should we allow ipv6 on port 139? */
1966 /* other OS never observed in Wild doing 139 with v6 */
1967 rc
= ipv6_connect(&sin_server6
, &csocket
);
1969 rc
= ipv4_connect(&sin_server
, &csocket
,
1970 volume_info
.source_rfc1001_name
,
1971 volume_info
.target_rfc1001_name
);
1973 cERROR(1, ("Error connecting to IPv4 socket. "
1974 "Aborting operation"));
1975 if (csocket
!= NULL
)
1976 sock_release(csocket
);
1980 srvTcp
= kzalloc(sizeof(struct TCP_Server_Info
), GFP_KERNEL
);
1983 sock_release(csocket
);
1986 memcpy(&srvTcp
->addr
.sockAddr
, &sin_server
,
1987 sizeof(struct sockaddr_in
));
1988 atomic_set(&srvTcp
->inFlight
, 0);
1989 /* BB Add code for ipv6 case too */
1990 srvTcp
->ssocket
= csocket
;
1991 srvTcp
->protocolType
= IPV4
;
1992 srvTcp
->hostname
= extract_hostname(volume_info
.UNC
);
1993 if (IS_ERR(srvTcp
->hostname
)) {
1994 rc
= PTR_ERR(srvTcp
->hostname
);
1995 sock_release(csocket
);
1998 init_waitqueue_head(&srvTcp
->response_q
);
1999 init_waitqueue_head(&srvTcp
->request_q
);
2000 INIT_LIST_HEAD(&srvTcp
->pending_mid_q
);
2001 /* at this point we are the only ones with the pointer
2002 to the struct since the kernel thread not created yet
2003 so no need to spinlock this init of tcpStatus */
2004 srvTcp
->tcpStatus
= CifsNew
;
2005 init_MUTEX(&srvTcp
->tcpSem
);
2006 srvTcp
->tsk
= kthread_run((void *)(void *)cifs_demultiplex_thread
, srvTcp
, "cifsd");
2007 if (IS_ERR(srvTcp
->tsk
)) {
2008 rc
= PTR_ERR(srvTcp
->tsk
);
2009 cERROR(1, ("error %d create cifsd thread", rc
));
2011 sock_release(csocket
);
2012 kfree(srvTcp
->hostname
);
2016 memcpy(srvTcp
->workstation_RFC1001_name
,
2017 volume_info
.source_rfc1001_name
, 16);
2018 memcpy(srvTcp
->server_RFC1001_name
,
2019 volume_info
.target_rfc1001_name
, 16);
2020 srvTcp
->sequence_number
= 0;
2024 if (existingCifsSes
) {
2025 pSesInfo
= existingCifsSes
;
2026 cFYI(1, ("Existing smb sess found (status=%d)",
2028 down(&pSesInfo
->sesSem
);
2029 if (pSesInfo
->status
== CifsNeedReconnect
) {
2030 cFYI(1, ("Session needs reconnect"));
2031 rc
= cifs_setup_session(xid
, pSesInfo
,
2032 cifs_sb
->local_nls
);
2034 up(&pSesInfo
->sesSem
);
2036 cFYI(1, ("Existing smb sess not found"));
2037 pSesInfo
= sesInfoAlloc();
2038 if (pSesInfo
== NULL
)
2041 pSesInfo
->server
= srvTcp
;
2042 sprintf(pSesInfo
->serverName
, "%u.%u.%u.%u",
2043 NIPQUAD(sin_server
.sin_addr
.s_addr
));
2047 /* volume_info.password freed at unmount */
2048 if (volume_info
.password
) {
2049 pSesInfo
->password
= volume_info
.password
;
2050 /* set to NULL to prevent freeing on exit */
2051 volume_info
.password
= NULL
;
2053 if (volume_info
.username
)
2054 strncpy(pSesInfo
->userName
,
2055 volume_info
.username
,
2057 if (volume_info
.domainname
) {
2058 int len
= strlen(volume_info
.domainname
);
2059 pSesInfo
->domainName
=
2060 kmalloc(len
+ 1, GFP_KERNEL
);
2061 if (pSesInfo
->domainName
)
2062 strcpy(pSesInfo
->domainName
,
2063 volume_info
.domainname
);
2065 pSesInfo
->linux_uid
= volume_info
.linux_uid
;
2066 pSesInfo
->overrideSecFlg
= volume_info
.secFlg
;
2067 down(&pSesInfo
->sesSem
);
2068 /* BB FIXME need to pass vol->secFlgs BB */
2069 rc
= cifs_setup_session(xid
, pSesInfo
,
2070 cifs_sb
->local_nls
);
2071 up(&pSesInfo
->sesSem
);
2073 atomic_inc(&srvTcp
->socketUseCount
);
2077 /* search for existing tcon to this server share */
2079 if (volume_info
.rsize
> CIFSMaxBufSize
) {
2080 cERROR(1, ("rsize %d too large, using MaxBufSize",
2081 volume_info
.rsize
));
2082 cifs_sb
->rsize
= CIFSMaxBufSize
;
2083 } else if ((volume_info
.rsize
) &&
2084 (volume_info
.rsize
<= CIFSMaxBufSize
))
2085 cifs_sb
->rsize
= volume_info
.rsize
;
2087 cifs_sb
->rsize
= CIFSMaxBufSize
;
2089 if (volume_info
.wsize
> PAGEVEC_SIZE
* PAGE_CACHE_SIZE
) {
2090 cERROR(1, ("wsize %d too large, using 4096 instead",
2091 volume_info
.wsize
));
2092 cifs_sb
->wsize
= 4096;
2093 } else if (volume_info
.wsize
)
2094 cifs_sb
->wsize
= volume_info
.wsize
;
2097 min_t(const int, PAGEVEC_SIZE
* PAGE_CACHE_SIZE
,
2099 /* old default of CIFSMaxBufSize was too small now
2100 that SMB Write2 can send multiple pages in kvec.
2101 RFC1001 does not describe what happens when frame
2102 bigger than 128K is sent so use that as max in
2103 conjunction with 52K kvec constraint on arch with 4K
2106 if (cifs_sb
->rsize
< 2048) {
2107 cifs_sb
->rsize
= 2048;
2108 /* Windows ME may prefer this */
2109 cFYI(1, ("readsize set to minimum: 2048"));
2111 /* calculate prepath */
2112 cifs_sb
->prepath
= volume_info
.prepath
;
2113 if (cifs_sb
->prepath
) {
2114 cifs_sb
->prepathlen
= strlen(cifs_sb
->prepath
);
2115 /* we can not convert the / to \ in the path
2116 separators in the prefixpath yet because we do not
2117 know (until reset_cifs_unix_caps is called later)
2118 whether POSIX PATH CAP is available. We normalize
2119 the / to \ after reset_cifs_unix_caps is called */
2120 volume_info
.prepath
= NULL
;
2122 cifs_sb
->prepathlen
= 0;
2123 cifs_sb
->mnt_uid
= volume_info
.linux_uid
;
2124 cifs_sb
->mnt_gid
= volume_info
.linux_gid
;
2125 cifs_sb
->mnt_file_mode
= volume_info
.file_mode
;
2126 cifs_sb
->mnt_dir_mode
= volume_info
.dir_mode
;
2127 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
2128 cifs_sb
->mnt_file_mode
, cifs_sb
->mnt_dir_mode
));
2130 if (volume_info
.noperm
)
2131 cifs_sb
->mnt_cifs_flags
|= CIFS_MOUNT_NO_PERM
;
2132 if (volume_info
.setuids
)
2133 cifs_sb
->mnt_cifs_flags
|= CIFS_MOUNT_SET_UID
;
2134 if (volume_info
.server_ino
)
2135 cifs_sb
->mnt_cifs_flags
|= CIFS_MOUNT_SERVER_INUM
;
2136 if (volume_info
.remap
)
2137 cifs_sb
->mnt_cifs_flags
|= CIFS_MOUNT_MAP_SPECIAL_CHR
;
2138 if (volume_info
.no_xattr
)
2139 cifs_sb
->mnt_cifs_flags
|= CIFS_MOUNT_NO_XATTR
;
2140 if (volume_info
.sfu_emul
)
2141 cifs_sb
->mnt_cifs_flags
|= CIFS_MOUNT_UNX_EMUL
;
2142 if (volume_info
.nobrl
)
2143 cifs_sb
->mnt_cifs_flags
|= CIFS_MOUNT_NO_BRL
;
2144 if (volume_info
.cifs_acl
)
2145 cifs_sb
->mnt_cifs_flags
|= CIFS_MOUNT_CIFS_ACL
;
2146 if (volume_info
.override_uid
)
2147 cifs_sb
->mnt_cifs_flags
|= CIFS_MOUNT_OVERR_UID
;
2148 if (volume_info
.override_gid
)
2149 cifs_sb
->mnt_cifs_flags
|= CIFS_MOUNT_OVERR_GID
;
2150 if (volume_info
.dynperm
)
2151 cifs_sb
->mnt_cifs_flags
|= CIFS_MOUNT_DYNPERM
;
2152 if (volume_info
.direct_io
) {
2153 cFYI(1, ("mounting share using direct i/o"));
2154 cifs_sb
->mnt_cifs_flags
|= CIFS_MOUNT_DIRECT_IO
;
2157 if ((volume_info
.cifs_acl
) && (volume_info
.dynperm
))
2158 cERROR(1, ("mount option dynperm ignored if cifsacl "
2159 "mount option supported"));
2162 find_unc(sin_server
.sin_addr
.s_addr
, volume_info
.UNC
,
2163 volume_info
.username
);
2165 cFYI(1, ("Found match on UNC path"));
2166 /* we can have only one retry value for a connection
2167 to a share so for resources mounted more than once
2168 to the same server share the last value passed in
2169 for the retry flag is used */
2170 tcon
->retry
= volume_info
.retry
;
2171 tcon
->nocase
= volume_info
.nocase
;
2172 if (tcon
->seal
!= volume_info
.seal
)
2173 cERROR(1, ("transport encryption setting "
2174 "conflicts with existing tid"));
2176 tcon
= tconInfoAlloc();
2180 /* check for null share name ie connecting to
2183 /* BB check if this works for exactly length
2185 if ((strchr(volume_info
.UNC
+ 3, '\\') == NULL
)
2186 && (strchr(volume_info
.UNC
+ 3, '/') ==
2188 /* rc = connect_to_dfs_path(xid, pSesInfo,
2189 "", cifs_sb->local_nls,
2190 cifs_sb->mnt_cifs_flags &
2191 CIFS_MOUNT_MAP_SPECIAL_CHR);*/
2192 cFYI(1, ("DFS root not supported"));
2196 /* BB Do we need to wrap sesSem around
2197 * this TCon call and Unix SetFS as
2198 * we do on SessSetup and reconnect? */
2199 rc
= CIFSTCon(xid
, pSesInfo
,
2201 tcon
, cifs_sb
->local_nls
);
2202 cFYI(1, ("CIFS Tcon rc = %d", rc
));
2203 if (volume_info
.nodfs
) {
2205 ~SMB_SHARE_IS_IN_DFS
;
2206 cFYI(1, ("DFS disabled (%d)",
2211 atomic_inc(&pSesInfo
->inUse
);
2212 tcon
->retry
= volume_info
.retry
;
2213 tcon
->nocase
= volume_info
.nocase
;
2214 tcon
->seal
= volume_info
.seal
;
2220 if (pSesInfo
->capabilities
& CAP_LARGE_FILES
) {
2221 sb
->s_maxbytes
= (u64
) 1 << 63;
2223 sb
->s_maxbytes
= (u64
) 1 << 31; /* 2 GB */
2226 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2227 sb
->s_time_gran
= 100;
2229 /* on error free sesinfo and tcon struct if needed */
2231 /* if session setup failed, use count is zero but
2232 we still need to free cifsd thread */
2233 if (atomic_read(&srvTcp
->socketUseCount
) == 0) {
2234 spin_lock(&GlobalMid_Lock
);
2235 srvTcp
->tcpStatus
= CifsExiting
;
2236 spin_unlock(&GlobalMid_Lock
);
2238 /* If we could verify that kthread_stop would
2239 always wake up processes blocked in
2240 tcp in recv_mesg then we could remove the
2242 force_sig(SIGKILL
, srvTcp
->tsk
);
2243 kthread_stop(srvTcp
->tsk
);
2246 /* If find_unc succeeded then rc == 0 so we can not end */
2247 if (tcon
) /* up accidently freeing someone elses tcon struct */
2249 if (existingCifsSes
== NULL
) {
2251 if ((pSesInfo
->server
) &&
2252 (pSesInfo
->status
== CifsGood
)) {
2254 temp_rc
= CIFSSMBLogoff(xid
, pSesInfo
);
2255 /* if the socketUseCount is now zero */
2256 if ((temp_rc
== -ESHUTDOWN
) &&
2257 (pSesInfo
->server
) &&
2258 (pSesInfo
->server
->tsk
)) {
2260 pSesInfo
->server
->tsk
);
2261 kthread_stop(pSesInfo
->server
->tsk
);
2264 cFYI(1, ("No session or bad tcon"));
2265 if ((pSesInfo
->server
) &&
2266 (pSesInfo
->server
->tsk
)) {
2268 pSesInfo
->server
->tsk
);
2269 kthread_stop(pSesInfo
->server
->tsk
);
2272 sesInfoFree(pSesInfo
);
2273 /* pSesInfo = NULL; */
2277 atomic_inc(&tcon
->useCount
);
2278 cifs_sb
->tcon
= tcon
;
2279 tcon
->ses
= pSesInfo
;
2281 /* do not care if following two calls succeed - informational */
2283 CIFSSMBQFSDeviceInfo(xid
, tcon
);
2284 CIFSSMBQFSAttributeInfo(xid
, tcon
);
2287 /* tell server which Unix caps we support */
2288 if (tcon
->ses
->capabilities
& CAP_UNIX
)
2289 /* reset of caps checks mount to see if unix extensions
2290 disabled for just this mount */
2291 reset_cifs_unix_caps(xid
, tcon
, sb
, &volume_info
);
2293 tcon
->unix_ext
= 0; /* server does not support them */
2295 /* convert forward to back slashes in prepath here if needed */
2296 if ((cifs_sb
->mnt_cifs_flags
& CIFS_MOUNT_POSIX_PATHS
) == 0)
2297 convert_delimiter(cifs_sb
->prepath
,
2298 CIFS_DIR_SEP(cifs_sb
));
2300 if ((tcon
->unix_ext
== 0) && (cifs_sb
->rsize
> (1024 * 127))) {
2301 cifs_sb
->rsize
= 1024 * 127;
2303 ("no very large read support, rsize now 127K"));
2305 if (!(tcon
->ses
->capabilities
& CAP_LARGE_WRITE_X
))
2306 cifs_sb
->wsize
= min(cifs_sb
->wsize
,
2307 (tcon
->ses
->server
->maxBuf
-
2308 MAX_CIFS_HDR_SIZE
));
2309 if (!(tcon
->ses
->capabilities
& CAP_LARGE_READ_X
))
2310 cifs_sb
->rsize
= min(cifs_sb
->rsize
,
2311 (tcon
->ses
->server
->maxBuf
-
2312 MAX_CIFS_HDR_SIZE
));
2315 /* volume_info.password is freed above when existing session found
2316 (in which case it is not needed anymore) but when new sesion is created
2317 the password ptr is put in the new session structure (in which case the
2318 password will be freed at unmount time) */
2320 /* zero out password before freeing */
2321 if (volume_info
.password
!= NULL
) {
2322 memset(volume_info
.password
, 0, strlen(volume_info
.password
));
2323 kfree(volume_info
.password
);
2325 kfree(volume_info
.UNC
);
2326 kfree(volume_info
.prepath
);
2332 CIFSSessSetup(unsigned int xid
, struct cifsSesInfo
*ses
,
2333 char session_key
[CIFS_SESS_KEY_SIZE
],
2334 const struct nls_table
*nls_codepage
)
2336 struct smb_hdr
*smb_buffer
;
2337 struct smb_hdr
*smb_buffer_response
;
2338 SESSION_SETUP_ANDX
*pSMB
;
2339 SESSION_SETUP_ANDX
*pSMBr
;
2344 int remaining_words
= 0;
2345 int bytes_returned
= 0;
2350 cFYI(1, ("In sesssetup"));
2353 user
= ses
->userName
;
2354 domain
= ses
->domainName
;
2355 smb_buffer
= cifs_buf_get();
2357 if (smb_buffer
== NULL
)
2360 smb_buffer_response
= smb_buffer
;
2361 pSMBr
= pSMB
= (SESSION_SETUP_ANDX
*) smb_buffer
;
2363 /* send SMBsessionSetup here */
2364 header_assemble(smb_buffer
, SMB_COM_SESSION_SETUP_ANDX
,
2365 NULL
/* no tCon exists yet */ , 13 /* wct */ );
2367 smb_buffer
->Mid
= GetNextMid(ses
->server
);
2368 pSMB
->req_no_secext
.AndXCommand
= 0xFF;
2369 pSMB
->req_no_secext
.MaxBufferSize
= cpu_to_le16(ses
->server
->maxBuf
);
2370 pSMB
->req_no_secext
.MaxMpxCount
= cpu_to_le16(ses
->server
->maxReq
);
2372 if (ses
->server
->secMode
&
2373 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
))
2374 smb_buffer
->Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
2376 capabilities
= CAP_LARGE_FILES
| CAP_NT_SMBS
| CAP_LEVEL_II_OPLOCKS
|
2377 CAP_LARGE_WRITE_X
| CAP_LARGE_READ_X
;
2378 if (ses
->capabilities
& CAP_UNICODE
) {
2379 smb_buffer
->Flags2
|= SMBFLG2_UNICODE
;
2380 capabilities
|= CAP_UNICODE
;
2382 if (ses
->capabilities
& CAP_STATUS32
) {
2383 smb_buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
2384 capabilities
|= CAP_STATUS32
;
2386 if (ses
->capabilities
& CAP_DFS
) {
2387 smb_buffer
->Flags2
|= SMBFLG2_DFS
;
2388 capabilities
|= CAP_DFS
;
2390 pSMB
->req_no_secext
.Capabilities
= cpu_to_le32(capabilities
);
2392 pSMB
->req_no_secext
.CaseInsensitivePasswordLength
=
2393 cpu_to_le16(CIFS_SESS_KEY_SIZE
);
2395 pSMB
->req_no_secext
.CaseSensitivePasswordLength
=
2396 cpu_to_le16(CIFS_SESS_KEY_SIZE
);
2397 bcc_ptr
= pByteArea(smb_buffer
);
2398 memcpy(bcc_ptr
, (char *) session_key
, CIFS_SESS_KEY_SIZE
);
2399 bcc_ptr
+= CIFS_SESS_KEY_SIZE
;
2400 memcpy(bcc_ptr
, (char *) session_key
, CIFS_SESS_KEY_SIZE
);
2401 bcc_ptr
+= CIFS_SESS_KEY_SIZE
;
2403 if (ses
->capabilities
& CAP_UNICODE
) {
2404 if ((long) bcc_ptr
% 2) { /* must be word aligned for Unicode */
2409 bytes_returned
= 0; /* skip null user */
2412 cifs_strtoUCS((__le16
*) bcc_ptr
, user
, 100,
2414 /* convert number of 16 bit words to bytes */
2415 bcc_ptr
+= 2 * bytes_returned
;
2416 bcc_ptr
+= 2; /* trailing null */
2419 cifs_strtoUCS((__le16
*) bcc_ptr
,
2420 "CIFS_LINUX_DOM", 32, nls_codepage
);
2423 cifs_strtoUCS((__le16
*) bcc_ptr
, domain
, 64,
2425 bcc_ptr
+= 2 * bytes_returned
;
2428 cifs_strtoUCS((__le16
*) bcc_ptr
, "Linux version ",
2430 bcc_ptr
+= 2 * bytes_returned
;
2432 cifs_strtoUCS((__le16
*) bcc_ptr
, utsname()->release
,
2434 bcc_ptr
+= 2 * bytes_returned
;
2437 cifs_strtoUCS((__le16
*) bcc_ptr
, CIFS_NETWORK_OPSYS
,
2439 bcc_ptr
+= 2 * bytes_returned
;
2443 strncpy(bcc_ptr
, user
, 200);
2444 bcc_ptr
+= strnlen(user
, 200);
2448 if (domain
== NULL
) {
2449 strcpy(bcc_ptr
, "CIFS_LINUX_DOM");
2450 bcc_ptr
+= strlen("CIFS_LINUX_DOM") + 1;
2452 strncpy(bcc_ptr
, domain
, 64);
2453 bcc_ptr
+= strnlen(domain
, 64);
2457 strcpy(bcc_ptr
, "Linux version ");
2458 bcc_ptr
+= strlen("Linux version ");
2459 strcpy(bcc_ptr
, utsname()->release
);
2460 bcc_ptr
+= strlen(utsname()->release
) + 1;
2461 strcpy(bcc_ptr
, CIFS_NETWORK_OPSYS
);
2462 bcc_ptr
+= strlen(CIFS_NETWORK_OPSYS
) + 1;
2464 count
= (long) bcc_ptr
- (long) pByteArea(smb_buffer
);
2465 smb_buffer
->smb_buf_length
+= count
;
2466 pSMB
->req_no_secext
.ByteCount
= cpu_to_le16(count
);
2468 rc
= SendReceive(xid
, ses
, smb_buffer
, smb_buffer_response
,
2469 &bytes_returned
, CIFS_LONG_OP
);
2471 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2472 } else if ((smb_buffer_response
->WordCount
== 3)
2473 || (smb_buffer_response
->WordCount
== 4)) {
2474 __u16 action
= le16_to_cpu(pSMBr
->resp
.Action
);
2475 __u16 blob_len
= le16_to_cpu(pSMBr
->resp
.SecurityBlobLength
);
2476 if (action
& GUEST_LOGIN
)
2477 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2478 ses
->Suid
= smb_buffer_response
->Uid
; /* UID left in wire format
2480 cFYI(1, ("UID = %d ", ses
->Suid
));
2481 /* response can have either 3 or 4 word count - Samba sends 3 */
2482 bcc_ptr
= pByteArea(smb_buffer_response
);
2483 if ((pSMBr
->resp
.hdr
.WordCount
== 3)
2484 || ((pSMBr
->resp
.hdr
.WordCount
== 4)
2485 && (blob_len
< pSMBr
->resp
.ByteCount
))) {
2486 if (pSMBr
->resp
.hdr
.WordCount
== 4)
2487 bcc_ptr
+= blob_len
;
2489 if (smb_buffer
->Flags2
& SMBFLG2_UNICODE
) {
2490 if ((long) (bcc_ptr
) % 2) {
2492 (BCC(smb_buffer_response
) - 1) / 2;
2493 /* Unicode strings must be word
2498 BCC(smb_buffer_response
) / 2;
2501 UniStrnlen((wchar_t *) bcc_ptr
,
2502 remaining_words
- 1);
2503 /* We look for obvious messed up bcc or strings in response so we do not go off
2504 the end since (at least) WIN2K and Windows XP have a major bug in not null
2505 terminating last Unicode string in response */
2507 kfree(ses
->serverOS
);
2508 ses
->serverOS
= kzalloc(2 * (len
+ 1),
2510 if (ses
->serverOS
== NULL
)
2511 goto sesssetup_nomem
;
2512 cifs_strfromUCS_le(ses
->serverOS
,
2515 bcc_ptr
+= 2 * (len
+ 1);
2516 remaining_words
-= len
+ 1;
2517 ses
->serverOS
[2 * len
] = 0;
2518 ses
->serverOS
[1 + (2 * len
)] = 0;
2519 if (remaining_words
> 0) {
2520 len
= UniStrnlen((wchar_t *)bcc_ptr
,
2522 kfree(ses
->serverNOS
);
2523 ses
->serverNOS
= kzalloc(2 * (len
+ 1),
2525 if (ses
->serverNOS
== NULL
)
2526 goto sesssetup_nomem
;
2527 cifs_strfromUCS_le(ses
->serverNOS
,
2530 bcc_ptr
+= 2 * (len
+ 1);
2531 ses
->serverNOS
[2 * len
] = 0;
2532 ses
->serverNOS
[1 + (2 * len
)] = 0;
2533 if (strncmp(ses
->serverNOS
,
2534 "NT LAN Manager 4", 16) == 0) {
2535 cFYI(1, ("NT4 server"));
2536 ses
->flags
|= CIFS_SES_NT4
;
2538 remaining_words
-= len
+ 1;
2539 if (remaining_words
> 0) {
2540 len
= UniStrnlen((wchar_t *) bcc_ptr
, remaining_words
);
2541 /* last string is not always null terminated
2542 (for e.g. for Windows XP & 2000) */
2543 if (ses
->serverDomain
)
2544 kfree(ses
->serverDomain
);
2548 if (ses
->serverDomain
== NULL
)
2549 goto sesssetup_nomem
;
2550 cifs_strfromUCS_le(ses
->serverDomain
,
2553 bcc_ptr
+= 2 * (len
+ 1);
2554 ses
->serverDomain
[2*len
] = 0;
2555 ses
->serverDomain
[1+(2*len
)] = 0;
2556 } else { /* else no more room so create
2557 dummy domain string */
2558 if (ses
->serverDomain
)
2559 kfree(ses
->serverDomain
);
2561 kzalloc(2, GFP_KERNEL
);
2563 } else { /* no room so create dummy domain
2566 /* if these kcallocs fail not much we
2567 can do, but better to not fail the
2569 kfree(ses
->serverDomain
);
2571 kzalloc(2, GFP_KERNEL
);
2572 kfree(ses
->serverNOS
);
2574 kzalloc(2, GFP_KERNEL
);
2576 } else { /* ASCII */
2577 len
= strnlen(bcc_ptr
, 1024);
2578 if (((long) bcc_ptr
+ len
) - (long)
2579 pByteArea(smb_buffer_response
)
2580 <= BCC(smb_buffer_response
)) {
2581 kfree(ses
->serverOS
);
2582 ses
->serverOS
= kzalloc(len
+ 1,
2584 if (ses
->serverOS
== NULL
)
2585 goto sesssetup_nomem
;
2586 strncpy(ses
->serverOS
, bcc_ptr
, len
);
2589 /* null terminate the string */
2593 len
= strnlen(bcc_ptr
, 1024);
2594 kfree(ses
->serverNOS
);
2595 ses
->serverNOS
= kzalloc(len
+ 1,
2597 if (ses
->serverNOS
== NULL
)
2598 goto sesssetup_nomem
;
2599 strncpy(ses
->serverNOS
, bcc_ptr
, len
);
2604 len
= strnlen(bcc_ptr
, 1024);
2605 if (ses
->serverDomain
)
2606 kfree(ses
->serverDomain
);
2607 ses
->serverDomain
= kzalloc(len
+ 1,
2609 if (ses
->serverDomain
== NULL
)
2610 goto sesssetup_nomem
;
2611 strncpy(ses
->serverDomain
, bcc_ptr
,
2618 ("Variable field of length %d "
2619 "extends beyond end of smb ",
2624 (" Security Blob Length extends beyond "
2629 (" Invalid Word count %d: ",
2630 smb_buffer_response
->WordCount
));
2633 sesssetup_nomem
: /* do not return an error on nomem for the info strings,
2634 since that could make reconnection harder, and
2635 reconnection might be needed to free memory */
2636 cifs_buf_release(smb_buffer
);
2642 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid
,
2643 struct cifsSesInfo
*ses
, bool *pNTLMv2_flag
,
2644 const struct nls_table
*nls_codepage
)
2646 struct smb_hdr
*smb_buffer
;
2647 struct smb_hdr
*smb_buffer_response
;
2648 SESSION_SETUP_ANDX
*pSMB
;
2649 SESSION_SETUP_ANDX
*pSMBr
;
2653 int remaining_words
= 0;
2654 int bytes_returned
= 0;
2656 int SecurityBlobLength
= sizeof(NEGOTIATE_MESSAGE
);
2657 PNEGOTIATE_MESSAGE SecurityBlob
;
2658 PCHALLENGE_MESSAGE SecurityBlob2
;
2659 __u32 negotiate_flags
, capabilities
;
2662 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2665 domain
= ses
->domainName
;
2666 *pNTLMv2_flag
= false;
2667 smb_buffer
= cifs_buf_get();
2668 if (smb_buffer
== NULL
) {
2671 smb_buffer_response
= smb_buffer
;
2672 pSMB
= (SESSION_SETUP_ANDX
*) smb_buffer
;
2673 pSMBr
= (SESSION_SETUP_ANDX
*) smb_buffer_response
;
2675 /* send SMBsessionSetup here */
2676 header_assemble(smb_buffer
, SMB_COM_SESSION_SETUP_ANDX
,
2677 NULL
/* no tCon exists yet */ , 12 /* wct */ );
2679 smb_buffer
->Mid
= GetNextMid(ses
->server
);
2680 pSMB
->req
.hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
2681 pSMB
->req
.hdr
.Flags
|= (SMBFLG_CASELESS
| SMBFLG_CANONICAL_PATH_FORMAT
);
2683 pSMB
->req
.AndXCommand
= 0xFF;
2684 pSMB
->req
.MaxBufferSize
= cpu_to_le16(ses
->server
->maxBuf
);
2685 pSMB
->req
.MaxMpxCount
= cpu_to_le16(ses
->server
->maxReq
);
2687 if (ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
))
2688 smb_buffer
->Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
2690 capabilities
= CAP_LARGE_FILES
| CAP_NT_SMBS
| CAP_LEVEL_II_OPLOCKS
|
2691 CAP_EXTENDED_SECURITY
;
2692 if (ses
->capabilities
& CAP_UNICODE
) {
2693 smb_buffer
->Flags2
|= SMBFLG2_UNICODE
;
2694 capabilities
|= CAP_UNICODE
;
2696 if (ses
->capabilities
& CAP_STATUS32
) {
2697 smb_buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
2698 capabilities
|= CAP_STATUS32
;
2700 if (ses
->capabilities
& CAP_DFS
) {
2701 smb_buffer
->Flags2
|= SMBFLG2_DFS
;
2702 capabilities
|= CAP_DFS
;
2704 pSMB
->req
.Capabilities
= cpu_to_le32(capabilities
);
2706 bcc_ptr
= (char *) &pSMB
->req
.SecurityBlob
;
2707 SecurityBlob
= (PNEGOTIATE_MESSAGE
) bcc_ptr
;
2708 strncpy(SecurityBlob
->Signature
, NTLMSSP_SIGNATURE
, 8);
2709 SecurityBlob
->MessageType
= NtLmNegotiate
;
2711 NTLMSSP_NEGOTIATE_UNICODE
| NTLMSSP_NEGOTIATE_OEM
|
2712 NTLMSSP_REQUEST_TARGET
| NTLMSSP_NEGOTIATE_NTLM
|
2713 NTLMSSP_NEGOTIATE_56
|
2714 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128
;
2716 negotiate_flags
|= NTLMSSP_NEGOTIATE_SIGN
;
2717 /* if (ntlmv2_support)
2718 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2719 /* setup pointers to domain name and workstation name */
2720 bcc_ptr
+= SecurityBlobLength
;
2722 SecurityBlob
->WorkstationName
.Buffer
= 0;
2723 SecurityBlob
->WorkstationName
.Length
= 0;
2724 SecurityBlob
->WorkstationName
.MaximumLength
= 0;
2726 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2727 along with username on auth request (ie the response to challenge) */
2728 SecurityBlob
->DomainName
.Buffer
= 0;
2729 SecurityBlob
->DomainName
.Length
= 0;
2730 SecurityBlob
->DomainName
.MaximumLength
= 0;
2731 if (ses
->capabilities
& CAP_UNICODE
) {
2732 if ((long) bcc_ptr
% 2) {
2738 cifs_strtoUCS((__le16
*) bcc_ptr
, "Linux version ",
2740 bcc_ptr
+= 2 * bytes_returned
;
2742 cifs_strtoUCS((__le16
*) bcc_ptr
, utsname()->release
, 32,
2744 bcc_ptr
+= 2 * bytes_returned
;
2745 bcc_ptr
+= 2; /* null terminate Linux version */
2747 cifs_strtoUCS((__le16
*) bcc_ptr
, CIFS_NETWORK_OPSYS
,
2749 bcc_ptr
+= 2 * bytes_returned
;
2752 bcc_ptr
+= 2; /* null terminate network opsys string */
2755 bcc_ptr
+= 2; /* null domain */
2756 } else { /* ASCII */
2757 strcpy(bcc_ptr
, "Linux version ");
2758 bcc_ptr
+= strlen("Linux version ");
2759 strcpy(bcc_ptr
, utsname()->release
);
2760 bcc_ptr
+= strlen(utsname()->release
) + 1;
2761 strcpy(bcc_ptr
, CIFS_NETWORK_OPSYS
);
2762 bcc_ptr
+= strlen(CIFS_NETWORK_OPSYS
) + 1;
2763 bcc_ptr
++; /* empty domain field */
2766 SecurityBlob
->NegotiateFlags
= cpu_to_le32(negotiate_flags
);
2767 pSMB
->req
.SecurityBlobLength
= cpu_to_le16(SecurityBlobLength
);
2768 count
= (long) bcc_ptr
- (long) pByteArea(smb_buffer
);
2769 smb_buffer
->smb_buf_length
+= count
;
2770 pSMB
->req
.ByteCount
= cpu_to_le16(count
);
2772 rc
= SendReceive(xid
, ses
, smb_buffer
, smb_buffer_response
,
2773 &bytes_returned
, CIFS_LONG_OP
);
2775 if (smb_buffer_response
->Status
.CifsError
==
2776 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED
))
2780 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2781 } else if ((smb_buffer_response
->WordCount
== 3)
2782 || (smb_buffer_response
->WordCount
== 4)) {
2783 __u16 action
= le16_to_cpu(pSMBr
->resp
.Action
);
2784 __u16 blob_len
= le16_to_cpu(pSMBr
->resp
.SecurityBlobLength
);
2786 if (action
& GUEST_LOGIN
)
2787 cFYI(1, (" Guest login"));
2788 /* Do we want to set anything in SesInfo struct when guest login? */
2790 bcc_ptr
= pByteArea(smb_buffer_response
);
2791 /* response can have either 3 or 4 word count - Samba sends 3 */
2793 SecurityBlob2
= (PCHALLENGE_MESSAGE
) bcc_ptr
;
2794 if (SecurityBlob2
->MessageType
!= NtLmChallenge
) {
2796 ("Unexpected NTLMSSP message type received %d",
2797 SecurityBlob2
->MessageType
));
2799 ses
->Suid
= smb_buffer_response
->Uid
; /* UID left in le format */
2800 cFYI(1, ("UID = %d", ses
->Suid
));
2801 if ((pSMBr
->resp
.hdr
.WordCount
== 3)
2802 || ((pSMBr
->resp
.hdr
.WordCount
== 4)
2804 pSMBr
->resp
.ByteCount
))) {
2806 if (pSMBr
->resp
.hdr
.WordCount
== 4) {
2807 bcc_ptr
+= blob_len
;
2808 cFYI(1, ("Security Blob Length %d",
2812 cFYI(1, ("NTLMSSP Challenge rcvd"));
2814 memcpy(ses
->server
->cryptKey
,
2815 SecurityBlob2
->Challenge
,
2816 CIFS_CRYPTO_KEY_SIZE
);
2817 if (SecurityBlob2
->NegotiateFlags
&
2818 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2
))
2819 *pNTLMv2_flag
= true;
2821 if ((SecurityBlob2
->NegotiateFlags
&
2822 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN
))
2823 || (sign_CIFS_PDUs
> 1))
2824 ses
->server
->secMode
|=
2825 SECMODE_SIGN_REQUIRED
;
2826 if ((SecurityBlob2
->NegotiateFlags
&
2827 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN
)) && (sign_CIFS_PDUs
))
2828 ses
->server
->secMode
|=
2829 SECMODE_SIGN_ENABLED
;
2831 if (smb_buffer
->Flags2
& SMBFLG2_UNICODE
) {
2832 if ((long) (bcc_ptr
) % 2) {
2834 (BCC(smb_buffer_response
)
2836 /* Must word align unicode strings */
2841 (smb_buffer_response
) / 2;
2844 UniStrnlen((wchar_t *) bcc_ptr
,
2845 remaining_words
- 1);
2846 /* We look for obvious messed up bcc or strings in response so we do not go off
2847 the end since (at least) WIN2K and Windows XP have a major bug in not null
2848 terminating last Unicode string in response */
2850 kfree(ses
->serverOS
);
2852 kzalloc(2 * (len
+ 1), GFP_KERNEL
);
2853 cifs_strfromUCS_le(ses
->serverOS
,
2857 bcc_ptr
+= 2 * (len
+ 1);
2858 remaining_words
-= len
+ 1;
2859 ses
->serverOS
[2 * len
] = 0;
2860 ses
->serverOS
[1 + (2 * len
)] = 0;
2861 if (remaining_words
> 0) {
2862 len
= UniStrnlen((wchar_t *)
2866 kfree(ses
->serverNOS
);
2868 kzalloc(2 * (len
+ 1),
2870 cifs_strfromUCS_le(ses
->
2876 bcc_ptr
+= 2 * (len
+ 1);
2877 ses
->serverNOS
[2 * len
] = 0;
2880 remaining_words
-= len
+ 1;
2881 if (remaining_words
> 0) {
2882 len
= UniStrnlen((wchar_t *) bcc_ptr
, remaining_words
);
2883 /* last string not always null terminated
2884 (for e.g. for Windows XP & 2000) */
2885 kfree(ses
->serverDomain
);
2897 ses
->serverDomain
[2*len
]
2902 } /* else no more room so create dummy domain string */
2904 kfree(ses
->serverDomain
);
2909 } else { /* no room so create dummy domain and NOS string */
2910 kfree(ses
->serverDomain
);
2912 kzalloc(2, GFP_KERNEL
);
2913 kfree(ses
->serverNOS
);
2915 kzalloc(2, GFP_KERNEL
);
2917 } else { /* ASCII */
2918 len
= strnlen(bcc_ptr
, 1024);
2919 if (((long) bcc_ptr
+ len
) - (long)
2920 pByteArea(smb_buffer_response
)
2921 <= BCC(smb_buffer_response
)) {
2923 kfree(ses
->serverOS
);
2927 strncpy(ses
->serverOS
,
2931 bcc_ptr
[0] = 0; /* null terminate string */
2934 len
= strnlen(bcc_ptr
, 1024);
2935 kfree(ses
->serverNOS
);
2939 strncpy(ses
->serverNOS
, bcc_ptr
, len
);
2944 len
= strnlen(bcc_ptr
, 1024);
2945 kfree(ses
->serverDomain
);
2949 strncpy(ses
->serverDomain
,
2956 ("field of length %d "
2957 "extends beyond end of smb",
2961 cERROR(1, ("Security Blob Length extends beyond"
2965 cERROR(1, ("No session structure passed in."));
2969 (" Invalid Word count %d:",
2970 smb_buffer_response
->WordCount
));
2974 cifs_buf_release(smb_buffer
);
2979 CIFSNTLMSSPAuthSessSetup(unsigned int xid
, struct cifsSesInfo
*ses
,
2980 char *ntlm_session_key
, bool ntlmv2_flag
,
2981 const struct nls_table
*nls_codepage
)
2983 struct smb_hdr
*smb_buffer
;
2984 struct smb_hdr
*smb_buffer_response
;
2985 SESSION_SETUP_ANDX
*pSMB
;
2986 SESSION_SETUP_ANDX
*pSMBr
;
2991 int remaining_words
= 0;
2992 int bytes_returned
= 0;
2994 int SecurityBlobLength
= sizeof(AUTHENTICATE_MESSAGE
);
2995 PAUTHENTICATE_MESSAGE SecurityBlob
;
2996 __u32 negotiate_flags
, capabilities
;
2999 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
3002 user
= ses
->userName
;
3003 domain
= ses
->domainName
;
3004 smb_buffer
= cifs_buf_get();
3005 if (smb_buffer
== NULL
) {
3008 smb_buffer_response
= smb_buffer
;
3009 pSMB
= (SESSION_SETUP_ANDX
*)smb_buffer
;
3010 pSMBr
= (SESSION_SETUP_ANDX
*)smb_buffer_response
;
3012 /* send SMBsessionSetup here */
3013 header_assemble(smb_buffer
, SMB_COM_SESSION_SETUP_ANDX
,
3014 NULL
/* no tCon exists yet */ , 12 /* wct */ );
3016 smb_buffer
->Mid
= GetNextMid(ses
->server
);
3017 pSMB
->req
.hdr
.Flags
|= (SMBFLG_CASELESS
| SMBFLG_CANONICAL_PATH_FORMAT
);
3018 pSMB
->req
.hdr
.Flags2
|= SMBFLG2_EXT_SEC
;
3019 pSMB
->req
.AndXCommand
= 0xFF;
3020 pSMB
->req
.MaxBufferSize
= cpu_to_le16(ses
->server
->maxBuf
);
3021 pSMB
->req
.MaxMpxCount
= cpu_to_le16(ses
->server
->maxReq
);
3023 pSMB
->req
.hdr
.Uid
= ses
->Suid
;
3025 if (ses
->server
->secMode
& (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
))
3026 smb_buffer
->Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
3028 capabilities
= CAP_LARGE_FILES
| CAP_NT_SMBS
| CAP_LEVEL_II_OPLOCKS
|
3029 CAP_EXTENDED_SECURITY
;
3030 if (ses
->capabilities
& CAP_UNICODE
) {
3031 smb_buffer
->Flags2
|= SMBFLG2_UNICODE
;
3032 capabilities
|= CAP_UNICODE
;
3034 if (ses
->capabilities
& CAP_STATUS32
) {
3035 smb_buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
3036 capabilities
|= CAP_STATUS32
;
3038 if (ses
->capabilities
& CAP_DFS
) {
3039 smb_buffer
->Flags2
|= SMBFLG2_DFS
;
3040 capabilities
|= CAP_DFS
;
3042 pSMB
->req
.Capabilities
= cpu_to_le32(capabilities
);
3044 bcc_ptr
= (char *)&pSMB
->req
.SecurityBlob
;
3045 SecurityBlob
= (PAUTHENTICATE_MESSAGE
)bcc_ptr
;
3046 strncpy(SecurityBlob
->Signature
, NTLMSSP_SIGNATURE
, 8);
3047 SecurityBlob
->MessageType
= NtLmAuthenticate
;
3048 bcc_ptr
+= SecurityBlobLength
;
3049 negotiate_flags
= NTLMSSP_NEGOTIATE_UNICODE
| NTLMSSP_REQUEST_TARGET
|
3050 NTLMSSP_NEGOTIATE_NTLM
| NTLMSSP_NEGOTIATE_TARGET_INFO
|
3051 0x80000000 | NTLMSSP_NEGOTIATE_128
;
3053 negotiate_flags
|= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN
;
3055 negotiate_flags
|= NTLMSSP_NEGOTIATE_NTLMV2
;
3057 /* setup pointers to domain name and workstation name */
3059 SecurityBlob
->WorkstationName
.Buffer
= 0;
3060 SecurityBlob
->WorkstationName
.Length
= 0;
3061 SecurityBlob
->WorkstationName
.MaximumLength
= 0;
3062 SecurityBlob
->SessionKey
.Length
= 0;
3063 SecurityBlob
->SessionKey
.MaximumLength
= 0;
3064 SecurityBlob
->SessionKey
.Buffer
= 0;
3066 SecurityBlob
->LmChallengeResponse
.Length
= 0;
3067 SecurityBlob
->LmChallengeResponse
.MaximumLength
= 0;
3068 SecurityBlob
->LmChallengeResponse
.Buffer
= 0;
3070 SecurityBlob
->NtChallengeResponse
.Length
=
3071 cpu_to_le16(CIFS_SESS_KEY_SIZE
);
3072 SecurityBlob
->NtChallengeResponse
.MaximumLength
=
3073 cpu_to_le16(CIFS_SESS_KEY_SIZE
);
3074 memcpy(bcc_ptr
, ntlm_session_key
, CIFS_SESS_KEY_SIZE
);
3075 SecurityBlob
->NtChallengeResponse
.Buffer
=
3076 cpu_to_le32(SecurityBlobLength
);
3077 SecurityBlobLength
+= CIFS_SESS_KEY_SIZE
;
3078 bcc_ptr
+= CIFS_SESS_KEY_SIZE
;
3080 if (ses
->capabilities
& CAP_UNICODE
) {
3081 if (domain
== NULL
) {
3082 SecurityBlob
->DomainName
.Buffer
= 0;
3083 SecurityBlob
->DomainName
.Length
= 0;
3084 SecurityBlob
->DomainName
.MaximumLength
= 0;
3086 __u16 ln
= cifs_strtoUCS((__le16
*) bcc_ptr
, domain
, 64,
3089 SecurityBlob
->DomainName
.MaximumLength
=
3091 SecurityBlob
->DomainName
.Buffer
=
3092 cpu_to_le32(SecurityBlobLength
);
3094 SecurityBlobLength
+= ln
;
3095 SecurityBlob
->DomainName
.Length
= cpu_to_le16(ln
);
3098 SecurityBlob
->UserName
.Buffer
= 0;
3099 SecurityBlob
->UserName
.Length
= 0;
3100 SecurityBlob
->UserName
.MaximumLength
= 0;
3102 __u16 ln
= cifs_strtoUCS((__le16
*) bcc_ptr
, user
, 64,
3105 SecurityBlob
->UserName
.MaximumLength
=
3107 SecurityBlob
->UserName
.Buffer
=
3108 cpu_to_le32(SecurityBlobLength
);
3110 SecurityBlobLength
+= ln
;
3111 SecurityBlob
->UserName
.Length
= cpu_to_le16(ln
);
3114 /* SecurityBlob->WorkstationName.Length =
3115 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3116 SecurityBlob->WorkstationName.Length *= 2;
3117 SecurityBlob->WorkstationName.MaximumLength =
3118 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3119 SecurityBlob->WorkstationName.Buffer =
3120 cpu_to_le32(SecurityBlobLength);
3121 bcc_ptr += SecurityBlob->WorkstationName.Length;
3122 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3123 SecurityBlob->WorkstationName.Length =
3124 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3126 if ((long) bcc_ptr
% 2) {
3131 cifs_strtoUCS((__le16
*) bcc_ptr
, "Linux version ",
3133 bcc_ptr
+= 2 * bytes_returned
;
3135 cifs_strtoUCS((__le16
*) bcc_ptr
, utsname()->release
, 32,
3137 bcc_ptr
+= 2 * bytes_returned
;
3138 bcc_ptr
+= 2; /* null term version string */
3140 cifs_strtoUCS((__le16
*) bcc_ptr
, CIFS_NETWORK_OPSYS
,
3142 bcc_ptr
+= 2 * bytes_returned
;
3145 bcc_ptr
+= 2; /* null terminate network opsys string */
3148 bcc_ptr
+= 2; /* null domain */
3149 } else { /* ASCII */
3150 if (domain
== NULL
) {
3151 SecurityBlob
->DomainName
.Buffer
= 0;
3152 SecurityBlob
->DomainName
.Length
= 0;
3153 SecurityBlob
->DomainName
.MaximumLength
= 0;
3156 negotiate_flags
|= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED
;
3157 strncpy(bcc_ptr
, domain
, 63);
3158 ln
= strnlen(domain
, 64);
3159 SecurityBlob
->DomainName
.MaximumLength
=
3161 SecurityBlob
->DomainName
.Buffer
=
3162 cpu_to_le32(SecurityBlobLength
);
3164 SecurityBlobLength
+= ln
;
3165 SecurityBlob
->DomainName
.Length
= cpu_to_le16(ln
);
3168 SecurityBlob
->UserName
.Buffer
= 0;
3169 SecurityBlob
->UserName
.Length
= 0;
3170 SecurityBlob
->UserName
.MaximumLength
= 0;
3173 strncpy(bcc_ptr
, user
, 63);
3174 ln
= strnlen(user
, 64);
3175 SecurityBlob
->UserName
.MaximumLength
= cpu_to_le16(ln
);
3176 SecurityBlob
->UserName
.Buffer
=
3177 cpu_to_le32(SecurityBlobLength
);
3179 SecurityBlobLength
+= ln
;
3180 SecurityBlob
->UserName
.Length
= cpu_to_le16(ln
);
3182 /* BB fill in our workstation name if known BB */
3184 strcpy(bcc_ptr
, "Linux version ");
3185 bcc_ptr
+= strlen("Linux version ");
3186 strcpy(bcc_ptr
, utsname()->release
);
3187 bcc_ptr
+= strlen(utsname()->release
) + 1;
3188 strcpy(bcc_ptr
, CIFS_NETWORK_OPSYS
);
3189 bcc_ptr
+= strlen(CIFS_NETWORK_OPSYS
) + 1;
3190 bcc_ptr
++; /* null domain */
3193 SecurityBlob
->NegotiateFlags
= cpu_to_le32(negotiate_flags
);
3194 pSMB
->req
.SecurityBlobLength
= cpu_to_le16(SecurityBlobLength
);
3195 count
= (long) bcc_ptr
- (long) pByteArea(smb_buffer
);
3196 smb_buffer
->smb_buf_length
+= count
;
3197 pSMB
->req
.ByteCount
= cpu_to_le16(count
);
3199 rc
= SendReceive(xid
, ses
, smb_buffer
, smb_buffer_response
,
3200 &bytes_returned
, CIFS_LONG_OP
);
3202 /* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3203 } else if ((smb_buffer_response
->WordCount
== 3) ||
3204 (smb_buffer_response
->WordCount
== 4)) {
3205 __u16 action
= le16_to_cpu(pSMBr
->resp
.Action
);
3206 __u16 blob_len
= le16_to_cpu(pSMBr
->resp
.SecurityBlobLength
);
3207 if (action
& GUEST_LOGIN
)
3208 cFYI(1, (" Guest login")); /* BB Should we set anything
3209 in SesInfo struct ? */
3210 /* if (SecurityBlob2->MessageType != NtLm??) {
3211 cFYI("Unexpected message type on auth response is %d"));
3216 ("Check challenge UID %d vs auth response UID %d",
3217 ses
->Suid
, smb_buffer_response
->Uid
));
3218 /* UID left in wire format */
3219 ses
->Suid
= smb_buffer_response
->Uid
;
3220 bcc_ptr
= pByteArea(smb_buffer_response
);
3221 /* response can have either 3 or 4 word count - Samba sends 3 */
3222 if ((pSMBr
->resp
.hdr
.WordCount
== 3)
3223 || ((pSMBr
->resp
.hdr
.WordCount
== 4)
3225 pSMBr
->resp
.ByteCount
))) {
3226 if (pSMBr
->resp
.hdr
.WordCount
== 4) {
3230 ("Security Blob Length %d ",
3235 ("NTLMSSP response to Authenticate "));
3237 if (smb_buffer
->Flags2
& SMBFLG2_UNICODE
) {
3238 if ((long) (bcc_ptr
) % 2) {
3240 (BCC(smb_buffer_response
)
3242 bcc_ptr
++; /* Unicode strings must be word aligned */
3244 remaining_words
= BCC(smb_buffer_response
) / 2;
3246 len
= UniStrnlen((wchar_t *) bcc_ptr
,
3247 remaining_words
- 1);
3248 /* We look for obvious messed up bcc or strings in response so we do not go off
3249 the end since (at least) WIN2K and Windows XP have a major bug in not null
3250 terminating last Unicode string in response */
3252 kfree(ses
->serverOS
);
3254 kzalloc(2 * (len
+ 1), GFP_KERNEL
);
3255 cifs_strfromUCS_le(ses
->serverOS
,
3259 bcc_ptr
+= 2 * (len
+ 1);
3260 remaining_words
-= len
+ 1;
3261 ses
->serverOS
[2 * len
] = 0;
3262 ses
->serverOS
[1 + (2 * len
)] = 0;
3263 if (remaining_words
> 0) {
3264 len
= UniStrnlen((wchar_t *)
3268 kfree(ses
->serverNOS
);
3270 kzalloc(2 * (len
+ 1),
3272 cifs_strfromUCS_le(ses
->
3278 bcc_ptr
+= 2 * (len
+ 1);
3279 ses
->serverNOS
[2 * len
] = 0;
3280 ses
->serverNOS
[1+(2*len
)] = 0;
3281 remaining_words
-= len
+ 1;
3282 if (remaining_words
> 0) {
3283 len
= UniStrnlen((wchar_t *) bcc_ptr
, remaining_words
);
3284 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3285 if (ses
->serverDomain
)
3286 kfree(ses
->serverDomain
);
3311 } /* else no more room so create dummy domain string */
3313 if (ses
->serverDomain
)
3314 kfree(ses
->serverDomain
);
3315 ses
->serverDomain
= kzalloc(2,GFP_KERNEL
);
3317 } else { /* no room so create dummy domain and NOS string */
3318 if (ses
->serverDomain
)
3319 kfree(ses
->serverDomain
);
3320 ses
->serverDomain
= kzalloc(2, GFP_KERNEL
);
3321 kfree(ses
->serverNOS
);
3322 ses
->serverNOS
= kzalloc(2, GFP_KERNEL
);
3324 } else { /* ASCII */
3325 len
= strnlen(bcc_ptr
, 1024);
3326 if (((long) bcc_ptr
+ len
) -
3327 (long) pByteArea(smb_buffer_response
)
3328 <= BCC(smb_buffer_response
)) {
3330 kfree(ses
->serverOS
);
3331 ses
->serverOS
= kzalloc(len
+ 1, GFP_KERNEL
);
3332 strncpy(ses
->serverOS
,bcc_ptr
, len
);
3335 bcc_ptr
[0] = 0; /* null terminate the string */
3338 len
= strnlen(bcc_ptr
, 1024);
3339 kfree(ses
->serverNOS
);
3340 ses
->serverNOS
= kzalloc(len
+1,
3342 strncpy(ses
->serverNOS
,
3348 len
= strnlen(bcc_ptr
, 1024);
3349 if (ses
->serverDomain
)
3350 kfree(ses
->serverDomain
);
3354 strncpy(ses
->serverDomain
,
3360 cFYI(1, ("field of length %d "
3361 "extends beyond end of smb ",
3365 cERROR(1, ("Security Blob extends beyond end "
3369 cERROR(1, ("No session structure passed in."));
3372 cERROR(1, ("Invalid Word count %d: ",
3373 smb_buffer_response
->WordCount
));
3377 cifs_buf_release(smb_buffer
);
3383 CIFSTCon(unsigned int xid
, struct cifsSesInfo
*ses
,
3384 const char *tree
, struct cifsTconInfo
*tcon
,
3385 const struct nls_table
*nls_codepage
)
3387 struct smb_hdr
*smb_buffer
;
3388 struct smb_hdr
*smb_buffer_response
;
3391 unsigned char *bcc_ptr
;
3399 smb_buffer
= cifs_buf_get();
3400 if (smb_buffer
== NULL
) {
3403 smb_buffer_response
= smb_buffer
;
3405 header_assemble(smb_buffer
, SMB_COM_TREE_CONNECT_ANDX
,
3406 NULL
/*no tid */ , 4 /*wct */ );
3408 smb_buffer
->Mid
= GetNextMid(ses
->server
);
3409 smb_buffer
->Uid
= ses
->Suid
;
3410 pSMB
= (TCONX_REQ
*) smb_buffer
;
3411 pSMBr
= (TCONX_RSP
*) smb_buffer_response
;
3413 pSMB
->AndXCommand
= 0xFF;
3414 pSMB
->Flags
= cpu_to_le16(TCON_EXTENDED_SECINFO
);
3415 bcc_ptr
= &pSMB
->Password
[0];
3416 if ((ses
->server
->secMode
) & SECMODE_USER
) {
3417 pSMB
->PasswordLength
= cpu_to_le16(1); /* minimum */
3418 *bcc_ptr
= 0; /* password is null byte */
3419 bcc_ptr
++; /* skip password */
3420 /* already aligned so no need to do it below */
3422 pSMB
->PasswordLength
= cpu_to_le16(CIFS_SESS_KEY_SIZE
);
3423 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3424 specified as required (when that support is added to
3425 the vfs in the future) as only NTLM or the much
3426 weaker LANMAN (which we do not send by default) is accepted
3427 by Samba (not sure whether other servers allow
3428 NTLMv2 password here) */
3429 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3430 if ((extended_security
& CIFSSEC_MAY_LANMAN
) &&
3431 (ses
->server
->secType
== LANMAN
))
3432 calc_lanman_hash(ses
, bcc_ptr
);
3434 #endif /* CIFS_WEAK_PW_HASH */
3435 SMBNTencrypt(ses
->password
,
3436 ses
->server
->cryptKey
,
3439 bcc_ptr
+= CIFS_SESS_KEY_SIZE
;
3440 if (ses
->capabilities
& CAP_UNICODE
) {
3441 /* must align unicode strings */
3442 *bcc_ptr
= 0; /* null byte password */
3447 if (ses
->server
->secMode
&
3448 (SECMODE_SIGN_REQUIRED
| SECMODE_SIGN_ENABLED
))
3449 smb_buffer
->Flags2
|= SMBFLG2_SECURITY_SIGNATURE
;
3451 if (ses
->capabilities
& CAP_STATUS32
) {
3452 smb_buffer
->Flags2
|= SMBFLG2_ERR_STATUS
;
3454 if (ses
->capabilities
& CAP_DFS
) {
3455 smb_buffer
->Flags2
|= SMBFLG2_DFS
;
3457 if (ses
->capabilities
& CAP_UNICODE
) {
3458 smb_buffer
->Flags2
|= SMBFLG2_UNICODE
;
3460 cifs_strtoUCS((__le16
*) bcc_ptr
, tree
,
3461 6 /* max utf8 char length in bytes */ *
3462 (/* server len*/ + 256 /* share len */), nls_codepage
);
3463 bcc_ptr
+= 2 * length
; /* convert num 16 bit words to bytes */
3464 bcc_ptr
+= 2; /* skip trailing null */
3465 } else { /* ASCII */
3466 strcpy(bcc_ptr
, tree
);
3467 bcc_ptr
+= strlen(tree
) + 1;
3469 strcpy(bcc_ptr
, "?????");
3470 bcc_ptr
+= strlen("?????");
3472 count
= bcc_ptr
- &pSMB
->Password
[0];
3473 pSMB
->hdr
.smb_buf_length
+= count
;
3474 pSMB
->ByteCount
= cpu_to_le16(count
);
3476 rc
= SendReceive(xid
, ses
, smb_buffer
, smb_buffer_response
, &length
,
3479 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3480 /* above now done in SendReceive */
3481 if ((rc
== 0) && (tcon
!= NULL
)) {
3482 tcon
->tidStatus
= CifsGood
;
3483 tcon
->tid
= smb_buffer_response
->Tid
;
3484 bcc_ptr
= pByteArea(smb_buffer_response
);
3485 length
= strnlen(bcc_ptr
, BCC(smb_buffer_response
) - 2);
3486 /* skip service field (NB: this field is always ASCII) */
3488 if ((bcc_ptr
[0] == 'I') && (bcc_ptr
[1] == 'P') &&
3489 (bcc_ptr
[2] == 'C')) {
3490 cFYI(1, ("IPC connection"));
3493 } else if (length
== 2) {
3494 if ((bcc_ptr
[0] == 'A') && (bcc_ptr
[1] == ':')) {
3495 /* the most common case */
3496 cFYI(1, ("disk share connection"));
3499 bcc_ptr
+= length
+ 1;
3500 strncpy(tcon
->treeName
, tree
, MAX_TREE_SIZE
);
3501 if (smb_buffer
->Flags2
& SMBFLG2_UNICODE
) {
3502 length
= UniStrnlen((wchar_t *) bcc_ptr
, 512);
3503 if ((bcc_ptr
+ (2 * length
)) -
3504 pByteArea(smb_buffer_response
) <=
3505 BCC(smb_buffer_response
)) {
3506 kfree(tcon
->nativeFileSystem
);
3507 tcon
->nativeFileSystem
=
3508 kzalloc(length
+ 2, GFP_KERNEL
);
3509 if (tcon
->nativeFileSystem
)
3511 tcon
->nativeFileSystem
,
3513 length
, nls_codepage
);
3514 bcc_ptr
+= 2 * length
;
3515 bcc_ptr
[0] = 0; /* null terminate the string */
3519 /* else do not bother copying these information fields*/
3521 length
= strnlen(bcc_ptr
, 1024);
3522 if ((bcc_ptr
+ length
) -
3523 pByteArea(smb_buffer_response
) <=
3524 BCC(smb_buffer_response
)) {
3525 kfree(tcon
->nativeFileSystem
);
3526 tcon
->nativeFileSystem
=
3527 kzalloc(length
+ 1, GFP_KERNEL
);
3528 if (tcon
->nativeFileSystem
)
3529 strncpy(tcon
->nativeFileSystem
, bcc_ptr
,
3532 /* else do not bother copying these information fields*/
3534 if ((smb_buffer_response
->WordCount
== 3) ||
3535 (smb_buffer_response
->WordCount
== 7))
3536 /* field is in same location */
3537 tcon
->Flags
= le16_to_cpu(pSMBr
->OptionalSupport
);
3540 cFYI(1, ("Tcon flags: 0x%x ", tcon
->Flags
));
3541 } else if ((rc
== 0) && tcon
== NULL
) {
3542 /* all we need to save for IPC$ connection */
3543 ses
->ipc_tid
= smb_buffer_response
->Tid
;
3546 cifs_buf_release(smb_buffer
);
3551 cifs_umount(struct super_block
*sb
, struct cifs_sb_info
*cifs_sb
)
3555 struct cifsSesInfo
*ses
= NULL
;
3556 struct task_struct
*cifsd_task
;
3561 if (cifs_sb
->tcon
) {
3562 ses
= cifs_sb
->tcon
->ses
; /* save ptr to ses before delete tcon!*/
3563 rc
= CIFSSMBTDis(xid
, cifs_sb
->tcon
);
3568 DeleteTconOplockQEntries(cifs_sb
->tcon
);
3569 tconInfoFree(cifs_sb
->tcon
);
3570 if ((ses
) && (ses
->server
)) {
3571 /* save off task so we do not refer to ses later */
3572 cifsd_task
= ses
->server
->tsk
;
3573 cFYI(1, ("About to do SMBLogoff "));
3574 rc
= CIFSSMBLogoff(xid
, ses
);
3578 } else if (rc
== -ESHUTDOWN
) {
3579 cFYI(1, ("Waking up socket by sending signal"));
3581 force_sig(SIGKILL
, cifsd_task
);
3582 kthread_stop(cifsd_task
);
3585 } /* else - we have an smb session
3586 left on this socket do not kill cifsd */
3588 cFYI(1, ("No session or bad tcon"));
3591 cifs_sb
->tcon
= NULL
;
3592 tmp
= cifs_sb
->prepath
;
3593 cifs_sb
->prepathlen
= 0;
3594 cifs_sb
->prepath
= NULL
;
3603 int cifs_setup_session(unsigned int xid
, struct cifsSesInfo
*pSesInfo
,
3604 struct nls_table
*nls_info
)
3607 char ntlm_session_key
[CIFS_SESS_KEY_SIZE
];
3608 bool ntlmv2_flag
= false;
3610 struct TCP_Server_Info
*server
= pSesInfo
->server
;
3612 /* what if server changes its buffer size after dropping the session? */
3613 if (server
->maxBuf
== 0) /* no need to send on reconnect */ {
3614 rc
= CIFSSMBNegotiate(xid
, pSesInfo
);
3615 if (rc
== -EAGAIN
) {
3616 /* retry only once on 1st time connection */
3617 rc
= CIFSSMBNegotiate(xid
, pSesInfo
);
3622 spin_lock(&GlobalMid_Lock
);
3623 if (server
->tcpStatus
!= CifsExiting
)
3624 server
->tcpStatus
= CifsGood
;
3627 spin_unlock(&GlobalMid_Lock
);
3636 pSesInfo
->flags
= 0;
3637 pSesInfo
->capabilities
= server
->capabilities
;
3638 if (linuxExtEnabled
== 0)
3639 pSesInfo
->capabilities
&= (~CAP_UNIX
);
3640 /* pSesInfo->sequence_number = 0;*/
3641 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3642 server
->secMode
, server
->capabilities
, server
->timeAdj
));
3644 if (experimEnabled
< 2)
3645 rc
= CIFS_SessSetup(xid
, pSesInfo
, first_time
, nls_info
);
3646 else if (extended_security
3647 && (pSesInfo
->capabilities
& CAP_EXTENDED_SECURITY
)
3648 && (server
->secType
== NTLMSSP
)) {
3650 } else if (extended_security
3651 && (pSesInfo
->capabilities
& CAP_EXTENDED_SECURITY
)
3652 && (server
->secType
== RawNTLMSSP
)) {
3653 cFYI(1, ("NTLMSSP sesssetup"));
3654 rc
= CIFSNTLMSSPNegotiateSessSetup(xid
, pSesInfo
, &ntlmv2_flag
,
3659 cFYI(1, ("more secure NTLM ver2 hash"));
3660 if (CalcNTLMv2_partial_mac_key(pSesInfo
,
3665 v2_response
= kmalloc(16 + 64 /* blob*/,
3668 CalcNTLMv2_response(pSesInfo
,
3671 cifs_calculate_ntlmv2_mac_key */
3673 /* BB Put dummy sig in SessSetup PDU? */
3680 SMBNTencrypt(pSesInfo
->password
,
3685 cifs_calculate_mac_key(
3686 &server
->mac_signing_key
,
3688 pSesInfo
->password
);
3690 /* for better security the weaker lanman hash not sent
3691 in AuthSessSetup so we no longer calculate it */
3693 rc
= CIFSNTLMSSPAuthSessSetup(xid
, pSesInfo
,
3698 } else { /* old style NTLM 0.12 session setup */
3699 SMBNTencrypt(pSesInfo
->password
, server
->cryptKey
,
3703 cifs_calculate_mac_key(&server
->mac_signing_key
,
3705 pSesInfo
->password
);
3707 rc
= CIFSSessSetup(xid
, pSesInfo
, ntlm_session_key
, nls_info
);
3710 cERROR(1, ("Send error in SessSetup = %d", rc
));
3712 cFYI(1, ("CIFS Session Established successfully"));
3713 pSesInfo
->status
= CifsGood
;