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