Merge ../linux-2.6-watchdog-mm
[platform/adaptation/renesas_rcar/renesas_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 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, 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, 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         if(strncmp(ses->serverOS, "OS/2",4) == 0) {
275                         cFYI(1,("OS/2 server"));
276                         ses->flags |= CIFS_SES_OS2;
277         }
278
279         bcc_ptr += len + 1;
280         bleft -= len + 1;
281
282         len = strnlen(bcc_ptr, bleft);
283         if(len >= bleft)
284                 return rc;
285
286         if(ses->serverNOS)
287                 kfree(ses->serverNOS);
288
289         ses->serverNOS = kzalloc(len + 1, GFP_KERNEL);
290         if(ses->serverNOS)
291                 strncpy(ses->serverNOS, bcc_ptr, len);
292
293         bcc_ptr += len + 1;
294         bleft -= len + 1;
295
296         len = strnlen(bcc_ptr, bleft);
297         if(len > bleft)
298                 return rc;
299
300         /* No domain field in LANMAN case. Domain is
301            returned by old servers in the SMB negprot response */
302         /* BB For newer servers which do not support Unicode,
303            but thus do return domain here we could add parsing
304            for it later, but it is not very important */
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         char *str_area;
319         SESSION_SETUP_ANDX *pSMB;
320         __u32 capabilities;
321         int count;
322         int resp_buf_type = 0;
323         struct kvec iov[2];
324         enum securityEnum type;
325         __u16 action;
326         int bytes_remaining;
327
328         if(ses == NULL)
329                 return -EINVAL;
330
331         type = ses->server->secType;
332
333         cFYI(1,("sess setup type %d",type));
334         if(type == LANMAN) {
335 #ifndef CONFIG_CIFS_WEAK_PW_HASH
336                 /* LANMAN and plaintext are less secure and off by default.
337                 So we make this explicitly be turned on in kconfig (in the
338                 build) and turned on at runtime (changed from the default)
339                 in proc/fs/cifs or via mount parm.  Unfortunately this is
340                 needed for old Win (e.g. Win95), some obscure NAS and OS/2 */
341                 return -EOPNOTSUPP;
342 #endif
343                 wct = 10; /* lanman 2 style sessionsetup */
344         } else if((type == NTLM) || (type == NTLMv2)) { 
345                 /* For NTLMv2 failures eventually may need to retry NTLM */
346                 wct = 13; /* old style NTLM sessionsetup */
347         } else /* same size for negotiate or auth, NTLMSSP or extended security */
348                 wct = 12;
349
350         rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
351                             (void **)&smb_buf);
352         if(rc)
353                 return rc;
354
355         pSMB = (SESSION_SETUP_ANDX *)smb_buf;
356
357         capabilities = cifs_ssetup_hdr(ses, pSMB);
358
359         /* we will send the SMB in two pieces,
360         a fixed length beginning part, and a
361         second part which will include the strings
362         and rest of bcc area, in order to avoid having
363         to do a large buffer 17K allocation */
364         iov[0].iov_base = (char *)pSMB;
365         iov[0].iov_len = smb_buf->smb_buf_length + 4;
366
367         /* 2000 big enough to fit max user, domain, NOS name etc. */
368         str_area = kmalloc(2000, GFP_KERNEL);
369         bcc_ptr = str_area;
370
371         ses->flags &= ~CIFS_SES_LANMAN;
372
373         if(type == LANMAN) {
374 #ifdef CONFIG_CIFS_WEAK_PW_HASH
375                 char lnm_session_key[CIFS_SESS_KEY_SIZE];
376
377                 /* no capabilities flags in old lanman negotiation */
378
379                 pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE); 
380                 /* BB calculate hash with password */
381                 /* and copy into bcc */
382
383                 calc_lanman_hash(ses, lnm_session_key);
384                 ses->flags |= CIFS_SES_LANMAN; 
385 /* #ifdef CONFIG_CIFS_DEBUG2
386                 cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
387                         CIFS_SESS_KEY_SIZE);
388 #endif */
389                 memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
390                 bcc_ptr += CIFS_SESS_KEY_SIZE;
391
392                 /* can not sign if LANMAN negotiated so no need
393                 to calculate signing key? but what if server
394                 changed to do higher than lanman dialect and
395                 we reconnected would we ever calc signing_key? */
396
397                 cFYI(1,("Negotiating LANMAN setting up strings"));
398                 /* Unicode not allowed for LANMAN dialects */
399                 ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
400 #endif    
401         } else if (type == NTLM) {
402                 char ntlm_session_key[CIFS_SESS_KEY_SIZE];
403
404                 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
405                 pSMB->req_no_secext.CaseInsensitivePasswordLength =
406                         cpu_to_le16(CIFS_SESS_KEY_SIZE);
407                 pSMB->req_no_secext.CaseSensitivePasswordLength =
408                         cpu_to_le16(CIFS_SESS_KEY_SIZE);
409         
410                 /* calculate session key */
411                 SMBNTencrypt(ses->password, ses->server->cryptKey,
412                              ntlm_session_key);
413
414                 if(first_time) /* should this be moved into common code 
415                                   with similar ntlmv2 path? */
416                         cifs_calculate_mac_key(ses->server->mac_signing_key,
417                                 ntlm_session_key, ses->password);
418                 /* copy session key */
419
420                 memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
421                 bcc_ptr += CIFS_SESS_KEY_SIZE;
422                 memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
423                 bcc_ptr += CIFS_SESS_KEY_SIZE;
424                 if(ses->capabilities & CAP_UNICODE) {
425                         /* unicode strings must be word aligned */
426                         if (iov[0].iov_len % 2) {
427                                 *bcc_ptr = 0;
428                                 bcc_ptr++;              
429                         }       
430                         unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
431                 } else
432                         ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
433         } else if (type == NTLMv2) {
434                 char * v2_sess_key = 
435                         kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
436
437                 /* BB FIXME change all users of v2_sess_key to
438                    struct ntlmv2_resp */
439
440                 if(v2_sess_key == NULL) {
441                         cifs_small_buf_release(smb_buf);
442                         return -ENOMEM;
443                 }
444
445                 pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
446
447                 /* LM2 password would be here if we supported it */
448                 pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
449                 /*      cpu_to_le16(LM2_SESS_KEY_SIZE); */
450
451                 pSMB->req_no_secext.CaseSensitivePasswordLength =
452                         cpu_to_le16(sizeof(struct ntlmv2_resp));
453
454                 /* calculate session key */
455                 setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
456                 if(first_time) /* should this be moved into common code
457                                   with similar ntlmv2 path? */
458                 /*   cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
459                                 response BB FIXME, v2_sess_key); */
460
461                 /* copy session key */
462
463         /*      memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
464                 bcc_ptr += LM2_SESS_KEY_SIZE; */
465                 memcpy(bcc_ptr, (char *)v2_sess_key, sizeof(struct ntlmv2_resp));
466                 bcc_ptr += sizeof(struct ntlmv2_resp);
467                 kfree(v2_sess_key);
468                 if(ses->capabilities & CAP_UNICODE) {
469                         if(iov[0].iov_len % 2) {
470                                 *bcc_ptr = 0;
471                         }       bcc_ptr++;
472                         unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
473                 } else
474                         ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
475         } else /* NTLMSSP or SPNEGO */ {
476                 pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
477                 capabilities |= CAP_EXTENDED_SECURITY;
478                 pSMB->req.Capabilities = cpu_to_le32(capabilities);
479                 /* BB set password lengths */
480         }
481
482         count = (long) bcc_ptr - (long) str_area;
483         smb_buf->smb_buf_length += count;
484
485         BCC_LE(smb_buf) = cpu_to_le16(count);
486
487         iov[1].iov_base = str_area;
488         iov[1].iov_len = count; 
489         rc = SendReceive2(xid, ses, iov, 2 /* num_iovecs */, &resp_buf_type, 0);
490         /* SMB request buf freed in SendReceive2 */
491
492         cFYI(1,("ssetup rc from sendrecv2 is %d",rc));
493         if(rc)
494                 goto ssetup_exit;
495
496         pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
497         smb_buf = (struct smb_hdr *)iov[0].iov_base;
498
499         if((smb_buf->WordCount != 3) && (smb_buf->WordCount != 4)) {
500                 rc = -EIO;
501                 cERROR(1,("bad word count %d", smb_buf->WordCount));
502                 goto ssetup_exit;
503         }
504         action = le16_to_cpu(pSMB->resp.Action);
505         if (action & GUEST_LOGIN)
506                 cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
507         ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
508         cFYI(1, ("UID = %d ", ses->Suid));
509         /* response can have either 3 or 4 word count - Samba sends 3 */
510         /* and lanman response is 3 */
511         bytes_remaining = BCC(smb_buf);
512         bcc_ptr = pByteArea(smb_buf);
513
514         if(smb_buf->WordCount == 4) {
515                 __u16 blob_len;
516                 blob_len = le16_to_cpu(pSMB->resp.SecurityBlobLength);
517                 bcc_ptr += blob_len;
518                 if(blob_len > bytes_remaining) {
519                         cERROR(1,("bad security blob length %d", blob_len));
520                         rc = -EINVAL;
521                         goto ssetup_exit;
522                 }
523                 bytes_remaining -= blob_len;
524         }       
525
526         /* BB check if Unicode and decode strings */
527         if(smb_buf->Flags2 & SMBFLG2_UNICODE)
528                 rc = decode_unicode_ssetup(&bcc_ptr, bytes_remaining,
529                                                    ses, nls_cp);
530         else
531                 rc = decode_ascii_ssetup(&bcc_ptr, bytes_remaining, ses,nls_cp);
532         
533 ssetup_exit:
534         kfree(str_area);
535         if(resp_buf_type == CIFS_SMALL_BUFFER) {
536                 cFYI(1,("ssetup freeing small buf %p", iov[0].iov_base));
537                 cifs_small_buf_release(iov[0].iov_base);
538         } else if(resp_buf_type == CIFS_LARGE_BUFFER)
539                 cifs_buf_release(iov[0].iov_base);
540
541         return rc;
542 }