CIFS] Support for older servers which require plaintext passwords - part 2
[pandora-kernel.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
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 #ifdef CONFIG_CIFS_EXPERIMENTAL
37
38 static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
39 {
40         __u32 capabilities = 0;
41
42         /* init fields common to all four types of SessSetup */
43         /* note that header is initialized to zero in header_assemble */
44         pSMB->req.AndXCommand = 0xFF;
45         pSMB->req.MaxBufferSize = cpu_to_le16(ses->server->maxBuf);
46         pSMB->req.MaxMpxCount = cpu_to_le16(ses->server->maxReq);
47
48         /* Now no need to set SMBFLG_CASELESS or obsolete CANONICAL PATH */
49
50         /* BB verify whether signing required on neg or just on auth frame 
51            (and NTLM case) */
52
53         capabilities = CAP_LARGE_FILES | CAP_NT_SMBS | CAP_LEVEL_II_OPLOCKS |
54                         CAP_LARGE_WRITE_X | CAP_LARGE_READ_X;
55
56         if(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
57                 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
58
59         if (ses->capabilities & CAP_UNICODE) {
60                 pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
61                 capabilities |= CAP_UNICODE;
62         }
63         if (ses->capabilities & CAP_STATUS32) {
64                 pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
65                 capabilities |= CAP_STATUS32;
66         }
67         if (ses->capabilities & CAP_DFS) {
68                 pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
69                 capabilities |= CAP_DFS;
70         }
71         if (ses->capabilities & CAP_UNIX) {
72                 capabilities |= CAP_UNIX;
73         }
74
75         /* BB check whether to init vcnum BB */
76         return capabilities;
77 }
78
79 static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
80                             const struct nls_table * nls_cp)
81 {
82         char * bcc_ptr = *pbcc_area;
83         int bytes_ret = 0;
84
85         /* BB FIXME add check that strings total less
86         than 335 or will need to send them as arrays */
87
88         /* align unicode strings, must be word aligned */
89         if ((long) bcc_ptr % 2) {
90                 *bcc_ptr = 0;
91                 bcc_ptr++;
92         }
93         /* copy user */
94         if(ses->userName == NULL) {
95                 /* BB what about null user mounts - check that we do this BB */
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                 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr,
105                                           "CIFS_LINUX_DOM", 32, nls_cp);
106         else
107                 bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, ses->domainName, 
108                                           256, nls_cp);
109         bcc_ptr += 2 * bytes_ret;
110         bcc_ptr += 2;  /* account for null terminator */
111
112         /* Copy OS version */
113         bytes_ret = cifs_strtoUCS((__le16 *)bcc_ptr, "Linux version ", 32,
114                                   nls_cp);
115         bcc_ptr += 2 * bytes_ret;
116         bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, system_utsname.release,
117                                   32, nls_cp);
118         bcc_ptr += 2 * bytes_ret;
119         bcc_ptr += 2; /* trailing null */
120
121         bytes_ret = cifs_strtoUCS((__le16 *) bcc_ptr, CIFS_NETWORK_OPSYS,
122                                   32, nls_cp);
123         bcc_ptr += 2 * bytes_ret;
124         bcc_ptr += 2; /* trailing null */
125
126         *pbcc_area = bcc_ptr;
127 }
128
129 static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
130                           const struct nls_table * nls_cp)
131 {
132         char * bcc_ptr = *pbcc_area;
133
134         /* copy user */
135         /* BB what about null user mounts - check that we do this BB */
136         /* copy user */
137         if(ses->userName == NULL) {
138                 /* BB what about null user mounts - check that we do this BB */
139         } else { /* 300 should be long enough for any conceivable user name */
140                 strncpy(bcc_ptr, ses->userName, 300);
141         }
142         /* BB improve check for overflow */
143         bcc_ptr += strnlen(ses->userName, 200);
144         *bcc_ptr = 0;
145         bcc_ptr++; /* account for null termination */
146
147         /* copy domain */
148         
149         if(ses->domainName == NULL) {
150                 strcpy(bcc_ptr, "CIFS_LINUX_DOM");
151                 bcc_ptr += 14;  /* strlen(CIFS_LINUX_DOM) */
152         } else {
153                 strncpy(bcc_ptr, ses->domainName, 256); 
154                 bcc_ptr += strnlen(ses->domainName, 256);
155         }
156         *bcc_ptr = 0;
157         bcc_ptr++;
158
159         /* BB check for overflow here */
160
161         strcpy(bcc_ptr, "Linux version ");
162         bcc_ptr += strlen("Linux version ");
163         strcpy(bcc_ptr, system_utsname.release);
164         bcc_ptr += strlen(system_utsname.release) + 1;
165
166         strcpy(bcc_ptr, CIFS_NETWORK_OPSYS);
167         bcc_ptr += strlen(CIFS_NETWORK_OPSYS) + 1;
168
169         *pbcc_area = bcc_ptr;
170 }
171
172 static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses,
173                             const struct nls_table * nls_cp)
174 {
175         int rc = 0;
176         int words_left, len;
177         char * data = *pbcc_area;
178
179
180
181         cFYI(1,("bleft %d",bleft));
182
183
184         /* word align, if bytes remaining is not even */
185         if(bleft % 2) {
186                 bleft--;
187                 data++;
188         }
189         words_left = bleft / 2;
190
191         /* save off server operating system */
192         len = UniStrnlen((wchar_t *) data, words_left);
193
194 /* We look for obvious messed up bcc or strings in response so we do not go off
195    the end since (at least) WIN2K and Windows XP have a major bug in not null
196    terminating last Unicode string in response  */
197         if(len >= words_left)
198                 return rc;
199
200         if(ses->serverOS)
201                 kfree(ses->serverOS);
202         /* UTF-8 string will not grow more than four times as big as UCS-16 */
203         ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
204         if(ses->serverOS != NULL) {
205                 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len,
206                                    nls_cp);
207         }
208         data += 2 * (len + 1);
209         words_left -= len + 1;
210
211         /* save off server network operating system */
212         len = UniStrnlen((wchar_t *) data, words_left);
213
214         if(len >= words_left)
215                 return rc;
216
217         if(ses->serverNOS)
218                 kfree(ses->serverNOS);
219         ses->serverNOS = kzalloc(4 * len, GFP_KERNEL); /* BB this is wrong length FIXME BB */
220         if(ses->serverNOS != NULL) {
221                 cifs_strfromUCS_le(ses->serverNOS, (__le16 *)data, len,
222                                    nls_cp);
223                 if(strncmp(ses->serverNOS, "NT LAN Manager 4",16) == 0) {
224                         cFYI(1,("NT4 server"));
225                         ses->flags |= CIFS_SES_NT4;
226                 }
227         }
228         data += 2 * (len + 1);
229         words_left -= len + 1;
230
231         /* save off server domain */
232         len = UniStrnlen((wchar_t *) data, words_left);
233
234         if(len > words_left)
235                 return rc;
236
237         if(ses->serverDomain)
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, struct cifsSesInfo *ses,
255                             const struct nls_table * nls_cp)
256 {
257         int rc = 0;
258         int len;
259         char * bcc_ptr = *pbcc_area;
260
261         cFYI(1,("decode sessetup ascii. bleft %d", bleft));
262         
263         len = strnlen(bcc_ptr, bleft);
264         if(len >= bleft)
265                 return rc;
266         
267         if(ses->serverOS)
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
274         bcc_ptr += len + 1;
275         bleft -= len + 1;
276
277         len = strnlen(bcc_ptr, bleft);
278         if(len >= bleft)
279                 return rc;
280
281         if(ses->serverNOS)
282                 kfree(ses->serverNOS);
283
284         ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
285         if(ses->serverNOS)
286                 strncpy(ses->serverNOS, bcc_ptr, len);
287
288         bcc_ptr += len + 1;
289         bleft -= len + 1;
290
291         len = strnlen(bcc_ptr, bleft);
292         if(len > bleft)
293                 return rc;
294
295         if(ses->serverDomain)
296                 kfree(ses->serverDomain);
297
298         ses->serverDomain = kzalloc(len + 1, GFP_KERNEL);
299         if(ses->serverOS)
300                 strncpy(ses->serverOS, bcc_ptr, len);
301
302         bcc_ptr += len + 1;
303         bleft -= len + 1;
304
305         cFYI(1,("ascii: bytes left %d",bleft));
306
307         return rc;
308 }
309
310 int 
311 CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
312                 const struct nls_table *nls_cp)
313 {
314         int rc = 0;
315         int wct;
316         struct smb_hdr *smb_buf;
317         char *bcc_ptr;
318         SESSION_SETUP_ANDX *pSMB;
319         __u32 capabilities;
320         int count;
321         int resp_buf_type = 0;
322         struct kvec iov[1];
323         enum securityEnum type;
324         __u16 action;
325         int bytes_remaining;
326
327         cFYI(1,("new sess setup"));
328         if(ses == NULL)
329                 return -EINVAL;
330
331         type = ses->server->secType;
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)) /* NTLMv2 may retry NTLM */
343                 wct = 13; /* old style NTLM sessionsetup */
344         else /* same size for negotiate or auth, NTLMSSP or extended security */
345                 wct = 12;
346
347         rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
348                             (void **)&smb_buf);
349         if(rc)
350                 return rc;
351
352         pSMB = (SESSION_SETUP_ANDX *)smb_buf;
353
354         capabilities = cifs_ssetup_hdr(ses, pSMB);
355         bcc_ptr = pByteArea(smb_buf);
356
357         if(type == LANMAN) {
358 #ifdef CONFIG_CIFS_WEAK_PW_HASH
359                 char lnm_session_key[CIFS_SESS_KEY_SIZE];
360
361                 /* no capabilities flags in old lanman negotiation */
362
363                 pSMB->old_req.PasswordLength = CIFS_SESS_KEY_SIZE; 
364                 /* BB calculate hash with password */
365                 /* and copy into bcc */
366
367                 calc_lanman_hash(ses, lnm_session_key);
368
369 #ifdef CONFIG_CIFS_DEBUG2
370                 cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
371                         CIFS_SESS_KEY_SIZE);
372 #endif
373                 memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
374                 bcc_ptr += CIFS_SESS_KEY_SIZE;
375
376                 /* can not sign if LANMAN negotiated so no need
377                 to calculate signing key? but what if server
378                 changed to do higher than lanman dialect and
379                 we reconnected would we ever calc signing_key? */
380
381                 cERROR(1,("Negotiating LANMAN setting up strings"));
382                 /* Unicode not allowed for LANMAN dialects */
383                 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
384 #endif    
385         } else if (type == NTLM) {
386                 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
387
388                 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
389                 pSMB->req_no_secext.CaseInsensitivePasswordLength =
390                         cpu_to_le16(CIFS_SESS_KEY_SIZE);
391                 pSMB->req_no_secext.CaseSensitivePasswordLength =
392                         cpu_to_le16(CIFS_SESS_KEY_SIZE);
393         
394                 /* calculate session key */
395                 SMBNTencrypt(ses->password, ses->server->cryptKey,
396                              ntlm_session_key);
397
398                 if(first_time) /* should this be moved into common code 
399                                   with similar ntlmv2 path? */
400                         cifs_calculate_mac_key( ses->server->mac_signing_key,
401                                 ntlm_session_key, ses->password);
402                 /* copy session key */
403
404                 memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
405                 bcc_ptr += CIFS_SESS_KEY_SIZE;
406                 memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
407                 bcc_ptr += CIFS_SESS_KEY_SIZE;
408                 if(ses->capabilities & CAP_UNICODE)
409                         unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
410                 else
411                         ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
412         } else if (type == NTLMv2) {
413                 char * v2_sess_key = kmalloc(V2_SESS_KEY_SIZE, GFP_KERNEL);
414
415                 if(v2_sess_key == NULL) {
416                         cifs_small_buf_release(smb_buf);
417                         return -ENOMEM;
418                 }
419
420                 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
421
422                 /* LM2 password would be here if we supported it */
423                 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
424                 /*      cpu_to_le16(LM2_SESS_KEY_SIZE); */
425
426                 pSMB->req_no_secext.CaseSensitivePasswordLength =
427                         cpu_to_le16(V2_SESS_KEY_SIZE);
428
429                 /* calculate session key */
430                 CalcNTLMv2_response(ses, v2_sess_key);
431                 if(first_time) /* should this be moved into common code
432                                   with similar ntlmv2 path? */
433                 /*   cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
434                                 response BB FIXME, v2_sess_key); */
435
436                 /* copy session key */
437
438         /*      memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
439                 bcc_ptr += LM2_SESS_KEY_SIZE; */
440                 memcpy(bcc_ptr, (char *)v2_sess_key, V2_SESS_KEY_SIZE);
441                 bcc_ptr += V2_SESS_KEY_SIZE;
442                 if(ses->capabilities & CAP_UNICODE)
443                         unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
444                 else
445                         ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
446         } else /* NTLMSSP or SPNEGO */ {
447                 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
448                 capabilities |= CAP_EXTENDED_SECURITY;
449                 pSMB->req.Capabilities = cpu_to_le32(capabilities);
450                 /* BB set password lengths */
451         }
452
453         count = (long) bcc_ptr - (long) pByteArea(smb_buf);
454         smb_buf->smb_buf_length += count;
455
456         /* if we switch to small buffers, count will need to be fewer
457            than 383 (strings less than 335 bytes) */
458
459         BCC_LE(smb_buf) = cpu_to_le16(count);
460
461
462         /* BB FIXME check for other non ntlm code paths */
463
464         /* BB check is this too big for a small smb? */
465
466         iov[0].iov_base = (char *)pSMB;
467         iov[0].iov_len = smb_buf->smb_buf_length + 4;
468
469         rc = SendReceive2(xid, ses, iov, 1 /* num_iovecs */, &resp_buf_type, 0);
470         /* SMB request buf freed in SendReceive2 */
471
472         cFYI(1,("ssetup rc from sendrecv2 is %d",rc));
473         if(rc)
474                 goto ssetup_exit;
475
476         pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
477         smb_buf = (struct smb_hdr *)iov[0].iov_base;
478
479         if((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
480                 rc = -EIO;
481                 cERROR(1,("bad word count %d", smb_buf->WordCount));
482                 goto ssetup_exit;
483         }
484         action = le16_to_cpu(pSMB->resp.Action);
485         if (action & GUEST_LOGIN)
486                 cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
487         ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
488         cFYI(1, ("UID = %d ", ses->Suid));
489         /* response can have either 3 or 4 word count - Samba sends 3 */
490         /* and lanman response is 3 */
491         bytes_remaining = BCC(smb_buf);
492         bcc_ptr = pByteArea(smb_buf);
493
494         if(smb_buf->WordCount == 4) {
495                 __u16 blob_len;
496                 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
497                 bcc_ptr += blob_len;
498                 if(blob_len > bytes_remaining) {
499                         cERROR(1,("bad security blob length %d", blob_len));
500                         rc = -EINVAL;
501                         goto ssetup_exit;
502                 }
503                 bytes_remaining -= blob_len;
504         }       
505
506         /* BB check if Unicode and decode strings */
507         if(smb_buf->Flags2 & SMBFLG2_UNICODE)
508                 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
509                                                    ses, nls_cp);
510         else
511                 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,nls_cp);
512         
513 ssetup_exit:
514         if(resp_buf_type == CIFS_SMALL_BUFFER) {
515                 cFYI(1,("ssetup freeing small buf %p", iov[0].iov_base));
516                 cifs_small_buf_release(iov[0].iov_base);
517         } else if(resp_buf_type == CIFS_LARGE_BUFFER)
518                 cifs_buf_release(iov[0].iov_base);
519
520         return rc;
521 }
522 #endif /* CONFIG_CIFS_EXPERIMENTAL */