const DATA_BLOB *new_password,
const struct samr_Password *lmNewHash,
const struct samr_Password *ntNewHash,
- const struct samr_Password *lmOldHash,
- const struct samr_Password *ntOldHash,
+ enum dsdb_password_checked old_password_checked,
enum samPwdChangeReason *reject_reason,
struct samr_DomInfo1 **_dominfo,
bool permit_interdomain_trust)
}
/* A password change operation */
- if ((ntOldHash != NULL) || (lmOldHash != NULL)) {
+ if (old_password_checked == DSDB_PASSWORD_CHECKED_AND_CORRECT) {
struct dsdb_control_password_change *change;
change = talloc(req, struct dsdb_control_password_change);
return NT_STATUS_NO_MEMORY;
}
- change->old_nt_pwd_hash = ntOldHash;
- change->old_lm_pwd_hash = lmOldHash;
+ change->old_password_checked = old_password_checked;
ret = ldb_request_add_control(req,
DSDB_CONTROL_PASSWORD_CHANGE_OID,
const DATA_BLOB *new_password,
const struct samr_Password *lmNewHash,
const struct samr_Password *ntNewHash,
- const struct samr_Password *lmOldHash,
- const struct samr_Password *ntOldHash,
+ enum dsdb_password_checked old_password_checked,
enum samPwdChangeReason *reject_reason,
struct samr_DomInfo1 **_dominfo)
{
user_dn, domain_dn,
new_password,
lmNewHash, ntNewHash,
- lmOldHash, ntOldHash,
+ old_password_checked,
reject_reason, _dominfo,
false); /* reject trusts */
}
const DATA_BLOB *new_password,
const struct samr_Password *lmNewHash,
const struct samr_Password *ntNewHash,
- const struct samr_Password *lmOldHash,
- const struct samr_Password *ntOldHash,
+ enum dsdb_password_checked old_password_checked,
enum samPwdChangeReason *reject_reason,
struct samr_DomInfo1 **_dominfo)
{
user_msg->dn, NULL,
new_password,
lmNewHash, ntNewHash,
- lmOldHash, ntOldHash,
+ old_password_checked,
reject_reason, _dominfo,
true); /* permit trusts */
if (!NT_STATUS_IS_OK(nt_status)) {
return LDB_SUCCESS;
}
- /* First check the old password is correct, for password changes */
- if (!io->ac->pwd_reset) {
+ /*
+ * First check the old password is correct, for password
+ * changes when this hasn't already been checked by a
+ * trustwrothy layer above
+ */
+ if (!io->ac->pwd_reset && !(io->ac->change
+ && io->ac->change->old_password_checked == DSDB_PASSWORD_CHECKED_AND_CORRECT)) {
bool nt_hash_checked = false;
/* we need the old nt or lm hash given by the client */
*/
if (ac->change != NULL) {
io->og.nt_hash = NULL;
- if (ac->change->old_nt_pwd_hash != NULL) {
- io->og.nt_hash = talloc_memdup(io->ac,
- ac->change->old_nt_pwd_hash,
- sizeof(struct samr_Password));
- }
io->og.lm_hash = NULL;
- if (lpcfg_lanman_auth(lp_ctx) && (ac->change->old_lm_pwd_hash != NULL)) {
- io->og.lm_hash = talloc_memdup(io->ac,
- ac->change->old_lm_pwd_hash,
- sizeof(struct samr_Password));
- }
}
/* refuse the change if someone wants to change the clear-
return LDB_ERR_UNWILLING_TO_PERFORM;
}
- /* refuse the change if someone wants to compare against a plaintext
- or hash at the same time for a "password modify" operation... */
+ /*
+ * refuse the change if someone wants to compare against a
+ * plaintext or dsdb_control_password_change at the same time
+ * for a "password modify" operation...
+ */
if ((io->og.cleartext_utf8 || io->og.cleartext_utf16)
- && (io->og.nt_hash || io->og.lm_hash)) {
+ && ac->change) {
ldb_asprintf_errstring(ldb,
"setup_io: "
- "it's only allowed to provide the old password in form of cleartext attributes or as hashes");
+ "it's only allowed to provide the old password in form of cleartext attributes or as the dsdb_control_password_change");
return LDB_ERR_UNWILLING_TO_PERFORM;
}
*/
ac->pwd_reset = pav->pwd_reset;
} else if (io->og.cleartext_utf8 || io->og.cleartext_utf16
- || io->og.nt_hash || io->og.lm_hash) {
- /* If we have an old password specified then for sure it
- * is a user "password change" */
+ || ac->change) {
+ /*
+ * If we have an old password specified or the
+ * dsdb_control_password_change then for sure
+ * it is a user "password change"
+ */
ac->pwd_reset = false;
} else {
/* Otherwise we have also here a "password reset" */
struct tsocket_address;
struct dsdb_trust_routing_table;
+enum dsdb_password_checked {
+ DSDB_PASSWORD_NOT_CHECKED = 0, /* unused */
+ DSDB_PASSWORD_RESET,
+ DSDB_PASSWORD_CHECKED_AND_CORRECT
+};
+
#include "librpc/gen_ndr/security.h"
#include <ldb.h>
#include "lib/ldb-samba/ldif_handlers.h"
#define DSDB_CONTROL_PASSWORD_CHANGE_OID "1.3.6.1.4.1.7165.4.3.10"
struct dsdb_control_password_change {
- const struct samr_Password *old_nt_pwd_hash;
- const struct samr_Password *old_lm_pwd_hash;
+ enum dsdb_password_checked old_password_checked;
};
/**
password,
NULL, /* lmNewHash */
NULL, /* ntNewHash */
- NULL, /* lmOldHash */
- NULL, /* ntOldHash */
+ DSDB_PASSWORD_RESET,
reject_reason,
dominfo);
if (NT_STATUS_IS_OK(status)) {
password,
NULL,
NULL,
- oldLmHash,
- oldNtHash, /* this is a user password change */
+ DSDB_PASSWORD_CHECKED_AND_CORRECT,
reject_reason,
dominfo);
if (!NT_STATUS_IS_OK(status)) {
NULL, /* Don't have version */
NULL, /* Don't have plaintext */
NULL, r->in.new_password,
- NULL, oldNtHash, /* Password change */
+ DSDB_PASSWORD_CHECKED_AND_CORRECT, /* Password change */
NULL, NULL);
return nt_status;
}
new_version,
&new_password, /* we have plaintext */
NULL, NULL,
- oldLmHash, oldNtHash, /* Password change */
+ DSDB_PASSWORD_CHECKED_AND_CORRECT, /* Password change */
NULL, NULL);
return nt_status;
}
user_dn, NULL,
&new_unicode_password,
NULL, NULL,
- lm_pwd, NULL, /* this is a user password change */
+ DSDB_PASSWORD_CHECKED_AND_CORRECT,
NULL,
NULL);
if (!NT_STATUS_IS_OK(status)) {
user_dn, NULL,
&new_password,
NULL, NULL,
- lm_pwd, nt_pwd, /* this is a user password change */
+ DSDB_PASSWORD_CHECKED_AND_CORRECT,
&reason,
&dominfo);
&new_password,
NULL,
NULL,
- NULL,
- NULL, /* This is a password set, not change */
+ DSDB_PASSWORD_RESET,
NULL,
NULL);
out:
&new_password,
NULL,
NULL,
- NULL,
- NULL, /* This is a password set, not change */
+ DSDB_PASSWORD_RESET,
NULL,
NULL);
ZERO_ARRAY_LEN(new_password.data,
nt_status = samdb_set_password(sam_ctx, mem_ctx, account_dn,
domain_dn, NULL,
d_lm_pwd_hash, d_nt_pwd_hash,
- NULL, NULL, /* this is a password set */
+ DSDB_PASSWORD_RESET,
NULL, NULL);
}