]> git.karo-electronics.de Git - mv-sheeva.git/blob - fs/cifs/connect.c
c42d37fb5b7c48a9699123cb6f61f1ca0de6b773
[mv-sheeva.git] / fs / cifs / connect.c
1 /*
2  *   fs/cifs/connect.c
3  *
4  *   Copyright (C) International Business Machines  Corp., 2002,2009
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/slab.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 <linux/namei.h>
37 #include <asm/uaccess.h>
38 #include <asm/processor.h>
39 #include <linux/inet.h>
40 #include <net/ipv6.h>
41 #include "cifspdu.h"
42 #include "cifsglob.h"
43 #include "cifsproto.h"
44 #include "cifs_unicode.h"
45 #include "cifs_debug.h"
46 #include "cifs_fs_sb.h"
47 #include "ntlmssp.h"
48 #include "nterr.h"
49 #include "rfc1002pdu.h"
50 #include "fscache.h"
51
52 #define CIFS_PORT 445
53 #define RFC1001_PORT 139
54
55 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
56                          unsigned char *p24);
57
58 extern mempool_t *cifs_req_poolp;
59
60 struct smb_vol {
61         char *username;
62         char *password;
63         char *domainname;
64         char *UNC;
65         char *UNCip;
66         char *iocharset;  /* local code page for mapping to and from Unicode */
67         char source_rfc1001_name[16]; /* netbios name of client */
68         char target_rfc1001_name[16]; /* netbios name of server for Win9x/ME */
69         uid_t cred_uid;
70         uid_t linux_uid;
71         gid_t linux_gid;
72         mode_t file_mode;
73         mode_t dir_mode;
74         unsigned secFlg;
75         bool retry:1;
76         bool intr:1;
77         bool setuids:1;
78         bool override_uid:1;
79         bool override_gid:1;
80         bool dynperm:1;
81         bool noperm:1;
82         bool no_psx_acl:1; /* set if posix acl support should be disabled */
83         bool cifs_acl:1;
84         bool no_xattr:1;   /* set if xattr (EA) support should be disabled*/
85         bool server_ino:1; /* use inode numbers from server ie UniqueId */
86         bool direct_io:1;
87         bool remap:1;      /* set to remap seven reserved chars in filenames */
88         bool posix_paths:1; /* unset to not ask for posix pathnames. */
89         bool no_linux_ext:1;
90         bool sfu_emul:1;
91         bool nullauth:1;   /* attempt to authenticate with null user */
92         bool nocase:1;     /* request case insensitive filenames */
93         bool nobrl:1;      /* disable sending byte range locks to srv */
94         bool mand_lock:1;  /* send mandatory not posix byte range lock reqs */
95         bool seal:1;       /* request transport encryption on share */
96         bool nodfs:1;      /* Do not request DFS, even if available */
97         bool local_lease:1; /* check leases only on local system, not remote */
98         bool noblocksnd:1;
99         bool noautotune:1;
100         bool nostrictsync:1; /* do not force expensive SMBflush on every sync */
101         bool fsc:1;     /* enable fscache */
102         bool mfsymlinks:1; /* use Minshall+French Symlinks */
103         unsigned int rsize;
104         unsigned int wsize;
105         bool sockopt_tcp_nodelay:1;
106         unsigned short int port;
107         char *prepath;
108         struct sockaddr_storage srcaddr; /* allow binding to a local IP */
109         struct nls_table *local_nls;
110 };
111
112 static int ipv4_connect(struct TCP_Server_Info *server);
113 static int ipv6_connect(struct TCP_Server_Info *server);
114
115 /*
116  * cifs tcp session reconnection
117  *
118  * mark tcp session as reconnecting so temporarily locked
119  * mark all smb sessions as reconnecting for tcp session
120  * reconnect tcp session
121  * wake up waiters on reconnection? - (not needed currently)
122  */
123 static int
124 cifs_reconnect(struct TCP_Server_Info *server)
125 {
126         int rc = 0;
127         struct list_head *tmp, *tmp2;
128         struct cifsSesInfo *ses;
129         struct cifsTconInfo *tcon;
130         struct mid_q_entry *mid_entry;
131
132         spin_lock(&GlobalMid_Lock);
133         if (server->tcpStatus == CifsExiting) {
134                 /* the demux thread will exit normally
135                 next time through the loop */
136                 spin_unlock(&GlobalMid_Lock);
137                 return rc;
138         } else
139                 server->tcpStatus = CifsNeedReconnect;
140         spin_unlock(&GlobalMid_Lock);
141         server->maxBuf = 0;
142
143         cFYI(1, "Reconnecting tcp session");
144
145         /* before reconnecting the tcp session, mark the smb session (uid)
146                 and the tid bad so they are not used until reconnected */
147         read_lock(&cifs_tcp_ses_lock);
148         list_for_each(tmp, &server->smb_ses_list) {
149                 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
150                 ses->need_reconnect = true;
151                 ses->ipc_tid = 0;
152                 list_for_each(tmp2, &ses->tcon_list) {
153                         tcon = list_entry(tmp2, struct cifsTconInfo, tcon_list);
154                         tcon->need_reconnect = true;
155                 }
156         }
157         read_unlock(&cifs_tcp_ses_lock);
158         /* do not want to be sending data on a socket we are freeing */
159         mutex_lock(&server->srv_mutex);
160         if (server->ssocket) {
161                 cFYI(1, "State: 0x%x Flags: 0x%lx", server->ssocket->state,
162                         server->ssocket->flags);
163                 kernel_sock_shutdown(server->ssocket, SHUT_WR);
164                 cFYI(1, "Post shutdown state: 0x%x Flags: 0x%lx",
165                         server->ssocket->state,
166                         server->ssocket->flags);
167                 sock_release(server->ssocket);
168                 server->ssocket = NULL;
169         }
170
171         spin_lock(&GlobalMid_Lock);
172         list_for_each(tmp, &server->pending_mid_q) {
173                 mid_entry = list_entry(tmp, struct
174                                         mid_q_entry,
175                                         qhead);
176                 if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
177                                 /* Mark other intransit requests as needing
178                                    retry so we do not immediately mark the
179                                    session bad again (ie after we reconnect
180                                    below) as they timeout too */
181                         mid_entry->midState = MID_RETRY_NEEDED;
182                 }
183         }
184         spin_unlock(&GlobalMid_Lock);
185         mutex_unlock(&server->srv_mutex);
186
187         while ((server->tcpStatus != CifsExiting) &&
188                (server->tcpStatus != CifsGood)) {
189                 try_to_freeze();
190                 if (server->addr.sockAddr6.sin6_family == AF_INET6)
191                         rc = ipv6_connect(server);
192                 else
193                         rc = ipv4_connect(server);
194                 if (rc) {
195                         cFYI(1, "reconnect error %d", rc);
196                         msleep(3000);
197                 } else {
198                         atomic_inc(&tcpSesReconnectCount);
199                         spin_lock(&GlobalMid_Lock);
200                         if (server->tcpStatus != CifsExiting)
201                                 server->tcpStatus = CifsGood;
202                         server->sequence_number = 0;
203                         spin_unlock(&GlobalMid_Lock);
204         /*              atomic_set(&server->inFlight,0);*/
205                         wake_up(&server->response_q);
206                 }
207         }
208         return rc;
209 }
210
211 /*
212         return codes:
213                 0       not a transact2, or all data present
214                 >0      transact2 with that much data missing
215                 -EINVAL = invalid transact2
216
217  */
218 static int check2ndT2(struct smb_hdr *pSMB, unsigned int maxBufSize)
219 {
220         struct smb_t2_rsp *pSMBt;
221         int total_data_size;
222         int data_in_this_rsp;
223         int remaining;
224
225         if (pSMB->Command != SMB_COM_TRANSACTION2)
226                 return 0;
227
228         /* check for plausible wct, bcc and t2 data and parm sizes */
229         /* check for parm and data offset going beyond end of smb */
230         if (pSMB->WordCount != 10) { /* coalesce_t2 depends on this */
231                 cFYI(1, "invalid transact2 word count");
232                 return -EINVAL;
233         }
234
235         pSMBt = (struct smb_t2_rsp *)pSMB;
236
237         total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
238         data_in_this_rsp = le16_to_cpu(pSMBt->t2_rsp.DataCount);
239
240         remaining = total_data_size - data_in_this_rsp;
241
242         if (remaining == 0)
243                 return 0;
244         else if (remaining < 0) {
245                 cFYI(1, "total data %d smaller than data in frame %d",
246                         total_data_size, data_in_this_rsp);
247                 return -EINVAL;
248         } else {
249                 cFYI(1, "missing %d bytes from transact2, check next response",
250                         remaining);
251                 if (total_data_size > maxBufSize) {
252                         cERROR(1, "TotalDataSize %d is over maximum buffer %d",
253                                 total_data_size, maxBufSize);
254                         return -EINVAL;
255                 }
256                 return remaining;
257         }
258 }
259
260 static int coalesce_t2(struct smb_hdr *psecond, struct smb_hdr *pTargetSMB)
261 {
262         struct smb_t2_rsp *pSMB2 = (struct smb_t2_rsp *)psecond;
263         struct smb_t2_rsp *pSMBt  = (struct smb_t2_rsp *)pTargetSMB;
264         int total_data_size;
265         int total_in_buf;
266         int remaining;
267         int total_in_buf2;
268         char *data_area_of_target;
269         char *data_area_of_buf2;
270         __u16 byte_count;
271
272         total_data_size = le16_to_cpu(pSMBt->t2_rsp.TotalDataCount);
273
274         if (total_data_size != le16_to_cpu(pSMB2->t2_rsp.TotalDataCount)) {
275                 cFYI(1, "total data size of primary and secondary t2 differ");
276         }
277
278         total_in_buf = le16_to_cpu(pSMBt->t2_rsp.DataCount);
279
280         remaining = total_data_size - total_in_buf;
281
282         if (remaining < 0)
283                 return -EINVAL;
284
285         if (remaining == 0) /* nothing to do, ignore */
286                 return 0;
287
288         total_in_buf2 = le16_to_cpu(pSMB2->t2_rsp.DataCount);
289         if (remaining < total_in_buf2) {
290                 cFYI(1, "transact2 2nd response contains too much data");
291         }
292
293         /* find end of first SMB data area */
294         data_area_of_target = (char *)&pSMBt->hdr.Protocol +
295                                 le16_to_cpu(pSMBt->t2_rsp.DataOffset);
296         /* validate target area */
297
298         data_area_of_buf2 = (char *) &pSMB2->hdr.Protocol +
299                                         le16_to_cpu(pSMB2->t2_rsp.DataOffset);
300
301         data_area_of_target += total_in_buf;
302
303         /* copy second buffer into end of first buffer */
304         memcpy(data_area_of_target, data_area_of_buf2, total_in_buf2);
305         total_in_buf += total_in_buf2;
306         pSMBt->t2_rsp.DataCount = cpu_to_le16(total_in_buf);
307         byte_count = le16_to_cpu(BCC_LE(pTargetSMB));
308         byte_count += total_in_buf2;
309         BCC_LE(pTargetSMB) = cpu_to_le16(byte_count);
310
311         byte_count = pTargetSMB->smb_buf_length;
312         byte_count += total_in_buf2;
313
314         /* BB also add check that we are not beyond maximum buffer size */
315
316         pTargetSMB->smb_buf_length = byte_count;
317
318         if (remaining == total_in_buf2) {
319                 cFYI(1, "found the last secondary response");
320                 return 0; /* we are done */
321         } else /* more responses to go */
322                 return 1;
323
324 }
325
326 static int
327 cifs_demultiplex_thread(struct TCP_Server_Info *server)
328 {
329         int length;
330         unsigned int pdu_length, total_read;
331         struct smb_hdr *smb_buffer = NULL;
332         struct smb_hdr *bigbuf = NULL;
333         struct smb_hdr *smallbuf = NULL;
334         struct msghdr smb_msg;
335         struct kvec iov;
336         struct socket *csocket = server->ssocket;
337         struct list_head *tmp;
338         struct cifsSesInfo *ses;
339         struct task_struct *task_to_wake = NULL;
340         struct mid_q_entry *mid_entry;
341         char temp;
342         bool isLargeBuf = false;
343         bool isMultiRsp;
344         int reconnect;
345
346         current->flags |= PF_MEMALLOC;
347         cFYI(1, "Demultiplex PID: %d", task_pid_nr(current));
348
349         length = atomic_inc_return(&tcpSesAllocCount);
350         if (length > 1)
351                 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
352                                 GFP_KERNEL);
353
354         set_freezable();
355         while (server->tcpStatus != CifsExiting) {
356                 if (try_to_freeze())
357                         continue;
358                 if (bigbuf == NULL) {
359                         bigbuf = cifs_buf_get();
360                         if (!bigbuf) {
361                                 cERROR(1, "No memory for large SMB response");
362                                 msleep(3000);
363                                 /* retry will check if exiting */
364                                 continue;
365                         }
366                 } else if (isLargeBuf) {
367                         /* we are reusing a dirty large buf, clear its start */
368                         memset(bigbuf, 0, sizeof(struct smb_hdr));
369                 }
370
371                 if (smallbuf == NULL) {
372                         smallbuf = cifs_small_buf_get();
373                         if (!smallbuf) {
374                                 cERROR(1, "No memory for SMB response");
375                                 msleep(1000);
376                                 /* retry will check if exiting */
377                                 continue;
378                         }
379                         /* beginning of smb buffer is cleared in our buf_get */
380                 } else /* if existing small buf clear beginning */
381                         memset(smallbuf, 0, sizeof(struct smb_hdr));
382
383                 isLargeBuf = false;
384                 isMultiRsp = false;
385                 smb_buffer = smallbuf;
386                 iov.iov_base = smb_buffer;
387                 iov.iov_len = 4;
388                 smb_msg.msg_control = NULL;
389                 smb_msg.msg_controllen = 0;
390                 pdu_length = 4; /* enough to get RFC1001 header */
391 incomplete_rcv:
392                 length =
393                     kernel_recvmsg(csocket, &smb_msg,
394                                 &iov, 1, pdu_length, 0 /* BB other flags? */);
395
396                 if (server->tcpStatus == CifsExiting) {
397                         break;
398                 } else if (server->tcpStatus == CifsNeedReconnect) {
399                         cFYI(1, "Reconnect after server stopped responding");
400                         cifs_reconnect(server);
401                         cFYI(1, "call to reconnect done");
402                         csocket = server->ssocket;
403                         continue;
404                 } else if (length == -ERESTARTSYS ||
405                            length == -EAGAIN ||
406                            length == -EINTR) {
407                         msleep(1); /* minimum sleep to prevent looping
408                                 allowing socket to clear and app threads to set
409                                 tcpStatus CifsNeedReconnect if server hung */
410                         if (pdu_length < 4) {
411                                 iov.iov_base = (4 - pdu_length) +
412                                                         (char *)smb_buffer;
413                                 iov.iov_len = pdu_length;
414                                 smb_msg.msg_control = NULL;
415                                 smb_msg.msg_controllen = 0;
416                                 goto incomplete_rcv;
417                         } else
418                                 continue;
419                 } else if (length <= 0) {
420                         cFYI(1, "Reconnect after unexpected peek error %d",
421                                 length);
422                         cifs_reconnect(server);
423                         csocket = server->ssocket;
424                         wake_up(&server->response_q);
425                         continue;
426                 } else if (length < pdu_length) {
427                         cFYI(1, "requested %d bytes but only got %d bytes",
428                                   pdu_length, length);
429                         pdu_length -= length;
430                         msleep(1);
431                         goto incomplete_rcv;
432                 }
433
434                 /* The right amount was read from socket - 4 bytes */
435                 /* so we can now interpret the length field */
436
437                 /* the first byte big endian of the length field,
438                 is actually not part of the length but the type
439                 with the most common, zero, as regular data */
440                 temp = *((char *) smb_buffer);
441
442                 /* Note that FC 1001 length is big endian on the wire,
443                 but we convert it here so it is always manipulated
444                 as host byte order */
445                 pdu_length = be32_to_cpu((__force __be32)smb_buffer->smb_buf_length);
446                 smb_buffer->smb_buf_length = pdu_length;
447
448                 cFYI(1, "rfc1002 length 0x%x", pdu_length+4);
449
450                 if (temp == (char) RFC1002_SESSION_KEEP_ALIVE) {
451                         continue;
452                 } else if (temp == (char)RFC1002_POSITIVE_SESSION_RESPONSE) {
453                         cFYI(1, "Good RFC 1002 session rsp");
454                         continue;
455                 } else if (temp == (char)RFC1002_NEGATIVE_SESSION_RESPONSE) {
456                         /* we get this from Windows 98 instead of
457                            an error on SMB negprot response */
458                         cFYI(1, "Negative RFC1002 Session Response Error 0x%x)",
459                                 pdu_length);
460                         /* give server a second to clean up  */
461                         msleep(1000);
462                         /* always try 445 first on reconnect since we get NACK
463                          * on some if we ever connected to port 139 (the NACK
464                          * is since we do not begin with RFC1001 session
465                          * initialize frame)
466                          */
467                         cifs_set_port((struct sockaddr *)
468                                         &server->addr.sockAddr, CIFS_PORT);
469                         cifs_reconnect(server);
470                         csocket = server->ssocket;
471                         wake_up(&server->response_q);
472                         continue;
473                 } else if (temp != (char) 0) {
474                         cERROR(1, "Unknown RFC 1002 frame");
475                         cifs_dump_mem(" Received Data: ", (char *)smb_buffer,
476                                       length);
477                         cifs_reconnect(server);
478                         csocket = server->ssocket;
479                         continue;
480                 }
481
482                 /* else we have an SMB response */
483                 if ((pdu_length > CIFSMaxBufSize + MAX_CIFS_HDR_SIZE - 4) ||
484                             (pdu_length < sizeof(struct smb_hdr) - 1 - 4)) {
485                         cERROR(1, "Invalid size SMB length %d pdu_length %d",
486                                         length, pdu_length+4);
487                         cifs_reconnect(server);
488                         csocket = server->ssocket;
489                         wake_up(&server->response_q);
490                         continue;
491                 }
492
493                 /* else length ok */
494                 reconnect = 0;
495
496                 if (pdu_length > MAX_CIFS_SMALL_BUFFER_SIZE - 4) {
497                         isLargeBuf = true;
498                         memcpy(bigbuf, smallbuf, 4);
499                         smb_buffer = bigbuf;
500                 }
501                 length = 0;
502                 iov.iov_base = 4 + (char *)smb_buffer;
503                 iov.iov_len = pdu_length;
504                 for (total_read = 0; total_read < pdu_length;
505                      total_read += length) {
506                         length = kernel_recvmsg(csocket, &smb_msg, &iov, 1,
507                                                 pdu_length - total_read, 0);
508                         if (server->tcpStatus == CifsExiting) {
509                                 /* then will exit */
510                                 reconnect = 2;
511                                 break;
512                         } else if (server->tcpStatus == CifsNeedReconnect) {
513                                 cifs_reconnect(server);
514                                 csocket = server->ssocket;
515                                 /* Reconnect wakes up rspns q */
516                                 /* Now we will reread sock */
517                                 reconnect = 1;
518                                 break;
519                         } else if (length == -ERESTARTSYS ||
520                                    length == -EAGAIN ||
521                                    length == -EINTR) {
522                                 msleep(1); /* minimum sleep to prevent looping,
523                                               allowing socket to clear and app
524                                               threads to set tcpStatus
525                                               CifsNeedReconnect if server hung*/
526                                 length = 0;
527                                 continue;
528                         } else if (length <= 0) {
529                                 cERROR(1, "Received no data, expecting %d",
530                                               pdu_length - total_read);
531                                 cifs_reconnect(server);
532                                 csocket = server->ssocket;
533                                 reconnect = 1;
534                                 break;
535                         }
536                 }
537                 if (reconnect == 2)
538                         break;
539                 else if (reconnect == 1)
540                         continue;
541
542                 length += 4; /* account for rfc1002 hdr */
543
544
545                 dump_smb(smb_buffer, length);
546                 if (checkSMB(smb_buffer, smb_buffer->Mid, total_read+4)) {
547                         cifs_dump_mem("Bad SMB: ", smb_buffer, 48);
548                         continue;
549                 }
550
551
552                 task_to_wake = NULL;
553                 spin_lock(&GlobalMid_Lock);
554                 list_for_each(tmp, &server->pending_mid_q) {
555                         mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
556
557                         if ((mid_entry->mid == smb_buffer->Mid) &&
558                             (mid_entry->midState == MID_REQUEST_SUBMITTED) &&
559                             (mid_entry->command == smb_buffer->Command)) {
560                                 if (check2ndT2(smb_buffer,server->maxBuf) > 0) {
561                                         /* We have a multipart transact2 resp */
562                                         isMultiRsp = true;
563                                         if (mid_entry->resp_buf) {
564                                                 /* merge response - fix up 1st*/
565                                                 if (coalesce_t2(smb_buffer,
566                                                         mid_entry->resp_buf)) {
567                                                         mid_entry->multiRsp =
568                                                                  true;
569                                                         break;
570                                                 } else {
571                                                         /* all parts received */
572                                                         mid_entry->multiEnd =
573                                                                  true;
574                                                         goto multi_t2_fnd;
575                                                 }
576                                         } else {
577                                                 if (!isLargeBuf) {
578                                                         cERROR(1, "1st trans2 resp needs bigbuf");
579                                         /* BB maybe we can fix this up,  switch
580                                            to already allocated large buffer? */
581                                                 } else {
582                                                         /* Have first buffer */
583                                                         mid_entry->resp_buf =
584                                                                  smb_buffer;
585                                                         mid_entry->largeBuf =
586                                                                  true;
587                                                         bigbuf = NULL;
588                                                 }
589                                         }
590                                         break;
591                                 }
592                                 mid_entry->resp_buf = smb_buffer;
593                                 mid_entry->largeBuf = isLargeBuf;
594 multi_t2_fnd:
595                                 task_to_wake = mid_entry->tsk;
596                                 mid_entry->midState = MID_RESPONSE_RECEIVED;
597 #ifdef CONFIG_CIFS_STATS2
598                                 mid_entry->when_received = jiffies;
599 #endif
600                                 /* so we do not time out requests to  server
601                                 which is still responding (since server could
602                                 be busy but not dead) */
603                                 server->lstrp = jiffies;
604                                 break;
605                         }
606                 }
607                 spin_unlock(&GlobalMid_Lock);
608                 if (task_to_wake) {
609                         /* Was previous buf put in mpx struct for multi-rsp? */
610                         if (!isMultiRsp) {
611                                 /* smb buffer will be freed by user thread */
612                                 if (isLargeBuf)
613                                         bigbuf = NULL;
614                                 else
615                                         smallbuf = NULL;
616                         }
617                         wake_up_process(task_to_wake);
618                 } else if (!is_valid_oplock_break(smb_buffer, server) &&
619                            !isMultiRsp) {
620                         cERROR(1, "No task to wake, unknown frame received! "
621                                    "NumMids %d", midCount.counter);
622                         cifs_dump_mem("Received Data is: ", (char *)smb_buffer,
623                                       sizeof(struct smb_hdr));
624 #ifdef CONFIG_CIFS_DEBUG2
625                         cifs_dump_detail(smb_buffer);
626                         cifs_dump_mids(server);
627 #endif /* CIFS_DEBUG2 */
628
629                 }
630         } /* end while !EXITING */
631
632         /* take it off the list, if it's not already */
633         write_lock(&cifs_tcp_ses_lock);
634         list_del_init(&server->tcp_ses_list);
635         write_unlock(&cifs_tcp_ses_lock);
636
637         spin_lock(&GlobalMid_Lock);
638         server->tcpStatus = CifsExiting;
639         spin_unlock(&GlobalMid_Lock);
640         wake_up_all(&server->response_q);
641
642         /* check if we have blocked requests that need to free */
643         /* Note that cifs_max_pending is normally 50, but
644         can be set at module install time to as little as two */
645         spin_lock(&GlobalMid_Lock);
646         if (atomic_read(&server->inFlight) >= cifs_max_pending)
647                 atomic_set(&server->inFlight, cifs_max_pending - 1);
648         /* We do not want to set the max_pending too low or we
649         could end up with the counter going negative */
650         spin_unlock(&GlobalMid_Lock);
651         /* Although there should not be any requests blocked on
652         this queue it can not hurt to be paranoid and try to wake up requests
653         that may haven been blocked when more than 50 at time were on the wire
654         to the same server - they now will see the session is in exit state
655         and get out of SendReceive.  */
656         wake_up_all(&server->request_q);
657         /* give those requests time to exit */
658         msleep(125);
659
660         if (server->ssocket) {
661                 sock_release(csocket);
662                 server->ssocket = NULL;
663         }
664         /* buffer usuallly freed in free_mid - need to free it here on exit */
665         cifs_buf_release(bigbuf);
666         if (smallbuf) /* no sense logging a debug message if NULL */
667                 cifs_small_buf_release(smallbuf);
668
669         /*
670          * BB: we shouldn't have to do any of this. It shouldn't be
671          * possible to exit from the thread with active SMB sessions
672          */
673         read_lock(&cifs_tcp_ses_lock);
674         if (list_empty(&server->pending_mid_q)) {
675                 /* loop through server session structures attached to this and
676                     mark them dead */
677                 list_for_each(tmp, &server->smb_ses_list) {
678                         ses = list_entry(tmp, struct cifsSesInfo,
679                                          smb_ses_list);
680                         ses->status = CifsExiting;
681                         ses->server = NULL;
682                 }
683                 read_unlock(&cifs_tcp_ses_lock);
684         } else {
685                 /* although we can not zero the server struct pointer yet,
686                 since there are active requests which may depnd on them,
687                 mark the corresponding SMB sessions as exiting too */
688                 list_for_each(tmp, &server->smb_ses_list) {
689                         ses = list_entry(tmp, struct cifsSesInfo,
690                                          smb_ses_list);
691                         ses->status = CifsExiting;
692                 }
693
694                 spin_lock(&GlobalMid_Lock);
695                 list_for_each(tmp, &server->pending_mid_q) {
696                 mid_entry = list_entry(tmp, struct mid_q_entry, qhead);
697                         if (mid_entry->midState == MID_REQUEST_SUBMITTED) {
698                                 cFYI(1, "Clearing Mid 0x%x - waking up ",
699                                          mid_entry->mid);
700                                 task_to_wake = mid_entry->tsk;
701                                 if (task_to_wake)
702                                         wake_up_process(task_to_wake);
703                         }
704                 }
705                 spin_unlock(&GlobalMid_Lock);
706                 read_unlock(&cifs_tcp_ses_lock);
707                 /* 1/8th of sec is more than enough time for them to exit */
708                 msleep(125);
709         }
710
711         if (!list_empty(&server->pending_mid_q)) {
712                 /* mpx threads have not exited yet give them
713                 at least the smb send timeout time for long ops */
714                 /* due to delays on oplock break requests, we need
715                 to wait at least 45 seconds before giving up
716                 on a request getting a response and going ahead
717                 and killing cifsd */
718                 cFYI(1, "Wait for exit from demultiplex thread");
719                 msleep(46000);
720                 /* if threads still have not exited they are probably never
721                 coming home not much else we can do but free the memory */
722         }
723
724         /* last chance to mark ses pointers invalid
725         if there are any pointing to this (e.g
726         if a crazy root user tried to kill cifsd
727         kernel thread explicitly this might happen) */
728         /* BB: This shouldn't be necessary, see above */
729         read_lock(&cifs_tcp_ses_lock);
730         list_for_each(tmp, &server->smb_ses_list) {
731                 ses = list_entry(tmp, struct cifsSesInfo, smb_ses_list);
732                 ses->server = NULL;
733         }
734         read_unlock(&cifs_tcp_ses_lock);
735
736         kfree(server->hostname);
737         task_to_wake = xchg(&server->tsk, NULL);
738         kfree(server);
739
740         length = atomic_dec_return(&tcpSesAllocCount);
741         if (length  > 0)
742                 mempool_resize(cifs_req_poolp, length + cifs_min_rcv,
743                                 GFP_KERNEL);
744
745         /* if server->tsk was NULL then wait for a signal before exiting */
746         if (!task_to_wake) {
747                 set_current_state(TASK_INTERRUPTIBLE);
748                 while (!signal_pending(current)) {
749                         schedule();
750                         set_current_state(TASK_INTERRUPTIBLE);
751                 }
752                 set_current_state(TASK_RUNNING);
753         }
754
755         module_put_and_exit(0);
756 }
757
758 /* extract the host portion of the UNC string */
759 static char *
760 extract_hostname(const char *unc)
761 {
762         const char *src;
763         char *dst, *delim;
764         unsigned int len;
765
766         /* skip double chars at beginning of string */
767         /* BB: check validity of these bytes? */
768         src = unc + 2;
769
770         /* delimiter between hostname and sharename is always '\\' now */
771         delim = strchr(src, '\\');
772         if (!delim)
773                 return ERR_PTR(-EINVAL);
774
775         len = delim - src;
776         dst = kmalloc((len + 1), GFP_KERNEL);
777         if (dst == NULL)
778                 return ERR_PTR(-ENOMEM);
779
780         memcpy(dst, src, len);
781         dst[len] = '\0';
782
783         return dst;
784 }
785
786 static int
787 cifs_parse_mount_options(char *options, const char *devname,
788                          struct smb_vol *vol)
789 {
790         char *value;
791         char *data;
792         unsigned int  temp_len, i, j;
793         char separator[2];
794         short int override_uid = -1;
795         short int override_gid = -1;
796         bool uid_specified = false;
797         bool gid_specified = false;
798
799         separator[0] = ',';
800         separator[1] = 0;
801
802         if (Local_System_Name[0] != 0)
803                 memcpy(vol->source_rfc1001_name, Local_System_Name, 15);
804         else {
805                 char *nodename = utsname()->nodename;
806                 int n = strnlen(nodename, 15);
807                 memset(vol->source_rfc1001_name, 0x20, 15);
808                 for (i = 0; i < n; i++) {
809                         /* does not have to be perfect mapping since field is
810                         informational, only used for servers that do not support
811                         port 445 and it can be overridden at mount time */
812                         vol->source_rfc1001_name[i] = toupper(nodename[i]);
813                 }
814         }
815         vol->source_rfc1001_name[15] = 0;
816         /* null target name indicates to use *SMBSERVR default called name
817            if we end up sending RFC1001 session initialize */
818         vol->target_rfc1001_name[0] = 0;
819         vol->cred_uid = current_uid();
820         vol->linux_uid = current_uid();
821         vol->linux_gid = current_gid();
822
823         /* default to only allowing write access to owner of the mount */
824         vol->dir_mode = vol->file_mode = S_IRUGO | S_IXUGO | S_IWUSR;
825
826         /* vol->retry default is 0 (i.e. "soft" limited retry not hard retry) */
827         /* default is always to request posix paths. */
828         vol->posix_paths = 1;
829         /* default to using server inode numbers where available */
830         vol->server_ino = 1;
831
832         if (!options)
833                 return 1;
834
835         if (strncmp(options, "sep=", 4) == 0) {
836                 if (options[4] != 0) {
837                         separator[0] = options[4];
838                         options += 5;
839                 } else {
840                         cFYI(1, "Null separator not allowed");
841                 }
842         }
843
844         while ((data = strsep(&options, separator)) != NULL) {
845                 if (!*data)
846                         continue;
847                 if ((value = strchr(data, '=')) != NULL)
848                         *value++ = '\0';
849
850                 /* Have to parse this before we parse for "user" */
851                 if (strnicmp(data, "user_xattr", 10) == 0) {
852                         vol->no_xattr = 0;
853                 } else if (strnicmp(data, "nouser_xattr", 12) == 0) {
854                         vol->no_xattr = 1;
855                 } else if (strnicmp(data, "user", 4) == 0) {
856                         if (!value) {
857                                 printk(KERN_WARNING
858                                        "CIFS: invalid or missing username\n");
859                                 return 1;       /* needs_arg; */
860                         } else if (!*value) {
861                                 /* null user, ie anonymous, authentication */
862                                 vol->nullauth = 1;
863                         }
864                         if (strnlen(value, 200) < 200) {
865                                 vol->username = value;
866                         } else {
867                                 printk(KERN_WARNING "CIFS: username too long\n");
868                                 return 1;
869                         }
870                 } else if (strnicmp(data, "pass", 4) == 0) {
871                         if (!value) {
872                                 vol->password = NULL;
873                                 continue;
874                         } else if (value[0] == 0) {
875                                 /* check if string begins with double comma
876                                    since that would mean the password really
877                                    does start with a comma, and would not
878                                    indicate an empty string */
879                                 if (value[1] != separator[0]) {
880                                         vol->password = NULL;
881                                         continue;
882                                 }
883                         }
884                         temp_len = strlen(value);
885                         /* removed password length check, NTLM passwords
886                                 can be arbitrarily long */
887
888                         /* if comma in password, the string will be
889                         prematurely null terminated.  Commas in password are
890                         specified across the cifs mount interface by a double
891                         comma ie ,, and a comma used as in other cases ie ','
892                         as a parameter delimiter/separator is single and due
893                         to the strsep above is temporarily zeroed. */
894
895                         /* NB: password legally can have multiple commas and
896                         the only illegal character in a password is null */
897
898                         if ((value[temp_len] == 0) &&
899                             (value[temp_len+1] == separator[0])) {
900                                 /* reinsert comma */
901                                 value[temp_len] = separator[0];
902                                 temp_len += 2;  /* move after second comma */
903                                 while (value[temp_len] != 0)  {
904                                         if (value[temp_len] == separator[0]) {
905                                                 if (value[temp_len+1] ==
906                                                      separator[0]) {
907                                                 /* skip second comma */
908                                                         temp_len++;
909                                                 } else {
910                                                 /* single comma indicating start
911                                                          of next parm */
912                                                         break;
913                                                 }
914                                         }
915                                         temp_len++;
916                                 }
917                                 if (value[temp_len] == 0) {
918                                         options = NULL;
919                                 } else {
920                                         value[temp_len] = 0;
921                                         /* point option to start of next parm */
922                                         options = value + temp_len + 1;
923                                 }
924                                 /* go from value to value + temp_len condensing
925                                 double commas to singles. Note that this ends up
926                                 allocating a few bytes too many, which is ok */
927                                 vol->password = kzalloc(temp_len, GFP_KERNEL);
928                                 if (vol->password == NULL) {
929                                         printk(KERN_WARNING "CIFS: no memory "
930                                                             "for password\n");
931                                         return 1;
932                                 }
933                                 for (i = 0, j = 0; i < temp_len; i++, j++) {
934                                         vol->password[j] = value[i];
935                                         if (value[i] == separator[0]
936                                                 && value[i+1] == separator[0]) {
937                                                 /* skip second comma */
938                                                 i++;
939                                         }
940                                 }
941                                 vol->password[j] = 0;
942                         } else {
943                                 vol->password = kzalloc(temp_len+1, GFP_KERNEL);
944                                 if (vol->password == NULL) {
945                                         printk(KERN_WARNING "CIFS: no memory "
946                                                             "for password\n");
947                                         return 1;
948                                 }
949                                 strcpy(vol->password, value);
950                         }
951                 } else if (!strnicmp(data, "ip", 2) ||
952                            !strnicmp(data, "addr", 4)) {
953                         if (!value || !*value) {
954                                 vol->UNCip = NULL;
955                         } else if (strnlen(value, INET6_ADDRSTRLEN) <
956                                                         INET6_ADDRSTRLEN) {
957                                 vol->UNCip = value;
958                         } else {
959                                 printk(KERN_WARNING "CIFS: ip address "
960                                                     "too long\n");
961                                 return 1;
962                         }
963                 } else if (strnicmp(data, "sec", 3) == 0) {
964                         if (!value || !*value) {
965                                 cERROR(1, "no security value specified");
966                                 continue;
967                         } else if (strnicmp(value, "krb5i", 5) == 0) {
968                                 vol->secFlg |= CIFSSEC_MAY_KRB5 |
969                                         CIFSSEC_MUST_SIGN;
970                         } else if (strnicmp(value, "krb5p", 5) == 0) {
971                                 /* vol->secFlg |= CIFSSEC_MUST_SEAL |
972                                         CIFSSEC_MAY_KRB5; */
973                                 cERROR(1, "Krb5 cifs privacy not supported");
974                                 return 1;
975                         } else if (strnicmp(value, "krb5", 4) == 0) {
976                                 vol->secFlg |= CIFSSEC_MAY_KRB5;
977 #ifdef CONFIG_CIFS_EXPERIMENTAL
978                         } else if (strnicmp(value, "ntlmsspi", 8) == 0) {
979                                 vol->secFlg |= CIFSSEC_MAY_NTLMSSP |
980                                         CIFSSEC_MUST_SIGN;
981                         } else if (strnicmp(value, "ntlmssp", 7) == 0) {
982                                 vol->secFlg |= CIFSSEC_MAY_NTLMSSP;
983 #endif
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, "srcaddr", 7) == 0) {
1051                         vol->srcaddr.ss_family = AF_UNSPEC;
1052
1053                         if (!value || !*value) {
1054                                 printk(KERN_WARNING "CIFS: srcaddr value"
1055                                        " not specified.\n");
1056                                 return 1;       /* needs_arg; */
1057                         }
1058                         i = cifs_convert_address((struct sockaddr *)&vol->srcaddr,
1059                                                  value, strlen(value));
1060                         if (i < 0) {
1061                                 printk(KERN_WARNING "CIFS:  Could not parse"
1062                                        " srcaddr: %s\n",
1063                                        value);
1064                                 return 1;
1065                         }
1066                 } else if (strnicmp(data, "prefixpath", 10) == 0) {
1067                         if (!value || !*value) {
1068                                 printk(KERN_WARNING
1069                                         "CIFS: invalid path prefix\n");
1070                                 return 1;       /* needs_argument */
1071                         }
1072                         if ((temp_len = strnlen(value, 1024)) < 1024) {
1073                                 if (value[0] != '/')
1074                                         temp_len++;  /* missing leading slash */
1075                                 vol->prepath = kmalloc(temp_len+1, GFP_KERNEL);
1076                                 if (vol->prepath == NULL)
1077                                         return 1;
1078                                 if (value[0] != '/') {
1079                                         vol->prepath[0] = '/';
1080                                         strcpy(vol->prepath+1, value);
1081                                 } else
1082                                         strcpy(vol->prepath, value);
1083                                 cFYI(1, "prefix path %s", vol->prepath);
1084                         } else {
1085                                 printk(KERN_WARNING "CIFS: prefix too long\n");
1086                                 return 1;
1087                         }
1088                 } else if (strnicmp(data, "iocharset", 9) == 0) {
1089                         if (!value || !*value) {
1090                                 printk(KERN_WARNING "CIFS: invalid iocharset "
1091                                                     "specified\n");
1092                                 return 1;       /* needs_arg; */
1093                         }
1094                         if (strnlen(value, 65) < 65) {
1095                                 if (strnicmp(value, "default", 7))
1096                                         vol->iocharset = value;
1097                                 /* if iocharset not set then load_nls_default
1098                                    is used by caller */
1099                                 cFYI(1, "iocharset set to %s", value);
1100                         } else {
1101                                 printk(KERN_WARNING "CIFS: iocharset name "
1102                                                     "too long.\n");
1103                                 return 1;
1104                         }
1105                 } else if (!strnicmp(data, "uid", 3) && value && *value) {
1106                         vol->linux_uid = simple_strtoul(value, &value, 0);
1107                         uid_specified = true;
1108                 } else if (!strnicmp(data, "forceuid", 8)) {
1109                         override_uid = 1;
1110                 } else if (!strnicmp(data, "noforceuid", 10)) {
1111                         override_uid = 0;
1112                 } else if (!strnicmp(data, "gid", 3) && value && *value) {
1113                         vol->linux_gid = simple_strtoul(value, &value, 0);
1114                         gid_specified = true;
1115                 } else if (!strnicmp(data, "forcegid", 8)) {
1116                         override_gid = 1;
1117                 } else if (!strnicmp(data, "noforcegid", 10)) {
1118                         override_gid = 0;
1119                 } else if (strnicmp(data, "file_mode", 4) == 0) {
1120                         if (value && *value) {
1121                                 vol->file_mode =
1122                                         simple_strtoul(value, &value, 0);
1123                         }
1124                 } else if (strnicmp(data, "dir_mode", 4) == 0) {
1125                         if (value && *value) {
1126                                 vol->dir_mode =
1127                                         simple_strtoul(value, &value, 0);
1128                         }
1129                 } else if (strnicmp(data, "dirmode", 4) == 0) {
1130                         if (value && *value) {
1131                                 vol->dir_mode =
1132                                         simple_strtoul(value, &value, 0);
1133                         }
1134                 } else if (strnicmp(data, "port", 4) == 0) {
1135                         if (value && *value) {
1136                                 vol->port =
1137                                         simple_strtoul(value, &value, 0);
1138                         }
1139                 } else if (strnicmp(data, "rsize", 5) == 0) {
1140                         if (value && *value) {
1141                                 vol->rsize =
1142                                         simple_strtoul(value, &value, 0);
1143                         }
1144                 } else if (strnicmp(data, "wsize", 5) == 0) {
1145                         if (value && *value) {
1146                                 vol->wsize =
1147                                         simple_strtoul(value, &value, 0);
1148                         }
1149                 } else if (strnicmp(data, "sockopt", 5) == 0) {
1150                         if (!value || !*value) {
1151                                 cERROR(1, "no socket option specified");
1152                                 continue;
1153                         } else if (strnicmp(value, "TCP_NODELAY", 11) == 0) {
1154                                 vol->sockopt_tcp_nodelay = 1;
1155                         }
1156                 } else if (strnicmp(data, "netbiosname", 4) == 0) {
1157                         if (!value || !*value || (*value == ' ')) {
1158                                 cFYI(1, "invalid (empty) netbiosname");
1159                         } else {
1160                                 memset(vol->source_rfc1001_name, 0x20, 15);
1161                                 for (i = 0; i < 15; i++) {
1162                                 /* BB are there cases in which a comma can be
1163                                 valid in this workstation netbios name (and need
1164                                 special handling)? */
1165
1166                                 /* We do not uppercase netbiosname for user */
1167                                         if (value[i] == 0)
1168                                                 break;
1169                                         else
1170                                                 vol->source_rfc1001_name[i] =
1171                                                                 value[i];
1172                                 }
1173                                 /* The string has 16th byte zero still from
1174                                 set at top of the function  */
1175                                 if ((i == 15) && (value[i] != 0))
1176                                         printk(KERN_WARNING "CIFS: netbiosname"
1177                                                 " longer than 15 truncated.\n");
1178                         }
1179                 } else if (strnicmp(data, "servern", 7) == 0) {
1180                         /* servernetbiosname specified override *SMBSERVER */
1181                         if (!value || !*value || (*value == ' ')) {
1182                                 cFYI(1, "empty server netbiosname specified");
1183                         } else {
1184                                 /* last byte, type, is 0x20 for servr type */
1185                                 memset(vol->target_rfc1001_name, 0x20, 16);
1186
1187                                 for (i = 0; i < 15; i++) {
1188                                 /* BB are there cases in which a comma can be
1189                                    valid in this workstation netbios name
1190                                    (and need special handling)? */
1191
1192                                 /* user or mount helper must uppercase
1193                                    the netbiosname */
1194                                         if (value[i] == 0)
1195                                                 break;
1196                                         else
1197                                                 vol->target_rfc1001_name[i] =
1198                                                                 value[i];
1199                                 }
1200                                 /* The string has 16th byte zero still from
1201                                    set at top of the function  */
1202                                 if ((i == 15) && (value[i] != 0))
1203                                         printk(KERN_WARNING "CIFS: server net"
1204                                         "biosname longer than 15 truncated.\n");
1205                         }
1206                 } else if (strnicmp(data, "credentials", 4) == 0) {
1207                         /* ignore */
1208                 } else if (strnicmp(data, "version", 3) == 0) {
1209                         /* ignore */
1210                 } else if (strnicmp(data, "guest", 5) == 0) {
1211                         /* ignore */
1212                 } else if (strnicmp(data, "rw", 2) == 0) {
1213                         /* ignore */
1214                 } else if (strnicmp(data, "ro", 2) == 0) {
1215                         /* ignore */
1216                 } else if (strnicmp(data, "noblocksend", 11) == 0) {
1217                         vol->noblocksnd = 1;
1218                 } else if (strnicmp(data, "noautotune", 10) == 0) {
1219                         vol->noautotune = 1;
1220                 } else if ((strnicmp(data, "suid", 4) == 0) ||
1221                                    (strnicmp(data, "nosuid", 6) == 0) ||
1222                                    (strnicmp(data, "exec", 4) == 0) ||
1223                                    (strnicmp(data, "noexec", 6) == 0) ||
1224                                    (strnicmp(data, "nodev", 5) == 0) ||
1225                                    (strnicmp(data, "noauto", 6) == 0) ||
1226                                    (strnicmp(data, "dev", 3) == 0)) {
1227                         /*  The mount tool or mount.cifs helper (if present)
1228                             uses these opts to set flags, and the flags are read
1229                             by the kernel vfs layer before we get here (ie
1230                             before read super) so there is no point trying to
1231                             parse these options again and set anything and it
1232                             is ok to just ignore them */
1233                         continue;
1234                 } else if (strnicmp(data, "hard", 4) == 0) {
1235                         vol->retry = 1;
1236                 } else if (strnicmp(data, "soft", 4) == 0) {
1237                         vol->retry = 0;
1238                 } else if (strnicmp(data, "perm", 4) == 0) {
1239                         vol->noperm = 0;
1240                 } else if (strnicmp(data, "noperm", 6) == 0) {
1241                         vol->noperm = 1;
1242                 } else if (strnicmp(data, "mapchars", 8) == 0) {
1243                         vol->remap = 1;
1244                 } else if (strnicmp(data, "nomapchars", 10) == 0) {
1245                         vol->remap = 0;
1246                 } else if (strnicmp(data, "sfu", 3) == 0) {
1247                         vol->sfu_emul = 1;
1248                 } else if (strnicmp(data, "nosfu", 5) == 0) {
1249                         vol->sfu_emul = 0;
1250                 } else if (strnicmp(data, "nodfs", 5) == 0) {
1251                         vol->nodfs = 1;
1252                 } else if (strnicmp(data, "posixpaths", 10) == 0) {
1253                         vol->posix_paths = 1;
1254                 } else if (strnicmp(data, "noposixpaths", 12) == 0) {
1255                         vol->posix_paths = 0;
1256                 } else if (strnicmp(data, "nounix", 6) == 0) {
1257                         vol->no_linux_ext = 1;
1258                 } else if (strnicmp(data, "nolinux", 7) == 0) {
1259                         vol->no_linux_ext = 1;
1260                 } else if ((strnicmp(data, "nocase", 6) == 0) ||
1261                            (strnicmp(data, "ignorecase", 10)  == 0)) {
1262                         vol->nocase = 1;
1263                 } else if (strnicmp(data, "mand", 4) == 0) {
1264                         /* ignore */
1265                 } else if (strnicmp(data, "nomand", 6) == 0) {
1266                         /* ignore */
1267                 } else if (strnicmp(data, "_netdev", 7) == 0) {
1268                         /* ignore */
1269                 } else if (strnicmp(data, "brl", 3) == 0) {
1270                         vol->nobrl =  0;
1271                 } else if ((strnicmp(data, "nobrl", 5) == 0) ||
1272                            (strnicmp(data, "nolock", 6) == 0)) {
1273                         vol->nobrl =  1;
1274                         /* turn off mandatory locking in mode
1275                         if remote locking is turned off since the
1276                         local vfs will do advisory */
1277                         if (vol->file_mode ==
1278                                 (S_IALLUGO & ~(S_ISUID | S_IXGRP)))
1279                                 vol->file_mode = S_IALLUGO;
1280                 } else if (strnicmp(data, "forcemandatorylock", 9) == 0) {
1281                         /* will take the shorter form "forcemand" as well */
1282                         /* This mount option will force use of mandatory
1283                           (DOS/Windows style) byte range locks, instead of
1284                           using posix advisory byte range locks, even if the
1285                           Unix extensions are available and posix locks would
1286                           be supported otherwise. If Unix extensions are not
1287                           negotiated this has no effect since mandatory locks
1288                           would be used (mandatory locks is all that those
1289                           those servers support) */
1290                         vol->mand_lock = 1;
1291                 } else if (strnicmp(data, "setuids", 7) == 0) {
1292                         vol->setuids = 1;
1293                 } else if (strnicmp(data, "nosetuids", 9) == 0) {
1294                         vol->setuids = 0;
1295                 } else if (strnicmp(data, "dynperm", 7) == 0) {
1296                         vol->dynperm = true;
1297                 } else if (strnicmp(data, "nodynperm", 9) == 0) {
1298                         vol->dynperm = false;
1299                 } else if (strnicmp(data, "nohard", 6) == 0) {
1300                         vol->retry = 0;
1301                 } else if (strnicmp(data, "nosoft", 6) == 0) {
1302                         vol->retry = 1;
1303                 } else if (strnicmp(data, "nointr", 6) == 0) {
1304                         vol->intr = 0;
1305                 } else if (strnicmp(data, "intr", 4) == 0) {
1306                         vol->intr = 1;
1307                 } else if (strnicmp(data, "nostrictsync", 12) == 0) {
1308                         vol->nostrictsync = 1;
1309                 } else if (strnicmp(data, "strictsync", 10) == 0) {
1310                         vol->nostrictsync = 0;
1311                 } else if (strnicmp(data, "serverino", 7) == 0) {
1312                         vol->server_ino = 1;
1313                 } else if (strnicmp(data, "noserverino", 9) == 0) {
1314                         vol->server_ino = 0;
1315                 } else if (strnicmp(data, "cifsacl", 7) == 0) {
1316                         vol->cifs_acl = 1;
1317                 } else if (strnicmp(data, "nocifsacl", 9) == 0) {
1318                         vol->cifs_acl = 0;
1319                 } else if (strnicmp(data, "acl", 3) == 0) {
1320                         vol->no_psx_acl = 0;
1321                 } else if (strnicmp(data, "noacl", 5) == 0) {
1322                         vol->no_psx_acl = 1;
1323 #ifdef CONFIG_CIFS_EXPERIMENTAL
1324                 } else if (strnicmp(data, "locallease", 6) == 0) {
1325                         vol->local_lease = 1;
1326 #endif
1327                 } else if (strnicmp(data, "sign", 4) == 0) {
1328                         vol->secFlg |= CIFSSEC_MUST_SIGN;
1329                 } else if (strnicmp(data, "seal", 4) == 0) {
1330                         /* we do not do the following in secFlags because seal
1331                            is a per tree connection (mount) not a per socket
1332                            or per-smb connection option in the protocol */
1333                         /* vol->secFlg |= CIFSSEC_MUST_SEAL; */
1334                         vol->seal = 1;
1335                 } else if (strnicmp(data, "direct", 6) == 0) {
1336                         vol->direct_io = 1;
1337                 } else if (strnicmp(data, "forcedirectio", 13) == 0) {
1338                         vol->direct_io = 1;
1339                 } else if (strnicmp(data, "noac", 4) == 0) {
1340                         printk(KERN_WARNING "CIFS: Mount option noac not "
1341                                 "supported. Instead set "
1342                                 "/proc/fs/cifs/LookupCacheEnabled to 0\n");
1343                 } else if (strnicmp(data, "fsc", 3) == 0) {
1344                         vol->fsc = true;
1345                 } else if (strnicmp(data, "mfsymlinks", 10) == 0) {
1346                         vol->mfsymlinks = true;
1347                 } else
1348                         printk(KERN_WARNING "CIFS: Unknown mount option %s\n",
1349                                                 data);
1350         }
1351         if (vol->UNC == NULL) {
1352                 if (devname == NULL) {
1353                         printk(KERN_WARNING "CIFS: Missing UNC name for mount "
1354                                                 "target\n");
1355                         return 1;
1356                 }
1357                 if ((temp_len = strnlen(devname, 300)) < 300) {
1358                         vol->UNC = kmalloc(temp_len+1, GFP_KERNEL);
1359                         if (vol->UNC == NULL)
1360                                 return 1;
1361                         strcpy(vol->UNC, devname);
1362                         if (strncmp(vol->UNC, "//", 2) == 0) {
1363                                 vol->UNC[0] = '\\';
1364                                 vol->UNC[1] = '\\';
1365                         } else if (strncmp(vol->UNC, "\\\\", 2) != 0) {
1366                                 printk(KERN_WARNING "CIFS: UNC Path does not "
1367                                                     "begin with // or \\\\ \n");
1368                                 return 1;
1369                         }
1370                         value = strpbrk(vol->UNC+2, "/\\");
1371                         if (value)
1372                                 *value = '\\';
1373                 } else {
1374                         printk(KERN_WARNING "CIFS: UNC name too long\n");
1375                         return 1;
1376                 }
1377         }
1378         if (vol->UNCip == NULL)
1379                 vol->UNCip = &vol->UNC[2];
1380
1381         if (uid_specified)
1382                 vol->override_uid = override_uid;
1383         else if (override_uid == 1)
1384                 printk(KERN_NOTICE "CIFS: ignoring forceuid mount option "
1385                                    "specified with no uid= option.\n");
1386
1387         if (gid_specified)
1388                 vol->override_gid = override_gid;
1389         else if (override_gid == 1)
1390                 printk(KERN_NOTICE "CIFS: ignoring forcegid mount option "
1391                                    "specified with no gid= option.\n");
1392
1393         return 0;
1394 }
1395
1396 /** Returns true if srcaddr isn't specified and rhs isn't
1397  * specified, or if srcaddr is specified and
1398  * matches the IP address of the rhs argument.
1399  */
1400 static bool
1401 srcip_matches(struct sockaddr *srcaddr, struct sockaddr *rhs)
1402 {
1403         switch (srcaddr->sa_family) {
1404         case AF_UNSPEC:
1405                 return (rhs->sa_family == AF_UNSPEC);
1406         case AF_INET: {
1407                 struct sockaddr_in *saddr4 = (struct sockaddr_in *)srcaddr;
1408                 struct sockaddr_in *vaddr4 = (struct sockaddr_in *)rhs;
1409                 return (saddr4->sin_addr.s_addr == vaddr4->sin_addr.s_addr);
1410         }
1411         case AF_INET6: {
1412                 struct sockaddr_in6 *saddr6 = (struct sockaddr_in6 *)srcaddr;
1413                 struct sockaddr_in6 *vaddr6 = (struct sockaddr_in6 *)&rhs;
1414                 return ipv6_addr_equal(&saddr6->sin6_addr, &vaddr6->sin6_addr);
1415         }
1416         default:
1417                 WARN_ON(1);
1418                 return false; /* don't expect to be here */
1419         }
1420 }
1421
1422
1423 static bool
1424 match_address(struct TCP_Server_Info *server, struct sockaddr *addr,
1425               struct sockaddr *srcaddr)
1426 {
1427         struct sockaddr_in *addr4 = (struct sockaddr_in *)addr;
1428         struct sockaddr_in6 *addr6 = (struct sockaddr_in6 *)addr;
1429
1430         switch (addr->sa_family) {
1431         case AF_INET:
1432                 if (addr4->sin_addr.s_addr !=
1433                     server->addr.sockAddr.sin_addr.s_addr)
1434                         return false;
1435                 if (addr4->sin_port &&
1436                     addr4->sin_port != server->addr.sockAddr.sin_port)
1437                         return false;
1438                 break;
1439         case AF_INET6:
1440                 if (!ipv6_addr_equal(&addr6->sin6_addr,
1441                                      &server->addr.sockAddr6.sin6_addr))
1442                         return false;
1443                 if (addr6->sin6_scope_id !=
1444                     server->addr.sockAddr6.sin6_scope_id)
1445                         return false;
1446                 if (addr6->sin6_port &&
1447                     addr6->sin6_port != server->addr.sockAddr6.sin6_port)
1448                         return false;
1449                 break;
1450         }
1451
1452         if (!srcip_matches(srcaddr, (struct sockaddr *)&server->srcaddr))
1453                 return false;
1454
1455         return true;
1456 }
1457
1458 static bool
1459 match_security(struct TCP_Server_Info *server, struct smb_vol *vol)
1460 {
1461         unsigned int secFlags;
1462
1463         if (vol->secFlg & (~(CIFSSEC_MUST_SIGN | CIFSSEC_MUST_SEAL)))
1464                 secFlags = vol->secFlg;
1465         else
1466                 secFlags = global_secflags | vol->secFlg;
1467
1468         switch (server->secType) {
1469         case LANMAN:
1470                 if (!(secFlags & (CIFSSEC_MAY_LANMAN|CIFSSEC_MAY_PLNTXT)))
1471                         return false;
1472                 break;
1473         case NTLMv2:
1474                 if (!(secFlags & CIFSSEC_MAY_NTLMV2))
1475                         return false;
1476                 break;
1477         case NTLM:
1478                 if (!(secFlags & CIFSSEC_MAY_NTLM))
1479                         return false;
1480                 break;
1481         case Kerberos:
1482                 if (!(secFlags & CIFSSEC_MAY_KRB5))
1483                         return false;
1484                 break;
1485         case RawNTLMSSP:
1486                 if (!(secFlags & CIFSSEC_MAY_NTLMSSP))
1487                         return false;
1488                 break;
1489         default:
1490                 /* shouldn't happen */
1491                 return false;
1492         }
1493
1494         /* now check if signing mode is acceptible */
1495         if ((secFlags & CIFSSEC_MAY_SIGN) == 0 &&
1496             (server->secMode & SECMODE_SIGN_REQUIRED))
1497                         return false;
1498         else if (((secFlags & CIFSSEC_MUST_SIGN) == CIFSSEC_MUST_SIGN) &&
1499                  (server->secMode &
1500                   (SECMODE_SIGN_ENABLED|SECMODE_SIGN_REQUIRED)) == 0)
1501                         return false;
1502
1503         return true;
1504 }
1505
1506 static struct TCP_Server_Info *
1507 cifs_find_tcp_session(struct sockaddr *addr, struct smb_vol *vol)
1508 {
1509         struct TCP_Server_Info *server;
1510
1511         write_lock(&cifs_tcp_ses_lock);
1512         list_for_each_entry(server, &cifs_tcp_ses_list, tcp_ses_list) {
1513                 if (!match_address(server, addr,
1514                                    (struct sockaddr *)&vol->srcaddr))
1515                         continue;
1516
1517                 if (!match_security(server, vol))
1518                         continue;
1519
1520                 ++server->srv_count;
1521                 write_unlock(&cifs_tcp_ses_lock);
1522                 cFYI(1, "Existing tcp session with server found");
1523                 return server;
1524         }
1525         write_unlock(&cifs_tcp_ses_lock);
1526         return NULL;
1527 }
1528
1529 static void
1530 cifs_put_tcp_session(struct TCP_Server_Info *server)
1531 {
1532         struct task_struct *task;
1533
1534         write_lock(&cifs_tcp_ses_lock);
1535         if (--server->srv_count > 0) {
1536                 write_unlock(&cifs_tcp_ses_lock);
1537                 return;
1538         }
1539
1540         list_del_init(&server->tcp_ses_list);
1541         write_unlock(&cifs_tcp_ses_lock);
1542
1543         spin_lock(&GlobalMid_Lock);
1544         server->tcpStatus = CifsExiting;
1545         spin_unlock(&GlobalMid_Lock);
1546
1547         cifs_fscache_release_client_cookie(server);
1548
1549         task = xchg(&server->tsk, NULL);
1550         if (task)
1551                 force_sig(SIGKILL, task);
1552 }
1553
1554 static struct TCP_Server_Info *
1555 cifs_get_tcp_session(struct smb_vol *volume_info)
1556 {
1557         struct TCP_Server_Info *tcp_ses = NULL;
1558         struct sockaddr_storage addr;
1559         struct sockaddr_in *sin_server = (struct sockaddr_in *) &addr;
1560         struct sockaddr_in6 *sin_server6 = (struct sockaddr_in6 *) &addr;
1561         int rc;
1562
1563         memset(&addr, 0, sizeof(struct sockaddr_storage));
1564
1565         cFYI(1, "UNC: %s ip: %s", volume_info->UNC, volume_info->UNCip);
1566
1567         if (volume_info->UNCip && volume_info->UNC) {
1568                 rc = cifs_fill_sockaddr((struct sockaddr *)&addr,
1569                                         volume_info->UNCip,
1570                                         strlen(volume_info->UNCip),
1571                                         volume_info->port);
1572                 if (!rc) {
1573                         /* we failed translating address */
1574                         rc = -EINVAL;
1575                         goto out_err;
1576                 }
1577         } else if (volume_info->UNCip) {
1578                 /* BB using ip addr as tcp_ses name to connect to the
1579                    DFS root below */
1580                 cERROR(1, "Connecting to DFS root not implemented yet");
1581                 rc = -EINVAL;
1582                 goto out_err;
1583         } else /* which tcp_sess DFS root would we conect to */ {
1584                 cERROR(1, "CIFS mount error: No UNC path (e.g. -o "
1585                         "unc=//192.168.1.100/public) specified");
1586                 rc = -EINVAL;
1587                 goto out_err;
1588         }
1589
1590         /* see if we already have a matching tcp_ses */
1591         tcp_ses = cifs_find_tcp_session((struct sockaddr *)&addr, volume_info);
1592         if (tcp_ses)
1593                 return tcp_ses;
1594
1595         tcp_ses = kzalloc(sizeof(struct TCP_Server_Info), GFP_KERNEL);
1596         if (!tcp_ses) {
1597                 rc = -ENOMEM;
1598                 goto out_err;
1599         }
1600
1601         tcp_ses->hostname = extract_hostname(volume_info->UNC);
1602         if (IS_ERR(tcp_ses->hostname)) {
1603                 rc = PTR_ERR(tcp_ses->hostname);
1604                 goto out_err;
1605         }
1606
1607         tcp_ses->noblocksnd = volume_info->noblocksnd;
1608         tcp_ses->noautotune = volume_info->noautotune;
1609         tcp_ses->tcp_nodelay = volume_info->sockopt_tcp_nodelay;
1610         atomic_set(&tcp_ses->inFlight, 0);
1611         init_waitqueue_head(&tcp_ses->response_q);
1612         init_waitqueue_head(&tcp_ses->request_q);
1613         INIT_LIST_HEAD(&tcp_ses->pending_mid_q);
1614         mutex_init(&tcp_ses->srv_mutex);
1615         memcpy(tcp_ses->workstation_RFC1001_name,
1616                 volume_info->source_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1617         memcpy(tcp_ses->server_RFC1001_name,
1618                 volume_info->target_rfc1001_name, RFC1001_NAME_LEN_WITH_NULL);
1619         tcp_ses->sequence_number = 0;
1620         INIT_LIST_HEAD(&tcp_ses->tcp_ses_list);
1621         INIT_LIST_HEAD(&tcp_ses->smb_ses_list);
1622
1623         /*
1624          * at this point we are the only ones with the pointer
1625          * to the struct since the kernel thread not created yet
1626          * no need to spinlock this init of tcpStatus or srv_count
1627          */
1628         tcp_ses->tcpStatus = CifsNew;
1629         memcpy(&tcp_ses->srcaddr, &volume_info->srcaddr,
1630                sizeof(tcp_ses->srcaddr));
1631         ++tcp_ses->srv_count;
1632
1633         if (addr.ss_family == AF_INET6) {
1634                 cFYI(1, "attempting ipv6 connect");
1635                 /* BB should we allow ipv6 on port 139? */
1636                 /* other OS never observed in Wild doing 139 with v6 */
1637                 memcpy(&tcp_ses->addr.sockAddr6, sin_server6,
1638                         sizeof(struct sockaddr_in6));
1639                 rc = ipv6_connect(tcp_ses);
1640         } else {
1641                 memcpy(&tcp_ses->addr.sockAddr, sin_server,
1642                         sizeof(struct sockaddr_in));
1643                 rc = ipv4_connect(tcp_ses);
1644         }
1645         if (rc < 0) {
1646                 cERROR(1, "Error connecting to socket. Aborting operation");
1647                 goto out_err;
1648         }
1649
1650         /*
1651          * since we're in a cifs function already, we know that
1652          * this will succeed. No need for try_module_get().
1653          */
1654         __module_get(THIS_MODULE);
1655         tcp_ses->tsk = kthread_run((void *)(void *)cifs_demultiplex_thread,
1656                                   tcp_ses, "cifsd");
1657         if (IS_ERR(tcp_ses->tsk)) {
1658                 rc = PTR_ERR(tcp_ses->tsk);
1659                 cERROR(1, "error %d create cifsd thread", rc);
1660                 module_put(THIS_MODULE);
1661                 goto out_err;
1662         }
1663
1664         /* thread spawned, put it on the list */
1665         write_lock(&cifs_tcp_ses_lock);
1666         list_add(&tcp_ses->tcp_ses_list, &cifs_tcp_ses_list);
1667         write_unlock(&cifs_tcp_ses_lock);
1668
1669         cifs_fscache_get_client_cookie(tcp_ses);
1670
1671         return tcp_ses;
1672
1673 out_err:
1674         if (tcp_ses) {
1675                 if (!IS_ERR(tcp_ses->hostname))
1676                         kfree(tcp_ses->hostname);
1677                 if (tcp_ses->ssocket)
1678                         sock_release(tcp_ses->ssocket);
1679                 kfree(tcp_ses);
1680         }
1681         return ERR_PTR(rc);
1682 }
1683
1684 static struct cifsSesInfo *
1685 cifs_find_smb_ses(struct TCP_Server_Info *server, struct smb_vol *vol)
1686 {
1687         struct cifsSesInfo *ses;
1688
1689         write_lock(&cifs_tcp_ses_lock);
1690         list_for_each_entry(ses, &server->smb_ses_list, smb_ses_list) {
1691                 switch (server->secType) {
1692                 case Kerberos:
1693                         if (vol->cred_uid != ses->cred_uid)
1694                                 continue;
1695                         break;
1696                 default:
1697                         /* anything else takes username/password */
1698                         if (strncmp(ses->userName, vol->username,
1699                                     MAX_USERNAME_SIZE))
1700                                 continue;
1701                         if (strlen(vol->username) != 0 &&
1702                             ses->password != NULL &&
1703                             strncmp(ses->password,
1704                                     vol->password ? vol->password : "",
1705                                     MAX_PASSWORD_SIZE))
1706                                 continue;
1707                 }
1708                 ++ses->ses_count;
1709                 write_unlock(&cifs_tcp_ses_lock);
1710                 return ses;
1711         }
1712         write_unlock(&cifs_tcp_ses_lock);
1713         return NULL;
1714 }
1715
1716 static void
1717 cifs_put_smb_ses(struct cifsSesInfo *ses)
1718 {
1719         int xid;
1720         struct TCP_Server_Info *server = ses->server;
1721
1722         cFYI(1, "%s: ses_count=%d\n", __func__, ses->ses_count);
1723         write_lock(&cifs_tcp_ses_lock);
1724         if (--ses->ses_count > 0) {
1725                 write_unlock(&cifs_tcp_ses_lock);
1726                 return;
1727         }
1728
1729         list_del_init(&ses->smb_ses_list);
1730         write_unlock(&cifs_tcp_ses_lock);
1731
1732         if (ses->status == CifsGood) {
1733                 xid = GetXid();
1734                 CIFSSMBLogoff(xid, ses);
1735                 _FreeXid(xid);
1736         }
1737         sesInfoFree(ses);
1738         cifs_put_tcp_session(server);
1739 }
1740
1741 static struct cifsSesInfo *
1742 cifs_get_smb_ses(struct TCP_Server_Info *server, struct smb_vol *volume_info)
1743 {
1744         int rc = -ENOMEM, xid;
1745         struct cifsSesInfo *ses;
1746
1747         xid = GetXid();
1748
1749         ses = cifs_find_smb_ses(server, volume_info);
1750         if (ses) {
1751                 cFYI(1, "Existing smb sess found (status=%d)", ses->status);
1752
1753                 mutex_lock(&ses->session_mutex);
1754                 rc = cifs_negotiate_protocol(xid, ses);
1755                 if (rc) {
1756                         mutex_unlock(&ses->session_mutex);
1757                         /* problem -- put our ses reference */
1758                         cifs_put_smb_ses(ses);
1759                         FreeXid(xid);
1760                         return ERR_PTR(rc);
1761                 }
1762                 if (ses->need_reconnect) {
1763                         cFYI(1, "Session needs reconnect");
1764                         rc = cifs_setup_session(xid, ses,
1765                                                 volume_info->local_nls);
1766                         if (rc) {
1767                                 mutex_unlock(&ses->session_mutex);
1768                                 /* problem -- put our reference */
1769                                 cifs_put_smb_ses(ses);
1770                                 FreeXid(xid);
1771                                 return ERR_PTR(rc);
1772                         }
1773                 }
1774                 mutex_unlock(&ses->session_mutex);
1775
1776                 /* existing SMB ses has a server reference already */
1777                 cifs_put_tcp_session(server);
1778                 FreeXid(xid);
1779                 return ses;
1780         }
1781
1782         cFYI(1, "Existing smb sess not found");
1783         ses = sesInfoAlloc();
1784         if (ses == NULL)
1785                 goto get_ses_fail;
1786
1787         ses->tilen = 0;
1788         ses->tiblob = NULL;
1789         /* new SMB session uses our server ref */
1790         ses->server = server;
1791         if (server->addr.sockAddr6.sin6_family == AF_INET6)
1792                 sprintf(ses->serverName, "%pI6",
1793                         &server->addr.sockAddr6.sin6_addr);
1794         else
1795                 sprintf(ses->serverName, "%pI4",
1796                         &server->addr.sockAddr.sin_addr.s_addr);
1797
1798         if (volume_info->username)
1799                 strncpy(ses->userName, volume_info->username,
1800                         MAX_USERNAME_SIZE);
1801
1802         /* volume_info->password freed at unmount */
1803         if (volume_info->password) {
1804                 ses->password = kstrdup(volume_info->password, GFP_KERNEL);
1805                 if (!ses->password)
1806                         goto get_ses_fail;
1807         }
1808         if (volume_info->domainname) {
1809                 int len = strlen(volume_info->domainname);
1810                 ses->domainName = kmalloc(len + 1, GFP_KERNEL);
1811                 if (ses->domainName)
1812                         strcpy(ses->domainName, volume_info->domainname);
1813         }
1814         ses->cred_uid = volume_info->cred_uid;
1815         ses->linux_uid = volume_info->linux_uid;
1816         ses->overrideSecFlg = volume_info->secFlg;
1817
1818         mutex_lock(&ses->session_mutex);
1819         rc = cifs_negotiate_protocol(xid, ses);
1820         if (!rc)
1821                 rc = cifs_setup_session(xid, ses, volume_info->local_nls);
1822         mutex_unlock(&ses->session_mutex);
1823         if (rc)
1824                 goto get_ses_fail;
1825
1826         /* success, put it on the list */
1827         write_lock(&cifs_tcp_ses_lock);
1828         list_add(&ses->smb_ses_list, &server->smb_ses_list);
1829         write_unlock(&cifs_tcp_ses_lock);
1830
1831         FreeXid(xid);
1832         return ses;
1833
1834 get_ses_fail:
1835         sesInfoFree(ses);
1836         FreeXid(xid);
1837         return ERR_PTR(rc);
1838 }
1839
1840 static struct cifsTconInfo *
1841 cifs_find_tcon(struct cifsSesInfo *ses, const char *unc)
1842 {
1843         struct list_head *tmp;
1844         struct cifsTconInfo *tcon;
1845
1846         write_lock(&cifs_tcp_ses_lock);
1847         list_for_each(tmp, &ses->tcon_list) {
1848                 tcon = list_entry(tmp, struct cifsTconInfo, tcon_list);
1849                 if (tcon->tidStatus == CifsExiting)
1850                         continue;
1851                 if (strncmp(tcon->treeName, unc, MAX_TREE_SIZE))
1852                         continue;
1853
1854                 ++tcon->tc_count;
1855                 write_unlock(&cifs_tcp_ses_lock);
1856                 return tcon;
1857         }
1858         write_unlock(&cifs_tcp_ses_lock);
1859         return NULL;
1860 }
1861
1862 static void
1863 cifs_put_tcon(struct cifsTconInfo *tcon)
1864 {
1865         int xid;
1866         struct cifsSesInfo *ses = tcon->ses;
1867
1868         cFYI(1, "%s: tc_count=%d\n", __func__, tcon->tc_count);
1869         write_lock(&cifs_tcp_ses_lock);
1870         if (--tcon->tc_count > 0) {
1871                 write_unlock(&cifs_tcp_ses_lock);
1872                 return;
1873         }
1874
1875         list_del_init(&tcon->tcon_list);
1876         write_unlock(&cifs_tcp_ses_lock);
1877
1878         xid = GetXid();
1879         CIFSSMBTDis(xid, tcon);
1880         _FreeXid(xid);
1881
1882         cifs_fscache_release_super_cookie(tcon);
1883         tconInfoFree(tcon);
1884         cifs_put_smb_ses(ses);
1885 }
1886
1887 static struct cifsTconInfo *
1888 cifs_get_tcon(struct cifsSesInfo *ses, struct smb_vol *volume_info)
1889 {
1890         int rc, xid;
1891         struct cifsTconInfo *tcon;
1892
1893         tcon = cifs_find_tcon(ses, volume_info->UNC);
1894         if (tcon) {
1895                 cFYI(1, "Found match on UNC path");
1896                 /* existing tcon already has a reference */
1897                 cifs_put_smb_ses(ses);
1898                 if (tcon->seal != volume_info->seal)
1899                         cERROR(1, "transport encryption setting "
1900                                    "conflicts with existing tid");
1901                 return tcon;
1902         }
1903
1904         tcon = tconInfoAlloc();
1905         if (tcon == NULL) {
1906                 rc = -ENOMEM;
1907                 goto out_fail;
1908         }
1909
1910         tcon->ses = ses;
1911         if (volume_info->password) {
1912                 tcon->password = kstrdup(volume_info->password, GFP_KERNEL);
1913                 if (!tcon->password) {
1914                         rc = -ENOMEM;
1915                         goto out_fail;
1916                 }
1917         }
1918
1919         if (strchr(volume_info->UNC + 3, '\\') == NULL
1920             && strchr(volume_info->UNC + 3, '/') == NULL) {
1921                 cERROR(1, "Missing share name");
1922                 rc = -ENODEV;
1923                 goto out_fail;
1924         }
1925
1926         /* BB Do we need to wrap session_mutex around
1927          * this TCon call and Unix SetFS as
1928          * we do on SessSetup and reconnect? */
1929         xid = GetXid();
1930         rc = CIFSTCon(xid, ses, volume_info->UNC, tcon, volume_info->local_nls);
1931         FreeXid(xid);
1932         cFYI(1, "CIFS Tcon rc = %d", rc);
1933         if (rc)
1934                 goto out_fail;
1935
1936         if (volume_info->nodfs) {
1937                 tcon->Flags &= ~SMB_SHARE_IS_IN_DFS;
1938                 cFYI(1, "DFS disabled (%d)", tcon->Flags);
1939         }
1940         tcon->seal = volume_info->seal;
1941         /* we can have only one retry value for a connection
1942            to a share so for resources mounted more than once
1943            to the same server share the last value passed in
1944            for the retry flag is used */
1945         tcon->retry = volume_info->retry;
1946         tcon->nocase = volume_info->nocase;
1947         tcon->local_lease = volume_info->local_lease;
1948
1949         write_lock(&cifs_tcp_ses_lock);
1950         list_add(&tcon->tcon_list, &ses->tcon_list);
1951         write_unlock(&cifs_tcp_ses_lock);
1952
1953         cifs_fscache_get_super_cookie(tcon);
1954
1955         return tcon;
1956
1957 out_fail:
1958         tconInfoFree(tcon);
1959         return ERR_PTR(rc);
1960 }
1961
1962
1963 int
1964 get_dfs_path(int xid, struct cifsSesInfo *pSesInfo, const char *old_path,
1965              const struct nls_table *nls_codepage, unsigned int *pnum_referrals,
1966              struct dfs_info3_param **preferrals, int remap)
1967 {
1968         char *temp_unc;
1969         int rc = 0;
1970
1971         *pnum_referrals = 0;
1972         *preferrals = NULL;
1973
1974         if (pSesInfo->ipc_tid == 0) {
1975                 temp_unc = kmalloc(2 /* for slashes */ +
1976                         strnlen(pSesInfo->serverName,
1977                                 SERVER_NAME_LEN_WITH_NULL * 2)
1978                                  + 1 + 4 /* slash IPC$ */  + 2,
1979                                 GFP_KERNEL);
1980                 if (temp_unc == NULL)
1981                         return -ENOMEM;
1982                 temp_unc[0] = '\\';
1983                 temp_unc[1] = '\\';
1984                 strcpy(temp_unc + 2, pSesInfo->serverName);
1985                 strcpy(temp_unc + 2 + strlen(pSesInfo->serverName), "\\IPC$");
1986                 rc = CIFSTCon(xid, pSesInfo, temp_unc, NULL, nls_codepage);
1987                 cFYI(1, "CIFS Tcon rc = %d ipc_tid = %d", rc, pSesInfo->ipc_tid);
1988                 kfree(temp_unc);
1989         }
1990         if (rc == 0)
1991                 rc = CIFSGetDFSRefer(xid, pSesInfo, old_path, preferrals,
1992                                      pnum_referrals, nls_codepage, remap);
1993         /* BB map targetUNCs to dfs_info3 structures, here or
1994                 in CIFSGetDFSRefer BB */
1995
1996         return rc;
1997 }
1998
1999 #ifdef CONFIG_DEBUG_LOCK_ALLOC
2000 static struct lock_class_key cifs_key[2];
2001 static struct lock_class_key cifs_slock_key[2];
2002
2003 static inline void
2004 cifs_reclassify_socket4(struct socket *sock)
2005 {
2006         struct sock *sk = sock->sk;
2007         BUG_ON(sock_owned_by_user(sk));
2008         sock_lock_init_class_and_name(sk, "slock-AF_INET-CIFS",
2009                 &cifs_slock_key[0], "sk_lock-AF_INET-CIFS", &cifs_key[0]);
2010 }
2011
2012 static inline void
2013 cifs_reclassify_socket6(struct socket *sock)
2014 {
2015         struct sock *sk = sock->sk;
2016         BUG_ON(sock_owned_by_user(sk));
2017         sock_lock_init_class_and_name(sk, "slock-AF_INET6-CIFS",
2018                 &cifs_slock_key[1], "sk_lock-AF_INET6-CIFS", &cifs_key[1]);
2019 }
2020 #else
2021 static inline void
2022 cifs_reclassify_socket4(struct socket *sock)
2023 {
2024 }
2025
2026 static inline void
2027 cifs_reclassify_socket6(struct socket *sock)
2028 {
2029 }
2030 #endif
2031
2032 /* See RFC1001 section 14 on representation of Netbios names */
2033 static void rfc1002mangle(char *target, char *source, unsigned int length)
2034 {
2035         unsigned int i, j;
2036
2037         for (i = 0, j = 0; i < (length); i++) {
2038                 /* mask a nibble at a time and encode */
2039                 target[j] = 'A' + (0x0F & (source[i] >> 4));
2040                 target[j+1] = 'A' + (0x0F & source[i]);
2041                 j += 2;
2042         }
2043
2044 }
2045
2046 static int
2047 bind_socket(struct TCP_Server_Info *server)
2048 {
2049         int rc = 0;
2050         if (server->srcaddr.ss_family != AF_UNSPEC) {
2051                 /* Bind to the specified local IP address */
2052                 struct socket *socket = server->ssocket;
2053                 rc = socket->ops->bind(socket,
2054                                        (struct sockaddr *) &server->srcaddr,
2055                                        sizeof(server->srcaddr));
2056                 if (rc < 0) {
2057                         struct sockaddr_in *saddr4;
2058                         struct sockaddr_in6 *saddr6;
2059                         saddr4 = (struct sockaddr_in *)&server->srcaddr;
2060                         saddr6 = (struct sockaddr_in6 *)&server->srcaddr;
2061                         if (saddr6->sin6_family == AF_INET6)
2062                                 cERROR(1, "cifs: "
2063                                        "Failed to bind to: %pI6c, error: %d\n",
2064                                        &saddr6->sin6_addr, rc);
2065                         else
2066                                 cERROR(1, "cifs: "
2067                                        "Failed to bind to: %pI4, error: %d\n",
2068                                        &saddr4->sin_addr.s_addr, rc);
2069                 }
2070         }
2071         return rc;
2072 }
2073
2074 static int
2075 ipv4_connect(struct TCP_Server_Info *server)
2076 {
2077         int rc = 0;
2078         int val;
2079         bool connected = false;
2080         __be16 orig_port = 0;
2081         struct socket *socket = server->ssocket;
2082
2083         if (socket == NULL) {
2084                 rc = sock_create_kern(PF_INET, SOCK_STREAM,
2085                                       IPPROTO_TCP, &socket);
2086                 if (rc < 0) {
2087                         cERROR(1, "Error %d creating socket", rc);
2088                         return rc;
2089                 }
2090
2091                 /* BB other socket options to set KEEPALIVE, NODELAY? */
2092                 cFYI(1, "Socket created");
2093                 server->ssocket = socket;
2094                 socket->sk->sk_allocation = GFP_NOFS;
2095                 cifs_reclassify_socket4(socket);
2096         }
2097
2098         rc = bind_socket(server);
2099         if (rc < 0)
2100                 return rc;
2101
2102         /* user overrode default port */
2103         if (server->addr.sockAddr.sin_port) {
2104                 rc = socket->ops->connect(socket, (struct sockaddr *)
2105                                           &server->addr.sockAddr,
2106                                           sizeof(struct sockaddr_in), 0);
2107                 if (rc >= 0)
2108                         connected = true;
2109         }
2110
2111         if (!connected) {
2112                 /* save original port so we can retry user specified port
2113                         later if fall back ports fail this time  */
2114                 orig_port = server->addr.sockAddr.sin_port;
2115
2116                 /* do not retry on the same port we just failed on */
2117                 if (server->addr.sockAddr.sin_port != htons(CIFS_PORT)) {
2118                         server->addr.sockAddr.sin_port = htons(CIFS_PORT);
2119                         rc = socket->ops->connect(socket,
2120                                                 (struct sockaddr *)
2121                                                 &server->addr.sockAddr,
2122                                                 sizeof(struct sockaddr_in), 0);
2123                         if (rc >= 0)
2124                                 connected = true;
2125                 }
2126         }
2127         if (!connected) {
2128                 server->addr.sockAddr.sin_port = htons(RFC1001_PORT);
2129                 rc = socket->ops->connect(socket, (struct sockaddr *)
2130                                               &server->addr.sockAddr,
2131                                               sizeof(struct sockaddr_in), 0);
2132                 if (rc >= 0)
2133                         connected = true;
2134         }
2135
2136         /* give up here - unless we want to retry on different
2137                 protocol families some day */
2138         if (!connected) {
2139                 if (orig_port)
2140                         server->addr.sockAddr.sin_port = orig_port;
2141                 cFYI(1, "Error %d connecting to server via ipv4", rc);
2142                 sock_release(socket);
2143                 server->ssocket = NULL;
2144                 return rc;
2145         }
2146
2147
2148         /*
2149          * Eventually check for other socket options to change from
2150          *  the default. sock_setsockopt not used because it expects
2151          *  user space buffer
2152          */
2153         socket->sk->sk_rcvtimeo = 7 * HZ;
2154         socket->sk->sk_sndtimeo = 5 * HZ;
2155
2156         /* make the bufsizes depend on wsize/rsize and max requests */
2157         if (server->noautotune) {
2158                 if (socket->sk->sk_sndbuf < (200 * 1024))
2159                         socket->sk->sk_sndbuf = 200 * 1024;
2160                 if (socket->sk->sk_rcvbuf < (140 * 1024))
2161                         socket->sk->sk_rcvbuf = 140 * 1024;
2162         }
2163
2164         if (server->tcp_nodelay) {
2165                 val = 1;
2166                 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2167                                 (char *)&val, sizeof(val));
2168                 if (rc)
2169                         cFYI(1, "set TCP_NODELAY socket option error %d", rc);
2170         }
2171
2172          cFYI(1, "sndbuf %d rcvbuf %d rcvtimeo 0x%lx",
2173                  socket->sk->sk_sndbuf,
2174                  socket->sk->sk_rcvbuf, socket->sk->sk_rcvtimeo);
2175
2176         /* send RFC1001 sessinit */
2177         if (server->addr.sockAddr.sin_port == htons(RFC1001_PORT)) {
2178                 /* some servers require RFC1001 sessinit before sending
2179                 negprot - BB check reconnection in case where second
2180                 sessinit is sent but no second negprot */
2181                 struct rfc1002_session_packet *ses_init_buf;
2182                 struct smb_hdr *smb_buf;
2183                 ses_init_buf = kzalloc(sizeof(struct rfc1002_session_packet),
2184                                        GFP_KERNEL);
2185                 if (ses_init_buf) {
2186                         ses_init_buf->trailer.session_req.called_len = 32;
2187                         if (server->server_RFC1001_name &&
2188                             server->server_RFC1001_name[0] != 0)
2189                                 rfc1002mangle(ses_init_buf->trailer.
2190                                                 session_req.called_name,
2191                                               server->server_RFC1001_name,
2192                                               RFC1001_NAME_LEN_WITH_NULL);
2193                         else
2194                                 rfc1002mangle(ses_init_buf->trailer.
2195                                                 session_req.called_name,
2196                                               DEFAULT_CIFS_CALLED_NAME,
2197                                               RFC1001_NAME_LEN_WITH_NULL);
2198
2199                         ses_init_buf->trailer.session_req.calling_len = 32;
2200
2201                         /* calling name ends in null (byte 16) from old smb
2202                         convention. */
2203                         if (server->workstation_RFC1001_name &&
2204                             server->workstation_RFC1001_name[0] != 0)
2205                                 rfc1002mangle(ses_init_buf->trailer.
2206                                                 session_req.calling_name,
2207                                               server->workstation_RFC1001_name,
2208                                               RFC1001_NAME_LEN_WITH_NULL);
2209                         else
2210                                 rfc1002mangle(ses_init_buf->trailer.
2211                                                 session_req.calling_name,
2212                                               "LINUX_CIFS_CLNT",
2213                                               RFC1001_NAME_LEN_WITH_NULL);
2214
2215                         ses_init_buf->trailer.session_req.scope1 = 0;
2216                         ses_init_buf->trailer.session_req.scope2 = 0;
2217                         smb_buf = (struct smb_hdr *)ses_init_buf;
2218                         /* sizeof RFC1002_SESSION_REQUEST with no scope */
2219                         smb_buf->smb_buf_length = 0x81000044;
2220                         rc = smb_send(server, smb_buf, 0x44);
2221                         kfree(ses_init_buf);
2222                         msleep(1); /* RFC1001 layer in at least one server
2223                                       requires very short break before negprot
2224                                       presumably because not expecting negprot
2225                                       to follow so fast.  This is a simple
2226                                       solution that works without
2227                                       complicating the code and causes no
2228                                       significant slowing down on mount
2229                                       for everyone else */
2230                 }
2231                 /* else the negprot may still work without this
2232                 even though malloc failed */
2233
2234         }
2235
2236         return rc;
2237 }
2238
2239 static int
2240 ipv6_connect(struct TCP_Server_Info *server)
2241 {
2242         int rc = 0;
2243         int val;
2244         bool connected = false;
2245         __be16 orig_port = 0;
2246         struct socket *socket = server->ssocket;
2247
2248         if (socket == NULL) {
2249                 rc = sock_create_kern(PF_INET6, SOCK_STREAM,
2250                                       IPPROTO_TCP, &socket);
2251                 if (rc < 0) {
2252                         cERROR(1, "Error %d creating ipv6 socket", rc);
2253                         socket = NULL;
2254                         return rc;
2255                 }
2256
2257                 /* BB other socket options to set KEEPALIVE, NODELAY? */
2258                 cFYI(1, "ipv6 Socket created");
2259                 server->ssocket = socket;
2260                 socket->sk->sk_allocation = GFP_NOFS;
2261                 cifs_reclassify_socket6(socket);
2262         }
2263
2264         rc = bind_socket(server);
2265         if (rc < 0)
2266                 return rc;
2267
2268         /* user overrode default port */
2269         if (server->addr.sockAddr6.sin6_port) {
2270                 rc = socket->ops->connect(socket,
2271                                 (struct sockaddr *) &server->addr.sockAddr6,
2272                                 sizeof(struct sockaddr_in6), 0);
2273                 if (rc >= 0)
2274                         connected = true;
2275         }
2276
2277         if (!connected) {
2278                 /* save original port so we can retry user specified port
2279                         later if fall back ports fail this time  */
2280
2281                 orig_port = server->addr.sockAddr6.sin6_port;
2282                 /* do not retry on the same port we just failed on */
2283                 if (server->addr.sockAddr6.sin6_port != htons(CIFS_PORT)) {
2284                         server->addr.sockAddr6.sin6_port = htons(CIFS_PORT);
2285                         rc = socket->ops->connect(socket, (struct sockaddr *)
2286                                         &server->addr.sockAddr6,
2287                                         sizeof(struct sockaddr_in6), 0);
2288                         if (rc >= 0)
2289                                 connected = true;
2290                 }
2291         }
2292         if (!connected) {
2293                 server->addr.sockAddr6.sin6_port = htons(RFC1001_PORT);
2294                 rc = socket->ops->connect(socket, (struct sockaddr *)
2295                                 &server->addr.sockAddr6,
2296                                 sizeof(struct sockaddr_in6), 0);
2297                 if (rc >= 0)
2298                         connected = true;
2299         }
2300
2301         /* give up here - unless we want to retry on different
2302                 protocol families some day */
2303         if (!connected) {
2304                 if (orig_port)
2305                         server->addr.sockAddr6.sin6_port = orig_port;
2306                 cFYI(1, "Error %d connecting to server via ipv6", rc);
2307                 sock_release(socket);
2308                 server->ssocket = NULL;
2309                 return rc;
2310         }
2311
2312         /*
2313          * Eventually check for other socket options to change from
2314          * the default. sock_setsockopt not used because it expects
2315          * user space buffer
2316          */
2317         socket->sk->sk_rcvtimeo = 7 * HZ;
2318         socket->sk->sk_sndtimeo = 5 * HZ;
2319
2320         if (server->tcp_nodelay) {
2321                 val = 1;
2322                 rc = kernel_setsockopt(socket, SOL_TCP, TCP_NODELAY,
2323                                 (char *)&val, sizeof(val));
2324                 if (rc)
2325                         cFYI(1, "set TCP_NODELAY socket option error %d", rc);
2326         }
2327
2328         server->ssocket = socket;
2329
2330         return rc;
2331 }
2332
2333 void reset_cifs_unix_caps(int xid, struct cifsTconInfo *tcon,
2334                           struct super_block *sb, struct smb_vol *vol_info)
2335 {
2336         /* if we are reconnecting then should we check to see if
2337          * any requested capabilities changed locally e.g. via
2338          * remount but we can not do much about it here
2339          * if they have (even if we could detect it by the following)
2340          * Perhaps we could add a backpointer to array of sb from tcon
2341          * or if we change to make all sb to same share the same
2342          * sb as NFS - then we only have one backpointer to sb.
2343          * What if we wanted to mount the server share twice once with
2344          * and once without posixacls or posix paths? */
2345         __u64 saved_cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2346
2347         if (vol_info && vol_info->no_linux_ext) {
2348                 tcon->fsUnixInfo.Capability = 0;
2349                 tcon->unix_ext = 0; /* Unix Extensions disabled */
2350                 cFYI(1, "Linux protocol extensions disabled");
2351                 return;
2352         } else if (vol_info)
2353                 tcon->unix_ext = 1; /* Unix Extensions supported */
2354
2355         if (tcon->unix_ext == 0) {
2356                 cFYI(1, "Unix extensions disabled so not set on reconnect");
2357                 return;
2358         }
2359
2360         if (!CIFSSMBQFSUnixInfo(xid, tcon)) {
2361                 __u64 cap = le64_to_cpu(tcon->fsUnixInfo.Capability);
2362
2363                 /* check for reconnect case in which we do not
2364                    want to change the mount behavior if we can avoid it */
2365                 if (vol_info == NULL) {
2366                         /* turn off POSIX ACL and PATHNAMES if not set
2367                            originally at mount time */
2368                         if ((saved_cap & CIFS_UNIX_POSIX_ACL_CAP) == 0)
2369                                 cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2370                         if ((saved_cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2371                                 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2372                                         cERROR(1, "POSIXPATH support change");
2373                                 cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2374                         } else if ((cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) == 0) {
2375                                 cERROR(1, "possible reconnect error");
2376                                 cERROR(1, "server disabled POSIX path support");
2377                         }
2378                 }
2379
2380                 cap &= CIFS_UNIX_CAP_MASK;
2381                 if (vol_info && vol_info->no_psx_acl)
2382                         cap &= ~CIFS_UNIX_POSIX_ACL_CAP;
2383                 else if (CIFS_UNIX_POSIX_ACL_CAP & cap) {
2384                         cFYI(1, "negotiated posix acl support");
2385                         if (sb)
2386                                 sb->s_flags |= MS_POSIXACL;
2387                 }
2388
2389                 if (vol_info && vol_info->posix_paths == 0)
2390                         cap &= ~CIFS_UNIX_POSIX_PATHNAMES_CAP;
2391                 else if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP) {
2392                         cFYI(1, "negotiate posix pathnames");
2393                         if (sb)
2394                                 CIFS_SB(sb)->mnt_cifs_flags |=
2395                                         CIFS_MOUNT_POSIX_PATHS;
2396                 }
2397
2398                 /* We might be setting the path sep back to a different
2399                 form if we are reconnecting and the server switched its
2400                 posix path capability for this share */
2401                 if (sb && (CIFS_SB(sb)->prepathlen > 0))
2402                         CIFS_SB(sb)->prepath[0] = CIFS_DIR_SEP(CIFS_SB(sb));
2403
2404                 if (sb && (CIFS_SB(sb)->rsize > 127 * 1024)) {
2405                         if ((cap & CIFS_UNIX_LARGE_READ_CAP) == 0) {
2406                                 CIFS_SB(sb)->rsize = 127 * 1024;
2407                                 cFYI(DBG2, "larger reads not supported by srv");
2408                         }
2409                 }
2410
2411
2412                 cFYI(1, "Negotiate caps 0x%x", (int)cap);
2413 #ifdef CONFIG_CIFS_DEBUG2
2414                 if (cap & CIFS_UNIX_FCNTL_CAP)
2415                         cFYI(1, "FCNTL cap");
2416                 if (cap & CIFS_UNIX_EXTATTR_CAP)
2417                         cFYI(1, "EXTATTR cap");
2418                 if (cap & CIFS_UNIX_POSIX_PATHNAMES_CAP)
2419                         cFYI(1, "POSIX path cap");
2420                 if (cap & CIFS_UNIX_XATTR_CAP)
2421                         cFYI(1, "XATTR cap");
2422                 if (cap & CIFS_UNIX_POSIX_ACL_CAP)
2423                         cFYI(1, "POSIX ACL cap");
2424                 if (cap & CIFS_UNIX_LARGE_READ_CAP)
2425                         cFYI(1, "very large read cap");
2426                 if (cap & CIFS_UNIX_LARGE_WRITE_CAP)
2427                         cFYI(1, "very large write cap");
2428 #endif /* CIFS_DEBUG2 */
2429                 if (CIFSSMBSetFSUnixInfo(xid, tcon, cap)) {
2430                         if (vol_info == NULL) {
2431                                 cFYI(1, "resetting capabilities failed");
2432                         } else
2433                                 cERROR(1, "Negotiating Unix capabilities "
2434                                            "with the server failed.  Consider "
2435                                            "mounting with the Unix Extensions\n"
2436                                            "disabled, if problems are found, "
2437                                            "by specifying the nounix mount "
2438                                            "option.");
2439
2440                 }
2441         }
2442 }
2443
2444 static void
2445 convert_delimiter(char *path, char delim)
2446 {
2447         int i;
2448         char old_delim;
2449
2450         if (path == NULL)
2451                 return;
2452
2453         if (delim == '/')
2454                 old_delim = '\\';
2455         else
2456                 old_delim = '/';
2457
2458         for (i = 0; path[i] != '\0'; i++) {
2459                 if (path[i] == old_delim)
2460                         path[i] = delim;
2461         }
2462 }
2463
2464 static void setup_cifs_sb(struct smb_vol *pvolume_info,
2465                           struct cifs_sb_info *cifs_sb)
2466 {
2467         if (pvolume_info->rsize > CIFSMaxBufSize) {
2468                 cERROR(1, "rsize %d too large, using MaxBufSize",
2469                         pvolume_info->rsize);
2470                 cifs_sb->rsize = CIFSMaxBufSize;
2471         } else if ((pvolume_info->rsize) &&
2472                         (pvolume_info->rsize <= CIFSMaxBufSize))
2473                 cifs_sb->rsize = pvolume_info->rsize;
2474         else /* default */
2475                 cifs_sb->rsize = CIFSMaxBufSize;
2476
2477         if (pvolume_info->wsize > PAGEVEC_SIZE * PAGE_CACHE_SIZE) {
2478                 cERROR(1, "wsize %d too large, using 4096 instead",
2479                           pvolume_info->wsize);
2480                 cifs_sb->wsize = 4096;
2481         } else if (pvolume_info->wsize)
2482                 cifs_sb->wsize = pvolume_info->wsize;
2483         else
2484                 cifs_sb->wsize = min_t(const int,
2485                                         PAGEVEC_SIZE * PAGE_CACHE_SIZE,
2486                                         127*1024);
2487                 /* old default of CIFSMaxBufSize was too small now
2488                    that SMB Write2 can send multiple pages in kvec.
2489                    RFC1001 does not describe what happens when frame
2490                    bigger than 128K is sent so use that as max in
2491                    conjunction with 52K kvec constraint on arch with 4K
2492                    page size  */
2493
2494         if (cifs_sb->rsize < 2048) {
2495                 cifs_sb->rsize = 2048;
2496                 /* Windows ME may prefer this */
2497                 cFYI(1, "readsize set to minimum: 2048");
2498         }
2499         /* calculate prepath */
2500         cifs_sb->prepath = pvolume_info->prepath;
2501         if (cifs_sb->prepath) {
2502                 cifs_sb->prepathlen = strlen(cifs_sb->prepath);
2503                 /* we can not convert the / to \ in the path
2504                 separators in the prefixpath yet because we do not
2505                 know (until reset_cifs_unix_caps is called later)
2506                 whether POSIX PATH CAP is available. We normalize
2507                 the / to \ after reset_cifs_unix_caps is called */
2508                 pvolume_info->prepath = NULL;
2509         } else
2510                 cifs_sb->prepathlen = 0;
2511         cifs_sb->mnt_uid = pvolume_info->linux_uid;
2512         cifs_sb->mnt_gid = pvolume_info->linux_gid;
2513         cifs_sb->mnt_file_mode = pvolume_info->file_mode;
2514         cifs_sb->mnt_dir_mode = pvolume_info->dir_mode;
2515         cFYI(1, "file mode: 0x%x  dir mode: 0x%x",
2516                 cifs_sb->mnt_file_mode, cifs_sb->mnt_dir_mode);
2517
2518         if (pvolume_info->noperm)
2519                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_PERM;
2520         if (pvolume_info->setuids)
2521                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SET_UID;
2522         if (pvolume_info->server_ino)
2523                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_SERVER_INUM;
2524         if (pvolume_info->remap)
2525                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MAP_SPECIAL_CHR;
2526         if (pvolume_info->no_xattr)
2527                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_XATTR;
2528         if (pvolume_info->sfu_emul)
2529                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_UNX_EMUL;
2530         if (pvolume_info->nobrl)
2531                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NO_BRL;
2532         if (pvolume_info->nostrictsync)
2533                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOSSYNC;
2534         if (pvolume_info->mand_lock)
2535                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_NOPOSIXBRL;
2536         if (pvolume_info->cifs_acl)
2537                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_CIFS_ACL;
2538         if (pvolume_info->override_uid)
2539                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_UID;
2540         if (pvolume_info->override_gid)
2541                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_OVERR_GID;
2542         if (pvolume_info->dynperm)
2543                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DYNPERM;
2544         if (pvolume_info->fsc)
2545                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_FSCACHE;
2546         if (pvolume_info->direct_io) {
2547                 cFYI(1, "mounting share using direct i/o");
2548                 cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_DIRECT_IO;
2549         }
2550         if (pvolume_info->mfsymlinks) {
2551                 if (pvolume_info->sfu_emul) {
2552                         cERROR(1,  "mount option mfsymlinks ignored if sfu "
2553                                    "mount option is used");
2554                 } else {
2555                         cifs_sb->mnt_cifs_flags |= CIFS_MOUNT_MF_SYMLINKS;
2556                 }
2557         }
2558
2559         if ((pvolume_info->cifs_acl) && (pvolume_info->dynperm))
2560                 cERROR(1, "mount option dynperm ignored if cifsacl "
2561                            "mount option supported");
2562 }
2563
2564 static int
2565 is_path_accessible(int xid, struct cifsTconInfo *tcon,
2566                    struct cifs_sb_info *cifs_sb, const char *full_path)
2567 {
2568         int rc;
2569         FILE_ALL_INFO *pfile_info;
2570
2571         pfile_info = kmalloc(sizeof(FILE_ALL_INFO), GFP_KERNEL);
2572         if (pfile_info == NULL)
2573                 return -ENOMEM;
2574
2575         rc = CIFSSMBQPathInfo(xid, tcon, full_path, pfile_info,
2576                               0 /* not legacy */, cifs_sb->local_nls,
2577                               cifs_sb->mnt_cifs_flags &
2578                                 CIFS_MOUNT_MAP_SPECIAL_CHR);
2579         kfree(pfile_info);
2580         return rc;
2581 }
2582
2583 static void
2584 cleanup_volume_info(struct smb_vol **pvolume_info)
2585 {
2586         struct smb_vol *volume_info;
2587
2588         if (!pvolume_info || !*pvolume_info)
2589                 return;
2590
2591         volume_info = *pvolume_info;
2592         kzfree(volume_info->password);
2593         kfree(volume_info->UNC);
2594         kfree(volume_info->prepath);
2595         kfree(volume_info);
2596         *pvolume_info = NULL;
2597         return;
2598 }
2599
2600 #ifdef CONFIG_CIFS_DFS_UPCALL
2601 /* build_path_to_root returns full path to root when
2602  * we do not have an exiting connection (tcon) */
2603 static char *
2604 build_unc_path_to_root(const struct smb_vol *volume_info,
2605                 const struct cifs_sb_info *cifs_sb)
2606 {
2607         char *full_path;
2608
2609         int unc_len = strnlen(volume_info->UNC, MAX_TREE_SIZE + 1);
2610         full_path = kmalloc(unc_len + cifs_sb->prepathlen + 1, GFP_KERNEL);
2611         if (full_path == NULL)
2612                 return ERR_PTR(-ENOMEM);
2613
2614         strncpy(full_path, volume_info->UNC, unc_len);
2615         if (cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) {
2616                 int i;
2617                 for (i = 0; i < unc_len; i++) {
2618                         if (full_path[i] == '\\')
2619                                 full_path[i] = '/';
2620                 }
2621         }
2622
2623         if (cifs_sb->prepathlen)
2624                 strncpy(full_path + unc_len, cifs_sb->prepath,
2625                                 cifs_sb->prepathlen);
2626
2627         full_path[unc_len + cifs_sb->prepathlen] = 0; /* add trailing null */
2628         return full_path;
2629 }
2630 #endif
2631
2632 int
2633 cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,
2634                 char *mount_data_global, const char *devname)
2635 {
2636         int rc;
2637         int xid;
2638         struct smb_vol *volume_info;
2639         struct cifsSesInfo *pSesInfo;
2640         struct cifsTconInfo *tcon;
2641         struct TCP_Server_Info *srvTcp;
2642         char   *full_path;
2643         char *mount_data = mount_data_global;
2644 #ifdef CONFIG_CIFS_DFS_UPCALL
2645         struct dfs_info3_param *referrals = NULL;
2646         unsigned int num_referrals = 0;
2647         int referral_walks_count = 0;
2648 try_mount_again:
2649 #endif
2650         rc = 0;
2651         tcon = NULL;
2652         pSesInfo = NULL;
2653         srvTcp = NULL;
2654         full_path = NULL;
2655
2656         xid = GetXid();
2657
2658         volume_info = kzalloc(sizeof(struct smb_vol), GFP_KERNEL);
2659         if (!volume_info) {
2660                 rc = -ENOMEM;
2661                 goto out;
2662         }
2663
2664         if (cifs_parse_mount_options(mount_data, devname, volume_info)) {
2665                 rc = -EINVAL;
2666                 goto out;
2667         }
2668
2669         if (volume_info->nullauth) {
2670                 cFYI(1, "null user");
2671                 volume_info->username = "";
2672         } else if (volume_info->username) {
2673                 /* BB fixme parse for domain name here */
2674                 cFYI(1, "Username: %s", volume_info->username);
2675         } else {
2676                 cifserror("No username specified");
2677         /* In userspace mount helper we can get user name from alternate
2678            locations such as env variables and files on disk */
2679                 rc = -EINVAL;
2680                 goto out;
2681         }
2682
2683         /* this is needed for ASCII cp to Unicode converts */
2684         if (volume_info->iocharset == NULL) {
2685                 /* load_nls_default cannot return null */
2686                 volume_info->local_nls = load_nls_default();
2687         } else {
2688                 volume_info->local_nls = load_nls(volume_info->iocharset);
2689                 if (volume_info->local_nls == NULL) {
2690                         cERROR(1, "CIFS mount error: iocharset %s not found",
2691                                  volume_info->iocharset);
2692                         rc = -ELIBACC;
2693                         goto out;
2694                 }
2695         }
2696         cifs_sb->local_nls = volume_info->local_nls;
2697
2698         /* get a reference to a tcp session */
2699         srvTcp = cifs_get_tcp_session(volume_info);
2700         if (IS_ERR(srvTcp)) {
2701                 rc = PTR_ERR(srvTcp);
2702                 goto out;
2703         }
2704
2705         /* get a reference to a SMB session */
2706         pSesInfo = cifs_get_smb_ses(srvTcp, volume_info);
2707         if (IS_ERR(pSesInfo)) {
2708                 rc = PTR_ERR(pSesInfo);
2709                 pSesInfo = NULL;
2710                 goto mount_fail_check;
2711         }
2712
2713         setup_cifs_sb(volume_info, cifs_sb);
2714         if (pSesInfo->capabilities & CAP_LARGE_FILES)
2715                 sb->s_maxbytes = MAX_LFS_FILESIZE;
2716         else
2717                 sb->s_maxbytes = MAX_NON_LFS;
2718
2719         /* BB FIXME fix time_gran to be larger for LANMAN sessions */
2720         sb->s_time_gran = 100;
2721
2722         /* search for existing tcon to this server share */
2723         tcon = cifs_get_tcon(pSesInfo, volume_info);
2724         if (IS_ERR(tcon)) {
2725                 rc = PTR_ERR(tcon);
2726                 tcon = NULL;
2727                 goto remote_path_check;
2728         }
2729
2730         cifs_sb->tcon = tcon;
2731
2732         /* do not care if following two calls succeed - informational */
2733         if (!tcon->ipc) {
2734                 CIFSSMBQFSDeviceInfo(xid, tcon);
2735                 CIFSSMBQFSAttributeInfo(xid, tcon);
2736         }
2737
2738         /* tell server which Unix caps we support */
2739         if (tcon->ses->capabilities & CAP_UNIX)
2740                 /* reset of caps checks mount to see if unix extensions
2741                    disabled for just this mount */
2742                 reset_cifs_unix_caps(xid, tcon, sb, volume_info);
2743         else
2744                 tcon->unix_ext = 0; /* server does not support them */
2745
2746         /* convert forward to back slashes in prepath here if needed */
2747         if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2748                 convert_delimiter(cifs_sb->prepath, CIFS_DIR_SEP(cifs_sb));
2749
2750         if ((tcon->unix_ext == 0) && (cifs_sb->rsize > (1024 * 127))) {
2751                 cifs_sb->rsize = 1024 * 127;
2752                 cFYI(DBG2, "no very large read support, rsize now 127K");
2753         }
2754         if (!(tcon->ses->capabilities & CAP_LARGE_WRITE_X))
2755                 cifs_sb->wsize = min(cifs_sb->wsize,
2756                                (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2757         if (!(tcon->ses->capabilities & CAP_LARGE_READ_X))
2758                 cifs_sb->rsize = min(cifs_sb->rsize,
2759                                (tcon->ses->server->maxBuf - MAX_CIFS_HDR_SIZE));
2760
2761 remote_path_check:
2762         /* check if a whole path (including prepath) is not remote */
2763         if (!rc && cifs_sb->prepathlen && tcon) {
2764                 /* build_path_to_root works only when we have a valid tcon */
2765                 full_path = cifs_build_path_to_root(cifs_sb);
2766                 if (full_path == NULL) {
2767                         rc = -ENOMEM;
2768                         goto mount_fail_check;
2769                 }
2770                 rc = is_path_accessible(xid, tcon, cifs_sb, full_path);
2771                 if (rc != -EREMOTE) {
2772                         kfree(full_path);
2773                         goto mount_fail_check;
2774                 }
2775                 kfree(full_path);
2776         }
2777
2778         /* get referral if needed */
2779         if (rc == -EREMOTE) {
2780 #ifdef CONFIG_CIFS_DFS_UPCALL
2781                 if (referral_walks_count > MAX_NESTED_LINKS) {
2782                         /*
2783                          * BB: when we implement proper loop detection,
2784                          *     we will remove this check. But now we need it
2785                          *     to prevent an indefinite loop if 'DFS tree' is
2786                          *     misconfigured (i.e. has loops).
2787                          */
2788                         rc = -ELOOP;
2789                         goto mount_fail_check;
2790                 }
2791                 /* convert forward to back slashes in prepath here if needed */
2792                 if ((cifs_sb->mnt_cifs_flags & CIFS_MOUNT_POSIX_PATHS) == 0)
2793                         convert_delimiter(cifs_sb->prepath,
2794                                         CIFS_DIR_SEP(cifs_sb));
2795                 full_path = build_unc_path_to_root(volume_info, cifs_sb);
2796                 if (IS_ERR(full_path)) {
2797                         rc = PTR_ERR(full_path);
2798                         goto mount_fail_check;
2799                 }
2800
2801                 cFYI(1, "Getting referral for: %s", full_path);
2802                 rc = get_dfs_path(xid, pSesInfo , full_path + 1,
2803                         cifs_sb->local_nls, &num_referrals, &referrals,
2804                         cifs_sb->mnt_cifs_flags & CIFS_MOUNT_MAP_SPECIAL_CHR);
2805                 if (!rc && num_referrals > 0) {
2806                         char *fake_devname = NULL;
2807
2808                         if (mount_data != mount_data_global)
2809                                 kfree(mount_data);
2810
2811                         mount_data = cifs_compose_mount_options(
2812                                         cifs_sb->mountdata, full_path + 1,
2813                                         referrals, &fake_devname);
2814
2815                         free_dfs_info_array(referrals, num_referrals);
2816                         kfree(fake_devname);
2817                         kfree(full_path);
2818
2819                         if (IS_ERR(mount_data)) {
2820                                 rc = PTR_ERR(mount_data);
2821                                 mount_data = NULL;
2822                                 goto mount_fail_check;
2823                         }
2824
2825                         if (tcon)
2826                                 cifs_put_tcon(tcon);
2827                         else if (pSesInfo)
2828                                 cifs_put_smb_ses(pSesInfo);
2829
2830                         cleanup_volume_info(&volume_info);
2831                         referral_walks_count++;
2832                         FreeXid(xid);
2833                         goto try_mount_again;
2834                 }
2835 #else /* No DFS support, return error on mount */
2836                 rc = -EOPNOTSUPP;
2837 #endif
2838         }
2839
2840 mount_fail_check:
2841         /* on error free sesinfo and tcon struct if needed */
2842         if (rc) {
2843                 if (mount_data != mount_data_global)
2844                         kfree(mount_data);
2845                 /* If find_unc succeeded then rc == 0 so we can not end */
2846                 /* up accidently freeing someone elses tcon struct */
2847                 if (tcon)
2848                         cifs_put_tcon(tcon);
2849                 else if (pSesInfo)
2850                         cifs_put_smb_ses(pSesInfo);
2851                 else
2852                         cifs_put_tcp_session(srvTcp);
2853                 goto out;
2854         }
2855
2856         /* volume_info->password is freed above when existing session found
2857         (in which case it is not needed anymore) but when new sesion is created
2858         the password ptr is put in the new session structure (in which case the
2859         password will be freed at unmount time) */
2860 out:
2861         /* zero out password before freeing */
2862         cleanup_volume_info(&volume_info);
2863         FreeXid(xid);
2864         return rc;
2865 }
2866
2867 int
2868 CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
2869          const char *tree, struct cifsTconInfo *tcon,
2870          const struct nls_table *nls_codepage)
2871 {
2872         struct smb_hdr *smb_buffer;
2873         struct smb_hdr *smb_buffer_response;
2874         TCONX_REQ *pSMB;
2875         TCONX_RSP *pSMBr;
2876         unsigned char *bcc_ptr;
2877         int rc = 0;
2878         int length, bytes_left;
2879         __u16 count;
2880
2881         if (ses == NULL)
2882                 return -EIO;
2883
2884         smb_buffer = cifs_buf_get();
2885         if (smb_buffer == NULL)
2886                 return -ENOMEM;
2887
2888         smb_buffer_response = smb_buffer;
2889
2890         header_assemble(smb_buffer, SMB_COM_TREE_CONNECT_ANDX,
2891                         NULL /*no tid */ , 4 /*wct */ );
2892
2893         smb_buffer->Mid = GetNextMid(ses->server);
2894         smb_buffer->Uid = ses->Suid;
2895         pSMB = (TCONX_REQ *) smb_buffer;
2896         pSMBr = (TCONX_RSP *) smb_buffer_response;
2897
2898         pSMB->AndXCommand = 0xFF;
2899         pSMB->Flags = cpu_to_le16(TCON_EXTENDED_SECINFO);
2900         bcc_ptr = &pSMB->Password[0];
2901         if ((ses->server->secMode) & SECMODE_USER) {
2902                 pSMB->PasswordLength = cpu_to_le16(1);  /* minimum */
2903                 *bcc_ptr = 0; /* password is null byte */
2904                 bcc_ptr++;              /* skip password */
2905                 /* already aligned so no need to do it below */
2906         } else {
2907                 pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
2908                 /* BB FIXME add code to fail this if NTLMv2 or Kerberos
2909                    specified as required (when that support is added to
2910                    the vfs in the future) as only NTLM or the much
2911                    weaker LANMAN (which we do not send by default) is accepted
2912                    by Samba (not sure whether other servers allow
2913                    NTLMv2 password here) */
2914 #ifdef CONFIG_CIFS_WEAK_PW_HASH
2915                 if ((global_secflags & CIFSSEC_MAY_LANMAN) &&
2916                     (ses->server->secType == LANMAN))
2917                         calc_lanman_hash(tcon->password, ses->server->cryptKey,
2918                                          ses->server->secMode &
2919                                             SECMODE_PW_ENCRYPT ? true : false,
2920                                          bcc_ptr);
2921                 else
2922 #endif /* CIFS_WEAK_PW_HASH */
2923                 SMBNTencrypt(tcon->password, ses->server->cryptKey,
2924                              bcc_ptr);
2925
2926                 bcc_ptr += CIFS_SESS_KEY_SIZE;
2927                 if (ses->capabilities & CAP_UNICODE) {
2928                         /* must align unicode strings */
2929                         *bcc_ptr = 0; /* null byte password */
2930                         bcc_ptr++;
2931                 }
2932         }
2933
2934         if (ses->server->secMode &
2935                         (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
2936                 smb_buffer->Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
2937
2938         if (ses->capabilities & CAP_STATUS32) {
2939                 smb_buffer->Flags2 |= SMBFLG2_ERR_STATUS;
2940         }
2941         if (ses->capabilities & CAP_DFS) {
2942                 smb_buffer->Flags2 |= SMBFLG2_DFS;
2943         }
2944         if (ses->capabilities & CAP_UNICODE) {
2945                 smb_buffer->Flags2 |= SMBFLG2_UNICODE;
2946                 length =
2947                     cifs_strtoUCS((__le16 *) bcc_ptr, tree,
2948                         6 /* max utf8 char length in bytes */ *
2949                         (/* server len*/ + 256 /* share len */), nls_codepage);
2950                 bcc_ptr += 2 * length;  /* convert num 16 bit words to bytes */
2951                 bcc_ptr += 2;   /* skip trailing null */
2952         } else {                /* ASCII */
2953                 strcpy(bcc_ptr, tree);
2954                 bcc_ptr += strlen(tree) + 1;
2955         }
2956         strcpy(bcc_ptr, "?????");
2957         bcc_ptr += strlen("?????");
2958         bcc_ptr += 1;
2959         count = bcc_ptr - &pSMB->Password[0];
2960         pSMB->hdr.smb_buf_length += count;
2961         pSMB->ByteCount = cpu_to_le16(count);
2962
2963         rc = SendReceive(xid, ses, smb_buffer, smb_buffer_response, &length,
2964                          CIFS_STD_OP);
2965
2966         /* above now done in SendReceive */
2967         if ((rc == 0) && (tcon != NULL)) {
2968                 bool is_unicode;
2969
2970                 tcon->tidStatus = CifsGood;
2971                 tcon->need_reconnect = false;
2972                 tcon->tid = smb_buffer_response->Tid;
2973                 bcc_ptr = pByteArea(smb_buffer_response);
2974                 bytes_left = BCC(smb_buffer_response);
2975                 length = strnlen(bcc_ptr, bytes_left - 2);
2976                 if (smb_buffer->Flags2 & SMBFLG2_UNICODE)
2977                         is_unicode = true;
2978                 else
2979                         is_unicode = false;
2980
2981
2982                 /* skip service field (NB: this field is always ASCII) */
2983                 if (length == 3) {
2984                         if ((bcc_ptr[0] == 'I') && (bcc_ptr[1] == 'P') &&
2985                             (bcc_ptr[2] == 'C')) {
2986                                 cFYI(1, "IPC connection");
2987                                 tcon->ipc = 1;
2988                         }
2989                 } else if (length == 2) {
2990                         if ((bcc_ptr[0] == 'A') && (bcc_ptr[1] == ':')) {
2991                                 /* the most common case */
2992                                 cFYI(1, "disk share connection");
2993                         }
2994                 }
2995                 bcc_ptr += length + 1;
2996                 bytes_left -= (length + 1);
2997                 strncpy(tcon->treeName, tree, MAX_TREE_SIZE);
2998
2999                 /* mostly informational -- no need to fail on error here */
3000                 kfree(tcon->nativeFileSystem);
3001                 tcon->nativeFileSystem = cifs_strndup_from_ucs(bcc_ptr,
3002                                                       bytes_left, is_unicode,
3003                                                       nls_codepage);
3004
3005                 cFYI(1, "nativeFileSystem=%s", tcon->nativeFileSystem);
3006
3007                 if ((smb_buffer_response->WordCount == 3) ||
3008                          (smb_buffer_response->WordCount == 7))
3009                         /* field is in same location */
3010                         tcon->Flags = le16_to_cpu(pSMBr->OptionalSupport);
3011                 else
3012                         tcon->Flags = 0;
3013                 cFYI(1, "Tcon flags: 0x%x ", tcon->Flags);
3014         } else if ((rc == 0) && tcon == NULL) {
3015                 /* all we need to save for IPC$ connection */
3016                 ses->ipc_tid = smb_buffer_response->Tid;
3017         }
3018
3019         cifs_buf_release(smb_buffer);
3020         return rc;
3021 }
3022
3023 int
3024 cifs_umount(struct super_block *sb, struct cifs_sb_info *cifs_sb)
3025 {
3026         int rc = 0;
3027         char *tmp;
3028
3029         if (cifs_sb_tcon(cifs_sb))
3030                 cifs_put_tcon(cifs_sb_tcon(cifs_sb));
3031
3032         cifs_sb->tcon = NULL;
3033         tmp = cifs_sb->prepath;
3034         cifs_sb->prepathlen = 0;
3035         cifs_sb->prepath = NULL;
3036         kfree(tmp);
3037
3038         return rc;
3039 }
3040
3041 int cifs_negotiate_protocol(unsigned int xid, struct cifsSesInfo *ses)
3042 {
3043         int rc = 0;
3044         struct TCP_Server_Info *server = ses->server;
3045
3046         /* only send once per connect */
3047         if (server->maxBuf != 0)
3048                 return 0;
3049
3050         rc = CIFSSMBNegotiate(xid, ses);
3051         if (rc == -EAGAIN) {
3052                 /* retry only once on 1st time connection */
3053                 rc = CIFSSMBNegotiate(xid, ses);
3054                 if (rc == -EAGAIN)
3055                         rc = -EHOSTDOWN;
3056         }
3057         if (rc == 0) {
3058                 spin_lock(&GlobalMid_Lock);
3059                 if (server->tcpStatus != CifsExiting)
3060                         server->tcpStatus = CifsGood;
3061                 else
3062                         rc = -EHOSTDOWN;
3063                 spin_unlock(&GlobalMid_Lock);
3064
3065         }
3066
3067         return rc;
3068 }
3069
3070
3071 int cifs_setup_session(unsigned int xid, struct cifsSesInfo *ses,
3072                         struct nls_table *nls_info)
3073 {
3074         int rc = 0;
3075         struct TCP_Server_Info *server = ses->server;
3076
3077         ses->flags = 0;
3078         ses->capabilities = server->capabilities;
3079         if (linuxExtEnabled == 0)
3080                 ses->capabilities &= (~CAP_UNIX);
3081
3082         cFYI(1, "Security Mode: 0x%x Capabilities: 0x%x TimeAdjust: %d",
3083                  server->secMode, server->capabilities, server->timeAdj);
3084
3085         rc = CIFS_SessSetup(xid, ses, nls_info);
3086         if (rc) {
3087                 cERROR(1, "Send error in SessSetup = %d", rc);
3088         } else {
3089                 cFYI(1, "CIFS Session Established successfully");
3090                 spin_lock(&GlobalMid_Lock);
3091                 ses->status = CifsGood;
3092                 ses->need_reconnect = false;
3093                 spin_unlock(&GlobalMid_Lock);
3094         }
3095
3096         return rc;
3097 }
3098