cifs: take module reference when starting cifsd
[linux-2.6/cjktty.git] / fs / cifs / connect.c
blob701daf411a4bb7e3a63d3085b8fb0453d025f6e0
1 /*
2 * fs/cifs/connect.c
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
21 #include <linux/fs.h>
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>
38 #include "cifspdu.h"
39 #include "cifsglob.h"
40 #include "cifsproto.h"
41 #include "cifs_unicode.h"
42 #include "cifs_debug.h"
43 #include "cifs_fs_sb.h"
44 #include "ntlmssp.h"
45 #include "nterr.h"
46 #include "rfc1002pdu.h"
47 #include "cn_cifs.h"
49 #define CIFS_PORT 445
50 #define RFC1001_PORT 139
52 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
53 unsigned char *p24);
55 extern mempool_t *cifs_req_poolp;
57 struct smb_vol {
58 char *username;
59 char *password;
60 char *domainname;
61 char *UNC;
62 char *UNCip;
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 */
67 uid_t linux_uid;
68 gid_t linux_gid;
69 mode_t file_mode;
70 mode_t dir_mode;
71 unsigned secFlg;
72 bool rw:1;
73 bool retry:1;
74 bool intr:1;
75 bool setuids:1;
76 bool override_uid:1;
77 bool override_gid:1;
78 bool dynperm:1;
79 bool noperm:1;
80 bool no_psx_acl:1; /* set if posix acl support should be disabled */
81 bool cifs_acl:1;
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 */
84 bool direct_io:1;
85 bool remap:1; /* set to remap seven reserved chars in filenames */
86 bool posix_paths:1; /* unset to not ask for posix pathnames. */
87 bool no_linux_ext:1;
88 bool sfu_emul:1;
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 */
93 bool nodfs:1; /* Do not request DFS, even if available */
94 bool local_lease:1; /* check leases only on local system, not remote */
95 bool noblocksnd:1;
96 bool noautotune:1;
97 unsigned int rsize;
98 unsigned int wsize;
99 unsigned int sockopt;
100 unsigned short int port;
101 char *prepath;
104 static int ipv4_connect(struct sockaddr_in *psin_server,
105 struct socket **csocket,
106 char *netb_name,
107 char *server_netb_name,
108 bool noblocksnd,
109 bool nosndbuf); /* ipv6 never set sndbuf size */
110 static int ipv6_connect(struct sockaddr_in6 *psin_server,
111 struct socket **csocket, bool noblocksnd);
115 * cifs tcp session reconnection
117 * mark tcp session as reconnecting so temporarily locked
118 * mark all smb sessions as reconnecting for tcp session
119 * reconnect tcp session
120 * wake up waiters on reconnection? - (not needed currently)
123 static int
124 cifs_reconnect(struct TCP_Server_Info *server)
126 int rc = 0;
127 struct list_head *tmp, *tmp2;
128 struct cifsSesInfo *ses;
129 struct cifsTconInfo *tcon;
130 struct mid_q_entry *mid_entry;
132 spin_lock(&GlobalMid_Lock);
133 if (server->tcpStatus == CifsExiting) {
134 /* the demux thread will exit normally
135 next time through the loop */
136 spin_unlock(&GlobalMid_Lock);
137 return rc;
138 } else
139 server->tcpStatus = CifsNeedReconnect;
140 spin_unlock(&GlobalMid_Lock);
141 server->maxBuf = 0;
143 cFYI(1, ("Reconnecting tcp session"));
145 /* before reconnecting the tcp session, mark the smb session (uid)
146 and the tid bad so they are not used until reconnected */
147 read_lock(&cifs_tcp_ses_lock);
148 list_for_each(tmp, &server->smb_ses_list) {
149 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
150 ses->need_reconnect = true;
151 ses->ipc_tid = 0;
152 list_for_each(tmp2, &ses->tcon_list) {
153 tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list);
154 tcon->need_reconnect = true;
157 read_unlock(&cifs_tcp_ses_lock);
158 /* do not want to be sending data on a socket we are freeing */
159 down(&server->tcpSem);
160 if (server->ssocket) {
161 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
162 server->ssocket->flags));
163 kernel_sock_shutdown(server->ssocket, SHUT_WR);
164 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
165 server->ssocket->state,
166 server->ssocket->flags));
167 sock_release(server->ssocket);
168 server->ssocket = NULL;
171 spin_lock(&GlobalMid_Lock);
172 list_for_each(tmp, &server->pending_mid_q) {
173 mid_entry = list_entry(tmp, struct
174 mid_q_entry,
175 qhead);
176 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
177 /* Mark other intransit requests as needing
178 retry so we do not immediately mark the
179 session bad again (ie after we reconnect
180 below) as they timeout too */
181 mid_entry->midState = MID_RETRY_NEEDED;
184 spin_unlock(&GlobalMid_Lock);
185 up(&server->tcpSem);
187 while ((server->tcpStatus != CifsExiting) &&
188 (server->tcpStatus != CifsGood)) {
189 try_to_freeze();
190 if (server->addr.sockAddr6.sin6_family == AF_INET6) {
191 rc = ipv6_connect(&server->addr.sockAddr6,
192 &server->ssocket, server->noautotune);
193 } else {
194 rc = ipv4_connect(&server->addr.sockAddr,
195 &server->ssocket,
196 server->workstation_RFC1001_name,
197 server->server_RFC1001_name,
198 server->noblocksnd, server->noautotune);
200 if (rc) {
201 cFYI(1, ("reconnect error %d", rc));
202 msleep(3000);
203 } else {
204 atomic_inc(&tcpSesReconnectCount);
205 spin_lock(&GlobalMid_Lock);
206 if (server->tcpStatus != CifsExiting)
207 server->tcpStatus = CifsGood;
208 server->sequence_number = 0;
209 spin_unlock(&GlobalMid_Lock);
210 /* atomic_set(&server->inFlight,0);*/
211 wake_up(&server->response_q);
214 return rc;
218 return codes:
219 0 not a transact2, or all data present
220 >0 transact2 with that much data missing
221 -EINVAL = invalid transact2
224 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
226 struct smb_t2_rsp *pSMBt;
227 int total_data_size;
228 int data_in_this_rsp;
229 int remaining;
231 if (pSMB->Command != SMB_COM_TRANSACTION2)
232 return 0;
234 /* check for plausible wct, bcc and t2 data and parm sizes */
235 /* check for parm and data offset going beyond end of smb */
236 if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
237 cFYI(1, ("invalid transact2 word count"));
238 return -EINVAL;
241 pSMBt = (struct smb_t2_rsp *)pSMB;
243 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
244 data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
246 remaining = total_data_size - data_in_this_rsp;
248 if (remaining == 0)
249 return 0;
250 else if (remaining < 0) {
251 cFYI(1, ("total data %d smaller than data in frame %d",
252 total_data_size, data_in_this_rsp));
253 return -EINVAL;
254 } else {
255 cFYI(1, ("missing %d bytes from transact2, check next response",
256 remaining));
257 if (total_data_size > maxBufSize) {
258 cERROR(1, ("TotalDataSize %d is over maximum buffer %d",
259 total_data_size, maxBufSize));
260 return -EINVAL;
262 return remaining;
266 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
268 struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
269 struct smb_t2_rsp *pSMBt = (struct smb_t2_rsp *)pTargetSMB;
270 int total_data_size;
271 int total_in_buf;
272 int remaining;
273 int total_in_buf2;
274 char *data_area_of_target;
275 char *data_area_of_buf2;
276 __u16 byte_count;
278 total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
280 if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
281 cFYI(1, ("total data size of primary and secondary t2 differ"));
284 total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
286 remaining = total_data_size - total_in_buf;
288 if (remaining < 0)
289 return -EINVAL;
291 if (remaining == 0) /* nothing to do, ignore */
292 return 0;
294 total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
295 if (remaining < total_in_buf2) {
296 cFYI(1, ("transact2 2nd response contains too much data"));
299 /* find end of first SMB data area */
300 data_area_of_target = (char *)&pSMBt->hdr.Protocol +
301 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
302 /* validate target area */
304 data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
305 le16_to_cpu(pSMB2->t2_rsp.DataOffset);
307 data_area_of_target += total_in_buf;
309 /* copy second buffer into end of first buffer */
310 memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
311 total_in_buf += total_in_buf2;
312 pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
313 byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
314 byte_count += total_in_buf2;
315 BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
317 byte_count = pTargetSMB->smb_buf_length;
318 byte_count += total_in_buf2;
320 /* BB also add check that we are not beyond maximum buffer size */
322 pTargetSMB->smb_buf_length = byte_count;
324 if (remaining == total_in_buf2) {
325 cFYI(1, ("found the last secondary response"));
326 return 0; /* we are done */
327 } else /* more responses to go */
328 return 1;
332 static int
333 cifs_demultiplex_thread(struct TCP_Server_Info *server)
335 int length;
336 unsigned int pdu_length, total_read;
337 struct smb_hdr *smb_buffer = NULL;
338 struct smb_hdr *bigbuf = NULL;
339 struct smb_hdr *smallbuf = NULL;
340 struct msghdr smb_msg;
341 struct kvec iov;
342 struct socket *csocket = server->ssocket;
343 struct list_head *tmp;
344 struct cifsSesInfo *ses;
345 struct task_struct *task_to_wake = NULL;
346 struct mid_q_entry *mid_entry;
347 char temp;
348 bool isLargeBuf = false;
349 bool isMultiRsp;
350 int reconnect;
352 current->flags |= PF_MEMALLOC;
353 cFYI(1, ("Demultiplex PID: %d", task_pid_nr(current)));
355 length = atomic_inc_return(&tcpSesAllocCount);
356 if (length > 1)
357 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
358 GFP_KERNEL);
360 set_freezable();
361 while (server->tcpStatus != CifsExiting) {
362 if (try_to_freeze())
363 continue;
364 if (bigbuf == NULL) {
365 bigbuf = cifs_buf_get();
366 if (!bigbuf) {
367 cERROR(1, ("No memory for large SMB response"));
368 msleep(3000);
369 /* retry will check if exiting */
370 continue;
372 } else if (isLargeBuf) {
373 /* we are reusing a dirty large buf, clear its start */
374 memset(bigbuf, 0, sizeof(struct smb_hdr));
377 if (smallbuf == NULL) {
378 smallbuf = cifs_small_buf_get();
379 if (!smallbuf) {
380 cERROR(1, ("No memory for SMB response"));
381 msleep(1000);
382 /* retry will check if exiting */
383 continue;
385 /* beginning of smb buffer is cleared in our buf_get */
386 } else /* if existing small buf clear beginning */
387 memset(smallbuf, 0, sizeof(struct smb_hdr));
389 isLargeBuf = false;
390 isMultiRsp = false;
391 smb_buffer = smallbuf;
392 iov.iov_base = smb_buffer;
393 iov.iov_len = 4;
394 smb_msg.msg_control = NULL;
395 smb_msg.msg_controllen = 0;
396 pdu_length = 4; /* enough to get RFC1001 header */
397 incomplete_rcv:
398 length =
399 kernel_recvmsg(csocket, &smb_msg,
400 &iov, 1, pdu_length, 0 /* BB other flags? */);
402 if (server->tcpStatus == CifsExiting) {
403 break;
404 } else if (server->tcpStatus == CifsNeedReconnect) {
405 cFYI(1, ("Reconnect after server stopped responding"));
406 cifs_reconnect(server);
407 cFYI(1, ("call to reconnect done"));
408 csocket = server->ssocket;
409 continue;
410 } else if ((length == -ERESTARTSYS) || (length == -EAGAIN)) {
411 msleep(1); /* minimum sleep to prevent looping
412 allowing socket to clear and app threads to set
413 tcpStatus CifsNeedReconnect if server hung */
414 if (pdu_length < 4) {
415 iov.iov_base = (4 - pdu_length) +
416 (char *)smb_buffer;
417 iov.iov_len = pdu_length;
418 smb_msg.msg_control = NULL;
419 smb_msg.msg_controllen = 0;
420 goto incomplete_rcv;
421 } else
422 continue;
423 } else if (length <= 0) {
424 if (server->tcpStatus == CifsNew) {
425 cFYI(1, ("tcp session abend after SMBnegprot"));
426 /* some servers kill the TCP session rather than
427 returning an SMB negprot error, in which
428 case reconnecting here is not going to help,
429 and so simply return error to mount */
430 break;
432 if (!try_to_freeze() && (length == -EINTR)) {
433 cFYI(1, ("cifsd thread killed"));
434 break;
436 cFYI(1, ("Reconnect after unexpected peek error %d",
437 length));
438 cifs_reconnect(server);
439 csocket = server->ssocket;
440 wake_up(&server->response_q);
441 continue;
442 } else if (length < pdu_length) {
443 cFYI(1, ("requested %d bytes but only got %d bytes",
444 pdu_length, length));
445 pdu_length -= length;
446 msleep(1);
447 goto incomplete_rcv;
450 /* The right amount was read from socket - 4 bytes */
451 /* so we can now interpret the length field */
453 /* the first byte big endian of the length field,
454 is actually not part of the length but the type
455 with the most common, zero, as regular data */
456 temp = *((char *) smb_buffer);
458 /* Note that FC 1001 length is big endian on the wire,
459 but we convert it here so it is always manipulated
460 as host byte order */
461 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
462 smb_buffer->smb_buf_length = pdu_length;
464 cFYI(1, ("rfc1002 length 0x%x", pdu_length+4));
466 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
467 continue;
468 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
469 cFYI(1, ("Good RFC 1002 session rsp"));
470 continue;
471 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
472 /* we get this from Windows 98 instead of
473 an error on SMB negprot response */
474 cFYI(1, ("Negative RFC1002 Session Response Error 0x%x)",
475 pdu_length));
476 if (server->tcpStatus == CifsNew) {
477 /* if nack on negprot (rather than
478 ret of smb negprot error) reconnecting
479 not going to help, ret error to mount */
480 break;
481 } else {
482 /* give server a second to
483 clean up before reconnect attempt */
484 msleep(1000);
485 /* always try 445 first on reconnect
486 since we get NACK on some if we ever
487 connected to port 139 (the NACK is
488 since we do not begin with RFC1001
489 session initialize frame) */
490 server->addr.sockAddr.sin_port =
491 htons(CIFS_PORT);
492 cifs_reconnect(server);
493 csocket = server->ssocket;
494 wake_up(&server->response_q);
495 continue;
497 } else if (temp != (char) 0) {
498 cERROR(1, ("Unknown RFC 1002 frame"));
499 cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
500 length);
501 cifs_reconnect(server);
502 csocket = server->ssocket;
503 continue;
506 /* else we have an SMB response */
507 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
508 (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
509 cERROR(1, ("Invalid size SMB length %d pdu_length %d",
510 length, pdu_length+4));
511 cifs_reconnect(server);
512 csocket = server->ssocket;
513 wake_up(&server->response_q);
514 continue;
517 /* else length ok */
518 reconnect = 0;
520 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
521 isLargeBuf = true;
522 memcpy(bigbuf, smallbuf, 4);
523 smb_buffer = bigbuf;
525 length = 0;
526 iov.iov_base = 4 + (char *)smb_buffer;
527 iov.iov_len = pdu_length;
528 for (total_read = 0; total_read < pdu_length;
529 total_read += length) {
530 length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
531 pdu_length - total_read, 0);
532 if ((server->tcpStatus == CifsExiting) ||
533 (length == -EINTR)) {
534 /* then will exit */
535 reconnect = 2;
536 break;
537 } else if (server->tcpStatus == CifsNeedReconnect) {
538 cifs_reconnect(server);
539 csocket = server->ssocket;
540 /* Reconnect wakes up rspns q */
541 /* Now we will reread sock */
542 reconnect = 1;
543 break;
544 } else if ((length == -ERESTARTSYS) ||
545 (length == -EAGAIN)) {
546 msleep(1); /* minimum sleep to prevent looping,
547 allowing socket to clear and app
548 threads to set tcpStatus
549 CifsNeedReconnect if server hung*/
550 length = 0;
551 continue;
552 } else if (length <= 0) {
553 cERROR(1, ("Received no data, expecting %d",
554 pdu_length - total_read));
555 cifs_reconnect(server);
556 csocket = server->ssocket;
557 reconnect = 1;
558 break;
561 if (reconnect == 2)
562 break;
563 else if (reconnect == 1)
564 continue;
566 length += 4; /* account for rfc1002 hdr */
569 dump_smb(smb_buffer, length);
570 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
571 cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
572 continue;
576 task_to_wake = NULL;
577 spin_lock(&GlobalMid_Lock);
578 list_for_each(tmp, &server->pending_mid_q) {
579 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
581 if ((mid_entry->mid == smb_buffer->Mid) &&
582 (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
583 (mid_entry->command == smb_buffer->Command)) {
584 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
585 /* We have a multipart transact2 resp */
586 isMultiRsp = true;
587 if (mid_entry->resp_buf) {
588 /* merge response - fix up 1st*/
589 if (coalesce_t2(smb_buffer,
590 mid_entry->resp_buf)) {
591 mid_entry->multiRsp =
592 true;
593 break;
594 } else {
595 /* all parts received */
596 mid_entry->multiEnd =
597 true;
598 goto multi_t2_fnd;
600 } else {
601 if (!isLargeBuf) {
602 cERROR(1,("1st trans2 resp needs bigbuf"));
603 /* BB maybe we can fix this up, switch
604 to already allocated large buffer? */
605 } else {
606 /* Have first buffer */
607 mid_entry->resp_buf =
608 smb_buffer;
609 mid_entry->largeBuf =
610 true;
611 bigbuf = NULL;
614 break;
616 mid_entry->resp_buf = smb_buffer;
617 mid_entry->largeBuf = isLargeBuf;
618 multi_t2_fnd:
619 task_to_wake = mid_entry->tsk;
620 mid_entry->midState = MID_RESPONSE_RECEIVED;
621 #ifdef CONFIG_CIFS_STATS2
622 mid_entry->when_received = jiffies;
623 #endif
624 /* so we do not time out requests to server
625 which is still responding (since server could
626 be busy but not dead) */
627 server->lstrp = jiffies;
628 break;
631 spin_unlock(&GlobalMid_Lock);
632 if (task_to_wake) {
633 /* Was previous buf put in mpx struct for multi-rsp? */
634 if (!isMultiRsp) {
635 /* smb buffer will be freed by user thread */
636 if (isLargeBuf)
637 bigbuf = NULL;
638 else
639 smallbuf = NULL;
641 wake_up_process(task_to_wake);
642 } else if (!is_valid_oplock_break(smb_buffer, server) &&
643 !isMultiRsp) {
644 cERROR(1, ("No task to wake, unknown frame received! "
645 "NumMids %d", midCount.counter));
646 cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
647 sizeof(struct smb_hdr));
648 #ifdef CONFIG_CIFS_DEBUG2
649 cifs_dump_detail(smb_buffer);
650 cifs_dump_mids(server);
651 #endif /* CIFS_DEBUG2 */
654 } /* end while !EXITING */
656 /* take it off the list, if it's not already */
657 write_lock(&cifs_tcp_ses_lock);
658 list_del_init(&server->tcp_ses_list);
659 write_unlock(&cifs_tcp_ses_lock);
661 spin_lock(&GlobalMid_Lock);
662 server->tcpStatus = CifsExiting;
663 spin_unlock(&GlobalMid_Lock);
664 wake_up_all(&server->response_q);
666 /* check if we have blocked requests that need to free */
667 /* Note that cifs_max_pending is normally 50, but
668 can be set at module install time to as little as two */
669 spin_lock(&GlobalMid_Lock);
670 if (atomic_read(&server->inFlight) >= cifs_max_pending)
671 atomic_set(&server->inFlight, cifs_max_pending - 1);
672 /* We do not want to set the max_pending too low or we
673 could end up with the counter going negative */
674 spin_unlock(&GlobalMid_Lock);
675 /* Although there should not be any requests blocked on
676 this queue it can not hurt to be paranoid and try to wake up requests
677 that may haven been blocked when more than 50 at time were on the wire
678 to the same server - they now will see the session is in exit state
679 and get out of SendReceive. */
680 wake_up_all(&server->request_q);
681 /* give those requests time to exit */
682 msleep(125);
684 if (server->ssocket) {
685 sock_release(csocket);
686 server->ssocket = NULL;
688 /* buffer usuallly freed in free_mid - need to free it here on exit */
689 cifs_buf_release(bigbuf);
690 if (smallbuf) /* no sense logging a debug message if NULL */
691 cifs_small_buf_release(smallbuf);
694 * BB: we shouldn't have to do any of this. It shouldn't be
695 * possible to exit from the thread with active SMB sessions
697 read_lock(&cifs_tcp_ses_lock);
698 if (list_empty(&server->pending_mid_q)) {
699 /* loop through server session structures attached to this and
700 mark them dead */
701 list_for_each(tmp, &server->smb_ses_list) {
702 ses = list_entry(tmp, struct cifsSesInfo,
703 smb_ses_list);
704 ses->status = CifsExiting;
705 ses->server = NULL;
707 read_unlock(&cifs_tcp_ses_lock);
708 } else {
709 /* although we can not zero the server struct pointer yet,
710 since there are active requests which may depnd on them,
711 mark the corresponding SMB sessions as exiting too */
712 list_for_each(tmp, &server->smb_ses_list) {
713 ses = list_entry(tmp, struct cifsSesInfo,
714 smb_ses_list);
715 ses->status = CifsExiting;
718 spin_lock(&GlobalMid_Lock);
719 list_for_each(tmp, &server->pending_mid_q) {
720 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
721 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
722 cFYI(1, ("Clearing Mid 0x%x - waking up ",
723 mid_entry->mid));
724 task_to_wake = mid_entry->tsk;
725 if (task_to_wake)
726 wake_up_process(task_to_wake);
729 spin_unlock(&GlobalMid_Lock);
730 read_unlock(&cifs_tcp_ses_lock);
731 /* 1/8th of sec is more than enough time for them to exit */
732 msleep(125);
735 if (!list_empty(&server->pending_mid_q)) {
736 /* mpx threads have not exited yet give them
737 at least the smb send timeout time for long ops */
738 /* due to delays on oplock break requests, we need
739 to wait at least 45 seconds before giving up
740 on a request getting a response and going ahead
741 and killing cifsd */
742 cFYI(1, ("Wait for exit from demultiplex thread"));
743 msleep(46000);
744 /* if threads still have not exited they are probably never
745 coming home not much else we can do but free the memory */
748 /* last chance to mark ses pointers invalid
749 if there are any pointing to this (e.g
750 if a crazy root user tried to kill cifsd
751 kernel thread explicitly this might happen) */
752 /* BB: This shouldn't be necessary, see above */
753 read_lock(&cifs_tcp_ses_lock);
754 list_for_each(tmp, &server->smb_ses_list) {
755 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
756 ses->server = NULL;
758 read_unlock(&cifs_tcp_ses_lock);
760 kfree(server->hostname);
761 task_to_wake = xchg(&server->tsk, NULL);
762 kfree(server);
764 length = atomic_dec_return(&tcpSesAllocCount);
765 if (length > 0)
766 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
767 GFP_KERNEL);
769 /* if server->tsk was NULL then wait for a signal before exiting */
770 if (!task_to_wake) {
771 set_current_state(TASK_INTERRUPTIBLE);
772 while (!signal_pending(current)) {
773 schedule();
774 set_current_state(TASK_INTERRUPTIBLE);
776 set_current_state(TASK_RUNNING);
779 module_put_and_exit(0);
782 /* extract the host portion of the UNC string */
783 static char *
784 extract_hostname(const char *unc)
786 const char *src;
787 char *dst, *delim;
788 unsigned int len;
790 /* skip double chars at beginning of string */
791 /* BB: check validity of these bytes? */
792 src = unc + 2;
794 /* delimiter between hostname and sharename is always '\\' now */
795 delim = strchr(src, '\\');
796 if (!delim)
797 return ERR_PTR(-EINVAL);
799 len = delim - src;
800 dst = kmalloc((len + 1), GFP_KERNEL);
801 if (dst == NULL)
802 return ERR_PTR(-ENOMEM);
804 memcpy(dst, src, len);
805 dst[len] = '\0';
807 return dst;
810 static int
811 cifs_parse_mount_options(char *options, const char *devname,
812 struct smb_vol *vol)
814 char *value;
815 char *data;
816 unsigned int temp_len, i, j;
817 char separator[2];
819 separator[0] = ',';
820 separator[1] = 0;
822 if (Local_System_Name[0] != 0)
823 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
824 else {
825 char *nodename = utsname()->nodename;
826 int n = strnlen(nodename, 15);
827 memset(vol->source_rfc1001_name, 0x20, 15);
828 for (i = 0; i < n; i++) {
829 /* does not have to be perfect mapping since field is
830 informational, only used for servers that do not support
831 port 445 and it can be overridden at mount time */
832 vol->source_rfc1001_name[i] = toupper(nodename[i]);
835 vol->source_rfc1001_name[15] = 0;
836 /* null target name indicates to use *SMBSERVR default called name
837 if we end up sending RFC1001 session initialize */
838 vol->target_rfc1001_name[0] = 0;
839 vol->linux_uid = current->uid; /* current->euid instead? */
840 vol->linux_gid = current->gid;
841 vol->dir_mode = S_IRWXUGO;
842 /* 2767 perms indicate mandatory locking support */
843 vol->file_mode = (S_IRWXUGO | S_ISGID) & (~S_IXGRP);
845 /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
846 vol->rw = true;
847 /* default is always to request posix paths. */
848 vol->posix_paths = 1;
850 if (!options)
851 return 1;
853 if (strncmp(options, "sep=", 4) == 0) {
854 if (options[4] != 0) {
855 separator[0] = options[4];
856 options += 5;
857 } else {
858 cFYI(1, ("Null separator not allowed"));
862 while ((data = strsep(&options, separator)) != NULL) {
863 if (!*data)
864 continue;
865 if ((value = strchr(data, '=')) != NULL)
866 *value++ = '\0';
868 /* Have to parse this before we parse for "user" */
869 if (strnicmp(data, "user_xattr", 10) == 0) {
870 vol->no_xattr = 0;
871 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
872 vol->no_xattr = 1;
873 } else if (strnicmp(data, "user", 4) == 0) {
874 if (!value) {
875 printk(KERN_WARNING
876 "CIFS: invalid or missing username\n");
877 return 1; /* needs_arg; */
878 } else if (!*value) {
879 /* null user, ie anonymous, authentication */
880 vol->nullauth = 1;
882 if (strnlen(value, 200) < 200) {
883 vol->username = value;
884 } else {
885 printk(KERN_WARNING "CIFS: username too long\n");
886 return 1;
888 } else if (strnicmp(data, "pass", 4) == 0) {
889 if (!value) {
890 vol->password = NULL;
891 continue;
892 } else if (value[0] == 0) {
893 /* check if string begins with double comma
894 since that would mean the password really
895 does start with a comma, and would not
896 indicate an empty string */
897 if (value[1] != separator[0]) {
898 vol->password = NULL;
899 continue;
902 temp_len = strlen(value);
903 /* removed password length check, NTLM passwords
904 can be arbitrarily long */
906 /* if comma in password, the string will be
907 prematurely null terminated. Commas in password are
908 specified across the cifs mount interface by a double
909 comma ie ,, and a comma used as in other cases ie ','
910 as a parameter delimiter/separator is single and due
911 to the strsep above is temporarily zeroed. */
913 /* NB: password legally can have multiple commas and
914 the only illegal character in a password is null */
916 if ((value[temp_len] == 0) &&
917 (value[temp_len+1] == separator[0])) {
918 /* reinsert comma */
919 value[temp_len] = separator[0];
920 temp_len += 2; /* move after second comma */
921 while (value[temp_len] != 0) {
922 if (value[temp_len] == separator[0]) {
923 if (value[temp_len+1] ==
924 separator[0]) {
925 /* skip second comma */
926 temp_len++;
927 } else {
928 /* single comma indicating start
929 of next parm */
930 break;
933 temp_len++;
935 if (value[temp_len] == 0) {
936 options = NULL;
937 } else {
938 value[temp_len] = 0;
939 /* point option to start of next parm */
940 options = value + temp_len + 1;
942 /* go from value to value + temp_len condensing
943 double commas to singles. Note that this ends up
944 allocating a few bytes too many, which is ok */
945 vol->password = kzalloc(temp_len, GFP_KERNEL);
946 if (vol->password == NULL) {
947 printk(KERN_WARNING "CIFS: no memory "
948 "for password\n");
949 return 1;
951 for (i = 0, j = 0; i < temp_len; i++, j++) {
952 vol->password[j] = value[i];
953 if (value[i] == separator[0]
954 && value[i+1] == separator[0]) {
955 /* skip second comma */
956 i++;
959 vol->password[j] = 0;
960 } else {
961 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
962 if (vol->password == NULL) {
963 printk(KERN_WARNING "CIFS: no memory "
964 "for password\n");
965 return 1;
967 strcpy(vol->password, value);
969 } else if (strnicmp(data, "ip", 2) == 0) {
970 if (!value || !*value) {
971 vol->UNCip = NULL;
972 } else if (strnlen(value, 35) < 35) {
973 vol->UNCip = value;
974 } else {
975 printk(KERN_WARNING "CIFS: ip address "
976 "too long\n");
977 return 1;
979 } else if (strnicmp(data, "sec", 3) == 0) {
980 if (!value || !*value) {
981 cERROR(1, ("no security value specified"));
982 continue;
983 } else if (strnicmp(value, "krb5i", 5) == 0) {
984 vol->secFlg |= CIFSSEC_MAY_KRB5 |
985 CIFSSEC_MUST_SIGN;
986 } else if (strnicmp(value, "krb5p", 5) == 0) {
987 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
988 CIFSSEC_MAY_KRB5; */
989 cERROR(1, ("Krb5 cifs privacy not supported"));
990 return 1;
991 } else if (strnicmp(value, "krb5", 4) == 0) {
992 vol->secFlg |= CIFSSEC_MAY_KRB5;
993 } else if (strnicmp(value, "ntlmv2i", 7) == 0) {
994 vol->secFlg |= CIFSSEC_MAY_NTLMV2 |
995 CIFSSEC_MUST_SIGN;
996 } else if (strnicmp(value, "ntlmv2", 6) == 0) {
997 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
998 } else if (strnicmp(value, "ntlmi", 5) == 0) {
999 vol->secFlg |= CIFSSEC_MAY_NTLM |
1000 CIFSSEC_MUST_SIGN;
1001 } else if (strnicmp(value, "ntlm", 4) == 0) {
1002 /* ntlm is default so can be turned off too */
1003 vol->secFlg |= CIFSSEC_MAY_NTLM;
1004 } else if (strnicmp(value, "nontlm", 6) == 0) {
1005 /* BB is there a better way to do this? */
1006 vol->secFlg |= CIFSSEC_MAY_NTLMV2;
1007 #ifdef CONFIG_CIFS_WEAK_PW_HASH
1008 } else if (strnicmp(value, "lanman", 6) == 0) {
1009 vol->secFlg |= CIFSSEC_MAY_LANMAN;
1010 #endif
1011 } else if (strnicmp(value, "none", 4) == 0) {
1012 vol->nullauth = 1;
1013 } else {
1014 cERROR(1, ("bad security option: %s", value));
1015 return 1;
1017 } else if ((strnicmp(data, "unc", 3) == 0)
1018 || (strnicmp(data, "target", 6) == 0)
1019 || (strnicmp(data, "path", 4) == 0)) {
1020 if (!value || !*value) {
1021 printk(KERN_WARNING "CIFS: invalid path to "
1022 "network resource\n");
1023 return 1; /* needs_arg; */
1025 if ((temp_len = strnlen(value, 300)) < 300) {
1026 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1027 if (vol->UNC == NULL)
1028 return 1;
1029 strcpy(vol->UNC, value);
1030 if (strncmp(vol->UNC, "//", 2) == 0) {
1031 vol->UNC[0] = '\\';
1032 vol->UNC[1] = '\\';
1033 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1034 printk(KERN_WARNING
1035 "CIFS: UNC Path does not begin "
1036 "with // or \\\\ \n");
1037 return 1;
1039 } else {
1040 printk(KERN_WARNING "CIFS: UNC name too long\n");
1041 return 1;
1043 } else if ((strnicmp(data, "domain", 3) == 0)
1044 || (strnicmp(data, "workgroup", 5) == 0)) {
1045 if (!value || !*value) {
1046 printk(KERN_WARNING "CIFS: invalid domain name\n");
1047 return 1; /* needs_arg; */
1049 /* BB are there cases in which a comma can be valid in
1050 a domain name and need special handling? */
1051 if (strnlen(value, 256) < 256) {
1052 vol->domainname = value;
1053 cFYI(1, ("Domain name set"));
1054 } else {
1055 printk(KERN_WARNING "CIFS: domain name too "
1056 "long\n");
1057 return 1;
1059 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1060 if (!value || !*value) {
1061 printk(KERN_WARNING
1062 "CIFS: invalid path prefix\n");
1063 return 1; /* needs_argument */
1065 if ((temp_len = strnlen(value, 1024)) < 1024) {
1066 if (value[0] != '/')
1067 temp_len++; /* missing leading slash */
1068 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1069 if (vol->prepath == NULL)
1070 return 1;
1071 if (value[0] != '/') {
1072 vol->prepath[0] = '/';
1073 strcpy(vol->prepath+1, value);
1074 } else
1075 strcpy(vol->prepath, value);
1076 cFYI(1, ("prefix path %s", vol->prepath));
1077 } else {
1078 printk(KERN_WARNING "CIFS: prefix too long\n");
1079 return 1;
1081 } else if (strnicmp(data, "iocharset", 9) == 0) {
1082 if (!value || !*value) {
1083 printk(KERN_WARNING "CIFS: invalid iocharset "
1084 "specified\n");
1085 return 1; /* needs_arg; */
1087 if (strnlen(value, 65) < 65) {
1088 if (strnicmp(value, "default", 7))
1089 vol->iocharset = value;
1090 /* if iocharset not set then load_nls_default
1091 is used by caller */
1092 cFYI(1, ("iocharset set to %s", value));
1093 } else {
1094 printk(KERN_WARNING "CIFS: iocharset name "
1095 "too long.\n");
1096 return 1;
1098 } else if (strnicmp(data, "uid", 3) == 0) {
1099 if (value && *value) {
1100 vol->linux_uid =
1101 simple_strtoul(value, &value, 0);
1102 vol->override_uid = 1;
1104 } else if (strnicmp(data, "gid", 3) == 0) {
1105 if (value && *value) {
1106 vol->linux_gid =
1107 simple_strtoul(value, &value, 0);
1108 vol->override_gid = 1;
1110 } else if (strnicmp(data, "file_mode", 4) == 0) {
1111 if (value && *value) {
1112 vol->file_mode =
1113 simple_strtoul(value, &value, 0);
1115 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1116 if (value && *value) {
1117 vol->dir_mode =
1118 simple_strtoul(value, &value, 0);
1120 } else if (strnicmp(data, "dirmode", 4) == 0) {
1121 if (value && *value) {
1122 vol->dir_mode =
1123 simple_strtoul(value, &value, 0);
1125 } else if (strnicmp(data, "port", 4) == 0) {
1126 if (value && *value) {
1127 vol->port =
1128 simple_strtoul(value, &value, 0);
1130 } else if (strnicmp(data, "rsize", 5) == 0) {
1131 if (value && *value) {
1132 vol->rsize =
1133 simple_strtoul(value, &value, 0);
1135 } else if (strnicmp(data, "wsize", 5) == 0) {
1136 if (value && *value) {
1137 vol->wsize =
1138 simple_strtoul(value, &value, 0);
1140 } else if (strnicmp(data, "sockopt", 5) == 0) {
1141 if (value && *value) {
1142 vol->sockopt =
1143 simple_strtoul(value, &value, 0);
1145 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1146 if (!value || !*value || (*value == ' ')) {
1147 cFYI(1, ("invalid (empty) netbiosname"));
1148 } else {
1149 memset(vol->source_rfc1001_name, 0x20, 15);
1150 for (i = 0; i < 15; i++) {
1151 /* BB are there cases in which a comma can be
1152 valid in this workstation netbios name (and need
1153 special handling)? */
1155 /* We do not uppercase netbiosname for user */
1156 if (value[i] == 0)
1157 break;
1158 else
1159 vol->source_rfc1001_name[i] =
1160 value[i];
1162 /* The string has 16th byte zero still from
1163 set at top of the function */
1164 if ((i == 15) && (value[i] != 0))
1165 printk(KERN_WARNING "CIFS: netbiosname"
1166 " longer than 15 truncated.\n");
1168 } else if (strnicmp(data, "servern", 7) == 0) {
1169 /* servernetbiosname specified override *SMBSERVER */
1170 if (!value || !*value || (*value == ' ')) {
1171 cFYI(1, ("empty server netbiosname specified"));
1172 } else {
1173 /* last byte, type, is 0x20 for servr type */
1174 memset(vol->target_rfc1001_name, 0x20, 16);
1176 for (i = 0; i < 15; i++) {
1177 /* BB are there cases in which a comma can be
1178 valid in this workstation netbios name
1179 (and need special handling)? */
1181 /* user or mount helper must uppercase
1182 the netbiosname */
1183 if (value[i] == 0)
1184 break;
1185 else
1186 vol->target_rfc1001_name[i] =
1187 value[i];
1189 /* The string has 16th byte zero still from
1190 set at top of the function */
1191 if ((i == 15) && (value[i] != 0))
1192 printk(KERN_WARNING "CIFS: server net"
1193 "biosname longer than 15 truncated.\n");
1195 } else if (strnicmp(data, "credentials", 4) == 0) {
1196 /* ignore */
1197 } else if (strnicmp(data, "version", 3) == 0) {
1198 /* ignore */
1199 } else if (strnicmp(data, "guest", 5) == 0) {
1200 /* ignore */
1201 } else if (strnicmp(data, "rw", 2) == 0) {
1202 vol->rw = true;
1203 } else if (strnicmp(data, "noblocksend", 11) == 0) {
1204 vol->noblocksnd = 1;
1205 } else if (strnicmp(data, "noautotune", 10) == 0) {
1206 vol->noautotune = 1;
1207 } else if ((strnicmp(data, "suid", 4) == 0) ||
1208 (strnicmp(data, "nosuid", 6) == 0) ||
1209 (strnicmp(data, "exec", 4) == 0) ||
1210 (strnicmp(data, "noexec", 6) == 0) ||
1211 (strnicmp(data, "nodev", 5) == 0) ||
1212 (strnicmp(data, "noauto", 6) == 0) ||
1213 (strnicmp(data, "dev", 3) == 0)) {
1214 /* The mount tool or mount.cifs helper (if present)
1215 uses these opts to set flags, and the flags are read
1216 by the kernel vfs layer before we get here (ie
1217 before read super) so there is no point trying to
1218 parse these options again and set anything and it
1219 is ok to just ignore them */
1220 continue;
1221 } else if (strnicmp(data, "ro", 2) == 0) {
1222 vol->rw = false;
1223 } else if (strnicmp(data, "hard", 4) == 0) {
1224 vol->retry = 1;
1225 } else if (strnicmp(data, "soft", 4) == 0) {
1226 vol->retry = 0;
1227 } else if (strnicmp(data, "perm", 4) == 0) {
1228 vol->noperm = 0;
1229 } else if (strnicmp(data, "noperm", 6) == 0) {
1230 vol->noperm = 1;
1231 } else if (strnicmp(data, "mapchars", 8) == 0) {
1232 vol->remap = 1;
1233 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1234 vol->remap = 0;
1235 } else if (strnicmp(data, "sfu", 3) == 0) {
1236 vol->sfu_emul = 1;
1237 } else if (strnicmp(data, "nosfu", 5) == 0) {
1238 vol->sfu_emul = 0;
1239 } else if (strnicmp(data, "nodfs", 5) == 0) {
1240 vol->nodfs = 1;
1241 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1242 vol->posix_paths = 1;
1243 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1244 vol->posix_paths = 0;
1245 } else if (strnicmp(data, "nounix", 6) == 0) {
1246 vol->no_linux_ext = 1;
1247 } else if (strnicmp(data, "nolinux", 7) == 0) {
1248 vol->no_linux_ext = 1;
1249 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1250 (strnicmp(data, "ignorecase", 10) == 0)) {
1251 vol->nocase = 1;
1252 } else if (strnicmp(data, "brl", 3) == 0) {
1253 vol->nobrl = 0;
1254 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1255 (strnicmp(data, "nolock", 6) == 0)) {
1256 vol->nobrl = 1;
1257 /* turn off mandatory locking in mode
1258 if remote locking is turned off since the
1259 local vfs will do advisory */
1260 if (vol->file_mode ==
1261 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1262 vol->file_mode = S_IALLUGO;
1263 } else if (strnicmp(data, "setuids", 7) == 0) {
1264 vol->setuids = 1;
1265 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1266 vol->setuids = 0;
1267 } else if (strnicmp(data, "dynperm", 7) == 0) {
1268 vol->dynperm = true;
1269 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1270 vol->dynperm = false;
1271 } else if (strnicmp(data, "nohard", 6) == 0) {
1272 vol->retry = 0;
1273 } else if (strnicmp(data, "nosoft", 6) == 0) {
1274 vol->retry = 1;
1275 } else if (strnicmp(data, "nointr", 6) == 0) {
1276 vol->intr = 0;
1277 } else if (strnicmp(data, "intr", 4) == 0) {
1278 vol->intr = 1;
1279 } else if (strnicmp(data, "serverino", 7) == 0) {
1280 vol->server_ino = 1;
1281 } else if (strnicmp(data, "noserverino", 9) == 0) {
1282 vol->server_ino = 0;
1283 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1284 vol->cifs_acl = 1;
1285 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1286 vol->cifs_acl = 0;
1287 } else if (strnicmp(data, "acl", 3) == 0) {
1288 vol->no_psx_acl = 0;
1289 } else if (strnicmp(data, "noacl", 5) == 0) {
1290 vol->no_psx_acl = 1;
1291 #ifdef CONFIG_CIFS_EXPERIMENTAL
1292 } else if (strnicmp(data, "locallease", 6) == 0) {
1293 vol->local_lease = 1;
1294 #endif
1295 } else if (strnicmp(data, "sign", 4) == 0) {
1296 vol->secFlg |= CIFSSEC_MUST_SIGN;
1297 } else if (strnicmp(data, "seal", 4) == 0) {
1298 /* we do not do the following in secFlags because seal
1299 is a per tree connection (mount) not a per socket
1300 or per-smb connection option in the protocol */
1301 /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1302 vol->seal = 1;
1303 } else if (strnicmp(data, "direct", 6) == 0) {
1304 vol->direct_io = 1;
1305 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1306 vol->direct_io = 1;
1307 } else if (strnicmp(data, "in6_addr", 8) == 0) {
1308 if (!value || !*value) {
1309 vol->in6_addr = NULL;
1310 } else if (strnlen(value, 49) == 48) {
1311 vol->in6_addr = value;
1312 } else {
1313 printk(KERN_WARNING "CIFS: ip v6 address not "
1314 "48 characters long\n");
1315 return 1;
1317 } else if (strnicmp(data, "noac", 4) == 0) {
1318 printk(KERN_WARNING "CIFS: Mount option noac not "
1319 "supported. Instead set "
1320 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1321 } else
1322 printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1323 data);
1325 if (vol->UNC == NULL) {
1326 if (devname == NULL) {
1327 printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1328 "target\n");
1329 return 1;
1331 if ((temp_len = strnlen(devname, 300)) < 300) {
1332 vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1333 if (vol->UNC == NULL)
1334 return 1;
1335 strcpy(vol->UNC, devname);
1336 if (strncmp(vol->UNC, "//", 2) == 0) {
1337 vol->UNC[0] = '\\';
1338 vol->UNC[1] = '\\';
1339 } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1340 printk(KERN_WARNING "CIFS: UNC Path does not "
1341 "begin with // or \\\\ \n");
1342 return 1;
1344 value = strpbrk(vol->UNC+2, "/\\");
1345 if (value)
1346 *value = '\\';
1347 } else {
1348 printk(KERN_WARNING "CIFS: UNC name too long\n");
1349 return 1;
1352 if (vol->UNCip == NULL)
1353 vol->UNCip = &vol->UNC[2];
1355 return 0;
1358 static struct TCP_Server_Info *
1359 cifs_find_tcp_session(struct sockaddr *addr)
1361 struct list_head *tmp;
1362 struct TCP_Server_Info *server;
1363 struct sockaddr_in *addr4 = (struct sockaddr_in *) addr;
1364 struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *) addr;
1366 write_lock(&cifs_tcp_ses_lock);
1367 list_for_each(tmp, &cifs_tcp_ses_list) {
1368 server = list_entry(tmp, struct TCP_Server_Info,
1369 tcp_ses_list);
1371 * the demux thread can exit on its own while still in CifsNew
1372 * so don't accept any sockets in that state. Since the
1373 * tcpStatus never changes back to CifsNew it's safe to check
1374 * for this without a lock.
1376 if (server->tcpStatus == CifsNew)
1377 continue;
1379 if (addr->sa_family == AF_INET &&
1380 (addr4->sin_addr.s_addr !=
1381 server->addr.sockAddr.sin_addr.s_addr))
1382 continue;
1383 else if (addr->sa_family == AF_INET6 &&
1384 memcmp(&server->addr.sockAddr6.sin6_addr,
1385 &addr6->sin6_addr, sizeof(addr6->sin6_addr)))
1386 continue;
1388 ++server->srv_count;
1389 write_unlock(&cifs_tcp_ses_lock);
1390 cFYI(1, ("Existing tcp session with server found"));
1391 return server;
1393 write_unlock(&cifs_tcp_ses_lock);
1394 return NULL;
1397 static void
1398 cifs_put_tcp_session(struct TCP_Server_Info *server)
1400 struct task_struct *task;
1402 write_lock(&cifs_tcp_ses_lock);
1403 if (--server->srv_count > 0) {
1404 write_unlock(&cifs_tcp_ses_lock);
1405 return;
1408 list_del_init(&server->tcp_ses_list);
1409 write_unlock(&cifs_tcp_ses_lock);
1411 spin_lock(&GlobalMid_Lock);
1412 server->tcpStatus = CifsExiting;
1413 spin_unlock(&GlobalMid_Lock);
1415 task = xchg(&server->tsk, NULL);
1416 if (task)
1417 force_sig(SIGKILL, task);
1420 static struct cifsSesInfo *
1421 cifs_find_smb_ses(struct TCP_Server_Info *server, char *username)
1423 struct list_head *tmp;
1424 struct cifsSesInfo *ses;
1426 write_lock(&cifs_tcp_ses_lock);
1427 list_for_each(tmp, &server->smb_ses_list) {
1428 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
1429 if (strncmp(ses->userName, username, MAX_USERNAME_SIZE))
1430 continue;
1432 ++ses->ses_count;
1433 write_unlock(&cifs_tcp_ses_lock);
1434 return ses;
1436 write_unlock(&cifs_tcp_ses_lock);
1437 return NULL;
1440 static void
1441 cifs_put_smb_ses(struct cifsSesInfo *ses)
1443 int xid;
1444 struct TCP_Server_Info *server = ses->server;
1446 write_lock(&cifs_tcp_ses_lock);
1447 if (--ses->ses_count > 0) {
1448 write_unlock(&cifs_tcp_ses_lock);
1449 return;
1452 list_del_init(&ses->smb_ses_list);
1453 write_unlock(&cifs_tcp_ses_lock);
1455 if (ses->status == CifsGood) {
1456 xid = GetXid();
1457 CIFSSMBLogoff(xid, ses);
1458 _FreeXid(xid);
1460 sesInfoFree(ses);
1461 cifs_put_tcp_session(server);
1464 static struct cifsTconInfo *
1465 cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1467 struct list_head *tmp;
1468 struct cifsTconInfo *tcon;
1470 write_lock(&cifs_tcp_ses_lock);
1471 list_for_each(tmp, &ses->tcon_list) {
1472 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1473 if (tcon->tidStatus == CifsExiting)
1474 continue;
1475 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
1476 continue;
1478 ++tcon->tc_count;
1479 write_unlock(&cifs_tcp_ses_lock);
1480 return tcon;
1482 write_unlock(&cifs_tcp_ses_lock);
1483 return NULL;
1486 static void
1487 cifs_put_tcon(struct cifsTconInfo *tcon)
1489 int xid;
1490 struct cifsSesInfo *ses = tcon->ses;
1492 write_lock(&cifs_tcp_ses_lock);
1493 if (--tcon->tc_count > 0) {
1494 write_unlock(&cifs_tcp_ses_lock);
1495 return;
1498 list_del_init(&tcon->tcon_list);
1499 write_unlock(&cifs_tcp_ses_lock);
1501 xid = GetXid();
1502 CIFSSMBTDis(xid, tcon);
1503 _FreeXid(xid);
1505 DeleteTconOplockQEntries(tcon);
1506 tconInfoFree(tcon);
1507 cifs_put_smb_ses(ses);
1511 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1512 const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1513 struct dfs_info3_param **preferrals, int remap)
1515 char *temp_unc;
1516 int rc = 0;
1518 *pnum_referrals = 0;
1519 *preferrals = NULL;
1521 if (pSesInfo->ipc_tid == 0) {
1522 temp_unc = kmalloc(2 /* for slashes */ +
1523 strnlen(pSesInfo->serverName,
1524 SERVER_NAME_LEN_WITH_NULL * 2)
1525 + 1 + 4 /* slash IPC$ */ + 2,
1526 GFP_KERNEL);
1527 if (temp_unc == NULL)
1528 return -ENOMEM;
1529 temp_unc[0] = '\\';
1530 temp_unc[1] = '\\';
1531 strcpy(temp_unc + 2, pSesInfo->serverName);
1532 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1533 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1534 cFYI(1,
1535 ("CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid));
1536 kfree(temp_unc);
1538 if (rc == 0)
1539 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1540 pnum_referrals, nls_codepage, remap);
1541 /* BB map targetUNCs to dfs_info3 structures, here or
1542 in CIFSGetDFSRefer BB */
1544 return rc;
1547 #ifdef CONFIG_DEBUG_LOCK_ALLOC
1548 static struct lock_class_key cifs_key[2];
1549 static struct lock_class_key cifs_slock_key[2];
1551 static inline void
1552 cifs_reclassify_socket4(struct socket *sock)
1554 struct sock *sk = sock->sk;
1555 BUG_ON(sock_owned_by_user(sk));
1556 sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
1557 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
1560 static inline void
1561 cifs_reclassify_socket6(struct socket *sock)
1563 struct sock *sk = sock->sk;
1564 BUG_ON(sock_owned_by_user(sk));
1565 sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
1566 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
1568 #else
1569 static inline void
1570 cifs_reclassify_socket4(struct socket *sock)
1574 static inline void
1575 cifs_reclassify_socket6(struct socket *sock)
1578 #endif
1580 /* See RFC1001 section 14 on representation of Netbios names */
1581 static void rfc1002mangle(char *target, char *source, unsigned int length)
1583 unsigned int i, j;
1585 for (i = 0, j = 0; i < (length); i++) {
1586 /* mask a nibble at a time and encode */
1587 target[j] = 'A' + (0x0F & (source[i] >> 4));
1588 target[j+1] = 'A' + (0x0F & source[i]);
1589 j += 2;
1595 static int
1596 ipv4_connect(struct sockaddr_in *psin_server, struct socket **csocket,
1597 char *netbios_name, char *target_name,
1598 bool noblocksnd, bool noautotune)
1600 int rc = 0;
1601 int connected = 0;
1602 __be16 orig_port = 0;
1604 if (*csocket == NULL) {
1605 rc = sock_create_kern(PF_INET, SOCK_STREAM,
1606 IPPROTO_TCP, csocket);
1607 if (rc < 0) {
1608 cERROR(1, ("Error %d creating socket", rc));
1609 *csocket = NULL;
1610 return rc;
1611 } else {
1612 /* BB other socket options to set KEEPALIVE, NODELAY? */
1613 cFYI(1, ("Socket created"));
1614 (*csocket)->sk->sk_allocation = GFP_NOFS;
1615 cifs_reclassify_socket4(*csocket);
1619 psin_server->sin_family = AF_INET;
1620 if (psin_server->sin_port) { /* user overrode default port */
1621 rc = (*csocket)->ops->connect(*csocket,
1622 (struct sockaddr *) psin_server,
1623 sizeof(struct sockaddr_in), 0);
1624 if (rc >= 0)
1625 connected = 1;
1628 if (!connected) {
1629 /* save original port so we can retry user specified port
1630 later if fall back ports fail this time */
1631 orig_port = psin_server->sin_port;
1633 /* do not retry on the same port we just failed on */
1634 if (psin_server->sin_port != htons(CIFS_PORT)) {
1635 psin_server->sin_port = htons(CIFS_PORT);
1637 rc = (*csocket)->ops->connect(*csocket,
1638 (struct sockaddr *) psin_server,
1639 sizeof(struct sockaddr_in), 0);
1640 if (rc >= 0)
1641 connected = 1;
1644 if (!connected) {
1645 psin_server->sin_port = htons(RFC1001_PORT);
1646 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1647 psin_server,
1648 sizeof(struct sockaddr_in), 0);
1649 if (rc >= 0)
1650 connected = 1;
1653 /* give up here - unless we want to retry on different
1654 protocol families some day */
1655 if (!connected) {
1656 if (orig_port)
1657 psin_server->sin_port = orig_port;
1658 cFYI(1, ("Error %d connecting to server via ipv4", rc));
1659 sock_release(*csocket);
1660 *csocket = NULL;
1661 return rc;
1663 /* Eventually check for other socket options to change from
1664 the default. sock_setsockopt not used because it expects
1665 user space buffer */
1666 cFYI(1, ("sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
1667 (*csocket)->sk->sk_sndbuf,
1668 (*csocket)->sk->sk_rcvbuf, (*csocket)->sk->sk_rcvtimeo));
1669 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1670 if (!noblocksnd)
1671 (*csocket)->sk->sk_sndtimeo = 3 * HZ;
1673 /* make the bufsizes depend on wsize/rsize and max requests */
1674 if (noautotune) {
1675 if ((*csocket)->sk->sk_sndbuf < (200 * 1024))
1676 (*csocket)->sk->sk_sndbuf = 200 * 1024;
1677 if ((*csocket)->sk->sk_rcvbuf < (140 * 1024))
1678 (*csocket)->sk->sk_rcvbuf = 140 * 1024;
1681 /* send RFC1001 sessinit */
1682 if (psin_server->sin_port == htons(RFC1001_PORT)) {
1683 /* some servers require RFC1001 sessinit before sending
1684 negprot - BB check reconnection in case where second
1685 sessinit is sent but no second negprot */
1686 struct rfc1002_session_packet *ses_init_buf;
1687 struct smb_hdr *smb_buf;
1688 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
1689 GFP_KERNEL);
1690 if (ses_init_buf) {
1691 ses_init_buf->trailer.session_req.called_len = 32;
1692 if (target_name && (target_name[0] != 0)) {
1693 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1694 target_name, 16);
1695 } else {
1696 rfc1002mangle(ses_init_buf->trailer.session_req.called_name,
1697 DEFAULT_CIFS_CALLED_NAME, 16);
1700 ses_init_buf->trailer.session_req.calling_len = 32;
1701 /* calling name ends in null (byte 16) from old smb
1702 convention. */
1703 if (netbios_name && (netbios_name[0] != 0)) {
1704 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1705 netbios_name, 16);
1706 } else {
1707 rfc1002mangle(ses_init_buf->trailer.session_req.calling_name,
1708 "LINUX_CIFS_CLNT", 16);
1710 ses_init_buf->trailer.session_req.scope1 = 0;
1711 ses_init_buf->trailer.session_req.scope2 = 0;
1712 smb_buf = (struct smb_hdr *)ses_init_buf;
1713 /* sizeof RFC1002_SESSION_REQUEST with no scope */
1714 smb_buf->smb_buf_length = 0x81000044;
1715 rc = smb_send(*csocket, smb_buf, 0x44,
1716 (struct sockaddr *)psin_server, noblocksnd);
1717 kfree(ses_init_buf);
1718 msleep(1); /* RFC1001 layer in at least one server
1719 requires very short break before negprot
1720 presumably because not expecting negprot
1721 to follow so fast. This is a simple
1722 solution that works without
1723 complicating the code and causes no
1724 significant slowing down on mount
1725 for everyone else */
1727 /* else the negprot may still work without this
1728 even though malloc failed */
1732 return rc;
1735 static int
1736 ipv6_connect(struct sockaddr_in6 *psin_server, struct socket **csocket,
1737 bool noblocksnd)
1739 int rc = 0;
1740 int connected = 0;
1741 __be16 orig_port = 0;
1743 if (*csocket == NULL) {
1744 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
1745 IPPROTO_TCP, csocket);
1746 if (rc < 0) {
1747 cERROR(1, ("Error %d creating ipv6 socket", rc));
1748 *csocket = NULL;
1749 return rc;
1750 } else {
1751 /* BB other socket options to set KEEPALIVE, NODELAY? */
1752 cFYI(1, ("ipv6 Socket created"));
1753 (*csocket)->sk->sk_allocation = GFP_NOFS;
1754 cifs_reclassify_socket6(*csocket);
1758 psin_server->sin6_family = AF_INET6;
1760 if (psin_server->sin6_port) { /* user overrode default port */
1761 rc = (*csocket)->ops->connect(*csocket,
1762 (struct sockaddr *) psin_server,
1763 sizeof(struct sockaddr_in6), 0);
1764 if (rc >= 0)
1765 connected = 1;
1768 if (!connected) {
1769 /* save original port so we can retry user specified port
1770 later if fall back ports fail this time */
1772 orig_port = psin_server->sin6_port;
1773 /* do not retry on the same port we just failed on */
1774 if (psin_server->sin6_port != htons(CIFS_PORT)) {
1775 psin_server->sin6_port = htons(CIFS_PORT);
1777 rc = (*csocket)->ops->connect(*csocket,
1778 (struct sockaddr *) psin_server,
1779 sizeof(struct sockaddr_in6), 0);
1780 if (rc >= 0)
1781 connected = 1;
1784 if (!connected) {
1785 psin_server->sin6_port = htons(RFC1001_PORT);
1786 rc = (*csocket)->ops->connect(*csocket, (struct sockaddr *)
1787 psin_server, sizeof(struct sockaddr_in6), 0);
1788 if (rc >= 0)
1789 connected = 1;
1792 /* give up here - unless we want to retry on different
1793 protocol families some day */
1794 if (!connected) {
1795 if (orig_port)
1796 psin_server->sin6_port = orig_port;
1797 cFYI(1, ("Error %d connecting to server via ipv6", rc));
1798 sock_release(*csocket);
1799 *csocket = NULL;
1800 return rc;
1802 /* Eventually check for other socket options to change from
1803 the default. sock_setsockopt not used because it expects
1804 user space buffer */
1805 (*csocket)->sk->sk_rcvtimeo = 7 * HZ;
1806 if (!noblocksnd)
1807 (*csocket)->sk->sk_sndtimeo = 3 * HZ;
1810 return rc;
1813 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
1814 struct super_block *sb, struct smb_vol *vol_info)
1816 /* if we are reconnecting then should we check to see if
1817 * any requested capabilities changed locally e.g. via
1818 * remount but we can not do much about it here
1819 * if they have (even if we could detect it by the following)
1820 * Perhaps we could add a backpointer to array of sb from tcon
1821 * or if we change to make all sb to same share the same
1822 * sb as NFS - then we only have one backpointer to sb.
1823 * What if we wanted to mount the server share twice once with
1824 * and once without posixacls or posix paths? */
1825 __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1827 if (vol_info && vol_info->no_linux_ext) {
1828 tcon->fsUnixInfo.Capability = 0;
1829 tcon->unix_ext = 0; /* Unix Extensions disabled */
1830 cFYI(1, ("Linux protocol extensions disabled"));
1831 return;
1832 } else if (vol_info)
1833 tcon->unix_ext = 1; /* Unix Extensions supported */
1835 if (tcon->unix_ext == 0) {
1836 cFYI(1, ("Unix extensions disabled so not set on reconnect"));
1837 return;
1840 if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
1841 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
1843 /* check for reconnect case in which we do not
1844 want to change the mount behavior if we can avoid it */
1845 if (vol_info == NULL) {
1846 /* turn off POSIX ACL and PATHNAMES if not set
1847 originally at mount time */
1848 if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
1849 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1850 if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
1851 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1852 cERROR(1, ("POSIXPATH support change"));
1853 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1854 } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
1855 cERROR(1, ("possible reconnect error"));
1856 cERROR(1,
1857 ("server disabled POSIX path support"));
1861 cap &= CIFS_UNIX_CAP_MASK;
1862 if (vol_info && vol_info->no_psx_acl)
1863 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
1864 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
1865 cFYI(1, ("negotiated posix acl support"));
1866 if (sb)
1867 sb->s_flags |= MS_POSIXACL;
1870 if (vol_info && vol_info->posix_paths == 0)
1871 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
1872 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
1873 cFYI(1, ("negotiate posix pathnames"));
1874 if (sb)
1875 CIFS_SB(sb)->mnt_cifs_flags |=
1876 CIFS_MOUNT_POSIX_PATHS;
1879 /* We might be setting the path sep back to a different
1880 form if we are reconnecting and the server switched its
1881 posix path capability for this share */
1882 if (sb && (CIFS_SB(sb)->prepathlen > 0))
1883 CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
1885 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
1886 if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
1887 CIFS_SB(sb)->rsize = 127 * 1024;
1888 cFYI(DBG2,
1889 ("larger reads not supported by srv"));
1894 cFYI(1, ("Negotiate caps 0x%x", (int)cap));
1895 #ifdef CONFIG_CIFS_DEBUG2
1896 if (cap & CIFS_UNIX_FCNTL_CAP)
1897 cFYI(1, ("FCNTL cap"));
1898 if (cap & CIFS_UNIX_EXTATTR_CAP)
1899 cFYI(1, ("EXTATTR cap"));
1900 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
1901 cFYI(1, ("POSIX path cap"));
1902 if (cap & CIFS_UNIX_XATTR_CAP)
1903 cFYI(1, ("XATTR cap"));
1904 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
1905 cFYI(1, ("POSIX ACL cap"));
1906 if (cap & CIFS_UNIX_LARGE_READ_CAP)
1907 cFYI(1, ("very large read cap"));
1908 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
1909 cFYI(1, ("very large write cap"));
1910 #endif /* CIFS_DEBUG2 */
1911 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
1912 if (vol_info == NULL) {
1913 cFYI(1, ("resetting capabilities failed"));
1914 } else
1915 cERROR(1, ("Negotiating Unix capabilities "
1916 "with the server failed. Consider "
1917 "mounting with the Unix Extensions\n"
1918 "disabled, if problems are found, "
1919 "by specifying the nounix mount "
1920 "option."));
1926 static void
1927 convert_delimiter(char *path, char delim)
1929 int i;
1930 char old_delim;
1932 if (path == NULL)
1933 return;
1935 if (delim == '/')
1936 old_delim = '\\';
1937 else
1938 old_delim = '/';
1940 for (i = 0; path[i] != '\0'; i++) {
1941 if (path[i] == old_delim)
1942 path[i] = delim;
1946 static void setup_cifs_sb(struct smb_vol *pvolume_info,
1947 struct cifs_sb_info *cifs_sb)
1949 if (pvolume_info->rsize > CIFSMaxBufSize) {
1950 cERROR(1, ("rsize %d too large, using MaxBufSize",
1951 pvolume_info->rsize));
1952 cifs_sb->rsize = CIFSMaxBufSize;
1953 } else if ((pvolume_info->rsize) &&
1954 (pvolume_info->rsize <= CIFSMaxBufSize))
1955 cifs_sb->rsize = pvolume_info->rsize;
1956 else /* default */
1957 cifs_sb->rsize = CIFSMaxBufSize;
1959 if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
1960 cERROR(1, ("wsize %d too large, using 4096 instead",
1961 pvolume_info->wsize));
1962 cifs_sb->wsize = 4096;
1963 } else if (pvolume_info->wsize)
1964 cifs_sb->wsize = pvolume_info->wsize;
1965 else
1966 cifs_sb->wsize = min_t(const int,
1967 PAGEVEC_SIZE * PAGE_CACHE_SIZE,
1968 127*1024);
1969 /* old default of CIFSMaxBufSize was too small now
1970 that SMB Write2 can send multiple pages in kvec.
1971 RFC1001 does not describe what happens when frame
1972 bigger than 128K is sent so use that as max in
1973 conjunction with 52K kvec constraint on arch with 4K
1974 page size */
1976 if (cifs_sb->rsize < 2048) {
1977 cifs_sb->rsize = 2048;
1978 /* Windows ME may prefer this */
1979 cFYI(1, ("readsize set to minimum: 2048"));
1981 /* calculate prepath */
1982 cifs_sb->prepath = pvolume_info->prepath;
1983 if (cifs_sb->prepath) {
1984 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
1985 /* we can not convert the / to \ in the path
1986 separators in the prefixpath yet because we do not
1987 know (until reset_cifs_unix_caps is called later)
1988 whether POSIX PATH CAP is available. We normalize
1989 the / to \ after reset_cifs_unix_caps is called */
1990 pvolume_info->prepath = NULL;
1991 } else
1992 cifs_sb->prepathlen = 0;
1993 cifs_sb->mnt_uid = pvolume_info->linux_uid;
1994 cifs_sb->mnt_gid = pvolume_info->linux_gid;
1995 cifs_sb->mnt_file_mode = pvolume_info->file_mode;
1996 cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
1997 cFYI(1, ("file mode: 0x%x dir mode: 0x%x",
1998 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
2000 if (pvolume_info->noperm)
2001 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2002 if (pvolume_info->setuids)
2003 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2004 if (pvolume_info->server_ino)
2005 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2006 if (pvolume_info->remap)
2007 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2008 if (pvolume_info->no_xattr)
2009 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2010 if (pvolume_info->sfu_emul)
2011 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2012 if (pvolume_info->nobrl)
2013 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2014 if (pvolume_info->cifs_acl)
2015 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2016 if (pvolume_info->override_uid)
2017 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2018 if (pvolume_info->override_gid)
2019 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2020 if (pvolume_info->dynperm)
2021 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2022 if (pvolume_info->direct_io) {
2023 cFYI(1, ("mounting share using direct i/o"));
2024 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2027 if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2028 cERROR(1, ("mount option dynperm ignored if cifsacl "
2029 "mount option supported"));
2033 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2034 char *mount_data, const char *devname)
2036 int rc = 0;
2037 int xid;
2038 struct socket *csocket = NULL;
2039 struct sockaddr addr;
2040 struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
2041 struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
2042 struct smb_vol volume_info;
2043 struct cifsSesInfo *pSesInfo = NULL;
2044 struct cifsTconInfo *tcon = NULL;
2045 struct TCP_Server_Info *srvTcp = NULL;
2047 xid = GetXid();
2049 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
2051 memset(&addr, 0, sizeof(struct sockaddr));
2052 memset(&volume_info, 0, sizeof(struct smb_vol));
2053 if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
2054 rc = -EINVAL;
2055 goto out;
2058 if (volume_info.nullauth) {
2059 cFYI(1, ("null user"));
2060 volume_info.username = "";
2061 } else if (volume_info.username) {
2062 /* BB fixme parse for domain name here */
2063 cFYI(1, ("Username: %s", volume_info.username));
2064 } else {
2065 cifserror("No username specified");
2066 /* In userspace mount helper we can get user name from alternate
2067 locations such as env variables and files on disk */
2068 rc = -EINVAL;
2069 goto out;
2072 if (volume_info.UNCip && volume_info.UNC) {
2073 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
2074 &sin_server->sin_addr.s_addr);
2076 if (rc <= 0) {
2077 /* not ipv4 address, try ipv6 */
2078 rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
2079 &sin_server6->sin6_addr.in6_u);
2080 if (rc > 0)
2081 addr.sa_family = AF_INET6;
2082 } else {
2083 addr.sa_family = AF_INET;
2086 if (rc <= 0) {
2087 /* we failed translating address */
2088 rc = -EINVAL;
2089 goto out;
2092 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
2093 /* success */
2094 rc = 0;
2095 } else if (volume_info.UNCip) {
2096 /* BB using ip addr as server name to connect to the
2097 DFS root below */
2098 cERROR(1, ("Connecting to DFS root not implemented yet"));
2099 rc = -EINVAL;
2100 goto out;
2101 } else /* which servers DFS root would we conect to */ {
2102 cERROR(1,
2103 ("CIFS mount error: No UNC path (e.g. -o "
2104 "unc=//192.168.1.100/public) specified"));
2105 rc = -EINVAL;
2106 goto out;
2109 /* this is needed for ASCII cp to Unicode converts */
2110 if (volume_info.iocharset == NULL) {
2111 cifs_sb->local_nls = load_nls_default();
2112 /* load_nls_default can not return null */
2113 } else {
2114 cifs_sb->local_nls = load_nls(volume_info.iocharset);
2115 if (cifs_sb->local_nls == NULL) {
2116 cERROR(1, ("CIFS mount error: iocharset %s not found",
2117 volume_info.iocharset));
2118 rc = -ELIBACC;
2119 goto out;
2123 srvTcp = cifs_find_tcp_session(&addr);
2124 if (!srvTcp) { /* create socket */
2125 if (addr.sa_family == AF_INET6) {
2126 cFYI(1, ("attempting ipv6 connect"));
2127 /* BB should we allow ipv6 on port 139? */
2128 /* other OS never observed in Wild doing 139 with v6 */
2129 sin_server6->sin6_port = htons(volume_info.port);
2130 rc = ipv6_connect(sin_server6, &csocket,
2131 volume_info.noblocksnd);
2132 } else {
2133 sin_server->sin_port = htons(volume_info.port);
2134 rc = ipv4_connect(sin_server, &csocket,
2135 volume_info.source_rfc1001_name,
2136 volume_info.target_rfc1001_name,
2137 volume_info.noblocksnd,
2138 volume_info.noautotune);
2140 if (rc < 0) {
2141 cERROR(1, ("Error connecting to socket. "
2142 "Aborting operation"));
2143 if (csocket != NULL)
2144 sock_release(csocket);
2145 goto out;
2148 srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
2149 if (!srvTcp) {
2150 rc = -ENOMEM;
2151 sock_release(csocket);
2152 goto out;
2153 } else {
2154 srvTcp->noblocksnd = volume_info.noblocksnd;
2155 srvTcp->noautotune = volume_info.noautotune;
2156 if (addr.sa_family == AF_INET6)
2157 memcpy(&srvTcp->addr.sockAddr6, sin_server6,
2158 sizeof(struct sockaddr_in6));
2159 else
2160 memcpy(&srvTcp->addr.sockAddr, sin_server,
2161 sizeof(struct sockaddr_in));
2162 atomic_set(&srvTcp->inFlight, 0);
2163 /* BB Add code for ipv6 case too */
2164 srvTcp->ssocket = csocket;
2165 srvTcp->hostname = extract_hostname(volume_info.UNC);
2166 if (IS_ERR(srvTcp->hostname)) {
2167 rc = PTR_ERR(srvTcp->hostname);
2168 sock_release(csocket);
2169 goto out;
2171 init_waitqueue_head(&srvTcp->response_q);
2172 init_waitqueue_head(&srvTcp->request_q);
2173 INIT_LIST_HEAD(&srvTcp->pending_mid_q);
2174 /* at this point we are the only ones with the pointer
2175 to the struct since the kernel thread not created yet
2176 so no need to spinlock this init of tcpStatus */
2177 srvTcp->tcpStatus = CifsNew;
2178 init_MUTEX(&srvTcp->tcpSem);
2181 * since we're in a cifs function already, we know that
2182 * this will succeed. No need for try_module_get().
2184 __module_get(THIS_MODULE);
2185 srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
2186 if (IS_ERR(srvTcp->tsk)) {
2187 rc = PTR_ERR(srvTcp->tsk);
2188 cERROR(1, ("error %d create cifsd thread", rc));
2189 module_put(THIS_MODULE);
2190 srvTcp->tsk = NULL;
2191 sock_release(csocket);
2192 kfree(srvTcp->hostname);
2193 goto out;
2195 rc = 0;
2196 memcpy(srvTcp->workstation_RFC1001_name,
2197 volume_info.source_rfc1001_name, 16);
2198 memcpy(srvTcp->server_RFC1001_name,
2199 volume_info.target_rfc1001_name, 16);
2200 srvTcp->sequence_number = 0;
2201 INIT_LIST_HEAD(&srvTcp->tcp_ses_list);
2202 INIT_LIST_HEAD(&srvTcp->smb_ses_list);
2203 ++srvTcp->srv_count;
2204 write_lock(&cifs_tcp_ses_lock);
2205 list_add(&srvTcp->tcp_ses_list,
2206 &cifs_tcp_ses_list);
2207 write_unlock(&cifs_tcp_ses_lock);
2211 pSesInfo = cifs_find_smb_ses(srvTcp, volume_info.username);
2212 if (pSesInfo) {
2213 cFYI(1, ("Existing smb sess found (status=%d)",
2214 pSesInfo->status));
2216 * The existing SMB session already has a reference to srvTcp,
2217 * so we can put back the extra one we got before
2219 cifs_put_tcp_session(srvTcp);
2221 down(&pSesInfo->sesSem);
2222 if (pSesInfo->need_reconnect) {
2223 cFYI(1, ("Session needs reconnect"));
2224 rc = cifs_setup_session(xid, pSesInfo,
2225 cifs_sb->local_nls);
2227 up(&pSesInfo->sesSem);
2228 } else if (!rc) {
2229 cFYI(1, ("Existing smb sess not found"));
2230 pSesInfo = sesInfoAlloc();
2231 if (pSesInfo == NULL) {
2232 rc = -ENOMEM;
2233 goto mount_fail_check;
2236 /* new SMB session uses our srvTcp ref */
2237 pSesInfo->server = srvTcp;
2238 sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
2239 NIPQUAD(sin_server->sin_addr.s_addr));
2241 write_lock(&cifs_tcp_ses_lock);
2242 list_add(&pSesInfo->smb_ses_list, &srvTcp->smb_ses_list);
2243 write_unlock(&cifs_tcp_ses_lock);
2245 /* volume_info.password freed at unmount */
2246 if (volume_info.password) {
2247 pSesInfo->password = volume_info.password;
2248 /* set to NULL to prevent freeing on exit */
2249 volume_info.password = NULL;
2251 if (volume_info.username)
2252 strncpy(pSesInfo->userName, volume_info.username,
2253 MAX_USERNAME_SIZE);
2254 if (volume_info.domainname) {
2255 int len = strlen(volume_info.domainname);
2256 pSesInfo->domainName = kmalloc(len + 1, GFP_KERNEL);
2257 if (pSesInfo->domainName)
2258 strcpy(pSesInfo->domainName,
2259 volume_info.domainname);
2261 pSesInfo->linux_uid = volume_info.linux_uid;
2262 pSesInfo->overrideSecFlg = volume_info.secFlg;
2263 down(&pSesInfo->sesSem);
2265 /* BB FIXME need to pass vol->secFlgs BB */
2266 rc = cifs_setup_session(xid, pSesInfo,
2267 cifs_sb->local_nls);
2268 up(&pSesInfo->sesSem);
2271 /* search for existing tcon to this server share */
2272 if (!rc) {
2273 setup_cifs_sb(&volume_info, cifs_sb);
2275 tcon = cifs_find_tcon(pSesInfo, volume_info.UNC);
2276 if (tcon) {
2277 cFYI(1, ("Found match on UNC path"));
2278 /* existing tcon already has a reference */
2279 cifs_put_smb_ses(pSesInfo);
2280 if (tcon->seal != volume_info.seal)
2281 cERROR(1, ("transport encryption setting "
2282 "conflicts with existing tid"));
2283 } else {
2284 tcon = tconInfoAlloc();
2285 if (tcon == NULL) {
2286 rc = -ENOMEM;
2287 goto mount_fail_check;
2289 tcon->ses = pSesInfo;
2291 /* check for null share name ie connect to dfs root */
2292 if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2293 && (strchr(volume_info.UNC + 3, '/') == NULL)) {
2294 /* rc = connect_to_dfs_path(...) */
2295 cFYI(1, ("DFS root not supported"));
2296 rc = -ENODEV;
2297 goto mount_fail_check;
2298 } else {
2299 /* BB Do we need to wrap sesSem around
2300 * this TCon call and Unix SetFS as
2301 * we do on SessSetup and reconnect? */
2302 rc = CIFSTCon(xid, pSesInfo, volume_info.UNC,
2303 tcon, cifs_sb->local_nls);
2304 cFYI(1, ("CIFS Tcon rc = %d", rc));
2305 if (volume_info.nodfs) {
2306 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2307 cFYI(1, ("DFS disabled (%d)",
2308 tcon->Flags));
2311 if (rc)
2312 goto mount_fail_check;
2313 tcon->seal = volume_info.seal;
2314 write_lock(&cifs_tcp_ses_lock);
2315 list_add(&tcon->tcon_list, &pSesInfo->tcon_list);
2316 write_unlock(&cifs_tcp_ses_lock);
2319 /* we can have only one retry value for a connection
2320 to a share so for resources mounted more than once
2321 to the same server share the last value passed in
2322 for the retry flag is used */
2323 tcon->retry = volume_info.retry;
2324 tcon->nocase = volume_info.nocase;
2325 tcon->local_lease = volume_info.local_lease;
2327 if (pSesInfo) {
2328 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2329 sb->s_maxbytes = (u64) 1 << 63;
2330 } else
2331 sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2334 /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2335 sb->s_time_gran = 100;
2337 mount_fail_check:
2338 /* on error free sesinfo and tcon struct if needed */
2339 if (rc) {
2340 /* If find_unc succeeded then rc == 0 so we can not end */
2341 /* up accidently freeing someone elses tcon struct */
2342 if (tcon)
2343 cifs_put_tcon(tcon);
2344 else if (pSesInfo)
2345 cifs_put_smb_ses(pSesInfo);
2346 else
2347 cifs_put_tcp_session(srvTcp);
2348 goto out;
2350 cifs_sb->tcon = tcon;
2352 /* do not care if following two calls succeed - informational */
2353 if (!tcon->ipc) {
2354 CIFSSMBQFSDeviceInfo(xid, tcon);
2355 CIFSSMBQFSAttributeInfo(xid, tcon);
2358 /* tell server which Unix caps we support */
2359 if (tcon->ses->capabilities & CAP_UNIX)
2360 /* reset of caps checks mount to see if unix extensions
2361 disabled for just this mount */
2362 reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2363 else
2364 tcon->unix_ext = 0; /* server does not support them */
2366 /* convert forward to back slashes in prepath here if needed */
2367 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2368 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
2370 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2371 cifs_sb->rsize = 1024 * 127;
2372 cFYI(DBG2, ("no very large read support, rsize now 127K"));
2374 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2375 cifs_sb->wsize = min(cifs_sb->wsize,
2376 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2377 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2378 cifs_sb->rsize = min(cifs_sb->rsize,
2379 (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2381 /* volume_info.password is freed above when existing session found
2382 (in which case it is not needed anymore) but when new sesion is created
2383 the password ptr is put in the new session structure (in which case the
2384 password will be freed at unmount time) */
2385 out:
2386 /* zero out password before freeing */
2387 if (volume_info.password != NULL) {
2388 memset(volume_info.password, 0, strlen(volume_info.password));
2389 kfree(volume_info.password);
2391 kfree(volume_info.UNC);
2392 kfree(volume_info.prepath);
2393 FreeXid(xid);
2394 return rc;
2397 static int
2398 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2399 char session_key[CIFS_SESS_KEY_SIZE],
2400 const struct nls_table *nls_codepage)
2402 struct smb_hdr *smb_buffer;
2403 struct smb_hdr *smb_buffer_response;
2404 SESSION_SETUP_ANDX *pSMB;
2405 SESSION_SETUP_ANDX *pSMBr;
2406 char *bcc_ptr;
2407 char *user;
2408 char *domain;
2409 int rc = 0;
2410 int remaining_words = 0;
2411 int bytes_returned = 0;
2412 int len;
2413 __u32 capabilities;
2414 __u16 count;
2416 cFYI(1, ("In sesssetup"));
2417 if (ses == NULL)
2418 return -EINVAL;
2419 user = ses->userName;
2420 domain = ses->domainName;
2421 smb_buffer = cifs_buf_get();
2423 if (smb_buffer == NULL)
2424 return -ENOMEM;
2426 smb_buffer_response = smb_buffer;
2427 pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2429 /* send SMBsessionSetup here */
2430 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2431 NULL /* no tCon exists yet */ , 13 /* wct */ );
2433 smb_buffer->Mid = GetNextMid(ses->server);
2434 pSMB->req_no_secext.AndXCommand = 0xFF;
2435 pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2436 pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2438 if (ses->server->secMode &
2439 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2440 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2442 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2443 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2444 if (ses->capabilities & CAP_UNICODE) {
2445 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2446 capabilities |= CAP_UNICODE;
2448 if (ses->capabilities & CAP_STATUS32) {
2449 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2450 capabilities |= CAP_STATUS32;
2452 if (ses->capabilities & CAP_DFS) {
2453 smb_buffer->Flags2 |= SMBFLG2_DFS;
2454 capabilities |= CAP_DFS;
2456 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2458 pSMB->req_no_secext.CaseInsensitivePasswordLength =
2459 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2461 pSMB->req_no_secext.CaseSensitivePasswordLength =
2462 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2463 bcc_ptr = pByteArea(smb_buffer);
2464 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2465 bcc_ptr += CIFS_SESS_KEY_SIZE;
2466 memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2467 bcc_ptr += CIFS_SESS_KEY_SIZE;
2469 if (ses->capabilities & CAP_UNICODE) {
2470 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2471 *bcc_ptr = 0;
2472 bcc_ptr++;
2474 if (user == NULL)
2475 bytes_returned = 0; /* skip null user */
2476 else
2477 bytes_returned =
2478 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2479 nls_codepage);
2480 /* convert number of 16 bit words to bytes */
2481 bcc_ptr += 2 * bytes_returned;
2482 bcc_ptr += 2; /* trailing null */
2483 if (domain == NULL)
2484 bytes_returned =
2485 cifs_strtoUCS((__le16 *) bcc_ptr,
2486 "CIFS_LINUX_DOM", 32, nls_codepage);
2487 else
2488 bytes_returned =
2489 cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2490 nls_codepage);
2491 bcc_ptr += 2 * bytes_returned;
2492 bcc_ptr += 2;
2493 bytes_returned =
2494 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2495 32, nls_codepage);
2496 bcc_ptr += 2 * bytes_returned;
2497 bytes_returned =
2498 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2499 32, nls_codepage);
2500 bcc_ptr += 2 * bytes_returned;
2501 bcc_ptr += 2;
2502 bytes_returned =
2503 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2504 64, nls_codepage);
2505 bcc_ptr += 2 * bytes_returned;
2506 bcc_ptr += 2;
2507 } else {
2508 if (user != NULL) {
2509 strncpy(bcc_ptr, user, 200);
2510 bcc_ptr += strnlen(user, 200);
2512 *bcc_ptr = 0;
2513 bcc_ptr++;
2514 if (domain == NULL) {
2515 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2516 bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2517 } else {
2518 strncpy(bcc_ptr, domain, 64);
2519 bcc_ptr += strnlen(domain, 64);
2520 *bcc_ptr = 0;
2521 bcc_ptr++;
2523 strcpy(bcc_ptr, "Linux version ");
2524 bcc_ptr += strlen("Linux version ");
2525 strcpy(bcc_ptr, utsname()->release);
2526 bcc_ptr += strlen(utsname()->release) + 1;
2527 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2528 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2530 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2531 smb_buffer->smb_buf_length += count;
2532 pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2534 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2535 &bytes_returned, CIFS_LONG_OP);
2536 if (rc) {
2537 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2538 } else if ((smb_buffer_response->WordCount == 3)
2539 || (smb_buffer_response->WordCount == 4)) {
2540 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2541 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2542 if (action & GUEST_LOGIN)
2543 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2544 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2545 (little endian) */
2546 cFYI(1, ("UID = %d ", ses->Suid));
2547 /* response can have either 3 or 4 word count - Samba sends 3 */
2548 bcc_ptr = pByteArea(smb_buffer_response);
2549 if ((pSMBr->resp.hdr.WordCount == 3)
2550 || ((pSMBr->resp.hdr.WordCount == 4)
2551 && (blob_len < pSMBr->resp.ByteCount))) {
2552 if (pSMBr->resp.hdr.WordCount == 4)
2553 bcc_ptr += blob_len;
2555 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2556 if ((long) (bcc_ptr) % 2) {
2557 remaining_words =
2558 (BCC(smb_buffer_response) - 1) / 2;
2559 /* Unicode strings must be word
2560 aligned */
2561 bcc_ptr++;
2562 } else {
2563 remaining_words =
2564 BCC(smb_buffer_response) / 2;
2566 len =
2567 UniStrnlen((wchar_t *) bcc_ptr,
2568 remaining_words - 1);
2569 /* We look for obvious messed up bcc or strings in response so we do not go off
2570 the end since (at least) WIN2K and Windows XP have a major bug in not null
2571 terminating last Unicode string in response */
2572 if (ses->serverOS)
2573 kfree(ses->serverOS);
2574 ses->serverOS = kzalloc(2 * (len + 1),
2575 GFP_KERNEL);
2576 if (ses->serverOS == NULL)
2577 goto sesssetup_nomem;
2578 cifs_strfromUCS_le(ses->serverOS,
2579 (__le16 *)bcc_ptr,
2580 len, nls_codepage);
2581 bcc_ptr += 2 * (len + 1);
2582 remaining_words -= len + 1;
2583 ses->serverOS[2 * len] = 0;
2584 ses->serverOS[1 + (2 * len)] = 0;
2585 if (remaining_words > 0) {
2586 len = UniStrnlen((wchar_t *)bcc_ptr,
2587 remaining_words-1);
2588 kfree(ses->serverNOS);
2589 ses->serverNOS = kzalloc(2 * (len + 1),
2590 GFP_KERNEL);
2591 if (ses->serverNOS == NULL)
2592 goto sesssetup_nomem;
2593 cifs_strfromUCS_le(ses->serverNOS,
2594 (__le16 *)bcc_ptr,
2595 len, nls_codepage);
2596 bcc_ptr += 2 * (len + 1);
2597 ses->serverNOS[2 * len] = 0;
2598 ses->serverNOS[1 + (2 * len)] = 0;
2599 if (strncmp(ses->serverNOS,
2600 "NT LAN Manager 4", 16) == 0) {
2601 cFYI(1, ("NT4 server"));
2602 ses->flags |= CIFS_SES_NT4;
2604 remaining_words -= len + 1;
2605 if (remaining_words > 0) {
2606 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2607 /* last string is not always null terminated
2608 (for e.g. for Windows XP & 2000) */
2609 if (ses->serverDomain)
2610 kfree(ses->serverDomain);
2611 ses->serverDomain =
2612 kzalloc(2*(len+1),
2613 GFP_KERNEL);
2614 if (ses->serverDomain == NULL)
2615 goto sesssetup_nomem;
2616 cifs_strfromUCS_le(ses->serverDomain,
2617 (__le16 *)bcc_ptr,
2618 len, nls_codepage);
2619 bcc_ptr += 2 * (len + 1);
2620 ses->serverDomain[2*len] = 0;
2621 ses->serverDomain[1+(2*len)] = 0;
2622 } else { /* else no more room so create
2623 dummy domain string */
2624 if (ses->serverDomain)
2625 kfree(ses->serverDomain);
2626 ses->serverDomain =
2627 kzalloc(2, GFP_KERNEL);
2629 } else { /* no room so create dummy domain
2630 and NOS string */
2632 /* if these kcallocs fail not much we
2633 can do, but better to not fail the
2634 sesssetup itself */
2635 kfree(ses->serverDomain);
2636 ses->serverDomain =
2637 kzalloc(2, GFP_KERNEL);
2638 kfree(ses->serverNOS);
2639 ses->serverNOS =
2640 kzalloc(2, GFP_KERNEL);
2642 } else { /* ASCII */
2643 len = strnlen(bcc_ptr, 1024);
2644 if (((long) bcc_ptr + len) - (long)
2645 pByteArea(smb_buffer_response)
2646 <= BCC(smb_buffer_response)) {
2647 kfree(ses->serverOS);
2648 ses->serverOS = kzalloc(len + 1,
2649 GFP_KERNEL);
2650 if (ses->serverOS == NULL)
2651 goto sesssetup_nomem;
2652 strncpy(ses->serverOS, bcc_ptr, len);
2654 bcc_ptr += len;
2655 /* null terminate the string */
2656 bcc_ptr[0] = 0;
2657 bcc_ptr++;
2659 len = strnlen(bcc_ptr, 1024);
2660 kfree(ses->serverNOS);
2661 ses->serverNOS = kzalloc(len + 1,
2662 GFP_KERNEL);
2663 if (ses->serverNOS == NULL)
2664 goto sesssetup_nomem;
2665 strncpy(ses->serverNOS, bcc_ptr, len);
2666 bcc_ptr += len;
2667 bcc_ptr[0] = 0;
2668 bcc_ptr++;
2670 len = strnlen(bcc_ptr, 1024);
2671 if (ses->serverDomain)
2672 kfree(ses->serverDomain);
2673 ses->serverDomain = kzalloc(len + 1,
2674 GFP_KERNEL);
2675 if (ses->serverDomain == NULL)
2676 goto sesssetup_nomem;
2677 strncpy(ses->serverDomain, bcc_ptr,
2678 len);
2679 bcc_ptr += len;
2680 bcc_ptr[0] = 0;
2681 bcc_ptr++;
2682 } else
2683 cFYI(1,
2684 ("Variable field of length %d "
2685 "extends beyond end of smb ",
2686 len));
2688 } else {
2689 cERROR(1,
2690 (" Security Blob Length extends beyond "
2691 "end of SMB"));
2693 } else {
2694 cERROR(1,
2695 (" Invalid Word count %d: ",
2696 smb_buffer_response->WordCount));
2697 rc = -EIO;
2699 sesssetup_nomem: /* do not return an error on nomem for the info strings,
2700 since that could make reconnection harder, and
2701 reconnection might be needed to free memory */
2702 cifs_buf_release(smb_buffer);
2704 return rc;
2707 static int
2708 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2709 struct cifsSesInfo *ses, bool *pNTLMv2_flag,
2710 const struct nls_table *nls_codepage)
2712 struct smb_hdr *smb_buffer;
2713 struct smb_hdr *smb_buffer_response;
2714 SESSION_SETUP_ANDX *pSMB;
2715 SESSION_SETUP_ANDX *pSMBr;
2716 char *bcc_ptr;
2717 char *domain;
2718 int rc = 0;
2719 int remaining_words = 0;
2720 int bytes_returned = 0;
2721 int len;
2722 int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
2723 PNEGOTIATE_MESSAGE SecurityBlob;
2724 PCHALLENGE_MESSAGE SecurityBlob2;
2725 __u32 negotiate_flags, capabilities;
2726 __u16 count;
2728 cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2729 if (ses == NULL)
2730 return -EINVAL;
2731 domain = ses->domainName;
2732 *pNTLMv2_flag = false;
2733 smb_buffer = cifs_buf_get();
2734 if (smb_buffer == NULL) {
2735 return -ENOMEM;
2737 smb_buffer_response = smb_buffer;
2738 pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2739 pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2741 /* send SMBsessionSetup here */
2742 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2743 NULL /* no tCon exists yet */ , 12 /* wct */ );
2745 smb_buffer->Mid = GetNextMid(ses->server);
2746 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2747 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2749 pSMB->req.AndXCommand = 0xFF;
2750 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2751 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2753 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2754 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2756 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2757 CAP_EXTENDED_SECURITY;
2758 if (ses->capabilities & CAP_UNICODE) {
2759 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2760 capabilities |= CAP_UNICODE;
2762 if (ses->capabilities & CAP_STATUS32) {
2763 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2764 capabilities |= CAP_STATUS32;
2766 if (ses->capabilities & CAP_DFS) {
2767 smb_buffer->Flags2 |= SMBFLG2_DFS;
2768 capabilities |= CAP_DFS;
2770 pSMB->req.Capabilities = cpu_to_le32(capabilities);
2772 bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2773 SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2774 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2775 SecurityBlob->MessageType = NtLmNegotiate;
2776 negotiate_flags =
2777 NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2778 NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2779 NTLMSSP_NEGOTIATE_56 |
2780 /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2781 if (sign_CIFS_PDUs)
2782 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2783 /* if (ntlmv2_support)
2784 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2785 /* setup pointers to domain name and workstation name */
2786 bcc_ptr += SecurityBlobLength;
2788 SecurityBlob->WorkstationName.Buffer = 0;
2789 SecurityBlob->WorkstationName.Length = 0;
2790 SecurityBlob->WorkstationName.MaximumLength = 0;
2792 /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2793 along with username on auth request (ie the response to challenge) */
2794 SecurityBlob->DomainName.Buffer = 0;
2795 SecurityBlob->DomainName.Length = 0;
2796 SecurityBlob->DomainName.MaximumLength = 0;
2797 if (ses->capabilities & CAP_UNICODE) {
2798 if ((long) bcc_ptr % 2) {
2799 *bcc_ptr = 0;
2800 bcc_ptr++;
2803 bytes_returned =
2804 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2805 32, nls_codepage);
2806 bcc_ptr += 2 * bytes_returned;
2807 bytes_returned =
2808 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2809 nls_codepage);
2810 bcc_ptr += 2 * bytes_returned;
2811 bcc_ptr += 2; /* null terminate Linux version */
2812 bytes_returned =
2813 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2814 64, nls_codepage);
2815 bcc_ptr += 2 * bytes_returned;
2816 *(bcc_ptr + 1) = 0;
2817 *(bcc_ptr + 2) = 0;
2818 bcc_ptr += 2; /* null terminate network opsys string */
2819 *(bcc_ptr + 1) = 0;
2820 *(bcc_ptr + 2) = 0;
2821 bcc_ptr += 2; /* null domain */
2822 } else { /* ASCII */
2823 strcpy(bcc_ptr, "Linux version ");
2824 bcc_ptr += strlen("Linux version ");
2825 strcpy(bcc_ptr, utsname()->release);
2826 bcc_ptr += strlen(utsname()->release) + 1;
2827 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2828 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2829 bcc_ptr++; /* empty domain field */
2830 *bcc_ptr = 0;
2832 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2833 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2834 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2835 smb_buffer->smb_buf_length += count;
2836 pSMB->req.ByteCount = cpu_to_le16(count);
2838 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2839 &bytes_returned, CIFS_LONG_OP);
2841 if (smb_buffer_response->Status.CifsError ==
2842 cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2843 rc = 0;
2845 if (rc) {
2846 /* rc = map_smb_to_linux_error(smb_buffer_response); *//* done in SendReceive now */
2847 } else if ((smb_buffer_response->WordCount == 3)
2848 || (smb_buffer_response->WordCount == 4)) {
2849 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2850 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2852 if (action & GUEST_LOGIN)
2853 cFYI(1, (" Guest login"));
2854 /* Do we want to set anything in SesInfo struct when guest login? */
2856 bcc_ptr = pByteArea(smb_buffer_response);
2857 /* response can have either 3 or 4 word count - Samba sends 3 */
2859 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2860 if (SecurityBlob2->MessageType != NtLmChallenge) {
2861 cFYI(1,
2862 ("Unexpected NTLMSSP message type received %d",
2863 SecurityBlob2->MessageType));
2864 } else if (ses) {
2865 ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2866 cFYI(1, ("UID = %d", ses->Suid));
2867 if ((pSMBr->resp.hdr.WordCount == 3)
2868 || ((pSMBr->resp.hdr.WordCount == 4)
2869 && (blob_len <
2870 pSMBr->resp.ByteCount))) {
2872 if (pSMBr->resp.hdr.WordCount == 4) {
2873 bcc_ptr += blob_len;
2874 cFYI(1, ("Security Blob Length %d",
2875 blob_len));
2878 cFYI(1, ("NTLMSSP Challenge rcvd"));
2880 memcpy(ses->server->cryptKey,
2881 SecurityBlob2->Challenge,
2882 CIFS_CRYPTO_KEY_SIZE);
2883 if (SecurityBlob2->NegotiateFlags &
2884 cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2885 *pNTLMv2_flag = true;
2887 if ((SecurityBlob2->NegotiateFlags &
2888 cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2889 || (sign_CIFS_PDUs > 1))
2890 ses->server->secMode |=
2891 SECMODE_SIGN_REQUIRED;
2892 if ((SecurityBlob2->NegotiateFlags &
2893 cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2894 ses->server->secMode |=
2895 SECMODE_SIGN_ENABLED;
2897 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2898 if ((long) (bcc_ptr) % 2) {
2899 remaining_words =
2900 (BCC(smb_buffer_response)
2901 - 1) / 2;
2902 /* Must word align unicode strings */
2903 bcc_ptr++;
2904 } else {
2905 remaining_words =
2907 (smb_buffer_response) / 2;
2909 len =
2910 UniStrnlen((wchar_t *) bcc_ptr,
2911 remaining_words - 1);
2912 /* We look for obvious messed up bcc or strings in response so we do not go off
2913 the end since (at least) WIN2K and Windows XP have a major bug in not null
2914 terminating last Unicode string in response */
2915 if (ses->serverOS)
2916 kfree(ses->serverOS);
2917 ses->serverOS =
2918 kzalloc(2 * (len + 1), GFP_KERNEL);
2919 cifs_strfromUCS_le(ses->serverOS,
2920 (__le16 *)
2921 bcc_ptr, len,
2922 nls_codepage);
2923 bcc_ptr += 2 * (len + 1);
2924 remaining_words -= len + 1;
2925 ses->serverOS[2 * len] = 0;
2926 ses->serverOS[1 + (2 * len)] = 0;
2927 if (remaining_words > 0) {
2928 len = UniStrnlen((wchar_t *)
2929 bcc_ptr,
2930 remaining_words
2931 - 1);
2932 kfree(ses->serverNOS);
2933 ses->serverNOS =
2934 kzalloc(2 * (len + 1),
2935 GFP_KERNEL);
2936 cifs_strfromUCS_le(ses->
2937 serverNOS,
2938 (__le16 *)
2939 bcc_ptr,
2940 len,
2941 nls_codepage);
2942 bcc_ptr += 2 * (len + 1);
2943 ses->serverNOS[2 * len] = 0;
2944 ses->serverNOS[1 +
2945 (2 * len)] = 0;
2946 remaining_words -= len + 1;
2947 if (remaining_words > 0) {
2948 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2949 /* last string not always null terminated
2950 (for e.g. for Windows XP & 2000) */
2951 kfree(ses->serverDomain);
2952 ses->serverDomain =
2953 kzalloc(2 *
2954 (len +
2956 GFP_KERNEL);
2957 cifs_strfromUCS_le
2958 (ses->serverDomain,
2959 (__le16 *)bcc_ptr,
2960 len, nls_codepage);
2961 bcc_ptr +=
2962 2 * (len + 1);
2963 ses->serverDomain[2*len]
2964 = 0;
2965 ses->serverDomain
2966 [1 + (2 * len)]
2967 = 0;
2968 } /* else no more room so create dummy domain string */
2969 else {
2970 kfree(ses->serverDomain);
2971 ses->serverDomain =
2972 kzalloc(2,
2973 GFP_KERNEL);
2975 } else { /* no room so create dummy domain and NOS string */
2976 kfree(ses->serverDomain);
2977 ses->serverDomain =
2978 kzalloc(2, GFP_KERNEL);
2979 kfree(ses->serverNOS);
2980 ses->serverNOS =
2981 kzalloc(2, GFP_KERNEL);
2983 } else { /* ASCII */
2984 len = strnlen(bcc_ptr, 1024);
2985 if (((long) bcc_ptr + len) - (long)
2986 pByteArea(smb_buffer_response)
2987 <= BCC(smb_buffer_response)) {
2988 if (ses->serverOS)
2989 kfree(ses->serverOS);
2990 ses->serverOS =
2991 kzalloc(len + 1,
2992 GFP_KERNEL);
2993 strncpy(ses->serverOS,
2994 bcc_ptr, len);
2996 bcc_ptr += len;
2997 bcc_ptr[0] = 0; /* null terminate string */
2998 bcc_ptr++;
3000 len = strnlen(bcc_ptr, 1024);
3001 kfree(ses->serverNOS);
3002 ses->serverNOS =
3003 kzalloc(len + 1,
3004 GFP_KERNEL);
3005 strncpy(ses->serverNOS, bcc_ptr, len);
3006 bcc_ptr += len;
3007 bcc_ptr[0] = 0;
3008 bcc_ptr++;
3010 len = strnlen(bcc_ptr, 1024);
3011 kfree(ses->serverDomain);
3012 ses->serverDomain =
3013 kzalloc(len + 1,
3014 GFP_KERNEL);
3015 strncpy(ses->serverDomain,
3016 bcc_ptr, len);
3017 bcc_ptr += len;
3018 bcc_ptr[0] = 0;
3019 bcc_ptr++;
3020 } else
3021 cFYI(1,
3022 ("field of length %d "
3023 "extends beyond end of smb",
3024 len));
3026 } else {
3027 cERROR(1, ("Security Blob Length extends beyond"
3028 " end of SMB"));
3030 } else {
3031 cERROR(1, ("No session structure passed in."));
3033 } else {
3034 cERROR(1,
3035 (" Invalid Word count %d:",
3036 smb_buffer_response->WordCount));
3037 rc = -EIO;
3040 cifs_buf_release(smb_buffer);
3042 return rc;
3044 static int
3045 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3046 char *ntlm_session_key, bool ntlmv2_flag,
3047 const struct nls_table *nls_codepage)
3049 struct smb_hdr *smb_buffer;
3050 struct smb_hdr *smb_buffer_response;
3051 SESSION_SETUP_ANDX *pSMB;
3052 SESSION_SETUP_ANDX *pSMBr;
3053 char *bcc_ptr;
3054 char *user;
3055 char *domain;
3056 int rc = 0;
3057 int remaining_words = 0;
3058 int bytes_returned = 0;
3059 int len;
3060 int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
3061 PAUTHENTICATE_MESSAGE SecurityBlob;
3062 __u32 negotiate_flags, capabilities;
3063 __u16 count;
3065 cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
3066 if (ses == NULL)
3067 return -EINVAL;
3068 user = ses->userName;
3069 domain = ses->domainName;
3070 smb_buffer = cifs_buf_get();
3071 if (smb_buffer == NULL) {
3072 return -ENOMEM;
3074 smb_buffer_response = smb_buffer;
3075 pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
3076 pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
3078 /* send SMBsessionSetup here */
3079 header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
3080 NULL /* no tCon exists yet */ , 12 /* wct */ );
3082 smb_buffer->Mid = GetNextMid(ses->server);
3083 pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
3084 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
3085 pSMB->req.AndXCommand = 0xFF;
3086 pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
3087 pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
3089 pSMB->req.hdr.Uid = ses->Suid;
3091 if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3092 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3094 capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
3095 CAP_EXTENDED_SECURITY;
3096 if (ses->capabilities & CAP_UNICODE) {
3097 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3098 capabilities |= CAP_UNICODE;
3100 if (ses->capabilities & CAP_STATUS32) {
3101 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3102 capabilities |= CAP_STATUS32;
3104 if (ses->capabilities & CAP_DFS) {
3105 smb_buffer->Flags2 |= SMBFLG2_DFS;
3106 capabilities |= CAP_DFS;
3108 pSMB->req.Capabilities = cpu_to_le32(capabilities);
3110 bcc_ptr = (char *)&pSMB->req.SecurityBlob;
3111 SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
3112 strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
3113 SecurityBlob->MessageType = NtLmAuthenticate;
3114 bcc_ptr += SecurityBlobLength;
3115 negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
3116 NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
3117 0x80000000 | NTLMSSP_NEGOTIATE_128;
3118 if (sign_CIFS_PDUs)
3119 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
3120 if (ntlmv2_flag)
3121 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
3123 /* setup pointers to domain name and workstation name */
3125 SecurityBlob->WorkstationName.Buffer = 0;
3126 SecurityBlob->WorkstationName.Length = 0;
3127 SecurityBlob->WorkstationName.MaximumLength = 0;
3128 SecurityBlob->SessionKey.Length = 0;
3129 SecurityBlob->SessionKey.MaximumLength = 0;
3130 SecurityBlob->SessionKey.Buffer = 0;
3132 SecurityBlob->LmChallengeResponse.Length = 0;
3133 SecurityBlob->LmChallengeResponse.MaximumLength = 0;
3134 SecurityBlob->LmChallengeResponse.Buffer = 0;
3136 SecurityBlob->NtChallengeResponse.Length =
3137 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3138 SecurityBlob->NtChallengeResponse.MaximumLength =
3139 cpu_to_le16(CIFS_SESS_KEY_SIZE);
3140 memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
3141 SecurityBlob->NtChallengeResponse.Buffer =
3142 cpu_to_le32(SecurityBlobLength);
3143 SecurityBlobLength += CIFS_SESS_KEY_SIZE;
3144 bcc_ptr += CIFS_SESS_KEY_SIZE;
3146 if (ses->capabilities & CAP_UNICODE) {
3147 if (domain == NULL) {
3148 SecurityBlob->DomainName.Buffer = 0;
3149 SecurityBlob->DomainName.Length = 0;
3150 SecurityBlob->DomainName.MaximumLength = 0;
3151 } else {
3152 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
3153 nls_codepage);
3154 ln *= 2;
3155 SecurityBlob->DomainName.MaximumLength =
3156 cpu_to_le16(ln);
3157 SecurityBlob->DomainName.Buffer =
3158 cpu_to_le32(SecurityBlobLength);
3159 bcc_ptr += ln;
3160 SecurityBlobLength += ln;
3161 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3163 if (user == NULL) {
3164 SecurityBlob->UserName.Buffer = 0;
3165 SecurityBlob->UserName.Length = 0;
3166 SecurityBlob->UserName.MaximumLength = 0;
3167 } else {
3168 __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
3169 nls_codepage);
3170 ln *= 2;
3171 SecurityBlob->UserName.MaximumLength =
3172 cpu_to_le16(ln);
3173 SecurityBlob->UserName.Buffer =
3174 cpu_to_le32(SecurityBlobLength);
3175 bcc_ptr += ln;
3176 SecurityBlobLength += ln;
3177 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3180 /* SecurityBlob->WorkstationName.Length =
3181 cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3182 SecurityBlob->WorkstationName.Length *= 2;
3183 SecurityBlob->WorkstationName.MaximumLength =
3184 cpu_to_le16(SecurityBlob->WorkstationName.Length);
3185 SecurityBlob->WorkstationName.Buffer =
3186 cpu_to_le32(SecurityBlobLength);
3187 bcc_ptr += SecurityBlob->WorkstationName.Length;
3188 SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3189 SecurityBlob->WorkstationName.Length =
3190 cpu_to_le16(SecurityBlob->WorkstationName.Length); */
3192 if ((long) bcc_ptr % 2) {
3193 *bcc_ptr = 0;
3194 bcc_ptr++;
3196 bytes_returned =
3197 cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3198 32, nls_codepage);
3199 bcc_ptr += 2 * bytes_returned;
3200 bytes_returned =
3201 cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3202 nls_codepage);
3203 bcc_ptr += 2 * bytes_returned;
3204 bcc_ptr += 2; /* null term version string */
3205 bytes_returned =
3206 cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3207 64, nls_codepage);
3208 bcc_ptr += 2 * bytes_returned;
3209 *(bcc_ptr + 1) = 0;
3210 *(bcc_ptr + 2) = 0;
3211 bcc_ptr += 2; /* null terminate network opsys string */
3212 *(bcc_ptr + 1) = 0;
3213 *(bcc_ptr + 2) = 0;
3214 bcc_ptr += 2; /* null domain */
3215 } else { /* ASCII */
3216 if (domain == NULL) {
3217 SecurityBlob->DomainName.Buffer = 0;
3218 SecurityBlob->DomainName.Length = 0;
3219 SecurityBlob->DomainName.MaximumLength = 0;
3220 } else {
3221 __u16 ln;
3222 negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3223 strncpy(bcc_ptr, domain, 63);
3224 ln = strnlen(domain, 64);
3225 SecurityBlob->DomainName.MaximumLength =
3226 cpu_to_le16(ln);
3227 SecurityBlob->DomainName.Buffer =
3228 cpu_to_le32(SecurityBlobLength);
3229 bcc_ptr += ln;
3230 SecurityBlobLength += ln;
3231 SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3233 if (user == NULL) {
3234 SecurityBlob->UserName.Buffer = 0;
3235 SecurityBlob->UserName.Length = 0;
3236 SecurityBlob->UserName.MaximumLength = 0;
3237 } else {
3238 __u16 ln;
3239 strncpy(bcc_ptr, user, 63);
3240 ln = strnlen(user, 64);
3241 SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
3242 SecurityBlob->UserName.Buffer =
3243 cpu_to_le32(SecurityBlobLength);
3244 bcc_ptr += ln;
3245 SecurityBlobLength += ln;
3246 SecurityBlob->UserName.Length = cpu_to_le16(ln);
3248 /* BB fill in our workstation name if known BB */
3250 strcpy(bcc_ptr, "Linux version ");
3251 bcc_ptr += strlen("Linux version ");
3252 strcpy(bcc_ptr, utsname()->release);
3253 bcc_ptr += strlen(utsname()->release) + 1;
3254 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3255 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3256 bcc_ptr++; /* null domain */
3257 *bcc_ptr = 0;
3259 SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3260 pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3261 count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3262 smb_buffer->smb_buf_length += count;
3263 pSMB->req.ByteCount = cpu_to_le16(count);
3265 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3266 &bytes_returned, CIFS_LONG_OP);
3267 if (rc) {
3268 /* rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3269 } else if ((smb_buffer_response->WordCount == 3) ||
3270 (smb_buffer_response->WordCount == 4)) {
3271 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3272 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3273 if (action & GUEST_LOGIN)
3274 cFYI(1, (" Guest login")); /* BB Should we set anything
3275 in SesInfo struct ? */
3276 /* if (SecurityBlob2->MessageType != NtLm??) {
3277 cFYI("Unexpected message type on auth response is %d"));
3278 } */
3280 if (ses) {
3281 cFYI(1,
3282 ("Check challenge UID %d vs auth response UID %d",
3283 ses->Suid, smb_buffer_response->Uid));
3284 /* UID left in wire format */
3285 ses->Suid = smb_buffer_response->Uid;
3286 bcc_ptr = pByteArea(smb_buffer_response);
3287 /* response can have either 3 or 4 word count - Samba sends 3 */
3288 if ((pSMBr->resp.hdr.WordCount == 3)
3289 || ((pSMBr->resp.hdr.WordCount == 4)
3290 && (blob_len <
3291 pSMBr->resp.ByteCount))) {
3292 if (pSMBr->resp.hdr.WordCount == 4) {
3293 bcc_ptr +=
3294 blob_len;
3295 cFYI(1,
3296 ("Security Blob Length %d ",
3297 blob_len));
3300 cFYI(1,
3301 ("NTLMSSP response to Authenticate "));
3303 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3304 if ((long) (bcc_ptr) % 2) {
3305 remaining_words =
3306 (BCC(smb_buffer_response)
3307 - 1) / 2;
3308 bcc_ptr++; /* Unicode strings must be word aligned */
3309 } else {
3310 remaining_words = BCC(smb_buffer_response) / 2;
3312 len = UniStrnlen((wchar_t *) bcc_ptr,
3313 remaining_words - 1);
3314 /* We look for obvious messed up bcc or strings in response so we do not go off
3315 the end since (at least) WIN2K and Windows XP have a major bug in not null
3316 terminating last Unicode string in response */
3317 if (ses->serverOS)
3318 kfree(ses->serverOS);
3319 ses->serverOS =
3320 kzalloc(2 * (len + 1), GFP_KERNEL);
3321 cifs_strfromUCS_le(ses->serverOS,
3322 (__le16 *)
3323 bcc_ptr, len,
3324 nls_codepage);
3325 bcc_ptr += 2 * (len + 1);
3326 remaining_words -= len + 1;
3327 ses->serverOS[2 * len] = 0;
3328 ses->serverOS[1 + (2 * len)] = 0;
3329 if (remaining_words > 0) {
3330 len = UniStrnlen((wchar_t *)
3331 bcc_ptr,
3332 remaining_words
3333 - 1);
3334 kfree(ses->serverNOS);
3335 ses->serverNOS =
3336 kzalloc(2 * (len + 1),
3337 GFP_KERNEL);
3338 cifs_strfromUCS_le(ses->
3339 serverNOS,
3340 (__le16 *)
3341 bcc_ptr,
3342 len,
3343 nls_codepage);
3344 bcc_ptr += 2 * (len + 1);
3345 ses->serverNOS[2 * len] = 0;
3346 ses->serverNOS[1+(2*len)] = 0;
3347 remaining_words -= len + 1;
3348 if (remaining_words > 0) {
3349 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3350 /* last string not always null terminated (e.g. for Windows XP & 2000) */
3351 if (ses->serverDomain)
3352 kfree(ses->serverDomain);
3353 ses->serverDomain =
3354 kzalloc(2 *
3355 (len +
3357 GFP_KERNEL);
3358 cifs_strfromUCS_le
3359 (ses->
3360 serverDomain,
3361 (__le16 *)
3362 bcc_ptr, len,
3363 nls_codepage);
3364 bcc_ptr +=
3365 2 * (len + 1);
3366 ses->
3367 serverDomain[2
3368 * len]
3369 = 0;
3370 ses->
3371 serverDomain[1
3375 len)]
3376 = 0;
3377 } /* else no more room so create dummy domain string */
3378 else {
3379 if (ses->serverDomain)
3380 kfree(ses->serverDomain);
3381 ses->serverDomain = kzalloc(2,GFP_KERNEL);
3383 } else { /* no room so create dummy domain and NOS string */
3384 if (ses->serverDomain)
3385 kfree(ses->serverDomain);
3386 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3387 kfree(ses->serverNOS);
3388 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3390 } else { /* ASCII */
3391 len = strnlen(bcc_ptr, 1024);
3392 if (((long) bcc_ptr + len) -
3393 (long) pByteArea(smb_buffer_response)
3394 <= BCC(smb_buffer_response)) {
3395 if (ses->serverOS)
3396 kfree(ses->serverOS);
3397 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
3398 strncpy(ses->serverOS,bcc_ptr, len);
3400 bcc_ptr += len;
3401 bcc_ptr[0] = 0; /* null terminate the string */
3402 bcc_ptr++;
3404 len = strnlen(bcc_ptr, 1024);
3405 kfree(ses->serverNOS);
3406 ses->serverNOS = kzalloc(len+1,
3407 GFP_KERNEL);
3408 strncpy(ses->serverNOS,
3409 bcc_ptr, len);
3410 bcc_ptr += len;
3411 bcc_ptr[0] = 0;
3412 bcc_ptr++;
3414 len = strnlen(bcc_ptr, 1024);
3415 if (ses->serverDomain)
3416 kfree(ses->serverDomain);
3417 ses->serverDomain =
3418 kzalloc(len+1,
3419 GFP_KERNEL);
3420 strncpy(ses->serverDomain,
3421 bcc_ptr, len);
3422 bcc_ptr += len;
3423 bcc_ptr[0] = 0;
3424 bcc_ptr++;
3425 } else
3426 cFYI(1, ("field of length %d "
3427 "extends beyond end of smb ",
3428 len));
3430 } else {
3431 cERROR(1, ("Security Blob extends beyond end "
3432 "of SMB"));
3434 } else {
3435 cERROR(1, ("No session structure passed in."));
3437 } else {
3438 cERROR(1, ("Invalid Word count %d: ",
3439 smb_buffer_response->WordCount));
3440 rc = -EIO;
3443 cifs_buf_release(smb_buffer);
3445 return rc;
3449 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3450 const char *tree, struct cifsTconInfo *tcon,
3451 const struct nls_table *nls_codepage)
3453 struct smb_hdr *smb_buffer;
3454 struct smb_hdr *smb_buffer_response;
3455 TCONX_REQ *pSMB;
3456 TCONX_RSP *pSMBr;
3457 unsigned char *bcc_ptr;
3458 int rc = 0;
3459 int length;
3460 __u16 count;
3462 if (ses == NULL)
3463 return -EIO;
3465 smb_buffer = cifs_buf_get();
3466 if (smb_buffer == NULL) {
3467 return -ENOMEM;
3469 smb_buffer_response = smb_buffer;
3471 header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3472 NULL /*no tid */ , 4 /*wct */ );
3474 smb_buffer->Mid = GetNextMid(ses->server);
3475 smb_buffer->Uid = ses->Suid;
3476 pSMB = (TCONX_REQ *) smb_buffer;
3477 pSMBr = (TCONX_RSP *) smb_buffer_response;
3479 pSMB->AndXCommand = 0xFF;
3480 pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3481 bcc_ptr = &pSMB->Password[0];
3482 if ((ses->server->secMode) & SECMODE_USER) {
3483 pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
3484 *bcc_ptr = 0; /* password is null byte */
3485 bcc_ptr++; /* skip password */
3486 /* already aligned so no need to do it below */
3487 } else {
3488 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3489 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3490 specified as required (when that support is added to
3491 the vfs in the future) as only NTLM or the much
3492 weaker LANMAN (which we do not send by default) is accepted
3493 by Samba (not sure whether other servers allow
3494 NTLMv2 password here) */
3495 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3496 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3497 (ses->server->secType == LANMAN))
3498 calc_lanman_hash(ses, bcc_ptr);
3499 else
3500 #endif /* CIFS_WEAK_PW_HASH */
3501 SMBNTencrypt(ses->password,
3502 ses->server->cryptKey,
3503 bcc_ptr);
3505 bcc_ptr += CIFS_SESS_KEY_SIZE;
3506 if (ses->capabilities & CAP_UNICODE) {
3507 /* must align unicode strings */
3508 *bcc_ptr = 0; /* null byte password */
3509 bcc_ptr++;
3513 if (ses->server->secMode &
3514 (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3515 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3517 if (ses->capabilities & CAP_STATUS32) {
3518 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3520 if (ses->capabilities & CAP_DFS) {
3521 smb_buffer->Flags2 |= SMBFLG2_DFS;
3523 if (ses->capabilities & CAP_UNICODE) {
3524 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3525 length =
3526 cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3527 6 /* max utf8 char length in bytes */ *
3528 (/* server len*/ + 256 /* share len */), nls_codepage);
3529 bcc_ptr += 2 * length; /* convert num 16 bit words to bytes */
3530 bcc_ptr += 2; /* skip trailing null */
3531 } else { /* ASCII */
3532 strcpy(bcc_ptr, tree);
3533 bcc_ptr += strlen(tree) + 1;
3535 strcpy(bcc_ptr, "?????");
3536 bcc_ptr += strlen("?????");
3537 bcc_ptr += 1;
3538 count = bcc_ptr - &pSMB->Password[0];
3539 pSMB->hdr.smb_buf_length += count;
3540 pSMB->ByteCount = cpu_to_le16(count);
3542 rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3543 CIFS_STD_OP);
3545 /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3546 /* above now done in SendReceive */
3547 if ((rc == 0) && (tcon != NULL)) {
3548 tcon->tidStatus = CifsGood;
3549 tcon->need_reconnect = false;
3550 tcon->tid = smb_buffer_response->Tid;
3551 bcc_ptr = pByteArea(smb_buffer_response);
3552 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3553 /* skip service field (NB: this field is always ASCII) */
3554 if (length == 3) {
3555 if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3556 (bcc_ptr[2] == 'C')) {
3557 cFYI(1, ("IPC connection"));
3558 tcon->ipc = 1;
3560 } else if (length == 2) {
3561 if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3562 /* the most common case */
3563 cFYI(1, ("disk share connection"));
3566 bcc_ptr += length + 1;
3567 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3568 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3569 length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3570 if ((bcc_ptr + (2 * length)) -
3571 pByteArea(smb_buffer_response) <=
3572 BCC(smb_buffer_response)) {
3573 kfree(tcon->nativeFileSystem);
3574 tcon->nativeFileSystem =
3575 kzalloc(length + 2, GFP_KERNEL);
3576 if (tcon->nativeFileSystem)
3577 cifs_strfromUCS_le(
3578 tcon->nativeFileSystem,
3579 (__le16 *) bcc_ptr,
3580 length, nls_codepage);
3581 bcc_ptr += 2 * length;
3582 bcc_ptr[0] = 0; /* null terminate the string */
3583 bcc_ptr[1] = 0;
3584 bcc_ptr += 2;
3586 /* else do not bother copying these information fields*/
3587 } else {
3588 length = strnlen(bcc_ptr, 1024);
3589 if ((bcc_ptr + length) -
3590 pByteArea(smb_buffer_response) <=
3591 BCC(smb_buffer_response)) {
3592 kfree(tcon->nativeFileSystem);
3593 tcon->nativeFileSystem =
3594 kzalloc(length + 1, GFP_KERNEL);
3595 if (tcon->nativeFileSystem)
3596 strncpy(tcon->nativeFileSystem, bcc_ptr,
3597 length);
3599 /* else do not bother copying these information fields*/
3601 if ((smb_buffer_response->WordCount == 3) ||
3602 (smb_buffer_response->WordCount == 7))
3603 /* field is in same location */
3604 tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3605 else
3606 tcon->Flags = 0;
3607 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3608 } else if ((rc == 0) && tcon == NULL) {
3609 /* all we need to save for IPC$ connection */
3610 ses->ipc_tid = smb_buffer_response->Tid;
3613 cifs_buf_release(smb_buffer);
3614 return rc;
3618 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3620 int rc = 0;
3621 char *tmp;
3623 if (cifs_sb->tcon)
3624 cifs_put_tcon(cifs_sb->tcon);
3626 cifs_sb->tcon = NULL;
3627 tmp = cifs_sb->prepath;
3628 cifs_sb->prepathlen = 0;
3629 cifs_sb->prepath = NULL;
3630 kfree(tmp);
3632 return rc;
3635 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3636 struct nls_table *nls_info)
3638 int rc = 0;
3639 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3640 bool ntlmv2_flag = false;
3641 int first_time = 0;
3642 struct TCP_Server_Info *server = pSesInfo->server;
3644 /* what if server changes its buffer size after dropping the session? */
3645 if (server->maxBuf == 0) /* no need to send on reconnect */ {
3646 rc = CIFSSMBNegotiate(xid, pSesInfo);
3647 if (rc == -EAGAIN) {
3648 /* retry only once on 1st time connection */
3649 rc = CIFSSMBNegotiate(xid, pSesInfo);
3650 if (rc == -EAGAIN)
3651 rc = -EHOSTDOWN;
3653 if (rc == 0) {
3654 spin_lock(&GlobalMid_Lock);
3655 if (server->tcpStatus != CifsExiting)
3656 server->tcpStatus = CifsGood;
3657 else
3658 rc = -EHOSTDOWN;
3659 spin_unlock(&GlobalMid_Lock);
3662 first_time = 1;
3665 if (rc)
3666 goto ss_err_exit;
3668 pSesInfo->flags = 0;
3669 pSesInfo->capabilities = server->capabilities;
3670 if (linuxExtEnabled == 0)
3671 pSesInfo->capabilities &= (~CAP_UNIX);
3672 /* pSesInfo->sequence_number = 0;*/
3673 cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3674 server->secMode, server->capabilities, server->timeAdj));
3676 if (experimEnabled < 2)
3677 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
3678 else if (extended_security
3679 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3680 && (server->secType == NTLMSSP)) {
3681 rc = -EOPNOTSUPP;
3682 } else if (extended_security
3683 && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3684 && (server->secType == RawNTLMSSP)) {
3685 cFYI(1, ("NTLMSSP sesssetup"));
3686 rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag,
3687 nls_info);
3688 if (!rc) {
3689 if (ntlmv2_flag) {
3690 char *v2_response;
3691 cFYI(1, ("more secure NTLM ver2 hash"));
3692 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3693 nls_info)) {
3694 rc = -ENOMEM;
3695 goto ss_err_exit;
3696 } else
3697 v2_response = kmalloc(16 + 64 /* blob*/,
3698 GFP_KERNEL);
3699 if (v2_response) {
3700 CalcNTLMv2_response(pSesInfo,
3701 v2_response);
3702 /* if (first_time)
3703 cifs_calculate_ntlmv2_mac_key */
3704 kfree(v2_response);
3705 /* BB Put dummy sig in SessSetup PDU? */
3706 } else {
3707 rc = -ENOMEM;
3708 goto ss_err_exit;
3711 } else {
3712 SMBNTencrypt(pSesInfo->password,
3713 server->cryptKey,
3714 ntlm_session_key);
3716 if (first_time)
3717 cifs_calculate_mac_key(
3718 &server->mac_signing_key,
3719 ntlm_session_key,
3720 pSesInfo->password);
3722 /* for better security the weaker lanman hash not sent
3723 in AuthSessSetup so we no longer calculate it */
3725 rc = CIFSNTLMSSPAuthSessSetup(xid, pSesInfo,
3726 ntlm_session_key,
3727 ntlmv2_flag,
3728 nls_info);
3730 } else { /* old style NTLM 0.12 session setup */
3731 SMBNTencrypt(pSesInfo->password, server->cryptKey,
3732 ntlm_session_key);
3734 if (first_time)
3735 cifs_calculate_mac_key(&server->mac_signing_key,
3736 ntlm_session_key,
3737 pSesInfo->password);
3739 rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info);
3741 if (rc) {
3742 cERROR(1, ("Send error in SessSetup = %d", rc));
3743 } else {
3744 cFYI(1, ("CIFS Session Established successfully"));
3745 spin_lock(&GlobalMid_Lock);
3746 pSesInfo->status = CifsGood;
3747 pSesInfo->need_reconnect = false;
3748 spin_unlock(&GlobalMid_Lock);
3751 ss_err_exit:
3752 return rc;