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