Merge to Fedora kernel-2.6.18-1.2255_FC5-vs2.0.2.2-rc9 patched with stable patch...
[linux-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
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 & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
55                 pSMB->req.hdr.Flags2 |= SMBFLG2_SECURITY_SIGNATURE;
56
57         if (ses->capabilities & CAP_UNICODE) {
58                 pSMB->req.hdr.Flags2 |= SMBFLG2_UNICODE;
59                 capabilities |= CAP_UNICODE;
60         }
61         if (ses->capabilities & CAP_STATUS32) {
62                 pSMB->req.hdr.Flags2 |= SMBFLG2_ERR_STATUS;
63                 capabilities |= CAP_STATUS32;
64         }
65         if (ses->capabilities & CAP_DFS) {
66                 pSMB->req.hdr.Flags2 |= SMBFLG2_DFS;
67                 capabilities |= CAP_DFS;
68         }
69         if (ses->capabilities & CAP_UNIX) {
70                 capabilities |= CAP_UNIX;
71         }
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, system_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, system_utsname.release);
165         bcc_ptr += strlen(system_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, struct cifsSesInfo *ses,
174                             const struct nls_table * nls_cp)
175 {
176         int rc = 0;
177         int words_left, len;
178         char * data = *pbcc_area;
179
180
181
182         cFYI(1,("bleft %d",bleft));
183
184
185         /* word align, if bytes remaining is not even */
186         if(bleft % 2) {
187                 bleft--;
188                 data++;
189         }
190         words_left = bleft / 2;
191
192         /* save off server operating system */
193         len = UniStrnlen((wchar_t *) data, words_left);
194
195 /* We look for obvious messed up bcc or strings in response so we do not go off
196    the end since (at least) WIN2K and Windows XP have a major bug in not null
197    terminating last Unicode string in response  */
198         if(len >= words_left)
199                 return rc;
200
201         if(ses->serverOS)
202                 kfree(ses->serverOS);
203         /* UTF-8 string will not grow more than four times as big as UCS-16 */
204         ses->serverOS = kzalloc(4 * len, GFP_KERNEL);
205         if(ses->serverOS != NULL) {
206                 cifs_strfromUCS_le(ses->serverOS, (__le16 *)data, len,
207                                    nls_cp);
208         }
209         data += 2 * (len + 1);
210         words_left -= len + 1;
211
212         /* save off server network operating system */
213         len = UniStrnlen((wchar_t *) data, words_left);
214
215         if(len >= words_left)
216                 return rc;
217
218         if(ses->serverNOS)
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         if(ses->serverDomain)
239                 kfree(ses->serverDomain);
240         ses->serverDomain = kzalloc(2 * (len + 1), GFP_KERNEL); /* BB FIXME wrong length */
241         if(ses->serverDomain != NULL) {
242                 cifs_strfromUCS_le(ses->serverDomain, (__le16 *)data, len,
243                                    nls_cp);
244                 ses->serverDomain[2*len] = 0;
245                 ses->serverDomain[(2*len) + 1] = 0;
246         }
247         data += 2 * (len + 1);
248         words_left -= len + 1;
249         
250         cFYI(1,("words left: %d",words_left));
251
252         return rc;
253 }
254
255 static int decode_ascii_ssetup(char ** pbcc_area, int bleft, 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         if(ses->serverOS)
269                 kfree(ses->serverOS);
270
271         ses->serverOS = kzalloc(len + 1, GFP_KERNEL);
272         if(ses->serverOS)
273                 strncpy(ses->serverOS, bcc_ptr, len);
274
275         bcc_ptr += len + 1;
276         bleft -= len + 1;
277
278         len = strnlen(bcc_ptr, bleft);
279         if(len >= bleft)
280                 return rc;
281
282         if(ses->serverNOS)
283                 kfree(ses->serverNOS);
284
285         ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
286         if(ses->serverNOS)
287                 strncpy(ses->serverNOS, bcc_ptr, len);
288
289         bcc_ptr += len + 1;
290         bleft -= len + 1;
291
292         len = strnlen(bcc_ptr, bleft);
293         if(len > bleft)
294                 return rc;
295
296         if(ses->serverDomain)
297                 kfree(ses->serverDomain);
298
299         ses->serverDomain = kzalloc(len + 1, GFP_KERNEL);
300         if(ses->serverOS)
301                 strncpy(ses->serverOS, bcc_ptr, len);
302
303         bcc_ptr += len + 1;
304         bleft -= len + 1;
305
306         cFYI(1,("ascii: bytes left %d",bleft));
307
308         return rc;
309 }
310
311 int 
312 CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
313                 const struct nls_table *nls_cp)
314 {
315         int rc = 0;
316         int wct;
317         struct smb_hdr *smb_buf;
318         char *bcc_ptr;
319         char *str_area;
320         SESSION_SETUP_ANDX *pSMB;
321         __u32 capabilities;
322         int count;
323         int resp_buf_type = 0;
324         struct kvec iov[2];
325         enum securityEnum type;
326         __u16 action;
327         int bytes_remaining;
328
329         if(ses == NULL)
330                 return -EINVAL;
331
332         type = ses->server->secType;
333
334         cFYI(1,("sess setup type %d",type));
335         if(type == LANMAN) {
336 #ifndef CONFIG_CIFS_WEAK_PW_HASH
337                 /* LANMAN and plaintext are less secure and off by default.
338                 So we make this explicitly be turned on in kconfig (in the
339                 build) and turned on at runtime (changed from the default)
340                 in proc/fs/cifs or via mount parm.  Unfortunately this is
341                 needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
342                 return -EOPNOTSUPP;
343 #endif
344                 wct = 10; /* lanman 2 style sessionsetup */
345         } else if((type == NTLM) || (type == NTLMv2)) { 
346                 /* For NTLMv2 failures eventually may need to retry NTLM */
347                 wct = 13; /* old style NTLM sessionsetup */
348         } else /* same size for negotiate or auth, NTLMSSP or extended security */
349                 wct = 12;
350
351         rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
352                             (void **)&smb_buf);
353         if(rc)
354                 return rc;
355
356         pSMB = (SESSION_SETUP_ANDX *)smb_buf;
357
358         capabilities = cifs_ssetup_hdr(ses, pSMB);
359
360         /* we will send the SMB in two pieces,
361         a fixed length beginning part, and a
362         second part which will include the strings
363         and rest of bcc area, in order to avoid having
364         to do a large buffer 17K allocation */
365         iov[0].iov_base = (char *)pSMB;
366         iov[0].iov_len = smb_buf->smb_buf_length + 4;
367
368         /* 2000 big enough to fit max user, domain, NOS name etc. */
369         str_area = kmalloc(2000, GFP_KERNEL);
370         bcc_ptr = str_area;
371
372         if(type == LANMAN) {
373 #ifdef CONFIG_CIFS_WEAK_PW_HASH
374                 char lnm_session_key[CIFS_SESS_KEY_SIZE];
375
376                 /* no capabilities flags in old lanman negotiation */
377
378                 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE); 
379                 /* BB calculate hash with password */
380                 /* and copy into bcc */
381
382                 calc_lanman_hash(ses, lnm_session_key);
383
384 /* #ifdef CONFIG_CIFS_DEBUG2
385                 cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
386                         CIFS_SESS_KEY_SIZE);
387 #endif */
388                 memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
389                 bcc_ptr += CIFS_SESS_KEY_SIZE;
390
391                 /* can not sign if LANMAN negotiated so no need
392                 to calculate signing key? but what if server
393                 changed to do higher than lanman dialect and
394                 we reconnected would we ever calc signing_key? */
395
396                 cFYI(1,("Negotiating LANMAN setting up strings"));
397                 /* Unicode not allowed for LANMAN dialects */
398                 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
399 #endif    
400         } else if (type == NTLM) {
401                 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
402
403                 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
404                 pSMB->req_no_secext.CaseInsensitivePasswordLength =
405                         cpu_to_le16(CIFS_SESS_KEY_SIZE);
406                 pSMB->req_no_secext.CaseSensitivePasswordLength =
407                         cpu_to_le16(CIFS_SESS_KEY_SIZE);
408         
409                 /* calculate session key */
410                 SMBNTencrypt(ses->password, ses->server->cryptKey,
411                              ntlm_session_key);
412
413                 if(first_time) /* should this be moved into common code 
414                                   with similar ntlmv2 path? */
415                         cifs_calculate_mac_key(ses->server->mac_signing_key,
416                                 ntlm_session_key, ses->password);
417                 /* copy session key */
418
419                 memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
420                 bcc_ptr += CIFS_SESS_KEY_SIZE;
421                 memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
422                 bcc_ptr += CIFS_SESS_KEY_SIZE;
423                 if(ses->capabilities & CAP_UNICODE) {
424                         /* unicode strings must be word aligned */
425                         if (iov[0].iov_len % 2) {
426                                 *bcc_ptr = 0;
427                                 bcc_ptr++;              
428                         }       
429                         unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
430                 } else
431                         ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
432         } else if (type == NTLMv2) {
433                 char * v2_sess_key = 
434                         kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
435
436                 /* BB FIXME change all users of v2_sess_key to
437                    struct ntlmv2_resp */
438
439                 if(v2_sess_key == NULL) {
440                         cifs_small_buf_release(smb_buf);
441                         return -ENOMEM;
442                 }
443
444                 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
445
446                 /* LM2 password would be here if we supported it */
447                 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
448                 /*      cpu_to_le16(LM2_SESS_KEY_SIZE); */
449
450                 pSMB->req_no_secext.CaseSensitivePasswordLength =
451                         cpu_to_le16(sizeof(struct ntlmv2_resp));
452
453                 /* calculate session key */
454                 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
455                 if(first_time) /* should this be moved into common code
456                                   with similar ntlmv2 path? */
457                 /*   cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
458                                 response BB FIXME, v2_sess_key); */
459
460                 /* copy session key */
461
462         /*      memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
463                 bcc_ptr += LM2_SESS_KEY_SIZE; */
464                 memcpy(bcc_ptr, (char *)v2_sess_key, sizeof(struct ntlmv2_resp));
465                 bcc_ptr += sizeof(struct ntlmv2_resp);
466                 kfree(v2_sess_key);
467                 if(ses->capabilities & CAP_UNICODE) {
468                         if(iov[0].iov_len % 2) {
469                                 *bcc_ptr = 0;
470                         }       bcc_ptr++;
471                         unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
472                 } else
473                         ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
474         } else /* NTLMSSP or SPNEGO */ {
475                 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
476                 capabilities |= CAP_EXTENDED_SECURITY;
477                 pSMB->req.Capabilities = cpu_to_le32(capabilities);
478                 /* BB set password lengths */
479         }
480
481         count = (long) bcc_ptr - (long) str_area;
482         smb_buf->smb_buf_length += count;
483
484         BCC_LE(smb_buf) = cpu_to_le16(count);
485
486         iov[1].iov_base = str_area;
487         iov[1].iov_len = count; 
488         rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
489         /* SMB request buf freed in SendReceive2 */
490
491         cFYI(1,("ssetup rc from sendrecv2 is %d",rc));
492         if(rc)
493                 goto ssetup_exit;
494
495         pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
496         smb_buf = (struct smb_hdr *)iov[0].iov_base;
497
498         if((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
499                 rc = -EIO;
500                 cERROR(1,("bad word count %d", smb_buf->WordCount));
501                 goto ssetup_exit;
502         }
503         action = le16_to_cpu(pSMB->resp.Action);
504         if (action & GUEST_LOGIN)
505                 cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
506         ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
507         cFYI(1, ("UID = %d ", ses->Suid));
508         /* response can have either 3 or 4 word count - Samba sends 3 */
509         /* and lanman response is 3 */
510         bytes_remaining = BCC(smb_buf);
511         bcc_ptr = pByteArea(smb_buf);
512
513         if(smb_buf->WordCount == 4) {
514                 __u16 blob_len;
515                 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
516                 bcc_ptr += blob_len;
517                 if(blob_len > bytes_remaining) {
518                         cERROR(1,("bad security blob length %d", blob_len));
519                         rc = -EINVAL;
520                         goto ssetup_exit;
521                 }
522                 bytes_remaining -= blob_len;
523         }       
524
525         /* BB check if Unicode and decode strings */
526         if(smb_buf->Flags2 & SMBFLG2_UNICODE)
527                 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
528                                                    ses, nls_cp);
529         else
530                 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,nls_cp);
531         
532 ssetup_exit:
533         kfree(str_area);
534         if(resp_buf_type == CIFS_SMALL_BUFFER) {
535                 cFYI(1,("ssetup freeing small buf %p", iov[0].iov_base));
536                 cifs_small_buf_release(iov[0].iov_base);
537         } else if(resp_buf_type == CIFS_LARGE_BUFFER)
538                 cifs_buf_release(iov[0].iov_base);
539
540         return rc;
541 }