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