]> err.no Git - linux-2.6/blob - fs/cifs/sess.c
78797c0e076cf6d7a5ecdfc5e615d664f4501a9f
[linux-2.6] / 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 unicode_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
78                                    const struct nls_table *nls_cp)
79 {
80         char *bcc_ptr = *pbcc_area;
81         int bytes_ret = 0;
82
83         /* BB FIXME add check that strings total less
84         than 335 or will need to send them as arrays */
85
86         /* unicode strings, must be word aligned before the call */
87 /*      if ((long) bcc_ptr % 2) {
88                 *bcc_ptr = 0;
89                 bcc_ptr++;
90         } */
91         /* copy user */
92         if (ses->userName == NULL) {
93                 /* null user mount */
94                 *bcc_ptr = 0;
95                 *(bcc_ptr+1) = 0;
96         } else { /* 300 should be long enough for any conceivable user name */
97                 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->userName,
98                                           300, nls_cp);
99         }
100         bcc_ptr += 2 * bytes_ret;
101         bcc_ptr += 2; /* account for null termination */
102         /* copy domain */
103         if (ses->domainName == NULL) {
104                 /* Sending null domain better than using a bogus domain name (as
105                 we did briefly in 2.6.18) since server will use its default */
106                 *bcc_ptr = 0;
107                 *(bcc_ptr+1) = 0;
108                 bytes_ret = 0;
109         } else
110                 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName,
111                                           256, nls_cp);
112         bcc_ptr += 2 * bytes_ret;
113         bcc_ptr += 2;  /* account for null terminator */
114
115         /* Copy OS version */
116         bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
117                                   nls_cp);
118         bcc_ptr += 2 * bytes_ret;
119         bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, init_utsname()->release,
120                                   32, nls_cp);
121         bcc_ptr += 2 * bytes_ret;
122         bcc_ptr += 2; /* trailing null */
123
124         bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
125                                   32, nls_cp);
126         bcc_ptr += 2 * bytes_ret;
127         bcc_ptr += 2; /* trailing null */
128
129         *pbcc_area = bcc_ptr;
130 }
131
132 static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
133                                  const struct nls_table *nls_cp)
134 {
135         char *bcc_ptr = *pbcc_area;
136
137         /* copy user */
138         /* BB what about null user mounts - check that we do this BB */
139         /* copy user */
140         if (ses->userName == NULL) {
141                 /* BB what about null user mounts - check that we do this BB */
142         } else { /* 300 should be long enough for any conceivable user name */
143                 strncpy(bcc_ptr, ses->userName, 300);
144         }
145         /* BB improve check for overflow */
146         bcc_ptr += strnlen(ses->userName, 300);
147         *bcc_ptr = 0;
148         bcc_ptr++; /* account for null termination */
149
150         /* copy domain */
151
152         if (ses->domainName != NULL) {
153                 strncpy(bcc_ptr, ses->domainName, 256);
154                 bcc_ptr += strnlen(ses->domainName, 256);
155         } /* else we will send a null domain name
156              so the server will default to its own domain */
157         *bcc_ptr = 0;
158         bcc_ptr++;
159
160         /* BB check for overflow here */
161
162         strcpy(bcc_ptr, "Linux version ");
163         bcc_ptr += strlen("Linux version ");
164         strcpy(bcc_ptr, init_utsname()->release);
165         bcc_ptr += strlen(init_utsname()->release) + 1;
166
167         strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
168         bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
169
170         *pbcc_area = bcc_ptr;
171 }
172
173 static int decode_unicode_ssetup(char **pbcc_area, int bleft,
174                                  struct cifsSesInfo *ses,
175                                  const struct nls_table *nls_cp)
176 {
177         int rc = 0;
178         int words_left, len;
179         char *data = *pbcc_area;
180
181
182
183         cFYI(1, ("bleft %d", bleft));
184
185
186         /* SMB header is unaligned, so cifs servers word align start of
187            Unicode strings */
188         data++;
189         bleft--; /* Windows servers do not always double null terminate
190                     their final Unicode string - in which case we
191                     now will not attempt to decode the byte of junk
192                     which follows it */
193
194         words_left = bleft / 2;
195
196         /* save off server operating system */
197         len = UniStrnlen((wchar_t *) data, words_left);
198
199 /* We look for obvious messed up bcc or strings in response so we do not go off
200    the end since (at least) WIN2K and Windows XP have a major bug in not null
201    terminating last Unicode string in response  */
202         if (len >= words_left)
203                 return rc;
204
205         kfree(ses->serverOS);
206         /* UTF-8 string will not grow more than four times as big as UCS-16 */
207         ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
208         if (ses->serverOS != NULL)
209                 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len, nls_cp);
210         data += 2 * (len + 1);
211         words_left -= len + 1;
212
213         /* save off server network operating system */
214         len = UniStrnlen((wchar_t *) data, words_left);
215
216         if (len >= words_left)
217                 return rc;
218
219         kfree(ses->serverNOS);
220         ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
221         if (ses->serverNOS != NULL) {
222                 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
223                                    nls_cp);
224                 if (strncmp(ses->serverNOS, "NT LAN Manager 4", 16) == 0) {
225                         cFYI(1, ("NT4 server"));
226                         ses->flags |= CIFS_SES_NT4;
227                 }
228         }
229         data += 2 * (len + 1);
230         words_left -= len + 1;
231
232         /* save off server domain */
233         len = UniStrnlen((wchar_t *) data, words_left);
234
235         if (len > words_left)
236                 return rc;
237
238         kfree(ses->serverDomain);
239         ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
240         if (ses->serverDomain != NULL) {
241                 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
242                                    nls_cp);
243                 ses->serverDomain[2*len] = 0;
244                 ses->serverDomain[(2*len) + 1] = 0;
245         }
246         data += 2 * (len + 1);
247         words_left -= len + 1;
248
249         cFYI(1, ("words left: %d", words_left));
250
251         return rc;
252 }
253
254 static int decode_ascii_ssetup(char **pbcc_area, int bleft,
255                                struct cifsSesInfo *ses,
256                                const struct nls_table *nls_cp)
257 {
258         int rc = 0;
259         int len;
260         char *bcc_ptr = *pbcc_area;
261
262         cFYI(1, ("decode sessetup ascii. bleft %d", bleft));
263
264         len = strnlen(bcc_ptr, bleft);
265         if (len >= bleft)
266                 return rc;
267
268         kfree(ses->serverOS);
269
270         ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
271         if (ses->serverOS)
272                 strncpy(ses->serverOS, bcc_ptr, len);
273         if (strncmp(ses->serverOS, "OS/2", 4) == 0) {
274                         cFYI(1, ("OS/2 server"));
275                         ses->flags |= CIFS_SES_OS2;
276         }
277
278         bcc_ptr += len + 1;
279         bleft -= len + 1;
280
281         len = strnlen(bcc_ptr, bleft);
282         if (len >= bleft)
283                 return rc;
284
285         kfree(ses->serverNOS);
286
287         ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
288         if (ses->serverNOS)
289                 strncpy(ses->serverNOS, bcc_ptr, len);
290
291         bcc_ptr += len + 1;
292         bleft -= len + 1;
293
294         len = strnlen(bcc_ptr, bleft);
295         if (len > bleft)
296                 return rc;
297
298         /* No domain field in LANMAN case. Domain is
299            returned by old servers in the SMB negprot response */
300         /* BB For newer servers which do not support Unicode,
301            but thus do return domain here we could add parsing
302            for it later, but it is not very important */
303         cFYI(1, ("ascii: bytes left %d", bleft));
304
305         return rc;
306 }
307
308 int
309 CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
310                 const struct nls_table *nls_cp)
311 {
312         int rc = 0;
313         int wct;
314         struct smb_hdr *smb_buf;
315         char *bcc_ptr;
316         char *str_area;
317         SESSION_SETUP_ANDX *pSMB;
318         __u32 capabilities;
319         int count;
320         int resp_buf_type = 0;
321         struct kvec iov[2];
322         enum securityEnum type;
323         __u16 action;
324         int bytes_remaining;
325
326         if (ses == NULL)
327                 return -EINVAL;
328
329         type = ses->server->secType;
330
331         cFYI(1, ("sess setup type %d", type));
332         if (type == LANMAN) {
333 #ifndef CONFIG_CIFS_WEAK_PW_HASH
334                 /* LANMAN and plaintext are less secure and off by default.
335                 So we make this explicitly be turned on in kconfig (in the
336                 build) and turned on at runtime (changed from the default)
337                 in proc/fs/cifs or via mount parm.  Unfortunately this is
338                 needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
339                 return -EOPNOTSUPP;
340 #endif
341                 wct = 10; /* lanman 2 style sessionsetup */
342         } else if ((type == NTLM) || (type == NTLMv2)) {
343                 /* For NTLMv2 failures eventually may need to retry NTLM */
344                 wct = 13; /* old style NTLM sessionsetup */
345         } else /* same size: negotiate or auth, NTLMSSP or extended security */
346                 wct = 12;
347
348         rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
349                             (void **)&smb_buf);
350         if (rc)
351                 return rc;
352
353         pSMB = (SESSION_SETUP_ANDX *)smb_buf;
354
355         capabilities = cifs_ssetup_hdr(ses, pSMB);
356
357         /* we will send the SMB in two pieces,
358         a fixed length beginning part, and a
359         second part which will include the strings
360         and rest of bcc area, in order to avoid having
361         to do a large buffer 17K allocation */
362         iov[0].iov_base = (char *)pSMB;
363         iov[0].iov_len = smb_buf->smb_buf_length + 4;
364
365         /* 2000 big enough to fit max user, domain, NOS name etc. */
366         str_area = kmalloc(2000, GFP_KERNEL);
367         if (str_area == NULL) {
368                 cifs_small_buf_release(smb_buf);
369                 return -ENOMEM;
370         }
371         bcc_ptr = str_area;
372
373         ses->flags &= ~CIFS_SES_LANMAN;
374
375         if (type == LANMAN) {
376 #ifdef CONFIG_CIFS_WEAK_PW_HASH
377                 char lnm_session_key[CIFS_SESS_KEY_SIZE];
378
379                 /* no capabilities flags in old lanman negotiation */
380
381                 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
382                 /* BB calculate hash with password */
383                 /* and copy into bcc */
384
385                 calc_lanman_hash(ses, lnm_session_key);
386                 ses->flags |= CIFS_SES_LANMAN;
387 /* #ifdef CONFIG_CIFS_DEBUG2
388                 cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
389                         CIFS_SESS_KEY_SIZE);
390 #endif */
391                 memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
392                 bcc_ptr += CIFS_SESS_KEY_SIZE;
393
394                 /* can not sign if LANMAN negotiated so no need
395                 to calculate signing key? but what if server
396                 changed to do higher than lanman dialect and
397                 we reconnected would we ever calc signing_key? */
398
399                 cFYI(1, ("Negotiating LANMAN setting up strings"));
400                 /* Unicode not allowed for LANMAN dialects */
401                 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
402 #endif
403         } else if (type == NTLM) {
404                 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
405
406                 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
407                 pSMB->req_no_secext.CaseInsensitivePasswordLength =
408                         cpu_to_le16(CIFS_SESS_KEY_SIZE);
409                 pSMB->req_no_secext.CaseSensitivePasswordLength =
410                         cpu_to_le16(CIFS_SESS_KEY_SIZE);
411
412                 /* calculate session key */
413                 SMBNTencrypt(ses->password, ses->server->cryptKey,
414                              ntlm_session_key);
415
416                 if (first_time) /* should this be moved into common code
417                                   with similar ntlmv2 path? */
418                         cifs_calculate_mac_key(&ses->server->mac_signing_key,
419                                 ntlm_session_key, ses->password);
420                 /* copy session key */
421
422                 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
423                 bcc_ptr += CIFS_SESS_KEY_SIZE;
424                 memcpy(bcc_ptr, (char *)ntlm_session_key, CIFS_SESS_KEY_SIZE);
425                 bcc_ptr += CIFS_SESS_KEY_SIZE;
426                 if (ses->capabilities & CAP_UNICODE) {
427                         /* unicode strings must be word aligned */
428                         if (iov[0].iov_len % 2) {
429                                 *bcc_ptr = 0;
430                                 bcc_ptr++;
431                         }
432                         unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
433                 } else
434                         ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
435         } else if (type == NTLMv2) {
436                 char *v2_sess_key =
437                         kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
438
439                 /* BB FIXME change all users of v2_sess_key to
440                    struct ntlmv2_resp */
441
442                 if (v2_sess_key == NULL) {
443                         cifs_small_buf_release(smb_buf);
444                         return -ENOMEM;
445                 }
446
447                 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
448
449                 /* LM2 password would be here if we supported it */
450                 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
451                 /*      cpu_to_le16(LM2_SESS_KEY_SIZE); */
452
453                 pSMB->req_no_secext.CaseSensitivePasswordLength =
454                         cpu_to_le16(sizeof(struct ntlmv2_resp));
455
456                 /* calculate session key */
457                 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
458                 if (first_time) /* should this be moved into common code
459                                    with similar ntlmv2 path? */
460                 /*   cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
461                                 response BB FIXME, v2_sess_key); */
462
463                 /* copy session key */
464
465         /*      memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
466                 bcc_ptr += LM2_SESS_KEY_SIZE; */
467                 memcpy(bcc_ptr, (char *)v2_sess_key,
468                        sizeof(struct ntlmv2_resp));
469                 bcc_ptr += sizeof(struct ntlmv2_resp);
470                 kfree(v2_sess_key);
471                 if (ses->capabilities & CAP_UNICODE) {
472                         if (iov[0].iov_len % 2) {
473                                 *bcc_ptr = 0;
474                                 bcc_ptr++;
475                         }
476                         unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
477                 } else
478                         ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
479         } else /* NTLMSSP or SPNEGO */ {
480                 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
481                 capabilities |= CAP_EXTENDED_SECURITY;
482                 pSMB->req.Capabilities = cpu_to_le32(capabilities);
483                 /* BB set password lengths */
484         }
485
486         count = (long) bcc_ptr - (long) str_area;
487         smb_buf->smb_buf_length += count;
488
489         BCC_LE(smb_buf) = cpu_to_le16(count);
490
491         iov[1].iov_base = str_area;
492         iov[1].iov_len = count;
493         rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
494         /* SMB request buf freed in SendReceive2 */
495
496         cFYI(1, ("ssetup rc from sendrecv2 is %d", rc));
497         if (rc)
498                 goto ssetup_exit;
499
500         pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
501         smb_buf = (struct smb_hdr *)iov[0].iov_base;
502
503         if ((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
504                 rc = -EIO;
505                 cERROR(1, ("bad word count %d", smb_buf->WordCount));
506                 goto ssetup_exit;
507         }
508         action = le16_to_cpu(pSMB->resp.Action);
509         if (action & GUEST_LOGIN)
510                 cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
511         ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
512         cFYI(1, ("UID = %d ", ses->Suid));
513         /* response can have either 3 or 4 word count - Samba sends 3 */
514         /* and lanman response is 3 */
515         bytes_remaining = BCC(smb_buf);
516         bcc_ptr = pByteArea(smb_buf);
517
518         if (smb_buf->WordCount == 4) {
519                 __u16 blob_len;
520                 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
521                 bcc_ptr += blob_len;
522                 if (blob_len > bytes_remaining) {
523                         cERROR(1, ("bad security blob length %d", blob_len));
524                         rc = -EINVAL;
525                         goto ssetup_exit;
526                 }
527                 bytes_remaining -= blob_len;
528         }
529
530         /* BB check if Unicode and decode strings */
531         if (smb_buf->Flags2 & SMBFLG2_UNICODE)
532                 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
533                                                    ses, nls_cp);
534         else
535                 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining,
536                                          ses, nls_cp);
537
538 ssetup_exit:
539         kfree(str_area);
540         if (resp_buf_type == CIFS_SMALL_BUFFER) {
541                 cFYI(1, ("ssetup freeing small buf %p", iov[0].iov_base));
542                 cifs_small_buf_release(iov[0].iov_base);
543         } else if (resp_buf_type == CIFS_LARGE_BUFFER)
544                 cifs_buf_release(iov[0].iov_base);
545
546         return rc;
547 }