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