Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/roland...
[sfrench/cifs-2.6.git] / fs / cifs / sess.c
1 /*
2  *   fs/cifs/sess.c
3  *
4  *   SMB/CIFS session setup handling routines
5  *
6  *   Copyright (c) International Business Machines  Corp., 2006, 2007
7  *   Author(s): Steve French (sfrench@us.ibm.com)
8  *
9  *   This library is free software; you can redistribute it and/or modify
10  *   it under the terms of the GNU Lesser General Public License as published
11  *   by the Free Software Foundation; either version 2.1 of the License, or
12  *   (at your option) any later version.
13  *
14  *   This library is distributed in the hope that it will be useful,
15  *   but WITHOUT ANY WARRANTY; without even the implied warranty of
16  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See
17  *   the GNU Lesser General Public License for more details.
18  *
19  *   You should have received a copy of the GNU Lesser General Public License
20  *   along with this library; if not, write to the Free Software
21  *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
22  */
23
24 #include "cifspdu.h"
25 #include "cifsglob.h"
26 #include "cifsproto.h"
27 #include "cifs_unicode.h"
28 #include "cifs_debug.h"
29 #include "ntlmssp.h"
30 #include "nterr.h"
31 #include <linux/utsname.h>
32
33 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
34                          unsigned char *p24);
35
36 static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
37 {
38         __u32 capabilities = 0;
39
40         /* init fields common to all four types of SessSetup */
41         /* note that header is initialized to zero in header_assemble */
42         pSMB->req.AndXCommand = 0xFF;
43         pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
44         pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
45
46         /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
47
48         /* BB verify whether signing required on neg or just on auth frame
49            (and NTLM case) */
50
51         capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
52                         CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
53
54         if (ses->server->secMode &
55             (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
56                 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
57
58         if (ses->capabilities & CAP_UNICODE) {
59                 pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
60                 capabilities |= CAP_UNICODE;
61         }
62         if (ses->capabilities & CAP_STATUS32) {
63                 pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
64                 capabilities |= CAP_STATUS32;
65         }
66         if (ses->capabilities & CAP_DFS) {
67                 pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
68                 capabilities |= CAP_DFS;
69         }
70         if (ses->capabilities & CAP_UNIX)
71                 capabilities |= CAP_UNIX;
72
73         /* BB check whether to init vcnum BB */
74         return capabilities;
75 }
76
77 static void
78 unicode_oslm_strings(char **pbcc_area, const struct nls_table *nls_cp)
79 {
80         char *bcc_ptr = *pbcc_area;
81         int bytes_ret = 0;
82
83         /* Copy OS version */
84         bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
85                                   nls_cp);
86         bcc_ptr += 2 * bytes_ret;
87         bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
88                                   32, nls_cp);
89         bcc_ptr += 2 * bytes_ret;
90         bcc_ptr += 2; /* trailing null */
91
92         bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
93                                   32, nls_cp);
94         bcc_ptr += 2 * bytes_ret;
95         bcc_ptr += 2; /* trailing null */
96
97         *pbcc_area = bcc_ptr;
98 }
99
100 static void unicode_domain_string(char **pbcc_area, struct cifsSesInfo *ses,
101                                    const struct nls_table *nls_cp)
102 {
103         char *bcc_ptr = *pbcc_area;
104         int bytes_ret = 0;
105
106         /* copy domain */
107         if (ses->domainName == NULL) {
108                 /* Sending null domain better than using a bogus domain name (as
109                 we did briefly in 2.6.18) since server will use its default */
110                 *bcc_ptr = 0;
111                 *(bcc_ptr+1) = 0;
112                 bytes_ret = 0;
113         } else
114                 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
115                                           256, nls_cp);
116         bcc_ptr += 2 * bytes_ret;
117         bcc_ptr += 2;  /* account for null terminator */
118
119         *pbcc_area = bcc_ptr;
120 }
121
122
123 static void unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
124                                    const struct nls_table *nls_cp)
125 {
126         char *bcc_ptr = *pbcc_area;
127         int bytes_ret = 0;
128
129         /* BB FIXME add check that strings total less
130         than 335 or will need to send them as arrays */
131
132         /* unicode strings, must be word aligned before the call */
133 /*      if ((long) bcc_ptr % 2) {
134                 *bcc_ptr = 0;
135                 bcc_ptr++;
136         } */
137         /* copy user */
138         if (ses->userName == NULL) {
139                 /* null user mount */
140                 *bcc_ptr = 0;
141                 *(bcc_ptr+1) = 0;
142         } else { /* 300 should be long enough for any conceivable user name */
143                 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
144                                           300, nls_cp);
145         }
146         bcc_ptr += 2 * bytes_ret;
147         bcc_ptr += 2; /* account for null termination */
148
149         unicode_domain_string(&bcc_ptr, ses, nls_cp);
150         unicode_oslm_strings(&bcc_ptr, nls_cp);
151
152         *pbcc_area = bcc_ptr;
153 }
154
155 static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
156                                  const struct nls_table *nls_cp)
157 {
158         char *bcc_ptr = *pbcc_area;
159
160         /* copy user */
161         /* BB what about null user mounts - check that we do this BB */
162         /* copy user */
163         if (ses->userName == NULL) {
164                 /* BB what about null user mounts - check that we do this BB */
165         } else { /* 300 should be long enough for any conceivable user name */
166                 strncpy(bcc_ptr, ses->userName, 300);
167         }
168         /* BB improve check for overflow */
169         bcc_ptr += strnlen(ses->userName, 300);
170         *bcc_ptr = 0;
171         bcc_ptr++; /* account for null termination */
172
173         /* copy domain */
174
175         if (ses->domainName != NULL) {
176                 strncpy(bcc_ptr, ses->domainName, 256);
177                 bcc_ptr += strnlen(ses->domainName, 256);
178         } /* else we will send a null domain name
179              so the server will default to its own domain */
180         *bcc_ptr = 0;
181         bcc_ptr++;
182
183         /* BB check for overflow here */
184
185         strcpy(bcc_ptr, "Linux version ");
186         bcc_ptr += strlen("Linux version ");
187         strcpy(bcc_ptr, init_utsname()->release);
188         bcc_ptr += strlen(init_utsname()->release) + 1;
189
190         strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
191         bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
192
193         *pbcc_area = bcc_ptr;
194 }
195
196 static int decode_unicode_ssetup(char **pbcc_area, int bleft,
197                                  struct cifsSesInfo *ses,
198                                  const struct nls_table *nls_cp)
199 {
200         int rc = 0;
201         int words_left, len;
202         char *data = *pbcc_area;
203
204
205
206         cFYI(1, ("bleft %d", bleft));
207
208
209         /* SMB header is unaligned, so cifs servers word align start of
210            Unicode strings */
211         data++;
212         bleft--; /* Windows servers do not always double null terminate
213                     their final Unicode string - in which case we
214                     now will not attempt to decode the byte of junk
215                     which follows it */
216
217         words_left = bleft / 2;
218
219         /* save off server operating system */
220         len = UniStrnlen((wchar_t *) data, words_left);
221
222 /* We look for obvious messed up bcc or strings in response so we do not go off
223    the end since (at least) WIN2K and Windows XP have a major bug in not null
224    terminating last Unicode string in response  */
225         if (len >= words_left)
226                 return rc;
227
228         kfree(ses->serverOS);
229         /* UTF-8 string will not grow more than four times as big as UCS-16 */
230         ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
231         if (ses->serverOS != NULL)
232                 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
233         data += 2 * (len + 1);
234         words_left -= len + 1;
235
236         /* save off server network operating system */
237         len = UniStrnlen((wchar_t *) data, words_left);
238
239         if (len >= words_left)
240                 return rc;
241
242         kfree(ses->serverNOS);
243         ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
244         if (ses->serverNOS != NULL) {
245                 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
246                                    nls_cp);
247                 if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) {
248                         cFYI(1, ("NT4 server"));
249                         ses->flags |= CIFS_SES_NT4;
250                 }
251         }
252         data += 2 * (len + 1);
253         words_left -= len + 1;
254
255         /* save off server domain */
256         len = UniStrnlen((wchar_t *) data, words_left);
257
258         if (len > words_left)
259                 return rc;
260
261         kfree(ses->serverDomain);
262         ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
263         if (ses->serverDomain != NULL) {
264                 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
265                                    nls_cp);
266                 ses->serverDomain[2*len] = 0;
267                 ses->serverDomain[(2*len) + 1] = 0;
268         }
269         data += 2 * (len + 1);
270         words_left -= len + 1;
271
272         cFYI(1, ("words left: %d", words_left));
273
274         return rc;
275 }
276
277 static int decode_ascii_ssetup(char **pbcc_area, int bleft,
278                                struct cifsSesInfo *ses,
279                                const struct nls_table *nls_cp)
280 {
281         int rc = 0;
282         int len;
283         char *bcc_ptr = *pbcc_area;
284
285         cFYI(1, ("decode sessetup ascii. bleft %d", bleft));
286
287         len = strnlen(bcc_ptr, bleft);
288         if (len >= bleft)
289                 return rc;
290
291         kfree(ses->serverOS);
292
293         ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
294         if (ses->serverOS)
295                 strncpy(ses->serverOS, bcc_ptr, len);
296         if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
297                         cFYI(1, ("OS/2 server"));
298                         ses->flags |= CIFS_SES_OS2;
299         }
300
301         bcc_ptr += len + 1;
302         bleft -= len + 1;
303
304         len = strnlen(bcc_ptr, bleft);
305         if (len >= bleft)
306                 return rc;
307
308         kfree(ses->serverNOS);
309
310         ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
311         if (ses->serverNOS)
312                 strncpy(ses->serverNOS, bcc_ptr, len);
313
314         bcc_ptr += len + 1;
315         bleft -= len + 1;
316
317         len = strnlen(bcc_ptr, bleft);
318         if (len > bleft)
319                 return rc;
320
321         /* No domain field in LANMAN case. Domain is
322            returned by old servers in the SMB negprot response */
323         /* BB For newer servers which do not support Unicode,
324            but thus do return domain here we could add parsing
325            for it later, but it is not very important */
326         cFYI(1, ("ascii: bytes left %d", bleft));
327
328         return rc;
329 }
330
331 int
332 CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
333                 const struct nls_table *nls_cp)
334 {
335         int rc = 0;
336         int wct;
337         struct smb_hdr *smb_buf;
338         char *bcc_ptr;
339         char *str_area;
340         SESSION_SETUP_ANDX *pSMB;
341         __u32 capabilities;
342         int count;
343         int resp_buf_type = 0;
344         struct kvec iov[2];
345         enum securityEnum type;
346         __u16 action;
347         int bytes_remaining;
348
349         if (ses == NULL)
350                 return -EINVAL;
351
352         type = ses->server->secType;
353
354         cFYI(1, ("sess setup type %d", type));
355         if (type == LANMAN) {
356 #ifndef CONFIG_CIFS_WEAK_PW_HASH
357                 /* LANMAN and plaintext are less secure and off by default.
358                 So we make this explicitly be turned on in kconfig (in the
359                 build) and turned on at runtime (changed from the default)
360                 in proc/fs/cifs or via mount parm.  Unfortunately this is
361                 needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
362                 return -EOPNOTSUPP;
363 #endif
364                 wct = 10; /* lanman 2 style sessionsetup */
365         } else if ((type == NTLM) || (type == NTLMv2)) {
366                 /* For NTLMv2 failures eventually may need to retry NTLM */
367                 wct = 13; /* old style NTLM sessionsetup */
368         } else /* same size: negotiate or auth, NTLMSSP or extended security */
369                 wct = 12;
370
371         rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
372                             (void **)&smb_buf);
373         if (rc)
374                 return rc;
375
376         pSMB = (SESSION_SETUP_ANDX *)smb_buf;
377
378         capabilities = cifs_ssetup_hdr(ses, pSMB);
379
380         /* we will send the SMB in two pieces,
381         a fixed length beginning part, and a
382         second part which will include the strings
383         and rest of bcc area, in order to avoid having
384         to do a large buffer 17K allocation */
385         iov[0].iov_base = (char *)pSMB;
386         iov[0].iov_len = smb_buf->smb_buf_length + 4;
387
388         /* 2000 big enough to fit max user, domain, NOS name etc. */
389         str_area = kmalloc(2000, GFP_KERNEL);
390         if (str_area == NULL) {
391                 cifs_small_buf_release(smb_buf);
392                 return -ENOMEM;
393         }
394         bcc_ptr = str_area;
395
396         ses->flags &= ~CIFS_SES_LANMAN;
397
398         if (type == LANMAN) {
399 #ifdef CONFIG_CIFS_WEAK_PW_HASH
400                 char lnm_session_key[CIFS_SESS_KEY_SIZE];
401
402                 /* no capabilities flags in old lanman negotiation */
403
404                 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
405                 /* BB calculate hash with password */
406                 /* and copy into bcc */
407
408                 calc_lanman_hash(ses, lnm_session_key);
409                 ses->flags |= CIFS_SES_LANMAN;
410 /* #ifdef CONFIG_CIFS_DEBUG2
411                 cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
412                         CIFS_SESS_KEY_SIZE);
413 #endif */
414                 memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
415                 bcc_ptr += CIFS_SESS_KEY_SIZE;
416
417                 /* can not sign if LANMAN negotiated so no need
418                 to calculate signing key? but what if server
419                 changed to do higher than lanman dialect and
420                 we reconnected would we ever calc signing_key? */
421
422                 cFYI(1, ("Negotiating LANMAN setting up strings"));
423                 /* Unicode not allowed for LANMAN dialects */
424                 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
425 #endif
426         } else if (type == NTLM) {
427                 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
428
429                 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
430                 pSMB->req_no_secext.CaseInsensitivePasswordLength =
431                         cpu_to_le16(CIFS_SESS_KEY_SIZE);
432                 pSMB->req_no_secext.CaseSensitivePasswordLength =
433                         cpu_to_le16(CIFS_SESS_KEY_SIZE);
434
435                 /* calculate session key */
436                 SMBNTencrypt(ses->password, ses->server->cryptKey,
437                              ntlm_session_key);
438
439                 if (first_time) /* should this be moved into common code
440                                   with similar ntlmv2 path? */
441                         cifs_calculate_mac_key(&ses->server->mac_signing_key,
442                                 ntlm_session_key, ses->password);
443                 /* copy session key */
444
445                 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
446                 bcc_ptr += CIFS_SESS_KEY_SIZE;
447                 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
448                 bcc_ptr += CIFS_SESS_KEY_SIZE;
449                 if (ses->capabilities & CAP_UNICODE) {
450                         /* unicode strings must be word aligned */
451                         if (iov[0].iov_len % 2) {
452                                 *bcc_ptr = 0;
453                                 bcc_ptr++;
454                         }
455                         unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
456                 } else
457                         ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
458         } else if (type == NTLMv2) {
459                 char *v2_sess_key =
460                         kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
461
462                 /* BB FIXME change all users of v2_sess_key to
463                    struct ntlmv2_resp */
464
465                 if (v2_sess_key == NULL) {
466                         cifs_small_buf_release(smb_buf);
467                         return -ENOMEM;
468                 }
469
470                 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
471
472                 /* LM2 password would be here if we supported it */
473                 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
474                 /*      cpu_to_le16(LM2_SESS_KEY_SIZE); */
475
476                 pSMB->req_no_secext.CaseSensitivePasswordLength =
477                         cpu_to_le16(sizeof(struct ntlmv2_resp));
478
479                 /* calculate session key */
480                 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
481                 if (first_time) /* should this be moved into common code
482                                    with similar ntlmv2 path? */
483                 /*   cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
484                                 response BB FIXME, v2_sess_key); */
485
486                 /* copy session key */
487
488         /*      memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
489                 bcc_ptr += LM2_SESS_KEY_SIZE; */
490                 memcpy(bcc_ptr, (char *)v2_sess_key,
491                        sizeof(struct ntlmv2_resp));
492                 bcc_ptr += sizeof(struct ntlmv2_resp);
493                 kfree(v2_sess_key);
494                 if (ses->capabilities & CAP_UNICODE) {
495                         if (iov[0].iov_len % 2) {
496                                 *bcc_ptr = 0;
497                                 bcc_ptr++;
498                         }
499                         unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
500                 } else
501                         ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
502         } else /* NTLMSSP or SPNEGO */ {
503                 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
504                 capabilities |= CAP_EXTENDED_SECURITY;
505                 pSMB->req.Capabilities = cpu_to_le32(capabilities);
506                 /* BB set password lengths */
507         }
508
509         count = (long) bcc_ptr - (long) str_area;
510         smb_buf->smb_buf_length += count;
511
512         BCC_LE(smb_buf) = cpu_to_le16(count);
513
514         iov[1].iov_base = str_area;
515         iov[1].iov_len = count;
516         rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type,
517                           0 /* not long op */, 1 /* log NT STATUS if any */ );
518         /* SMB request buf freed in SendReceive2 */
519
520         cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
521         if (rc)
522                 goto ssetup_exit;
523
524         pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
525         smb_buf = (struct smb_hdr *)iov[0].iov_base;
526
527         if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
528                 rc = -EIO;
529                 cERROR(1, ("bad word count %d", smb_buf->WordCount));
530                 goto ssetup_exit;
531         }
532         action = le16_to_cpu(pSMB->resp.Action);
533         if (action & GUEST_LOGIN)
534                 cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
535         ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
536         cFYI(1, ("UID = %d ", ses->Suid));
537         /* response can have either 3 or 4 word count - Samba sends 3 */
538         /* and lanman response is 3 */
539         bytes_remaining = BCC(smb_buf);
540         bcc_ptr = pByteArea(smb_buf);
541
542         if (smb_buf->WordCount == 4) {
543                 __u16 blob_len;
544                 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
545                 bcc_ptr += blob_len;
546                 if (blob_len > bytes_remaining) {
547                         cERROR(1, ("bad security blob length %d", blob_len));
548                         rc = -EINVAL;
549                         goto ssetup_exit;
550                 }
551                 bytes_remaining -= blob_len;
552         }
553
554         /* BB check if Unicode and decode strings */
555         if (smb_buf->Flags2 & SMBFLG2_UNICODE)
556                 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
557                                                    ses, nls_cp);
558         else
559                 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
560                                          ses, nls_cp);
561
562 ssetup_exit:
563         kfree(str_area);
564         if (resp_buf_type == CIFS_SMALL_BUFFER) {
565                 cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
566                 cifs_small_buf_release(iov[0].iov_base);
567         } else if (resp_buf_type == CIFS_LARGE_BUFFER)
568                 cifs_buf_release(iov[0].iov_base);
569
570         return rc;
571 }