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