[CIFS] Fix cifs reconnection flags
[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->need_reconnect = true;
153                                 ses->ipc_tid = 0;
154                         }
155                 }
156                 /* else tcp and smb sessions need reconnection */
157         }
158         list_for_each(tmp, &GlobalTreeConnectionList) {
159                 tcon = list_entry(tmp, struct cifsTconInfo, cifsConnectionList);
160                 if ((tcon->ses) && (tcon->ses->server == server))
161                         tcon->need_reconnect = true;
162         }
163         read_unlock(&GlobalSMBSeslock);
164         /* do not want to be sending data on a socket we are freeing */
165         down(&server->tcpSem);
166         if (server->ssocket) {
167                 cFYI(1, ("State: 0x%x Flags: 0x%lx", server->ssocket->state,
168                         server->ssocket->flags));
169                 kernel_sock_shutdown(server->ssocket, SHUT_WR);
170                 cFYI(1, ("Post shutdown state: 0x%x Flags: 0x%lx",
171                         server->ssocket->state,
172                         server->ssocket->flags));
173                 sock_release(server->ssocket);
174                 server->ssocket = NULL;
175         }
176
177         spin_lock(&GlobalMid_Lock);
178         list_for_each(tmp, &server->pending_mid_q) {
179                 mid_entry = list_entry(tmp, struct
180                                         mid_q_entry,
181                                         qhead);
182                 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
183                                 /* Mark other intransit requests as needing
184                                    retry so we do not immediately mark the
185                                    session bad again (ie after we reconnect
186                                    below) as they timeout too */
187                         mid_entry->midState = MID_RETRY_NEEDED;
188                 }
189         }
190         spin_unlock(&GlobalMid_Lock);
191         up(&server->tcpSem);
192
193         while ((server->tcpStatus != CifsExiting) &&
194                (server->tcpStatus != CifsGood)) {
195                 try_to_freeze();
196                 if (server->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 static void setup_cifs_sb(struct smb_vol *pvolume_info,
1895                           struct cifs_sb_info *cifs_sb)
1896 {
1897         if (pvolume_info->rsize > CIFSMaxBufSize) {
1898                 cERROR(1, ("rsize %d too large, using MaxBufSize",
1899                         pvolume_info->rsize));
1900                 cifs_sb->rsize = CIFSMaxBufSize;
1901         } else if ((pvolume_info->rsize) &&
1902                         (pvolume_info->rsize <= CIFSMaxBufSize))
1903                 cifs_sb->rsize = pvolume_info->rsize;
1904         else /* default */
1905                 cifs_sb->rsize = CIFSMaxBufSize;
1906
1907         if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
1908                 cERROR(1, ("wsize %d too large, using 4096 instead",
1909                           pvolume_info->wsize));
1910                 cifs_sb->wsize = 4096;
1911         } else if (pvolume_info->wsize)
1912                 cifs_sb->wsize = pvolume_info->wsize;
1913         else
1914                 cifs_sb->wsize = min_t(const int,
1915                                         PAGEVEC_SIZE * PAGE_CACHE_SIZE,
1916                                         127*1024);
1917                 /* old default of CIFSMaxBufSize was too small now
1918                    that SMB Write2 can send multiple pages in kvec.
1919                    RFC1001 does not describe what happens when frame
1920                    bigger than 128K is sent so use that as max in
1921                    conjunction with 52K kvec constraint on arch with 4K
1922                    page size  */
1923
1924         if (cifs_sb->rsize < 2048) {
1925                 cifs_sb->rsize = 2048;
1926                 /* Windows ME may prefer this */
1927                 cFYI(1, ("readsize set to minimum: 2048"));
1928         }
1929         /* calculate prepath */
1930         cifs_sb->prepath = pvolume_info->prepath;
1931         if (cifs_sb->prepath) {
1932                 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
1933                 /* we can not convert the / to \ in the path
1934                 separators in the prefixpath yet because we do not
1935                 know (until reset_cifs_unix_caps is called later)
1936                 whether POSIX PATH CAP is available. We normalize
1937                 the / to \ after reset_cifs_unix_caps is called */
1938                 pvolume_info->prepath = NULL;
1939         } else
1940                 cifs_sb->prepathlen = 0;
1941         cifs_sb->mnt_uid = pvolume_info->linux_uid;
1942         cifs_sb->mnt_gid = pvolume_info->linux_gid;
1943         cifs_sb->mnt_file_mode = pvolume_info->file_mode;
1944         cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
1945         cFYI(1, ("file mode: 0x%x  dir mode: 0x%x",
1946                 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode));
1947
1948         if (pvolume_info->noperm)
1949                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
1950         if (pvolume_info->setuids)
1951                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
1952         if (pvolume_info->server_ino)
1953                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
1954         if (pvolume_info->remap)
1955                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
1956         if (pvolume_info->no_xattr)
1957                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
1958         if (pvolume_info->sfu_emul)
1959                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
1960         if (pvolume_info->nobrl)
1961                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
1962         if (pvolume_info->cifs_acl)
1963                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
1964         if (pvolume_info->override_uid)
1965                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
1966         if (pvolume_info->override_gid)
1967                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
1968         if (pvolume_info->dynperm)
1969                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
1970         if (pvolume_info->direct_io) {
1971                 cFYI(1, ("mounting share using direct i/o"));
1972                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
1973         }
1974
1975         if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
1976                 cERROR(1, ("mount option dynperm ignored if cifsacl "
1977                            "mount option supported"));
1978 }
1979
1980 int
1981 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
1982            char *mount_data, const char *devname)
1983 {
1984         int rc = 0;
1985         int xid;
1986         int address_type = AF_INET;
1987         struct socket *csocket = NULL;
1988         struct sockaddr_in sin_server;
1989         struct sockaddr_in6 sin_server6;
1990         struct smb_vol volume_info;
1991         struct cifsSesInfo *pSesInfo = NULL;
1992         struct cifsSesInfo *existingCifsSes = NULL;
1993         struct cifsTconInfo *tcon = NULL;
1994         struct TCP_Server_Info *srvTcp = NULL;
1995
1996         xid = GetXid();
1997
1998 /* cFYI(1, ("Entering cifs_mount. Xid: %d with: %s", xid, mount_data)); */
1999
2000         memset(&volume_info, 0, sizeof(struct smb_vol));
2001         if (cifs_parse_mount_options(mount_data, devname, &volume_info)) {
2002                 rc = -EINVAL;
2003                 goto out;
2004         }
2005
2006         if (volume_info.nullauth) {
2007                 cFYI(1, ("null user"));
2008                 volume_info.username = "";
2009         } else if (volume_info.username) {
2010                 /* BB fixme parse for domain name here */
2011                 cFYI(1, ("Username: %s", volume_info.username));
2012         } else {
2013                 cifserror("No username specified");
2014         /* In userspace mount helper we can get user name from alternate
2015            locations such as env variables and files on disk */
2016                 rc = -EINVAL;
2017                 goto out;
2018         }
2019
2020         if (volume_info.UNCip && volume_info.UNC) {
2021                 rc = cifs_inet_pton(AF_INET, volume_info.UNCip,
2022                                     &sin_server.sin_addr.s_addr);
2023
2024                 if (rc <= 0) {
2025                         /* not ipv4 address, try ipv6 */
2026                         rc = cifs_inet_pton(AF_INET6, volume_info.UNCip,
2027                                             &sin_server6.sin6_addr.in6_u);
2028                         if (rc > 0)
2029                                 address_type = AF_INET6;
2030                 } else {
2031                         address_type = AF_INET;
2032                 }
2033
2034                 if (rc <= 0) {
2035                         /* we failed translating address */
2036                         rc = -EINVAL;
2037                         goto out;
2038                 }
2039
2040                 cFYI(1, ("UNC: %s ip: %s", volume_info.UNC, volume_info.UNCip));
2041                 /* success */
2042                 rc = 0;
2043         } else if (volume_info.UNCip) {
2044                 /* BB using ip addr as server name to connect to the
2045                    DFS root below */
2046                 cERROR(1, ("Connecting to DFS root not implemented yet"));
2047                 rc = -EINVAL;
2048                 goto out;
2049         } else /* which servers DFS root would we conect to */ {
2050                 cERROR(1,
2051                        ("CIFS mount error: No UNC path (e.g. -o "
2052                         "unc=//192.168.1.100/public) specified"));
2053                 rc = -EINVAL;
2054                 goto out;
2055         }
2056
2057         /* this is needed for ASCII cp to Unicode converts */
2058         if (volume_info.iocharset == NULL) {
2059                 cifs_sb->local_nls = load_nls_default();
2060         /* load_nls_default can not return null */
2061         } else {
2062                 cifs_sb->local_nls = load_nls(volume_info.iocharset);
2063                 if (cifs_sb->local_nls == NULL) {
2064                         cERROR(1, ("CIFS mount error: iocharset %s not found",
2065                                  volume_info.iocharset));
2066                         rc = -ELIBACC;
2067                         goto out;
2068                 }
2069         }
2070
2071         if (address_type == AF_INET)
2072                 existingCifsSes = cifs_find_tcp_session(&sin_server.sin_addr,
2073                         NULL /* no ipv6 addr */,
2074                         volume_info.username, &srvTcp);
2075         else if (address_type == AF_INET6) {
2076                 cFYI(1, ("looking for ipv6 address"));
2077                 existingCifsSes = cifs_find_tcp_session(NULL /* no ipv4 addr */,
2078                         &sin_server6.sin6_addr,
2079                         volume_info.username, &srvTcp);
2080         } else {
2081                 rc = -EINVAL;
2082                 goto out;
2083         }
2084
2085         if (!srvTcp) {  /* create socket */
2086                 if (volume_info.port)
2087                         sin_server.sin_port = htons(volume_info.port);
2088                 else
2089                         sin_server.sin_port = 0;
2090                 if (address_type == AF_INET6) {
2091                         cFYI(1, ("attempting ipv6 connect"));
2092                         /* BB should we allow ipv6 on port 139? */
2093                         /* other OS never observed in Wild doing 139 with v6 */
2094                         rc = ipv6_connect(&sin_server6, &csocket,
2095                                         volume_info.noblocksnd);
2096                 } else
2097                         rc = ipv4_connect(&sin_server, &csocket,
2098                                   volume_info.source_rfc1001_name,
2099                                   volume_info.target_rfc1001_name,
2100                                   volume_info.noblocksnd,
2101                                   volume_info.noautotune);
2102                 if (rc < 0) {
2103                         cERROR(1, ("Error connecting to IPv4 socket. "
2104                                    "Aborting operation"));
2105                         if (csocket != NULL)
2106                                 sock_release(csocket);
2107                         goto out;
2108                 }
2109
2110                 srvTcp = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
2111                 if (!srvTcp) {
2112                         rc = -ENOMEM;
2113                         sock_release(csocket);
2114                         goto out;
2115                 } else {
2116                         srvTcp->noblocksnd = volume_info.noblocksnd;
2117                         srvTcp->noautotune = volume_info.noautotune;
2118                         memcpy(&srvTcp->addr.sockAddr, &sin_server,
2119                                 sizeof(struct sockaddr_in));
2120                         atomic_set(&srvTcp->inFlight, 0);
2121                         /* BB Add code for ipv6 case too */
2122                         srvTcp->ssocket = csocket;
2123                         srvTcp->protocolType = IPV4;
2124                         srvTcp->hostname = extract_hostname(volume_info.UNC);
2125                         if (IS_ERR(srvTcp->hostname)) {
2126                                 rc = PTR_ERR(srvTcp->hostname);
2127                                 sock_release(csocket);
2128                                 goto out;
2129                         }
2130                         init_waitqueue_head(&srvTcp->response_q);
2131                         init_waitqueue_head(&srvTcp->request_q);
2132                         INIT_LIST_HEAD(&srvTcp->pending_mid_q);
2133                         /* at this point we are the only ones with the pointer
2134                         to the struct since the kernel thread not created yet
2135                         so no need to spinlock this init of tcpStatus */
2136                         srvTcp->tcpStatus = CifsNew;
2137                         init_MUTEX(&srvTcp->tcpSem);
2138                         srvTcp->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread, srvTcp, "cifsd");
2139                         if (IS_ERR(srvTcp->tsk)) {
2140                                 rc = PTR_ERR(srvTcp->tsk);
2141                                 cERROR(1, ("error %d create cifsd thread", rc));
2142                                 srvTcp->tsk = NULL;
2143                                 sock_release(csocket);
2144                                 kfree(srvTcp->hostname);
2145                                 goto out;
2146                         }
2147                         rc = 0;
2148                         memcpy(srvTcp->workstation_RFC1001_name,
2149                                 volume_info.source_rfc1001_name, 16);
2150                         memcpy(srvTcp->server_RFC1001_name,
2151                                 volume_info.target_rfc1001_name, 16);
2152                         srvTcp->sequence_number = 0;
2153                 }
2154         }
2155
2156         if (existingCifsSes) {
2157                 pSesInfo = existingCifsSes;
2158                 cFYI(1, ("Existing smb sess found (status=%d)",
2159                         pSesInfo->status));
2160                 down(&pSesInfo->sesSem);
2161                 if (pSesInfo->need_reconnect) {
2162                         cFYI(1, ("Session needs reconnect"));
2163                         rc = cifs_setup_session(xid, pSesInfo,
2164                                                 cifs_sb->local_nls);
2165                 }
2166                 up(&pSesInfo->sesSem);
2167         } else if (!rc) {
2168                 cFYI(1, ("Existing smb sess not found"));
2169                 pSesInfo = sesInfoAlloc();
2170                 if (pSesInfo == NULL)
2171                         rc = -ENOMEM;
2172                 else {
2173                         pSesInfo->server = srvTcp;
2174                         sprintf(pSesInfo->serverName, "%u.%u.%u.%u",
2175                                 NIPQUAD(sin_server.sin_addr.s_addr));
2176                 }
2177
2178                 if (!rc) {
2179                         /* volume_info.password freed at unmount */
2180                         if (volume_info.password) {
2181                                 pSesInfo->password = volume_info.password;
2182                                 /* set to NULL to prevent freeing on exit */
2183                                 volume_info.password = NULL;
2184                         }
2185                         if (volume_info.username)
2186                                 strncpy(pSesInfo->userName,
2187                                         volume_info.username,
2188                                         MAX_USERNAME_SIZE);
2189                         if (volume_info.domainname) {
2190                                 int len = strlen(volume_info.domainname);
2191                                 pSesInfo->domainName =
2192                                         kmalloc(len + 1, GFP_KERNEL);
2193                                 if (pSesInfo->domainName)
2194                                         strcpy(pSesInfo->domainName,
2195                                                 volume_info.domainname);
2196                         }
2197                         pSesInfo->linux_uid = volume_info.linux_uid;
2198                         pSesInfo->overrideSecFlg = volume_info.secFlg;
2199                         down(&pSesInfo->sesSem);
2200                         /* BB FIXME need to pass vol->secFlgs BB */
2201                         rc = cifs_setup_session(xid, pSesInfo,
2202                                                 cifs_sb->local_nls);
2203                         up(&pSesInfo->sesSem);
2204                         if (!rc)
2205                                 atomic_inc(&srvTcp->socketUseCount);
2206                 }
2207         }
2208
2209         /* search for existing tcon to this server share */
2210         if (!rc) {
2211                 setup_cifs_sb(&volume_info, cifs_sb);
2212
2213                 tcon =
2214                     find_unc(sin_server.sin_addr.s_addr, volume_info.UNC,
2215                              volume_info.username);
2216                 if (tcon) {
2217                         cFYI(1, ("Found match on UNC path"));
2218                         if (tcon->seal != volume_info.seal)
2219                                 cERROR(1, ("transport encryption setting "
2220                                            "conflicts with existing tid"));
2221                 } else {
2222                         tcon = tconInfoAlloc();
2223                         if (tcon == NULL) {
2224                                 rc = -ENOMEM;
2225                                 goto mount_fail_check;
2226                         }
2227
2228                         /* check for null share name ie connect to dfs root */
2229
2230                         /* BB check if works for exactly length 3 strings */
2231                         if ((strchr(volume_info.UNC + 3, '\\') == NULL)
2232                             && (strchr(volume_info.UNC + 3, '/') == NULL)) {
2233                                 /* rc = connect_to_dfs_path(...) */
2234                                 cFYI(1, ("DFS root not supported"));
2235                                 rc = -ENODEV;
2236                                 goto mount_fail_check;
2237                         } else {
2238                                 /* BB Do we need to wrap sesSem around
2239                                  * this TCon call and Unix SetFS as
2240                                  * we do on SessSetup and reconnect? */
2241                                 rc = CIFSTCon(xid, pSesInfo, volume_info.UNC,
2242                                               tcon, cifs_sb->local_nls);
2243                                 cFYI(1, ("CIFS Tcon rc = %d", rc));
2244                                 if (volume_info.nodfs) {
2245                                         tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
2246                                         cFYI(1, ("DFS disabled (%d)",
2247                                                 tcon->Flags));
2248                                 }
2249                         }
2250                         if (!rc) {
2251                                 atomic_inc(&pSesInfo->inUse);
2252                                 tcon->seal = volume_info.seal;
2253                         } else
2254                                 goto mount_fail_check;
2255                 }
2256
2257                 /* we can have only one retry value for a connection
2258                    to a share so for resources mounted more than once
2259                    to the same server share the last value passed in
2260                    for the retry flag is used */
2261                 tcon->retry = volume_info.retry;
2262                 tcon->nocase = volume_info.nocase;
2263                 tcon->local_lease = volume_info.local_lease;
2264         }
2265         if (pSesInfo) {
2266                 if (pSesInfo->capabilities & CAP_LARGE_FILES) {
2267                         sb->s_maxbytes = (u64) 1 << 63;
2268                 } else
2269                         sb->s_maxbytes = (u64) 1 << 31; /* 2 GB */
2270         }
2271
2272         /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2273         sb->s_time_gran = 100;
2274
2275 /* on error free sesinfo and tcon struct if needed */
2276 mount_fail_check:
2277         if (rc) {
2278                 /* if session setup failed, use count is zero but
2279                 we still need to free cifsd thread */
2280                 if (atomic_read(&srvTcp->socketUseCount) == 0) {
2281                         spin_lock(&GlobalMid_Lock);
2282                         srvTcp->tcpStatus = CifsExiting;
2283                         spin_unlock(&GlobalMid_Lock);
2284                         kill_cifsd(srvTcp);
2285                 }
2286                  /* If find_unc succeeded then rc == 0 so we can not end */
2287                 if (tcon)  /* up accidently freeing someone elses tcon struct */
2288                         tconInfoFree(tcon);
2289                 if (existingCifsSes == NULL) {
2290                         if (pSesInfo) {
2291                                 if ((pSesInfo->server) &&
2292                                     (pSesInfo->status == CifsGood)) {
2293                                         int temp_rc;
2294                                         temp_rc = CIFSSMBLogoff(xid, pSesInfo);
2295                                         /* if the socketUseCount is now zero */
2296                                         if ((temp_rc == -ESHUTDOWN) &&
2297                                             (pSesInfo->server))
2298                                                 kill_cifsd(pSesInfo->server);
2299                                 } else {
2300                                         cFYI(1, ("No session or bad tcon"));
2301                                         if (pSesInfo->server) {
2302                                                 spin_lock(&GlobalMid_Lock);
2303                                                 srvTcp->tcpStatus = CifsExiting;
2304                                                 spin_unlock(&GlobalMid_Lock);
2305                                                 kill_cifsd(pSesInfo->server);
2306                                         }
2307                                 }
2308                                 sesInfoFree(pSesInfo);
2309                                 /* pSesInfo = NULL; */
2310                         }
2311                 }
2312         } else {
2313                 atomic_inc(&tcon->useCount);
2314                 cifs_sb->tcon = tcon;
2315                 tcon->ses = pSesInfo;
2316
2317                 /* do not care if following two calls succeed - informational */
2318                 if (!tcon->ipc) {
2319                         CIFSSMBQFSDeviceInfo(xid, tcon);
2320                         CIFSSMBQFSAttributeInfo(xid, tcon);
2321                 }
2322
2323                 /* tell server which Unix caps we support */
2324                 if (tcon->ses->capabilities & CAP_UNIX)
2325                         /* reset of caps checks mount to see if unix extensions
2326                            disabled for just this mount */
2327                         reset_cifs_unix_caps(xid, tcon, sb, &volume_info);
2328                 else
2329                         tcon->unix_ext = 0; /* server does not support them */
2330
2331                 /* convert forward to back slashes in prepath here if needed */
2332                 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2333                         convert_delimiter(cifs_sb->prepath,
2334                                           CIFS_DIR_SEP(cifs_sb));
2335
2336                 if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2337                         cifs_sb->rsize = 1024 * 127;
2338                         cFYI(DBG2,
2339                                 ("no very large read support, rsize now 127K"));
2340                 }
2341                 if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2342                         cifs_sb->wsize = min(cifs_sb->wsize,
2343                                              (tcon->ses->server->maxBuf -
2344                                               MAX_CIFS_HDR_SIZE));
2345                 if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2346                         cifs_sb->rsize = min(cifs_sb->rsize,
2347                                              (tcon->ses->server->maxBuf -
2348                                               MAX_CIFS_HDR_SIZE));
2349         }
2350
2351         /* volume_info.password is freed above when existing session found
2352         (in which case it is not needed anymore) but when new sesion is created
2353         the password ptr is put in the new session structure (in which case the
2354         password will be freed at unmount time) */
2355 out:
2356         /* zero out password before freeing */
2357         if (volume_info.password != NULL) {
2358                 memset(volume_info.password, 0, strlen(volume_info.password));
2359                 kfree(volume_info.password);
2360         }
2361         kfree(volume_info.UNC);
2362         kfree(volume_info.prepath);
2363         FreeXid(xid);
2364         return rc;
2365 }
2366
2367 static int
2368 CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
2369               char session_key[CIFS_SESS_KEY_SIZE],
2370               const struct nls_table *nls_codepage)
2371 {
2372         struct smb_hdr *smb_buffer;
2373         struct smb_hdr *smb_buffer_response;
2374         SESSION_SETUP_ANDX *pSMB;
2375         SESSION_SETUP_ANDX *pSMBr;
2376         char *bcc_ptr;
2377         char *user;
2378         char *domain;
2379         int rc = 0;
2380         int remaining_words = 0;
2381         int bytes_returned = 0;
2382         int len;
2383         __u32 capabilities;
2384         __u16 count;
2385
2386         cFYI(1, ("In sesssetup"));
2387         if (ses == NULL)
2388                 return -EINVAL;
2389         user = ses->userName;
2390         domain = ses->domainName;
2391         smb_buffer = cifs_buf_get();
2392
2393         if (smb_buffer == NULL)
2394                 return -ENOMEM;
2395
2396         smb_buffer_response = smb_buffer;
2397         pSMBr = pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2398
2399         /* send SMBsessionSetup here */
2400         header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2401                         NULL /* no tCon exists yet */ , 13 /* wct */ );
2402
2403         smb_buffer->Mid = GetNextMid(ses->server);
2404         pSMB->req_no_secext.AndXCommand = 0xFF;
2405         pSMB->req_no_secext.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2406         pSMB->req_no_secext.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2407
2408         if (ses->server->secMode &
2409                         (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2410                 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2411
2412         capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2413                 CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
2414         if (ses->capabilities & CAP_UNICODE) {
2415                 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2416                 capabilities |= CAP_UNICODE;
2417         }
2418         if (ses->capabilities & CAP_STATUS32) {
2419                 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2420                 capabilities |= CAP_STATUS32;
2421         }
2422         if (ses->capabilities & CAP_DFS) {
2423                 smb_buffer->Flags2 |= SMBFLG2_DFS;
2424                 capabilities |= CAP_DFS;
2425         }
2426         pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
2427
2428         pSMB->req_no_secext.CaseInsensitivePasswordLength =
2429                 cpu_to_le16(CIFS_SESS_KEY_SIZE);
2430
2431         pSMB->req_no_secext.CaseSensitivePasswordLength =
2432             cpu_to_le16(CIFS_SESS_KEY_SIZE);
2433         bcc_ptr = pByteArea(smb_buffer);
2434         memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2435         bcc_ptr += CIFS_SESS_KEY_SIZE;
2436         memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
2437         bcc_ptr += CIFS_SESS_KEY_SIZE;
2438
2439         if (ses->capabilities & CAP_UNICODE) {
2440                 if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
2441                         *bcc_ptr = 0;
2442                         bcc_ptr++;
2443                 }
2444                 if (user == NULL)
2445                         bytes_returned = 0; /* skip null user */
2446                 else
2447                         bytes_returned =
2448                                 cifs_strtoUCS((__le16 *) bcc_ptr, user, 100,
2449                                         nls_codepage);
2450                 /* convert number of 16 bit words to bytes */
2451                 bcc_ptr += 2 * bytes_returned;
2452                 bcc_ptr += 2;   /* trailing null */
2453                 if (domain == NULL)
2454                         bytes_returned =
2455                             cifs_strtoUCS((__le16 *) bcc_ptr,
2456                                           "CIFS_LINUX_DOM", 32, nls_codepage);
2457                 else
2458                         bytes_returned =
2459                             cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
2460                                           nls_codepage);
2461                 bcc_ptr += 2 * bytes_returned;
2462                 bcc_ptr += 2;
2463                 bytes_returned =
2464                     cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2465                                   32, nls_codepage);
2466                 bcc_ptr += 2 * bytes_returned;
2467                 bytes_returned =
2468                     cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release,
2469                                   32, nls_codepage);
2470                 bcc_ptr += 2 * bytes_returned;
2471                 bcc_ptr += 2;
2472                 bytes_returned =
2473                     cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2474                                   64, nls_codepage);
2475                 bcc_ptr += 2 * bytes_returned;
2476                 bcc_ptr += 2;
2477         } else {
2478                 if (user != NULL) {
2479                     strncpy(bcc_ptr, user, 200);
2480                     bcc_ptr += strnlen(user, 200);
2481                 }
2482                 *bcc_ptr = 0;
2483                 bcc_ptr++;
2484                 if (domain == NULL) {
2485                         strcpy(bcc_ptr, "CIFS_LINUX_DOM");
2486                         bcc_ptr += strlen("CIFS_LINUX_DOM") + 1;
2487                 } else {
2488                         strncpy(bcc_ptr, domain, 64);
2489                         bcc_ptr += strnlen(domain, 64);
2490                         *bcc_ptr = 0;
2491                         bcc_ptr++;
2492                 }
2493                 strcpy(bcc_ptr, "Linux version ");
2494                 bcc_ptr += strlen("Linux version ");
2495                 strcpy(bcc_ptr, utsname()->release);
2496                 bcc_ptr += strlen(utsname()->release) + 1;
2497                 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2498                 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2499         }
2500         count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2501         smb_buffer->smb_buf_length += count;
2502         pSMB->req_no_secext.ByteCount = cpu_to_le16(count);
2503
2504         rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2505                          &bytes_returned, CIFS_LONG_OP);
2506         if (rc) {
2507 /* rc = map_smb_to_linux_error(smb_buffer_response); now done in SendReceive */
2508         } else if ((smb_buffer_response->WordCount == 3)
2509                    || (smb_buffer_response->WordCount == 4)) {
2510                 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2511                 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2512                 if (action & GUEST_LOGIN)
2513                         cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
2514                 ses->Suid = smb_buffer_response->Uid; /* UID left in wire format
2515                                                          (little endian) */
2516                 cFYI(1, ("UID = %d ", ses->Suid));
2517         /* response can have either 3 or 4 word count - Samba sends 3 */
2518                 bcc_ptr = pByteArea(smb_buffer_response);
2519                 if ((pSMBr->resp.hdr.WordCount == 3)
2520                     || ((pSMBr->resp.hdr.WordCount == 4)
2521                         && (blob_len < pSMBr->resp.ByteCount))) {
2522                         if (pSMBr->resp.hdr.WordCount == 4)
2523                                 bcc_ptr += blob_len;
2524
2525                         if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2526                                 if ((long) (bcc_ptr) % 2) {
2527                                         remaining_words =
2528                                             (BCC(smb_buffer_response) - 1) / 2;
2529                                         /* Unicode strings must be word
2530                                            aligned */
2531                                         bcc_ptr++;
2532                                 } else {
2533                                         remaining_words =
2534                                                 BCC(smb_buffer_response) / 2;
2535                                 }
2536                                 len =
2537                                     UniStrnlen((wchar_t *) bcc_ptr,
2538                                                remaining_words - 1);
2539 /* We look for obvious messed up bcc or strings in response so we do not go off
2540    the end since (at least) WIN2K and Windows XP have a major bug in not null
2541    terminating last Unicode string in response  */
2542                                 if (ses->serverOS)
2543                                         kfree(ses->serverOS);
2544                                 ses->serverOS = kzalloc(2 * (len + 1),
2545                                                         GFP_KERNEL);
2546                                 if (ses->serverOS == NULL)
2547                                         goto sesssetup_nomem;
2548                                 cifs_strfromUCS_le(ses->serverOS,
2549                                                    (__le16 *)bcc_ptr,
2550                                                    len, nls_codepage);
2551                                 bcc_ptr += 2 * (len + 1);
2552                                 remaining_words -= len + 1;
2553                                 ses->serverOS[2 * len] = 0;
2554                                 ses->serverOS[1 + (2 * len)] = 0;
2555                                 if (remaining_words > 0) {
2556                                         len = UniStrnlen((wchar_t *)bcc_ptr,
2557                                                          remaining_words-1);
2558                                         kfree(ses->serverNOS);
2559                                         ses->serverNOS = kzalloc(2 * (len + 1),
2560                                                                  GFP_KERNEL);
2561                                         if (ses->serverNOS == NULL)
2562                                                 goto sesssetup_nomem;
2563                                         cifs_strfromUCS_le(ses->serverNOS,
2564                                                            (__le16 *)bcc_ptr,
2565                                                            len, nls_codepage);
2566                                         bcc_ptr += 2 * (len + 1);
2567                                         ses->serverNOS[2 * len] = 0;
2568                                         ses->serverNOS[1 + (2 * len)] = 0;
2569                                         if (strncmp(ses->serverNOS,
2570                                                 "NT LAN Manager 4", 16) == 0) {
2571                                                 cFYI(1, ("NT4 server"));
2572                                                 ses->flags |= CIFS_SES_NT4;
2573                                         }
2574                                         remaining_words -= len + 1;
2575                                         if (remaining_words > 0) {
2576                                                 len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2577                                 /* last string is not always null terminated
2578                                    (for e.g. for Windows XP & 2000) */
2579                                                 if (ses->serverDomain)
2580                                                         kfree(ses->serverDomain);
2581                                                 ses->serverDomain =
2582                                                     kzalloc(2*(len+1),
2583                                                             GFP_KERNEL);
2584                                                 if (ses->serverDomain == NULL)
2585                                                         goto sesssetup_nomem;
2586                                                 cifs_strfromUCS_le(ses->serverDomain,
2587                                                         (__le16 *)bcc_ptr,
2588                                                         len, nls_codepage);
2589                                                 bcc_ptr += 2 * (len + 1);
2590                                                 ses->serverDomain[2*len] = 0;
2591                                                 ses->serverDomain[1+(2*len)] = 0;
2592                                         } else { /* else no more room so create
2593                                                   dummy domain string */
2594                                                 if (ses->serverDomain)
2595                                                         kfree(ses->serverDomain);
2596                                                 ses->serverDomain =
2597                                                         kzalloc(2, GFP_KERNEL);
2598                                         }
2599                                 } else { /* no room so create dummy domain
2600                                             and NOS string */
2601
2602                                         /* if these kcallocs fail not much we
2603                                            can do, but better to not fail the
2604                                            sesssetup itself */
2605                                         kfree(ses->serverDomain);
2606                                         ses->serverDomain =
2607                                             kzalloc(2, GFP_KERNEL);
2608                                         kfree(ses->serverNOS);
2609                                         ses->serverNOS =
2610                                             kzalloc(2, GFP_KERNEL);
2611                                 }
2612                         } else {        /* ASCII */
2613                                 len = strnlen(bcc_ptr, 1024);
2614                                 if (((long) bcc_ptr + len) - (long)
2615                                     pByteArea(smb_buffer_response)
2616                                             <= BCC(smb_buffer_response)) {
2617                                         kfree(ses->serverOS);
2618                                         ses->serverOS = kzalloc(len + 1,
2619                                                                 GFP_KERNEL);
2620                                         if (ses->serverOS == NULL)
2621                                                 goto sesssetup_nomem;
2622                                         strncpy(ses->serverOS, bcc_ptr, len);
2623
2624                                         bcc_ptr += len;
2625                                         /* null terminate the string */
2626                                         bcc_ptr[0] = 0;
2627                                         bcc_ptr++;
2628
2629                                         len = strnlen(bcc_ptr, 1024);
2630                                         kfree(ses->serverNOS);
2631                                         ses->serverNOS = kzalloc(len + 1,
2632                                                                  GFP_KERNEL);
2633                                         if (ses->serverNOS == NULL)
2634                                                 goto sesssetup_nomem;
2635                                         strncpy(ses->serverNOS, bcc_ptr, len);
2636                                         bcc_ptr += len;
2637                                         bcc_ptr[0] = 0;
2638                                         bcc_ptr++;
2639
2640                                         len = strnlen(bcc_ptr, 1024);
2641                                         if (ses->serverDomain)
2642                                                 kfree(ses->serverDomain);
2643                                         ses->serverDomain = kzalloc(len + 1,
2644                                                                     GFP_KERNEL);
2645                                         if (ses->serverDomain == NULL)
2646                                                 goto sesssetup_nomem;
2647                                         strncpy(ses->serverDomain, bcc_ptr,
2648                                                 len);
2649                                         bcc_ptr += len;
2650                                         bcc_ptr[0] = 0;
2651                                         bcc_ptr++;
2652                                 } else
2653                                         cFYI(1,
2654                                              ("Variable field of length %d "
2655                                                 "extends beyond end of smb ",
2656                                               len));
2657                         }
2658                 } else {
2659                         cERROR(1,
2660                                (" Security Blob Length extends beyond "
2661                                 "end of SMB"));
2662                 }
2663         } else {
2664                 cERROR(1,
2665                        (" Invalid Word count %d: ",
2666                         smb_buffer_response->WordCount));
2667                 rc = -EIO;
2668         }
2669 sesssetup_nomem:        /* do not return an error on nomem for the info strings,
2670                            since that could make reconnection harder, and
2671                            reconnection might be needed to free memory */
2672         cifs_buf_release(smb_buffer);
2673
2674         return rc;
2675 }
2676
2677 static int
2678 CIFSNTLMSSPNegotiateSessSetup(unsigned int xid,
2679                               struct cifsSesInfo *ses, bool *pNTLMv2_flag,
2680                               const struct nls_table *nls_codepage)
2681 {
2682         struct smb_hdr *smb_buffer;
2683         struct smb_hdr *smb_buffer_response;
2684         SESSION_SETUP_ANDX *pSMB;
2685         SESSION_SETUP_ANDX *pSMBr;
2686         char *bcc_ptr;
2687         char *domain;
2688         int rc = 0;
2689         int remaining_words = 0;
2690         int bytes_returned = 0;
2691         int len;
2692         int SecurityBlobLength = sizeof(NEGOTIATE_MESSAGE);
2693         PNEGOTIATE_MESSAGE SecurityBlob;
2694         PCHALLENGE_MESSAGE SecurityBlob2;
2695         __u32 negotiate_flags, capabilities;
2696         __u16 count;
2697
2698         cFYI(1, ("In NTLMSSP sesssetup (negotiate)"));
2699         if (ses == NULL)
2700                 return -EINVAL;
2701         domain = ses->domainName;
2702         *pNTLMv2_flag = false;
2703         smb_buffer = cifs_buf_get();
2704         if (smb_buffer == NULL) {
2705                 return -ENOMEM;
2706         }
2707         smb_buffer_response = smb_buffer;
2708         pSMB = (SESSION_SETUP_ANDX *) smb_buffer;
2709         pSMBr = (SESSION_SETUP_ANDX *) smb_buffer_response;
2710
2711         /* send SMBsessionSetup here */
2712         header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
2713                         NULL /* no tCon exists yet */ , 12 /* wct */ );
2714
2715         smb_buffer->Mid = GetNextMid(ses->server);
2716         pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
2717         pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
2718
2719         pSMB->req.AndXCommand = 0xFF;
2720         pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
2721         pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
2722
2723         if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2724                 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2725
2726         capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
2727             CAP_EXTENDED_SECURITY;
2728         if (ses->capabilities & CAP_UNICODE) {
2729                 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2730                 capabilities |= CAP_UNICODE;
2731         }
2732         if (ses->capabilities & CAP_STATUS32) {
2733                 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2734                 capabilities |= CAP_STATUS32;
2735         }
2736         if (ses->capabilities & CAP_DFS) {
2737                 smb_buffer->Flags2 |= SMBFLG2_DFS;
2738                 capabilities |= CAP_DFS;
2739         }
2740         pSMB->req.Capabilities = cpu_to_le32(capabilities);
2741
2742         bcc_ptr = (char *) &pSMB->req.SecurityBlob;
2743         SecurityBlob = (PNEGOTIATE_MESSAGE) bcc_ptr;
2744         strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
2745         SecurityBlob->MessageType = NtLmNegotiate;
2746         negotiate_flags =
2747             NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM |
2748             NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_NTLM |
2749             NTLMSSP_NEGOTIATE_56 |
2750             /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN | */ NTLMSSP_NEGOTIATE_128;
2751         if (sign_CIFS_PDUs)
2752                 negotiate_flags |= NTLMSSP_NEGOTIATE_SIGN;
2753 /*      if (ntlmv2_support)
2754                 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;*/
2755         /* setup pointers to domain name and workstation name */
2756         bcc_ptr += SecurityBlobLength;
2757
2758         SecurityBlob->WorkstationName.Buffer = 0;
2759         SecurityBlob->WorkstationName.Length = 0;
2760         SecurityBlob->WorkstationName.MaximumLength = 0;
2761
2762         /* Domain not sent on first Sesssetup in NTLMSSP, instead it is sent
2763         along with username on auth request (ie the response to challenge) */
2764         SecurityBlob->DomainName.Buffer = 0;
2765         SecurityBlob->DomainName.Length = 0;
2766         SecurityBlob->DomainName.MaximumLength = 0;
2767         if (ses->capabilities & CAP_UNICODE) {
2768                 if ((long) bcc_ptr % 2) {
2769                         *bcc_ptr = 0;
2770                         bcc_ptr++;
2771                 }
2772
2773                 bytes_returned =
2774                     cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
2775                                   32, nls_codepage);
2776                 bcc_ptr += 2 * bytes_returned;
2777                 bytes_returned =
2778                     cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
2779                                   nls_codepage);
2780                 bcc_ptr += 2 * bytes_returned;
2781                 bcc_ptr += 2;   /* null terminate Linux version */
2782                 bytes_returned =
2783                     cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
2784                                   64, nls_codepage);
2785                 bcc_ptr += 2 * bytes_returned;
2786                 *(bcc_ptr + 1) = 0;
2787                 *(bcc_ptr + 2) = 0;
2788                 bcc_ptr += 2;   /* null terminate network opsys string */
2789                 *(bcc_ptr + 1) = 0;
2790                 *(bcc_ptr + 2) = 0;
2791                 bcc_ptr += 2;   /* null domain */
2792         } else {                /* ASCII */
2793                 strcpy(bcc_ptr, "Linux version ");
2794                 bcc_ptr += strlen("Linux version ");
2795                 strcpy(bcc_ptr, utsname()->release);
2796                 bcc_ptr += strlen(utsname()->release) + 1;
2797                 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
2798                 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
2799                 bcc_ptr++;      /* empty domain field */
2800                 *bcc_ptr = 0;
2801         }
2802         SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
2803         pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
2804         count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
2805         smb_buffer->smb_buf_length += count;
2806         pSMB->req.ByteCount = cpu_to_le16(count);
2807
2808         rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
2809                          &bytes_returned, CIFS_LONG_OP);
2810
2811         if (smb_buffer_response->Status.CifsError ==
2812             cpu_to_le32(NT_STATUS_MORE_PROCESSING_REQUIRED))
2813                 rc = 0;
2814
2815         if (rc) {
2816 /*    rc = map_smb_to_linux_error(smb_buffer_response);  *//* done in SendReceive now */
2817         } else if ((smb_buffer_response->WordCount == 3)
2818                    || (smb_buffer_response->WordCount == 4)) {
2819                 __u16 action = le16_to_cpu(pSMBr->resp.Action);
2820                 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
2821
2822                 if (action & GUEST_LOGIN)
2823                         cFYI(1, (" Guest login"));
2824         /* Do we want to set anything in SesInfo struct when guest login? */
2825
2826                 bcc_ptr = pByteArea(smb_buffer_response);
2827         /* response can have either 3 or 4 word count - Samba sends 3 */
2828
2829                 SecurityBlob2 = (PCHALLENGE_MESSAGE) bcc_ptr;
2830                 if (SecurityBlob2->MessageType != NtLmChallenge) {
2831                         cFYI(1,
2832                              ("Unexpected NTLMSSP message type received %d",
2833                               SecurityBlob2->MessageType));
2834                 } else if (ses) {
2835                         ses->Suid = smb_buffer_response->Uid; /* UID left in le format */
2836                         cFYI(1, ("UID = %d", ses->Suid));
2837                         if ((pSMBr->resp.hdr.WordCount == 3)
2838                             || ((pSMBr->resp.hdr.WordCount == 4)
2839                                 && (blob_len <
2840                                     pSMBr->resp.ByteCount))) {
2841
2842                                 if (pSMBr->resp.hdr.WordCount == 4) {
2843                                         bcc_ptr += blob_len;
2844                                         cFYI(1, ("Security Blob Length %d",
2845                                               blob_len));
2846                                 }
2847
2848                                 cFYI(1, ("NTLMSSP Challenge rcvd"));
2849
2850                                 memcpy(ses->server->cryptKey,
2851                                        SecurityBlob2->Challenge,
2852                                        CIFS_CRYPTO_KEY_SIZE);
2853                                 if (SecurityBlob2->NegotiateFlags &
2854                                         cpu_to_le32(NTLMSSP_NEGOTIATE_NTLMV2))
2855                                         *pNTLMv2_flag = true;
2856
2857                                 if ((SecurityBlob2->NegotiateFlags &
2858                                         cpu_to_le32(NTLMSSP_NEGOTIATE_ALWAYS_SIGN))
2859                                         || (sign_CIFS_PDUs > 1))
2860                                                 ses->server->secMode |=
2861                                                         SECMODE_SIGN_REQUIRED;
2862                                 if ((SecurityBlob2->NegotiateFlags &
2863                                         cpu_to_le32(NTLMSSP_NEGOTIATE_SIGN)) && (sign_CIFS_PDUs))
2864                                                 ses->server->secMode |=
2865                                                         SECMODE_SIGN_ENABLED;
2866
2867                                 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
2868                                         if ((long) (bcc_ptr) % 2) {
2869                                                 remaining_words =
2870                                                     (BCC(smb_buffer_response)
2871                                                      - 1) / 2;
2872                                          /* Must word align unicode strings */
2873                                                 bcc_ptr++;
2874                                         } else {
2875                                                 remaining_words =
2876                                                     BCC
2877                                                     (smb_buffer_response) / 2;
2878                                         }
2879                                         len =
2880                                             UniStrnlen((wchar_t *) bcc_ptr,
2881                                                        remaining_words - 1);
2882 /* We look for obvious messed up bcc or strings in response so we do not go off
2883    the end since (at least) WIN2K and Windows XP have a major bug in not null
2884    terminating last Unicode string in response  */
2885                                         if (ses->serverOS)
2886                                                 kfree(ses->serverOS);
2887                                         ses->serverOS =
2888                                             kzalloc(2 * (len + 1), GFP_KERNEL);
2889                                         cifs_strfromUCS_le(ses->serverOS,
2890                                                            (__le16 *)
2891                                                            bcc_ptr, len,
2892                                                            nls_codepage);
2893                                         bcc_ptr += 2 * (len + 1);
2894                                         remaining_words -= len + 1;
2895                                         ses->serverOS[2 * len] = 0;
2896                                         ses->serverOS[1 + (2 * len)] = 0;
2897                                         if (remaining_words > 0) {
2898                                                 len = UniStrnlen((wchar_t *)
2899                                                                  bcc_ptr,
2900                                                                  remaining_words
2901                                                                  - 1);
2902                                                 kfree(ses->serverNOS);
2903                                                 ses->serverNOS =
2904                                                     kzalloc(2 * (len + 1),
2905                                                             GFP_KERNEL);
2906                                                 cifs_strfromUCS_le(ses->
2907                                                                    serverNOS,
2908                                                                    (__le16 *)
2909                                                                    bcc_ptr,
2910                                                                    len,
2911                                                                    nls_codepage);
2912                                                 bcc_ptr += 2 * (len + 1);
2913                                                 ses->serverNOS[2 * len] = 0;
2914                                                 ses->serverNOS[1 +
2915                                                                (2 * len)] = 0;
2916                                                 remaining_words -= len + 1;
2917                                                 if (remaining_words > 0) {
2918                                                         len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
2919                                 /* last string not always null terminated
2920                                    (for e.g. for Windows XP & 2000) */
2921                                                         kfree(ses->serverDomain);
2922                                                         ses->serverDomain =
2923                                                             kzalloc(2 *
2924                                                                     (len +
2925                                                                      1),
2926                                                                     GFP_KERNEL);
2927                                                         cifs_strfromUCS_le
2928                                                             (ses->serverDomain,
2929                                                              (__le16 *)bcc_ptr,
2930                                                              len, nls_codepage);
2931                                                         bcc_ptr +=
2932                                                             2 * (len + 1);
2933                                                         ses->serverDomain[2*len]
2934                                                             = 0;
2935                                                         ses->serverDomain
2936                                                                 [1 + (2 * len)]
2937                                                             = 0;
2938                                                 } /* else no more room so create dummy domain string */
2939                                                 else {
2940                                                         kfree(ses->serverDomain);
2941                                                         ses->serverDomain =
2942                                                             kzalloc(2,
2943                                                                     GFP_KERNEL);
2944                                                 }
2945                                         } else {        /* no room so create dummy domain and NOS string */
2946                                                 kfree(ses->serverDomain);
2947                                                 ses->serverDomain =
2948                                                     kzalloc(2, GFP_KERNEL);
2949                                                 kfree(ses->serverNOS);
2950                                                 ses->serverNOS =
2951                                                     kzalloc(2, GFP_KERNEL);
2952                                         }
2953                                 } else {        /* ASCII */
2954                                         len = strnlen(bcc_ptr, 1024);
2955                                         if (((long) bcc_ptr + len) - (long)
2956                                             pByteArea(smb_buffer_response)
2957                                             <= BCC(smb_buffer_response)) {
2958                                                 if (ses->serverOS)
2959                                                         kfree(ses->serverOS);
2960                                                 ses->serverOS =
2961                                                     kzalloc(len + 1,
2962                                                             GFP_KERNEL);
2963                                                 strncpy(ses->serverOS,
2964                                                         bcc_ptr, len);
2965
2966                                                 bcc_ptr += len;
2967                                                 bcc_ptr[0] = 0; /* null terminate string */
2968                                                 bcc_ptr++;
2969
2970                                                 len = strnlen(bcc_ptr, 1024);
2971                                                 kfree(ses->serverNOS);
2972                                                 ses->serverNOS =
2973                                                     kzalloc(len + 1,
2974                                                             GFP_KERNEL);
2975                                                 strncpy(ses->serverNOS, bcc_ptr, len);
2976                                                 bcc_ptr += len;
2977                                                 bcc_ptr[0] = 0;
2978                                                 bcc_ptr++;
2979
2980                                                 len = strnlen(bcc_ptr, 1024);
2981                                                 kfree(ses->serverDomain);
2982                                                 ses->serverDomain =
2983                                                     kzalloc(len + 1,
2984                                                             GFP_KERNEL);
2985                                                 strncpy(ses->serverDomain,
2986                                                         bcc_ptr, len);
2987                                                 bcc_ptr += len;
2988                                                 bcc_ptr[0] = 0;
2989                                                 bcc_ptr++;
2990                                         } else
2991                                                 cFYI(1,
2992                                                      ("field of length %d "
2993                                                     "extends beyond end of smb",
2994                                                       len));
2995                                 }
2996                         } else {
2997                                 cERROR(1, ("Security Blob Length extends beyond"
2998                                            " end of SMB"));
2999                         }
3000                 } else {
3001                         cERROR(1, ("No session structure passed in."));
3002                 }
3003         } else {
3004                 cERROR(1,
3005                        (" Invalid Word count %d:",
3006                         smb_buffer_response->WordCount));
3007                 rc = -EIO;
3008         }
3009
3010         cifs_buf_release(smb_buffer);
3011
3012         return rc;
3013 }
3014 static int
3015 CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
3016                         char *ntlm_session_key, bool ntlmv2_flag,
3017                         const struct nls_table *nls_codepage)
3018 {
3019         struct smb_hdr *smb_buffer;
3020         struct smb_hdr *smb_buffer_response;
3021         SESSION_SETUP_ANDX *pSMB;
3022         SESSION_SETUP_ANDX *pSMBr;
3023         char *bcc_ptr;
3024         char *user;
3025         char *domain;
3026         int rc = 0;
3027         int remaining_words = 0;
3028         int bytes_returned = 0;
3029         int len;
3030         int SecurityBlobLength = sizeof(AUTHENTICATE_MESSAGE);
3031         PAUTHENTICATE_MESSAGE SecurityBlob;
3032         __u32 negotiate_flags, capabilities;
3033         __u16 count;
3034
3035         cFYI(1, ("In NTLMSSPSessSetup (Authenticate)"));
3036         if (ses == NULL)
3037                 return -EINVAL;
3038         user = ses->userName;
3039         domain = ses->domainName;
3040         smb_buffer = cifs_buf_get();
3041         if (smb_buffer == NULL) {
3042                 return -ENOMEM;
3043         }
3044         smb_buffer_response = smb_buffer;
3045         pSMB = (SESSION_SETUP_ANDX *)smb_buffer;
3046         pSMBr = (SESSION_SETUP_ANDX *)smb_buffer_response;
3047
3048         /* send SMBsessionSetup here */
3049         header_assemble(smb_buffer, SMB_COM_SESSION_SETUP_ANDX,
3050                         NULL /* no tCon exists yet */ , 12 /* wct */ );
3051
3052         smb_buffer->Mid = GetNextMid(ses->server);
3053         pSMB->req.hdr.Flags |= (SMBFLG_CASELESS | SMBFLG_CANONICAL_PATH_FORMAT);
3054         pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
3055         pSMB->req.AndXCommand = 0xFF;
3056         pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
3057         pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
3058
3059         pSMB->req.hdr.Uid = ses->Suid;
3060
3061         if (ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3062                 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3063
3064         capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
3065                         CAP_EXTENDED_SECURITY;
3066         if (ses->capabilities & CAP_UNICODE) {
3067                 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3068                 capabilities |= CAP_UNICODE;
3069         }
3070         if (ses->capabilities & CAP_STATUS32) {
3071                 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3072                 capabilities |= CAP_STATUS32;
3073         }
3074         if (ses->capabilities & CAP_DFS) {
3075                 smb_buffer->Flags2 |= SMBFLG2_DFS;
3076                 capabilities |= CAP_DFS;
3077         }
3078         pSMB->req.Capabilities = cpu_to_le32(capabilities);
3079
3080         bcc_ptr = (char *)&pSMB->req.SecurityBlob;
3081         SecurityBlob = (PAUTHENTICATE_MESSAGE)bcc_ptr;
3082         strncpy(SecurityBlob->Signature, NTLMSSP_SIGNATURE, 8);
3083         SecurityBlob->MessageType = NtLmAuthenticate;
3084         bcc_ptr += SecurityBlobLength;
3085         negotiate_flags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_REQUEST_TARGET |
3086                         NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_TARGET_INFO |
3087                         0x80000000 | NTLMSSP_NEGOTIATE_128;
3088         if (sign_CIFS_PDUs)
3089                 negotiate_flags |= /* NTLMSSP_NEGOTIATE_ALWAYS_SIGN |*/ NTLMSSP_NEGOTIATE_SIGN;
3090         if (ntlmv2_flag)
3091                 negotiate_flags |= NTLMSSP_NEGOTIATE_NTLMV2;
3092
3093 /* setup pointers to domain name and workstation name */
3094
3095         SecurityBlob->WorkstationName.Buffer = 0;
3096         SecurityBlob->WorkstationName.Length = 0;
3097         SecurityBlob->WorkstationName.MaximumLength = 0;
3098         SecurityBlob->SessionKey.Length = 0;
3099         SecurityBlob->SessionKey.MaximumLength = 0;
3100         SecurityBlob->SessionKey.Buffer = 0;
3101
3102         SecurityBlob->LmChallengeResponse.Length = 0;
3103         SecurityBlob->LmChallengeResponse.MaximumLength = 0;
3104         SecurityBlob->LmChallengeResponse.Buffer = 0;
3105
3106         SecurityBlob->NtChallengeResponse.Length =
3107             cpu_to_le16(CIFS_SESS_KEY_SIZE);
3108         SecurityBlob->NtChallengeResponse.MaximumLength =
3109             cpu_to_le16(CIFS_SESS_KEY_SIZE);
3110         memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
3111         SecurityBlob->NtChallengeResponse.Buffer =
3112             cpu_to_le32(SecurityBlobLength);
3113         SecurityBlobLength += CIFS_SESS_KEY_SIZE;
3114         bcc_ptr += CIFS_SESS_KEY_SIZE;
3115
3116         if (ses->capabilities & CAP_UNICODE) {
3117                 if (domain == NULL) {
3118                         SecurityBlob->DomainName.Buffer = 0;
3119                         SecurityBlob->DomainName.Length = 0;
3120                         SecurityBlob->DomainName.MaximumLength = 0;
3121                 } else {
3122                         __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, domain, 64,
3123                                           nls_codepage);
3124                         ln *= 2;
3125                         SecurityBlob->DomainName.MaximumLength =
3126                             cpu_to_le16(ln);
3127                         SecurityBlob->DomainName.Buffer =
3128                             cpu_to_le32(SecurityBlobLength);
3129                         bcc_ptr += ln;
3130                         SecurityBlobLength += ln;
3131                         SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3132                 }
3133                 if (user == NULL) {
3134                         SecurityBlob->UserName.Buffer = 0;
3135                         SecurityBlob->UserName.Length = 0;
3136                         SecurityBlob->UserName.MaximumLength = 0;
3137                 } else {
3138                         __u16 ln = cifs_strtoUCS((__le16 *) bcc_ptr, user, 64,
3139                                           nls_codepage);
3140                         ln *= 2;
3141                         SecurityBlob->UserName.MaximumLength =
3142                             cpu_to_le16(ln);
3143                         SecurityBlob->UserName.Buffer =
3144                             cpu_to_le32(SecurityBlobLength);
3145                         bcc_ptr += ln;
3146                         SecurityBlobLength += ln;
3147                         SecurityBlob->UserName.Length = cpu_to_le16(ln);
3148                 }
3149
3150                 /* SecurityBlob->WorkstationName.Length =
3151                  cifs_strtoUCS((__le16 *) bcc_ptr, "AMACHINE",64, nls_codepage);
3152                    SecurityBlob->WorkstationName.Length *= 2;
3153                    SecurityBlob->WorkstationName.MaximumLength =
3154                         cpu_to_le16(SecurityBlob->WorkstationName.Length);
3155                    SecurityBlob->WorkstationName.Buffer =
3156                                  cpu_to_le32(SecurityBlobLength);
3157                    bcc_ptr += SecurityBlob->WorkstationName.Length;
3158                    SecurityBlobLength += SecurityBlob->WorkstationName.Length;
3159                    SecurityBlob->WorkstationName.Length =
3160                         cpu_to_le16(SecurityBlob->WorkstationName.Length);  */
3161
3162                 if ((long) bcc_ptr % 2) {
3163                         *bcc_ptr = 0;
3164                         bcc_ptr++;
3165                 }
3166                 bytes_returned =
3167                     cifs_strtoUCS((__le16 *) bcc_ptr, "Linux version ",
3168                                   32, nls_codepage);
3169                 bcc_ptr += 2 * bytes_returned;
3170                 bytes_returned =
3171                     cifs_strtoUCS((__le16 *) bcc_ptr, utsname()->release, 32,
3172                                   nls_codepage);
3173                 bcc_ptr += 2 * bytes_returned;
3174                 bcc_ptr += 2;   /* null term version string */
3175                 bytes_returned =
3176                     cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
3177                                   64, nls_codepage);
3178                 bcc_ptr += 2 * bytes_returned;
3179                 *(bcc_ptr + 1) = 0;
3180                 *(bcc_ptr + 2) = 0;
3181                 bcc_ptr += 2;   /* null terminate network opsys string */
3182                 *(bcc_ptr + 1) = 0;
3183                 *(bcc_ptr + 2) = 0;
3184                 bcc_ptr += 2;   /* null domain */
3185         } else {                /* ASCII */
3186                 if (domain == NULL) {
3187                         SecurityBlob->DomainName.Buffer = 0;
3188                         SecurityBlob->DomainName.Length = 0;
3189                         SecurityBlob->DomainName.MaximumLength = 0;
3190                 } else {
3191                         __u16 ln;
3192                         negotiate_flags |= NTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED;
3193                         strncpy(bcc_ptr, domain, 63);
3194                         ln = strnlen(domain, 64);
3195                         SecurityBlob->DomainName.MaximumLength =
3196                             cpu_to_le16(ln);
3197                         SecurityBlob->DomainName.Buffer =
3198                             cpu_to_le32(SecurityBlobLength);
3199                         bcc_ptr += ln;
3200                         SecurityBlobLength += ln;
3201                         SecurityBlob->DomainName.Length = cpu_to_le16(ln);
3202                 }
3203                 if (user == NULL) {
3204                         SecurityBlob->UserName.Buffer = 0;
3205                         SecurityBlob->UserName.Length = 0;
3206                         SecurityBlob->UserName.MaximumLength = 0;
3207                 } else {
3208                         __u16 ln;
3209                         strncpy(bcc_ptr, user, 63);
3210                         ln = strnlen(user, 64);
3211                         SecurityBlob->UserName.MaximumLength = cpu_to_le16(ln);
3212                         SecurityBlob->UserName.Buffer =
3213                                                 cpu_to_le32(SecurityBlobLength);
3214                         bcc_ptr += ln;
3215                         SecurityBlobLength += ln;
3216                         SecurityBlob->UserName.Length = cpu_to_le16(ln);
3217                 }
3218                 /* BB fill in our workstation name if known BB */
3219
3220                 strcpy(bcc_ptr, "Linux version ");
3221                 bcc_ptr += strlen("Linux version ");
3222                 strcpy(bcc_ptr, utsname()->release);
3223                 bcc_ptr += strlen(utsname()->release) + 1;
3224                 strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
3225                 bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
3226                 bcc_ptr++;      /* null domain */
3227                 *bcc_ptr = 0;
3228         }
3229         SecurityBlob->NegotiateFlags = cpu_to_le32(negotiate_flags);
3230         pSMB->req.SecurityBlobLength = cpu_to_le16(SecurityBlobLength);
3231         count = (long) bcc_ptr - (long) pByteArea(smb_buffer);
3232         smb_buffer->smb_buf_length += count;
3233         pSMB->req.ByteCount = cpu_to_le16(count);
3234
3235         rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response,
3236                          &bytes_returned, CIFS_LONG_OP);
3237         if (rc) {
3238 /*   rc = map_smb_to_linux_error(smb_buffer_response) done in SendReceive now */
3239         } else if ((smb_buffer_response->WordCount == 3) ||
3240                    (smb_buffer_response->WordCount == 4)) {
3241                 __u16 action = le16_to_cpu(pSMBr->resp.Action);
3242                 __u16 blob_len = le16_to_cpu(pSMBr->resp.SecurityBlobLength);
3243                 if (action & GUEST_LOGIN)
3244                         cFYI(1, (" Guest login")); /* BB Should we set anything
3245                                                          in SesInfo struct ? */
3246 /*              if (SecurityBlob2->MessageType != NtLm??) {
3247                         cFYI("Unexpected message type on auth response is %d"));
3248                 } */
3249
3250                 if (ses) {
3251                         cFYI(1,
3252                              ("Check challenge UID %d vs auth response UID %d",
3253                               ses->Suid, smb_buffer_response->Uid));
3254                         /* UID left in wire format */
3255                         ses->Suid = smb_buffer_response->Uid;
3256                         bcc_ptr = pByteArea(smb_buffer_response);
3257                 /* response can have either 3 or 4 word count - Samba sends 3 */
3258                         if ((pSMBr->resp.hdr.WordCount == 3)
3259                             || ((pSMBr->resp.hdr.WordCount == 4)
3260                                 && (blob_len <
3261                                     pSMBr->resp.ByteCount))) {
3262                                 if (pSMBr->resp.hdr.WordCount == 4) {
3263                                         bcc_ptr +=
3264                                             blob_len;
3265                                         cFYI(1,
3266                                              ("Security Blob Length %d ",
3267                                               blob_len));
3268                                 }
3269
3270                                 cFYI(1,
3271                                      ("NTLMSSP response to Authenticate "));
3272
3273                                 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3274                                         if ((long) (bcc_ptr) % 2) {
3275                                                 remaining_words =
3276                                                     (BCC(smb_buffer_response)
3277                                                      - 1) / 2;
3278                                                 bcc_ptr++;      /* Unicode strings must be word aligned */
3279                                         } else {
3280                                                 remaining_words = BCC(smb_buffer_response) / 2;
3281                                         }
3282                                         len = UniStrnlen((wchar_t *) bcc_ptr,
3283                                                         remaining_words - 1);
3284 /* We look for obvious messed up bcc or strings in response so we do not go off
3285   the end since (at least) WIN2K and Windows XP have a major bug in not null
3286   terminating last Unicode string in response  */
3287                                         if (ses->serverOS)
3288                                                 kfree(ses->serverOS);
3289                                         ses->serverOS =
3290                                             kzalloc(2 * (len + 1), GFP_KERNEL);
3291                                         cifs_strfromUCS_le(ses->serverOS,
3292                                                            (__le16 *)
3293                                                            bcc_ptr, len,
3294                                                            nls_codepage);
3295                                         bcc_ptr += 2 * (len + 1);
3296                                         remaining_words -= len + 1;
3297                                         ses->serverOS[2 * len] = 0;
3298                                         ses->serverOS[1 + (2 * len)] = 0;
3299                                         if (remaining_words > 0) {
3300                                                 len = UniStrnlen((wchar_t *)
3301                                                                  bcc_ptr,
3302                                                                  remaining_words
3303                                                                  - 1);
3304                                                 kfree(ses->serverNOS);
3305                                                 ses->serverNOS =
3306                                                     kzalloc(2 * (len + 1),
3307                                                             GFP_KERNEL);
3308                                                 cifs_strfromUCS_le(ses->
3309                                                                    serverNOS,
3310                                                                    (__le16 *)
3311                                                                    bcc_ptr,
3312                                                                    len,
3313                                                                    nls_codepage);
3314                                                 bcc_ptr += 2 * (len + 1);
3315                                                 ses->serverNOS[2 * len] = 0;
3316                                                 ses->serverNOS[1+(2*len)] = 0;
3317                                                 remaining_words -= len + 1;
3318                                                 if (remaining_words > 0) {
3319                                                         len = UniStrnlen((wchar_t *) bcc_ptr, remaining_words);
3320      /* last string not always null terminated (e.g. for Windows XP & 2000) */
3321                                                         if (ses->serverDomain)
3322                                                                 kfree(ses->serverDomain);
3323                                                         ses->serverDomain =
3324                                                             kzalloc(2 *
3325                                                                     (len +
3326                                                                      1),
3327                                                                     GFP_KERNEL);
3328                                                         cifs_strfromUCS_le
3329                                                             (ses->
3330                                                              serverDomain,
3331                                                              (__le16 *)
3332                                                              bcc_ptr, len,
3333                                                              nls_codepage);
3334                                                         bcc_ptr +=
3335                                                             2 * (len + 1);
3336                                                         ses->
3337                                                             serverDomain[2
3338                                                                          * len]
3339                                                             = 0;
3340                                                         ses->
3341                                                             serverDomain[1
3342                                                                          +
3343                                                                          (2
3344                                                                           *
3345                                                                           len)]
3346                                                             = 0;
3347                                                 } /* else no more room so create dummy domain string */
3348                                                 else {
3349                                                         if (ses->serverDomain)
3350                                                                 kfree(ses->serverDomain);
3351                                                         ses->serverDomain = kzalloc(2,GFP_KERNEL);
3352                                                 }
3353                                         } else {  /* no room so create dummy domain and NOS string */
3354                                                 if (ses->serverDomain)
3355                                                         kfree(ses->serverDomain);
3356                                                 ses->serverDomain = kzalloc(2, GFP_KERNEL);
3357                                                 kfree(ses->serverNOS);
3358                                                 ses->serverNOS = kzalloc(2, GFP_KERNEL);
3359                                         }
3360                                 } else {        /* ASCII */
3361                                         len = strnlen(bcc_ptr, 1024);
3362                                         if (((long) bcc_ptr + len) -
3363                                            (long) pByteArea(smb_buffer_response)
3364                                                 <= BCC(smb_buffer_response)) {
3365                                                 if (ses->serverOS)
3366                                                         kfree(ses->serverOS);
3367                                                 ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
3368                                                 strncpy(ses->serverOS,bcc_ptr, len);
3369
3370                                                 bcc_ptr += len;
3371                                                 bcc_ptr[0] = 0; /* null terminate the string */
3372                                                 bcc_ptr++;
3373
3374                                                 len = strnlen(bcc_ptr, 1024);
3375                                                 kfree(ses->serverNOS);
3376                                                 ses->serverNOS = kzalloc(len+1,
3377                                                                     GFP_KERNEL);
3378                                                 strncpy(ses->serverNOS,
3379                                                         bcc_ptr, len);
3380                                                 bcc_ptr += len;
3381                                                 bcc_ptr[0] = 0;
3382                                                 bcc_ptr++;
3383
3384                                                 len = strnlen(bcc_ptr, 1024);
3385                                                 if (ses->serverDomain)
3386                                                         kfree(ses->serverDomain);
3387                                                 ses->serverDomain =
3388                                                                 kzalloc(len+1,
3389                                                                     GFP_KERNEL);
3390                                                 strncpy(ses->serverDomain,
3391                                                         bcc_ptr, len);
3392                                                 bcc_ptr += len;
3393                                                 bcc_ptr[0] = 0;
3394                                                 bcc_ptr++;
3395                                         } else
3396                                                 cFYI(1, ("field of length %d "
3397                                                    "extends beyond end of smb ",
3398                                                       len));
3399                                 }
3400                         } else {
3401                                 cERROR(1, ("Security Blob extends beyond end "
3402                                         "of SMB"));
3403                         }
3404                 } else {
3405                         cERROR(1, ("No session structure passed in."));
3406                 }
3407         } else {
3408                 cERROR(1, ("Invalid Word count %d: ",
3409                         smb_buffer_response->WordCount));
3410                 rc = -EIO;
3411         }
3412
3413         cifs_buf_release(smb_buffer);
3414
3415         return rc;
3416 }
3417
3418 int
3419 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
3420          const char *tree, struct cifsTconInfo *tcon,
3421          const struct nls_table *nls_codepage)
3422 {
3423         struct smb_hdr *smb_buffer;
3424         struct smb_hdr *smb_buffer_response;
3425         TCONX_REQ *pSMB;
3426         TCONX_RSP *pSMBr;
3427         unsigned char *bcc_ptr;
3428         int rc = 0;
3429         int length;
3430         __u16 count;
3431
3432         if (ses == NULL)
3433                 return -EIO;
3434
3435         smb_buffer = cifs_buf_get();
3436         if (smb_buffer == NULL) {
3437                 return -ENOMEM;
3438         }
3439         smb_buffer_response = smb_buffer;
3440
3441         header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
3442                         NULL /*no tid */ , 4 /*wct */ );
3443
3444         smb_buffer->Mid = GetNextMid(ses->server);
3445         smb_buffer->Uid = ses->Suid;
3446         pSMB = (TCONX_REQ *) smb_buffer;
3447         pSMBr = (TCONX_RSP *) smb_buffer_response;
3448
3449         pSMB->AndXCommand = 0xFF;
3450         pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
3451         bcc_ptr = &pSMB->Password[0];
3452         if ((ses->server->secMode) & SECMODE_USER) {
3453                 pSMB->PasswordLength = cpu_to_le16(1);  /* minimum */
3454                 *bcc_ptr = 0; /* password is null byte */
3455                 bcc_ptr++;              /* skip password */
3456                 /* already aligned so no need to do it below */
3457         } else {
3458                 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
3459                 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
3460                    specified as required (when that support is added to
3461                    the vfs in the future) as only NTLM or the much
3462                    weaker LANMAN (which we do not send by default) is accepted
3463                    by Samba (not sure whether other servers allow
3464                    NTLMv2 password here) */
3465 #ifdef CONFIG_CIFS_WEAK_PW_HASH
3466                 if ((extended_security & CIFSSEC_MAY_LANMAN) &&
3467                         (ses->server->secType == LANMAN))
3468                         calc_lanman_hash(ses, bcc_ptr);
3469                 else
3470 #endif /* CIFS_WEAK_PW_HASH */
3471                 SMBNTencrypt(ses->password,
3472                              ses->server->cryptKey,
3473                              bcc_ptr);
3474
3475                 bcc_ptr += CIFS_SESS_KEY_SIZE;
3476                 if (ses->capabilities & CAP_UNICODE) {
3477                         /* must align unicode strings */
3478                         *bcc_ptr = 0; /* null byte password */
3479                         bcc_ptr++;
3480                 }
3481         }
3482
3483         if (ses->server->secMode &
3484                         (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
3485                 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
3486
3487         if (ses->capabilities & CAP_STATUS32) {
3488                 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
3489         }
3490         if (ses->capabilities & CAP_DFS) {
3491                 smb_buffer->Flags2 |= SMBFLG2_DFS;
3492         }
3493         if (ses->capabilities & CAP_UNICODE) {
3494                 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
3495                 length =
3496                     cifs_strtoUCS((__le16 *) bcc_ptr, tree,
3497                         6 /* max utf8 char length in bytes */ *
3498                         (/* server len*/ + 256 /* share len */), nls_codepage);
3499                 bcc_ptr += 2 * length;  /* convert num 16 bit words to bytes */
3500                 bcc_ptr += 2;   /* skip trailing null */
3501         } else {                /* ASCII */
3502                 strcpy(bcc_ptr, tree);
3503                 bcc_ptr += strlen(tree) + 1;
3504         }
3505         strcpy(bcc_ptr, "?????");
3506         bcc_ptr += strlen("?????");
3507         bcc_ptr += 1;
3508         count = bcc_ptr - &pSMB->Password[0];
3509         pSMB->hdr.smb_buf_length += count;
3510         pSMB->ByteCount = cpu_to_le16(count);
3511
3512         rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
3513                          CIFS_STD_OP);
3514
3515         /* if (rc) rc = map_smb_to_linux_error(smb_buffer_response); */
3516         /* above now done in SendReceive */
3517         if ((rc == 0) && (tcon != NULL)) {
3518                 tcon->tidStatus = CifsGood;
3519                 tcon->need_reconnect = false;
3520                 tcon->tid = smb_buffer_response->Tid;
3521                 bcc_ptr = pByteArea(smb_buffer_response);
3522                 length = strnlen(bcc_ptr, BCC(smb_buffer_response) - 2);
3523                 /* skip service field (NB: this field is always ASCII) */
3524                 if (length == 3) {
3525                         if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
3526                             (bcc_ptr[2] == 'C')) {
3527                                 cFYI(1, ("IPC connection"));
3528                                 tcon->ipc = 1;
3529                         }
3530                 } else if (length == 2) {
3531                         if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
3532                                 /* the most common case */
3533                                 cFYI(1, ("disk share connection"));
3534                         }
3535                 }
3536                 bcc_ptr += length + 1;
3537                 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
3538                 if (smb_buffer->Flags2 & SMBFLG2_UNICODE) {
3539                         length = UniStrnlen((wchar_t *) bcc_ptr, 512);
3540                         if ((bcc_ptr + (2 * length)) -
3541                              pByteArea(smb_buffer_response) <=
3542                             BCC(smb_buffer_response)) {
3543                                 kfree(tcon->nativeFileSystem);
3544                                 tcon->nativeFileSystem =
3545                                     kzalloc(length + 2, GFP_KERNEL);
3546                                 if (tcon->nativeFileSystem)
3547                                         cifs_strfromUCS_le(
3548                                                 tcon->nativeFileSystem,
3549                                                 (__le16 *) bcc_ptr,
3550                                                 length, nls_codepage);
3551                                 bcc_ptr += 2 * length;
3552                                 bcc_ptr[0] = 0; /* null terminate the string */
3553                                 bcc_ptr[1] = 0;
3554                                 bcc_ptr += 2;
3555                         }
3556                         /* else do not bother copying these information fields*/
3557                 } else {
3558                         length = strnlen(bcc_ptr, 1024);
3559                         if ((bcc_ptr + length) -
3560                             pByteArea(smb_buffer_response) <=
3561                             BCC(smb_buffer_response)) {
3562                                 kfree(tcon->nativeFileSystem);
3563                                 tcon->nativeFileSystem =
3564                                     kzalloc(length + 1, GFP_KERNEL);
3565                                 if (tcon->nativeFileSystem)
3566                                         strncpy(tcon->nativeFileSystem, bcc_ptr,
3567                                                 length);
3568                         }
3569                         /* else do not bother copying these information fields*/
3570                 }
3571                 if ((smb_buffer_response->WordCount == 3) ||
3572                          (smb_buffer_response->WordCount == 7))
3573                         /* field is in same location */
3574                         tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3575                 else
3576                         tcon->Flags = 0;
3577                 cFYI(1, ("Tcon flags: 0x%x ", tcon->Flags));
3578         } else if ((rc == 0) && tcon == NULL) {
3579                 /* all we need to save for IPC$ connection */
3580                 ses->ipc_tid = smb_buffer_response->Tid;
3581         }
3582
3583         cifs_buf_release(smb_buffer);
3584         return rc;
3585 }
3586
3587 int
3588 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3589 {
3590         int rc = 0;
3591         int xid;
3592         struct cifsSesInfo *ses = NULL;
3593         char *tmp;
3594
3595         xid = GetXid();
3596
3597         if (cifs_sb->tcon) {
3598                 ses = cifs_sb->tcon->ses; /* save ptr to ses before delete tcon!*/
3599                 rc = CIFSSMBTDis(xid, cifs_sb->tcon);
3600                 if (rc == -EBUSY) {
3601                         FreeXid(xid);
3602                         return 0;
3603                 }
3604                 DeleteTconOplockQEntries(cifs_sb->tcon);
3605                 tconInfoFree(cifs_sb->tcon);
3606                 if ((ses) && (ses->server)) {
3607                         /* save off task so we do not refer to ses later */
3608                         cFYI(1, ("About to do SMBLogoff "));
3609                         rc = CIFSSMBLogoff(xid, ses);
3610                         if (rc == -EBUSY) {
3611                                 FreeXid(xid);
3612                                 return 0;
3613                         } else if (rc == -ESHUTDOWN) {
3614                                 cFYI(1, ("Waking up socket by sending signal"));
3615                                 if (ses->server)
3616                                         kill_cifsd(ses->server);
3617                                 rc = 0;
3618                         } /* else - we have an smb session
3619                                 left on this socket do not kill cifsd */
3620                 } else
3621                         cFYI(1, ("No session or bad tcon"));
3622         }
3623
3624         cifs_sb->tcon = NULL;
3625         tmp = cifs_sb->prepath;
3626         cifs_sb->prepathlen = 0;
3627         cifs_sb->prepath = NULL;
3628         kfree(tmp);
3629         if (ses)
3630                 sesInfoFree(ses);
3631
3632         FreeXid(xid);
3633         return rc;
3634 }
3635
3636 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
3637                                            struct nls_table *nls_info)
3638 {
3639         int rc = 0;
3640         char ntlm_session_key[CIFS_SESS_KEY_SIZE];
3641         bool ntlmv2_flag = false;
3642         int first_time = 0;
3643         struct TCP_Server_Info *server = pSesInfo->server;
3644
3645         /* what if server changes its buffer size after dropping the session? */
3646         if (server->maxBuf == 0) /* no need to send on reconnect */ {
3647                 rc = CIFSSMBNegotiate(xid, pSesInfo);
3648                 if (rc == -EAGAIN) {
3649                         /* retry only once on 1st time connection */
3650                         rc = CIFSSMBNegotiate(xid, pSesInfo);
3651                         if (rc == -EAGAIN)
3652                                 rc = -EHOSTDOWN;
3653                 }
3654                 if (rc == 0) {
3655                         spin_lock(&GlobalMid_Lock);
3656                         if (server->tcpStatus != CifsExiting)
3657                                 server->tcpStatus = CifsGood;
3658                         else
3659                                 rc = -EHOSTDOWN;
3660                         spin_unlock(&GlobalMid_Lock);
3661
3662                 }
3663                 first_time = 1;
3664         }
3665
3666         if (rc)
3667                 goto ss_err_exit;
3668
3669         pSesInfo->flags = 0;
3670         pSesInfo->capabilities = server->capabilities;
3671         if (linuxExtEnabled == 0)
3672                 pSesInfo->capabilities &= (~CAP_UNIX);
3673         /*      pSesInfo->sequence_number = 0;*/
3674         cFYI(1, ("Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3675                  server->secMode, server->capabilities, server->timeAdj));
3676
3677         if (experimEnabled < 2)
3678                 rc = CIFS_SessSetup(xid, pSesInfo, first_time, nls_info);
3679         else if (extended_security
3680                         && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3681                         && (server->secType == NTLMSSP)) {
3682                 rc = -EOPNOTSUPP;
3683         } else if (extended_security
3684                         && (pSesInfo->capabilities & CAP_EXTENDED_SECURITY)
3685                         && (server->secType == RawNTLMSSP)) {
3686                 cFYI(1, ("NTLMSSP sesssetup"));
3687                 rc = CIFSNTLMSSPNegotiateSessSetup(xid, pSesInfo, &ntlmv2_flag,
3688                                                    nls_info);
3689                 if (!rc) {
3690                         if (ntlmv2_flag) {
3691                                 char *v2_response;
3692                                 cFYI(1, ("more secure NTLM ver2 hash"));
3693                                 if (CalcNTLMv2_partial_mac_key(pSesInfo,
3694                                                                 nls_info)) {
3695                                         rc = -ENOMEM;
3696                                         goto ss_err_exit;
3697                                 } else
3698                                         v2_response = kmalloc(16 + 64 /* blob*/,
3699                                                                 GFP_KERNEL);
3700                                 if (v2_response) {
3701                                         CalcNTLMv2_response(pSesInfo,
3702                                                                 v2_response);
3703                                 /*      if (first_time)
3704                                                 cifs_calculate_ntlmv2_mac_key */
3705                                         kfree(v2_response);
3706                                         /* BB Put dummy sig in SessSetup PDU? */
3707                                 } else {
3708                                         rc = -ENOMEM;
3709                                         goto ss_err_exit;
3710                                 }
3711
3712                         } else {
3713                                 SMBNTencrypt(pSesInfo->password,
3714                                              server->cryptKey,
3715                                              ntlm_session_key);
3716
3717                                 if (first_time)
3718                                         cifs_calculate_mac_key(
3719                                              &server->mac_signing_key,
3720                                              ntlm_session_key,
3721                                              pSesInfo->password);
3722                         }
3723                         /* for better security the weaker lanman hash not sent
3724                            in AuthSessSetup so we no longer calculate it */
3725
3726                         rc = CIFSNTLMSSPAuthSessSetup(xid, pSesInfo,
3727                                                       ntlm_session_key,
3728                                                       ntlmv2_flag,
3729                                                       nls_info);
3730                 }
3731         } else { /* old style NTLM 0.12 session setup */
3732                 SMBNTencrypt(pSesInfo->password, server->cryptKey,
3733                              ntlm_session_key);
3734
3735                 if (first_time)
3736                         cifs_calculate_mac_key(&server->mac_signing_key,
3737                                                 ntlm_session_key,
3738                                                 pSesInfo->password);
3739
3740                 rc = CIFSSessSetup(xid, pSesInfo, ntlm_session_key, nls_info);
3741         }
3742         if (rc) {
3743                 cERROR(1, ("Send error in SessSetup = %d", rc));
3744         } else {
3745                 cFYI(1, ("CIFS Session Established successfully"));
3746                         spin_lock(&GlobalMid_Lock);
3747                         pSesInfo->status = CifsGood;
3748                         pSesInfo->need_reconnect = false;
3749                         spin_unlock(&GlobalMid_Lock);
3750         }
3751
3752 ss_err_exit:
3753         return rc;
3754 }
3755