TODO runtime tests of toggling s3:passdb: add pdb_get_trust_credentials()
authorStefan Metzmacher <metze@samba.org>
Wed, 7 Aug 2013 14:34:28 +0000 (16:34 +0200)
committerStefan Metzmacher <metze@samba.org>
Wed, 11 Apr 2018 06:49:24 +0000 (08:49 +0200)
WAS 36ab0fb8543c0b78df19f1ea99445f7f8d52e2b1

source3/passdb/passdb.c

index 64e05b346de02f580cfb8c1180b7fff81de81e20..34b1c95291de9825ed5e5ec255a08248499f9bc3 100644 (file)
@@ -2488,6 +2488,40 @@ bool get_trust_pw_hash(const char *domain, uint8_t ret_pwd[16],
        return true;
 }
 
+struct pdb_get_trust_credentials_state {
+       char *cur_pw;
+       char *prev_pw;
+       bool next_is_prev;
+};
+
+static int pdb_get_trust_credentials_destructor(struct pdb_get_trust_credentials_state *state)
+{
+       SAFE_FREE(state->cur_pw);
+       SAFE_FREE(state->prev_pw);
+       return 0;
+}
+
+static const char *pdb_get_trust_credentials_cb(struct cli_credentials *creds)
+{
+       struct pdb_get_trust_credentials_state *state =
+               cli_credentials_callback_data(creds,
+               struct pdb_get_trust_credentials_state);
+
+       /*
+        * This toggles between current and previous password
+        *
+        * The code cli_credentials code enforced the 3 tries
+        * rule above us.
+        */
+       if (!state->next_is_prev) {
+               state->next_is_prev = true;
+               return state->cur_pw;
+       } else {
+               state->next_is_prev = false;
+               return state->prev_pw;
+       }
+}
+
 NTSTATUS pdb_get_trust_credentials(const char *netbios_domain,
                                   const char *dns_domain, /* optional */
                                   TALLOC_CTX *mem_ctx,
@@ -2655,18 +2689,40 @@ NTSTATUS pdb_get_trust_credentials(const char *netbios_domain,
                goto done;
        }
 
-       ok = cli_credentials_set_password(creds, cur_pw, CRED_SPECIFIED);
-       if (!ok) {
-               status = NT_STATUS_NO_MEMORY;
-               goto fail;
-       }
-
-       if (prev_pw != NULL) {
-               ok = cli_credentials_set_old_password(creds, prev_pw, CRED_SPECIFIED);
+       if (prev_pw == NULL) {
+               ok = cli_credentials_set_password(creds, cur_pw, CRED_SPECIFIED);
                if (!ok) {
                        status = NT_STATUS_NO_MEMORY;
                        goto fail;
                }
+
+               goto done;
+       }
+
+       /*
+        * If we have 2 password (current and previous)
+        * we use a callback function to toggle between them
+        * based on the callers usage of cli_credentials_wrong_password()
+        */
+
+       state = talloc_zero(creds, struct pdb_get_trust_credentials_state);
+       if (state == NULL) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
+       }
+       talloc_set_destructor(state, pdb_get_trust_credentials_destructor);
+       state->cur_pw = cur_pw;
+       cur_pw = NULL;
+       state->prev_pw = prev_pw;
+       prev_pw = NULL;
+
+       cli_credentials_set_callback_data(creds, state);
+
+       ok = cli_credentials_set_password_callback(creds,
+                               pdb_get_trust_credentials_cb);
+       if (!ok) {
+               status = NT_STATUS_NO_MEMORY;
+               goto fail;
        }
 
  done: