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