ntlm_auth: Put huge NTLMv2 blobs into extra_data on CRAP auth
authorKai Blin <kai@samba.org>
Fri, 7 Nov 2008 08:43:46 +0000 (09:43 +0100)
committerKai Blin <kai@samba.org>
Mon, 10 Nov 2008 09:26:14 +0000 (10:26 +0100)
This fixes bug #5865

source/nsswitch/winbindd_nss.h
source/nsswitch/winbindd_pam.c
source/utils/ntlm_auth.c

index f011e203eb5bcba83e852fdfdc8fb7f3be4fa3d5..742a77446bde990d28686364b124bbecf730fd44 100644 (file)
@@ -207,6 +207,7 @@ typedef struct winbindd_gr {
 #define WBFLAG_PAM_FALLBACK_AFTER_KRB5 0x00002000
 #define WBFLAG_PAM_CACHED_LOGIN                0x00004000
 #define WBFLAG_PAM_GET_PWD_POLICY      0x00008000
+#define WBFLAG_BIG_NTLMV2_BLOB         0x00010000
 
 #define WINBINDD_MAX_EXTRA_DATA (128*1024)
 
index 8751c18ab3e1f9215a11cc8dd1b04b196bc3e580..708fc62dc476d69662e952bfa0a03f6a3cc992a4 100644 (file)
@@ -1762,17 +1762,27 @@ enum winbindd_result winbindd_dual_pam_auth_crap(struct winbindd_domain *domain,
 
        if (state->request.data.auth_crap.lm_resp_len > sizeof(state->request.data.auth_crap.lm_resp)
                || state->request.data.auth_crap.nt_resp_len > sizeof(state->request.data.auth_crap.nt_resp)) {
-               DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n", 
-                         state->request.data.auth_crap.lm_resp_len, 
-                         state->request.data.auth_crap.nt_resp_len));
-               result = NT_STATUS_INVALID_PARAMETER;
-               goto done;
+               if (!state->request.flags & WBFLAG_BIG_NTLMV2_BLOB ||
+                    state->request.extra_len != state->request.data.auth_crap.nt_resp_len) {
+                       DEBUG(0, ("winbindd_pam_auth_crap: invalid password length %u/%u\n",
+                                 state->request.data.auth_crap.lm_resp_len,
+                                 state->request.data.auth_crap.nt_resp_len));
+                                 result = NT_STATUS_INVALID_PARAMETER;
+                       goto done;
+               }
        }
 
        lm_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.lm_resp,
                                        state->request.data.auth_crap.lm_resp_len);
-       nt_resp = data_blob_talloc(state->mem_ctx, state->request.data.auth_crap.nt_resp,
-                                       state->request.data.auth_crap.nt_resp_len);
+       if (state->request.flags & WBFLAG_BIG_NTLMV2_BLOB) {
+               nt_resp = data_blob_talloc(state->mem_ctx,
+                                          state->request.extra_data.data,
+                                          state->request.data.auth_crap.nt_resp_len);
+       } else {
+               nt_resp = data_blob_talloc(state->mem_ctx,
+                                          state->request.data.auth_crap.nt_resp,
+                                          state->request.data.auth_crap.nt_resp_len);
+       }
 
        /* what domain should we contact? */
        
index 53647ad23d6efe87b8fe748a5f73261532f7799a..b42fe92e0f990a65e9257fcfffd3436b2a3426fa 100644 (file)
@@ -350,13 +350,25 @@ NTSTATUS contact_winbind_auth_crap(const char *username,
        }
 
        if (nt_response && nt_response->length) {
-               memcpy(request.data.auth_crap.nt_resp, 
-                      nt_response->data, 
-                      MIN(nt_response->length, sizeof(request.data.auth_crap.nt_resp)));
+               if (nt_response->length > sizeof(request.data.auth_crap.nt_resp)) {
+                       request.flags = request.flags | WBFLAG_BIG_NTLMV2_BLOB;
+                       request.extra_len = nt_response->length;
+                       request.extra_data.data = SMB_MALLOC_ARRAY(char, request.extra_len);
+                       if (request.extra_data.data == NULL) {
+                               return NT_STATUS_NO_MEMORY;
+                       }
+                       memcpy(request.extra_data.data, nt_response->data,
+                              nt_response->length);
+
+               } else {
+                       memcpy(request.data.auth_crap.nt_resp,
+                              nt_response->data, nt_response->length);
+               }
                 request.data.auth_crap.nt_resp_len = nt_response->length;
        }
-       
+
        result = winbindd_request_response(WINBINDD_PAM_AUTH_CRAP, &request, &response);
+       SAFE_FREE(request.extra_data.data);
 
        /* Display response */