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,
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: