]> pilppa.org Git - linux-2.6-omap-h63xx.git/blobdiff - fs/cifs/sess.c
Merge with /pub/scm/linux/kernel/git/torvalds/linux-2.6.git
[linux-2.6-omap-h63xx.git] / fs / cifs / sess.c
index 34998416eb730833ebbc8ecebb56555f740f83f0..70e32a81c213e0267dd3fc76a3d83f479e493c5f 100644 (file)
 #include "cifs_debug.h"
 #include "ntlmssp.h"
 #include "nterr.h"
-#include <linux/ctype.h>
-
-extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
-                       unsigned char *p24);
+#include <linux/utsname.h>
 
 extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8,
                          unsigned char *p24);
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-
 static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
 {
        __u32 capabilities = 0;
@@ -79,7 +74,7 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB)
        return capabilities;
 }
 
-void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
+static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
                            const struct nls_table * nls_cp)
 {
        char * bcc_ptr = *pbcc_area;
@@ -129,7 +124,7 @@ void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
        *pbcc_area = bcc_ptr;
 }
 
-void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
+static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
                          const struct nls_table * nls_cp)
 {
        char * bcc_ptr = *pbcc_area;
@@ -172,7 +167,7 @@ void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses,
         *pbcc_area = bcc_ptr;
 }
 
-int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses,
+static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses,
                             const struct nls_table * nls_cp)
 {
        int rc = 0;
@@ -254,7 +249,7 @@ int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses,
        return rc;
 }
 
-int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses,
+static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses,
                             const struct nls_table * nls_cp)
 {
        int rc = 0;
@@ -316,18 +311,18 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
 {
        int rc = 0;
        int wct;
-       int i;
        struct smb_hdr *smb_buf;
        char *bcc_ptr;
        SESSION_SETUP_ANDX *pSMB;
        __u32 capabilities;
        int count;
        int resp_buf_type = 0;
-       struct kvec iov[1];
+       struct kvec iov[2];  /* BB split variable length info into 2nd iovec */
        enum securityEnum type;
        __u16 action;
        int bytes_remaining;
-       
+
+       cFYI(1,("new sess setup"));
        if(ses == NULL)
                return -EINVAL;
 
@@ -342,9 +337,10 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
                return -EOPNOTSUPP;
 #endif
                wct = 10; /* lanman 2 style sessionsetup */
-       } else if(type == NTLM) /* NTLMv2 may retry NTLM */
+       } else if((type == NTLM) || (type == NTLMv2)) { 
+               /* For NTLMv2 failures eventually may need to retry NTLM */
                wct = 13; /* old style NTLM sessionsetup */
-       else /* same size for negotiate or auth, NTLMSSP or extended security */
+       else /* same size for negotiate or auth, NTLMSSP or extended security */
                wct = 12;
 
        rc = small_smb_init_no_tc(SMB_COM_SESSION_SETUP_ANDX, wct, ses,
@@ -359,41 +355,22 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
 
        if(type == LANMAN) {
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
-               char lnm_session_key[CIFS_SESSION_KEY_SIZE];
-               char password_with_pad[CIFS_ENCPWD_SIZE];
+               char lnm_session_key[CIFS_SESS_KEY_SIZE];
 
                /* no capabilities flags in old lanman negotiation */
 
-               pSMB->old_req.PasswordLength = CIFS_SESSION_KEY_SIZE; 
+               pSMB->old_req.PasswordLength = CIFS_SESS_KEY_SIZE; 
                /* BB calculate hash with password */
                /* and copy into bcc */
 
-               memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
-               strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE);
-
-               /* calculate old style session key */
-               /* toupper may be less broken then repeatedly calling
-               nls_toupper would be, but neither handles multibyte code pages
-               but the only alternative would be converting to UCS-16 (Unicode)
-               uppercasing and converting back which is only worth doing if
-               we knew it were utf8. utf8 code page needs its own
-               toupper and tolower and strnicmp functions */
-               
-               for(i = 0; i< CIFS_ENCPWD_SIZE; i++) {
-                       password_with_pad[i] = toupper(password_with_pad[i]);
-               }
-
-               SMBencrypt(password_with_pad, ses->server->cryptKey,
-                          lnm_session_key);
+               calc_lanman_hash(ses, lnm_session_key);
 
 #ifdef CONFIG_CIFS_DEBUG2
                cifs_dump_mem("cryptkey: ",ses->server->cryptKey,
-                       CIFS_SESSION_KEY_SIZE);
+                       CIFS_SESS_KEY_SIZE);
 #endif
-               /* clear password before we return/free memory */
-               memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
-               memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESSION_KEY_SIZE);
-               bcc_ptr += CIFS_SESSION_KEY_SIZE;
+               memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
+               bcc_ptr += CIFS_SESS_KEY_SIZE;
 
                /* can not sign if LANMAN negotiated so no need
                to calculate signing key? but what if server
@@ -405,13 +382,13 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
                ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
 #endif    
        } else if (type == NTLM) {
-               char ntlm_session_key[CIFS_SESSION_KEY_SIZE];
+               char ntlm_session_key[CIFS_SESS_KEY_SIZE];
 
                pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
                pSMB->req_no_secext.CaseInsensitivePasswordLength =
-                       cpu_to_le16(CIFS_SESSION_KEY_SIZE);
+                       cpu_to_le16(CIFS_SESS_KEY_SIZE);
                pSMB->req_no_secext.CaseSensitivePasswordLength =
-                       cpu_to_le16(CIFS_SESSION_KEY_SIZE);
+                       cpu_to_le16(CIFS_SESS_KEY_SIZE);
        
                /* calculate session key */
                SMBNTencrypt(ses->password, ses->server->cryptKey,
@@ -419,15 +396,53 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
 
                if(first_time) /* should this be moved into common code 
                                  with similar ntlmv2 path? */
-                       cifs_calculate_mac_key(
-                               ses->server->mac_signing_key,
+                       cifs_calculate_mac_key( ses->server->mac_signing_key,
                                ntlm_session_key, ses->password);
                /* copy session key */
 
-               memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESSION_KEY_SIZE);
-               bcc_ptr += CIFS_SESSION_KEY_SIZE;
-               memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESSION_KEY_SIZE);
-               bcc_ptr += CIFS_SESSION_KEY_SIZE;
+               memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
+               bcc_ptr += CIFS_SESS_KEY_SIZE;
+               memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE);
+               bcc_ptr += CIFS_SESS_KEY_SIZE;
+               if(ses->capabilities & CAP_UNICODE)
+                       unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
+               else
+                       ascii_ssetup_strings(&bcc_ptr, ses, nls_cp);
+       } else if (type == NTLMv2) {
+               char * v2_sess_key = 
+                       kmalloc(sizeof(struct ntlmv2_resp), GFP_KERNEL);
+
+               /* BB FIXME change all users of v2_sess_key to
+                  struct ntlmv2_resp */
+
+               if(v2_sess_key == NULL) {
+                       cifs_small_buf_release(smb_buf);
+                       return -ENOMEM;
+               }
+
+               pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);
+
+               /* LM2 password would be here if we supported it */
+               pSMB->req_no_secext.CaseInsensitivePasswordLength = 0;
+               /*      cpu_to_le16(LM2_SESS_KEY_SIZE); */
+
+               pSMB->req_no_secext.CaseSensitivePasswordLength =
+                       cpu_to_le16(sizeof(struct ntlmv2_resp));
+
+               /* calculate session key */
+               setup_ntlmv2_rsp(ses, v2_sess_key, nls_cp);
+               if(first_time) /* should this be moved into common code
+                                 with similar ntlmv2 path? */
+               /*   cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key,
+                               response BB FIXME, v2_sess_key); */
+
+               /* copy session key */
+
+       /*      memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE);
+               bcc_ptr += LM2_SESS_KEY_SIZE; */
+               memcpy(bcc_ptr, (char *)v2_sess_key, sizeof(struct ntlmv2_resp));
+               bcc_ptr += sizeof(struct ntlmv2_resp);
+               kfree(v2_sess_key);
                if(ses->capabilities & CAP_UNICODE)
                        unicode_ssetup_strings(&bcc_ptr, ses, nls_cp);
                else
@@ -472,7 +487,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time,
        }
        action = le16_to_cpu(pSMB->resp.Action);
        if (action & GUEST_LOGIN)
-               cFYI(1, (" Guest login")); /* BB mark SesInfo struct? */
+               cFYI(1, ("Guest login")); /* BB mark SesInfo struct? */
        ses->Suid = smb_buf->Uid;   /* UID left in wire format (le) */
        cFYI(1, ("UID = %d ", ses->Suid));
        /* response can have either 3 or 4 word count - Samba sends 3 */
@@ -508,4 +523,3 @@ ssetup_exit:
 
        return rc;
 }
-#endif /* CONFIG_CIFS_EXPERIMENTAL */