TODO: libcli/auth: add fallback logic to netlogon_creds_server_init()
authorStefan Metzmacher <metze@samba.org>
Tue, 25 Aug 2009 10:03:10 +0000 (12:03 +0200)
committerStefan Metzmacher <metze@samba.org>
Tue, 25 Aug 2009 15:53:43 +0000 (17:53 +0200)
It seems that we need to try fallback to weak sessions key
as W2K8R2 sends the strong key flag, but doesn't use
strong keys, if it has strong key support disabled.

TODO: real names and reference to registry key
metze

libcli/auth/credentials.c

index 87d1866ca49fbd11c0628723a643f4cf86235d87..a88f8fc803dac12080b4263a283da42d9a93db51 100644 (file)
@@ -226,7 +226,7 @@ struct netlogon_creds_CredentialState *netlogon_creds_client_init(TALLOC_CTX *me
        dump_data_pw("Server chall", server_challenge->data, sizeof(server_challenge->data));
        dump_data_pw("Machine Pass", machine_password->hash, sizeof(machine_password->hash));
 
-       if (negotiate_flags & NETLOGON_NEG_128BIT) {
+       if (negotiate_flags & NETLOGON_NEG_STRONG_KEYS) {
                netlogon_creds_init_128bit(creds, client_challenge, server_challenge, machine_password);
        } else {
                netlogon_creds_init_64bit(creds, client_challenge, server_challenge, machine_password);
@@ -326,9 +326,12 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me
                                                                  struct netr_Credential *credentials_out,
                                                                  uint32_t negotiate_flags)
 {
-       
        struct netlogon_creds_CredentialState *creds = talloc_zero(mem_ctx, struct netlogon_creds_CredentialState);
-       
+       bool ok = false;
+       bool try_strong = true;
+       bool try_weak = true;
+       bool fallback = false;
+
        if (!creds) {
                return NULL;
        }
@@ -347,19 +350,35 @@ struct netlogon_creds_CredentialState *netlogon_creds_server_init(TALLOC_CTX *me
                return NULL;
        }
 
-       if (negotiate_flags & NETLOGON_NEG_128BIT) {
+       if (!ok && try_strong) {
+               if (fallback) {
+                       DEBUG(2,("credentials check fallback to strong key\n"));
+               }
+               creds->negotiate_flags |= NETLOGON_NEG_STRONG_KEYS;
                netlogon_creds_init_128bit(creds, client_challenge, server_challenge, 
                                           machine_password);
-       } else {
+               netlogon_creds_first_step(creds, client_challenge, server_challenge);
+               ok = netlogon_creds_server_check_internal(creds, credentials_in);
+               if (!ok) {
+                       creds->negotiate_flags &= ~NETLOGON_NEG_STRONG_KEYS;
+                       fallback = true;
+               }
+       }
+
+       if (!ok && try_weak) {
+               if (fallback) {
+                       DEBUG(2,("credentials check fallback to weak key\n"));
+               }
+               creds->negotiate_flags &= ~NETLOGON_NEG_STRONG_KEYS;
                netlogon_creds_init_64bit(creds, client_challenge, server_challenge, 
                                          machine_password);
+               netlogon_creds_first_step(creds, client_challenge, server_challenge);
+               ok = netlogon_creds_server_check_internal(creds, credentials_in);
        }
 
-       netlogon_creds_first_step(creds, client_challenge, server_challenge);
-
        /* And before we leak information about the machine account
         * password, check that they got the first go right */
-       if (!netlogon_creds_server_check_internal(creds, credentials_in)) {
+       if (!ok) {
                talloc_free(creds);
                return NULL;
        }