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