]> git.karo-electronics.de Git - mv-sheeva.git/blobdiff - fs/cifs/sess.c
Merge tag 'v2.6.38' of git://git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux-2.6
[mv-sheeva.git] / fs / cifs / sess.c
index 7b01d3f6eed6e76cff6317f16c43b366c1af595d..16765703131be6288e41f0d22d6994ffe3d7685f 100644 (file)
@@ -277,7 +277,7 @@ static void ascii_ssetup_strings(char **pbcc_area, struct cifsSesInfo *ses,
 }
 
 static void
-decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
+decode_unicode_ssetup(char **pbcc_area, __u16 bleft, struct cifsSesInfo *ses,
                      const struct nls_table *nls_cp)
 {
        int len;
@@ -323,7 +323,7 @@ decode_unicode_ssetup(char **pbcc_area, int bleft, struct cifsSesInfo *ses,
        return;
 }
 
-static int decode_ascii_ssetup(char **pbcc_area, int bleft,
+static int decode_ascii_ssetup(char **pbcc_area, __u16 bleft,
                               struct cifsSesInfo *ses,
                               const struct nls_table *nls_cp)
 {
@@ -420,7 +420,6 @@ static int decode_ntlmssp_challenge(char *bcc_ptr, int blob_len,
        return 0;
 }
 
-#ifdef CONFIG_CIFS_EXPERIMENTAL
 /* BB Move to ntlmssp.c eventually */
 
 /* We do not malloc the blob, it is passed in pbuffer, because
@@ -431,13 +430,14 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
        NEGOTIATE_MESSAGE *sec_blob = (NEGOTIATE_MESSAGE *)pbuffer;
        __u32 flags;
 
+       memset(pbuffer, 0, sizeof(NEGOTIATE_MESSAGE));
        memcpy(sec_blob->Signature, NTLMSSP_SIGNATURE, 8);
        sec_blob->MessageType = NtLmNegotiate;
 
        /* BB is NTLMV2 session security format easier to use here? */
        flags = NTLMSSP_NEGOTIATE_56 |  NTLMSSP_REQUEST_TARGET |
                NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
-               NTLMSSP_NEGOTIATE_NTLM;
+               NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
        if (ses->server->secMode &
                        (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED)) {
                flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -446,7 +446,7 @@ static void build_ntlmssp_negotiate_blob(unsigned char *pbuffer,
                                NTLMSSP_NEGOTIATE_EXTENDED_SEC;
        }
 
-       sec_blob->NegotiateFlags |= cpu_to_le32(flags);
+       sec_blob->NegotiateFlags = cpu_to_le32(flags);
 
        sec_blob->WorkstationName.BufferOffset = 0;
        sec_blob->WorkstationName.Length = 0;
@@ -477,7 +477,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
        flags = NTLMSSP_NEGOTIATE_56 |
                NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_TARGET_INFO |
                NTLMSSP_NEGOTIATE_128 | NTLMSSP_NEGOTIATE_UNICODE |
-               NTLMSSP_NEGOTIATE_NTLM;
+               NTLMSSP_NEGOTIATE_NTLM | NTLMSSP_NEGOTIATE_EXTENDED_SEC;
        if (ses->server->secMode &
           (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))
                flags |= NTLMSSP_NEGOTIATE_SIGN;
@@ -485,7 +485,7 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
                flags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN;
 
        tmp = pbuffer + sizeof(AUTHENTICATE_MESSAGE);
-       sec_blob->NegotiateFlags |= cpu_to_le32(flags);
+       sec_blob->NegotiateFlags = cpu_to_le32(flags);
 
        sec_blob->LmChallengeResponse.BufferOffset =
                                cpu_to_le32(sizeof(AUTHENTICATE_MESSAGE));
@@ -544,8 +544,9 @@ static int build_ntlmssp_auth_blob(unsigned char *pbuffer,
        sec_blob->WorkstationName.MaximumLength = 0;
        tmp += 2;
 
-       if ((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) &&
-                       !calc_seckey(ses)) {
+       if (((ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_KEY_XCH) ||
+               (ses->ntlmssp->server_flags & NTLMSSP_NEGOTIATE_EXTENDED_SEC))
+                       && !calc_seckey(ses)) {
                memcpy(tmp, ses->ntlmssp->ciphertext, CIFS_CPHTXT_SIZE);
                sec_blob->SessionKey.BufferOffset = cpu_to_le32(tmp - pbuffer);
                sec_blob->SessionKey.Length = cpu_to_le16(CIFS_CPHTXT_SIZE);
@@ -563,17 +564,6 @@ setup_ntlmv2_ret:
        return rc;
 }
 
-
-static void setup_ntlmssp_neg_req(SESSION_SETUP_ANDX *pSMB,
-                                struct cifsSesInfo *ses)
-{
-       build_ntlmssp_negotiate_blob(&pSMB->req.SecurityBlob[0], ses);
-       pSMB->req.SecurityBlobLength = cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
-
-       return;
-}
-#endif
-
 int
 CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
               const struct nls_table *nls_cp)
@@ -585,12 +575,11 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses,
        char *str_area;
        SESSION_SETUP_ANDX *pSMB;
        __u32 capabilities;
-       int count;
+       __u16 count;
        int resp_buf_type;
        struct kvec iov[3];
        enum securityEnum type;
-       __u16 action;
-       int bytes_remaining;
+       __u16 action, bytes_remaining;
        struct key *spnego_key = NULL;
        __le32 phase = NtLmNegotiate; /* NTLMSSP, if needed, is multistage */
        u16 blob_len;
@@ -667,13 +656,13 @@ ssetup_ntlmssp_authenticate:
 
        if (type == LANMAN) {
 #ifdef CONFIG_CIFS_WEAK_PW_HASH
-               char lnm_session_key[CIFS_SESS_KEY_SIZE];
+               char lnm_session_key[CIFS_AUTH_RESP_SIZE];
 
                pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
 
                /* no capabilities flags in old lanman negotiation */
 
-               pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
+               pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
 
                /* Calculate hash with password and copy into bcc_ptr.
                 * Encryption Key (stored as in cryptkey) gets used if the
@@ -686,8 +675,8 @@ ssetup_ntlmssp_authenticate:
                                        true : false, lnm_session_key);
 
                ses->flags |= CIFS_SES_LANMAN;
-               memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
-               bcc_ptr += CIFS_SESS_KEY_SIZE;
+               memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
+               bcc_ptr += CIFS_AUTH_RESP_SIZE;
 
                /* can not sign if LANMAN negotiated so no need
                to calculate signing key? but what if server
@@ -814,71 +803,70 @@ ssetup_ntlmssp_authenticate:
                rc = -ENOSYS;
                goto ssetup_exit;
 #endif /* CONFIG_CIFS_UPCALL */
-       } else {
-#ifdef CONFIG_CIFS_EXPERIMENTAL
-               if (type == RawNTLMSSP) {
-                       if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
-                               cERROR(1, "NTLMSSP requires Unicode support");
-                               rc = -ENOSYS;
+       } else if (type == RawNTLMSSP) {
+               if ((pSMB->req.hdr.Flags2 & SMBFLG2_UNICODE) == 0) {
+                       cERROR(1, "NTLMSSP requires Unicode support");
+                       rc = -ENOSYS;
+                       goto ssetup_exit;
+               }
+
+               cFYI(1, "ntlmssp session setup phase %d", phase);
+               pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
+               capabilities |= CAP_EXTENDED_SECURITY;
+               pSMB->req.Capabilities |= cpu_to_le32(capabilities);
+               switch(phase) {
+               case NtLmNegotiate:
+                       build_ntlmssp_negotiate_blob(
+                               pSMB->req.SecurityBlob, ses);
+                       iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
+                       iov[1].iov_base = pSMB->req.SecurityBlob;
+                       pSMB->req.SecurityBlobLength =
+                               cpu_to_le16(sizeof(NEGOTIATE_MESSAGE));
+                       break;
+               case NtLmAuthenticate:
+                       /*
+                        * 5 is an empirical value, large enough to hold
+                        * authenticate message plus max 10 of av paris,
+                        * domain, user, workstation names, flags, etc.
+                        */
+                       ntlmsspblob = kzalloc(
+                               5*sizeof(struct _AUTHENTICATE_MESSAGE),
+                               GFP_KERNEL);
+                       if (!ntlmsspblob) {
+                               cERROR(1, "Can't allocate NTLMSSP blob");
+                               rc = -ENOMEM;
                                goto ssetup_exit;
                        }
 
-                       cFYI(1, "ntlmssp session setup phase %d", phase);
-                       pSMB->req.hdr.Flags2 |= SMBFLG2_EXT_SEC;
-                       capabilities |= CAP_EXTENDED_SECURITY;
-                       pSMB->req.Capabilities |= cpu_to_le32(capabilities);
-                       if (phase == NtLmNegotiate) {
-                               setup_ntlmssp_neg_req(pSMB, ses);
-                               iov[1].iov_len = sizeof(NEGOTIATE_MESSAGE);
-                               iov[1].iov_base = &pSMB->req.SecurityBlob[0];
-                       } else if (phase == NtLmAuthenticate) {
-                               /* 5 is an empirical value, large enought to
-                                * hold authenticate message, max 10 of
-                                * av paris, doamin,user,workstation mames,
-                                * flags etc..
-                                */
-                               ntlmsspblob = kmalloc(
-                                       5*sizeof(struct _AUTHENTICATE_MESSAGE),
-                                       GFP_KERNEL);
-                               if (!ntlmsspblob) {
-                                       cERROR(1, "Can't allocate NTLMSSP");
-                                       rc = -ENOMEM;
-                                       goto ssetup_exit;
-                               }
-
-                               rc = build_ntlmssp_auth_blob(ntlmsspblob,
-                                                       &blob_len, ses, nls_cp);
-                               if (rc)
-                                       goto ssetup_exit;
-                               iov[1].iov_len = blob_len;
-                               iov[1].iov_base = ntlmsspblob;
-                               pSMB->req.SecurityBlobLength =
-                                       cpu_to_le16(blob_len);
-                               /* Make sure that we tell the server that we
-                                  are using the uid that it just gave us back
-                                  on the response (challenge) */
-                               smb_buf->Uid = ses->Suid;
-                       } else {
-                               cERROR(1, "invalid phase %d", phase);
-                               rc = -ENOSYS;
+                       rc = build_ntlmssp_auth_blob(ntlmsspblob,
+                                               &blob_len, ses, nls_cp);
+                       if (rc)
                                goto ssetup_exit;
-                       }
-                       /* unicode strings must be word aligned */
-                       if ((iov[0].iov_len + iov[1].iov_len) % 2) {
-                               *bcc_ptr = 0;
-                               bcc_ptr++;
-                       }
-                       unicode_oslm_strings(&bcc_ptr, nls_cp);
-               } else {
-                       cERROR(1, "secType %d not supported!", type);
+                       iov[1].iov_len = blob_len;
+                       iov[1].iov_base = ntlmsspblob;
+                       pSMB->req.SecurityBlobLength = cpu_to_le16(blob_len);
+                       /*
+                        * Make sure that we tell the server that we are using
+                        * the uid that it just gave us back on the response
+                        * (challenge)
+                        */
+                       smb_buf->Uid = ses->Suid;
+                       break;
+               default:
+                       cERROR(1, "invalid phase %d", phase);
                        rc = -ENOSYS;
                        goto ssetup_exit;
                }
-#else
+               /* unicode strings must be word aligned */
+               if ((iov[0].iov_len + iov[1].iov_len) % 2) {
+                       *bcc_ptr = 0;
+                       bcc_ptr++;
+               }
+               unicode_oslm_strings(&bcc_ptr, nls_cp);
+       } else {
                cERROR(1, "secType %d not supported!", type);
                rc = -ENOSYS;
                goto ssetup_exit;
-#endif
        }
 
        iov[2].iov_base = str_area;
@@ -887,10 +875,10 @@ ssetup_ntlmssp_authenticate:
        count = iov[1].iov_len + iov[2].iov_len;
        smb_buf->smb_buf_length += count;
 
-       BCC_LE(smb_buf) = cpu_to_le16(count);
+       put_bcc_le(count, smb_buf);
 
        rc = SendReceive2(xid, ses, iov, 3 /* num_iovecs */, &resp_buf_type,
-                         CIFS_STD_OP /* not long */ | CIFS_LOG_ERROR);
+                         CIFS_LOG_ERROR);
        /* SMB request buf freed in SendReceive2 */
 
        pSMB = (SESSION_SETUP_ANDX *)iov[0].iov_base;
@@ -921,7 +909,7 @@ ssetup_ntlmssp_authenticate:
        cFYI(1, "UID = %d ", ses->Suid);
        /* response can have either 3 or 4 word count - Samba sends 3 */
        /* and lanman response is 3 */
-       bytes_remaining = BCC(smb_buf);
+       bytes_remaining = get_bcc(smb_buf);
        bcc_ptr = pByteArea(smb_buf);
 
        if (smb_buf->WordCount == 4) {