summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--source4/dsdb/samdb/samdb.c317
-rw-r--r--source4/dsdb/samdb/samdb.h1
-rw-r--r--source4/rpc_server/samr/samr_password.c309
3 files changed, 318 insertions, 309 deletions
diff --git a/source4/dsdb/samdb/samdb.c b/source4/dsdb/samdb/samdb.c
index 0f6e57c9cf..35de578f38 100644
--- a/source4/dsdb/samdb/samdb.c
+++ b/source4/dsdb/samdb/samdb.c
@@ -27,6 +27,9 @@
#include "lib/ldb/include/ldb.h"
#include "lib/ldb/include/ldb_errors.h"
#include "libcli/security/proto.h"
+#include "auth/credentials/credentials.h"
+#include "libcli/auth/proto.h"
+#include "libcli/ldap/ldap.h"
#include "system/time.h"
#include "system/filesys.h"
#include "db_wrap.h"
@@ -1036,3 +1039,317 @@ failed:
talloc_free(tmp_ctx);
return NULL;
}
+
+/*
+ check that a password is sufficiently complex
+*/
+static BOOL samdb_password_complexity_ok(const char *pass)
+{
+ return check_password_quality(pass);
+}
+
+
+
+/*
+ set the user password using plaintext, obeying any user or domain
+ password restrictions
+
+ note that this function doesn't actually store the result in the
+ database, it just fills in the "mod" structure with ldb modify
+ elements to setup the correct change when samdb_replace() is
+ called. This allows the caller to combine the change with other
+ changes (as is needed by some of the set user info levels)
+
+ The caller should probably have a transaction wrapping this
+*/
+_PUBLIC_ NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
+ const struct ldb_dn *user_dn,
+ const struct ldb_dn *domain_dn,
+ struct ldb_message *mod,
+ const char *new_pass,
+ struct samr_Password *lmNewHash,
+ struct samr_Password *ntNewHash,
+ BOOL user_change,
+ BOOL restrictions,
+ enum samr_RejectReason *reject_reason,
+ struct samr_DomInfo1 **_dominfo)
+{
+ const char * const user_attrs[] = { "userAccountControl", "sambaLMPwdHistory",
+ "sambaNTPwdHistory",
+ "lmPwdHash", "ntPwdHash",
+ "objectSid",
+ "pwdLastSet", NULL };
+ const char * const domain_attrs[] = { "pwdProperties", "pwdHistoryLength",
+ "maxPwdAge", "minPwdAge",
+ "minPwdLength", NULL };
+ NTTIME pwdLastSet;
+ int64_t minPwdAge;
+ uint_t minPwdLength, pwdProperties, pwdHistoryLength;
+ uint_t userAccountControl;
+ struct samr_Password *sambaLMPwdHistory, *sambaNTPwdHistory, *lmPwdHash, *ntPwdHash;
+ struct samr_Password local_lmNewHash, local_ntNewHash;
+ int sambaLMPwdHistory_len, sambaNTPwdHistory_len;
+ struct dom_sid *domain_sid;
+ struct ldb_message **res;
+ int count;
+ time_t now = time(NULL);
+ NTTIME now_nt;
+ int i;
+
+ /* we need to know the time to compute password age */
+ unix_to_nt_time(&now_nt, now);
+
+ /* pull all the user parameters */
+ count = gendb_search_dn(ctx, mem_ctx, user_dn, &res, user_attrs);
+ if (count != 1) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+ userAccountControl = samdb_result_uint(res[0], "userAccountControl", 0);
+ sambaLMPwdHistory_len = samdb_result_hashes(mem_ctx, res[0],
+ "sambaLMPwdHistory", &sambaLMPwdHistory);
+ sambaNTPwdHistory_len = samdb_result_hashes(mem_ctx, res[0],
+ "sambaNTPwdHistory", &sambaNTPwdHistory);
+ lmPwdHash = samdb_result_hash(mem_ctx, res[0], "lmPwdHash");
+ ntPwdHash = samdb_result_hash(mem_ctx, res[0], "ntPwdHash");
+ pwdLastSet = samdb_result_uint64(res[0], "pwdLastSet", 0);
+
+ if (domain_dn) {
+ /* pull the domain parameters */
+ count = gendb_search_dn(ctx, mem_ctx, domain_dn, &res, domain_attrs);
+ if (count != 1) {
+ return NT_STATUS_NO_SUCH_DOMAIN;
+ }
+ } else {
+ /* work out the domain sid, and pull the domain from there */
+ domain_sid = samdb_result_sid_prefix(mem_ctx, res[0], "objectSid");
+ if (domain_sid == NULL) {
+ return NT_STATUS_INTERNAL_DB_CORRUPTION;
+ }
+
+ count = gendb_search(ctx, mem_ctx, NULL, &res, domain_attrs,
+ "(objectSid=%s)",
+ ldap_encode_ndr_dom_sid(mem_ctx, domain_sid));
+ if (count != 1) {
+ return NT_STATUS_NO_SUCH_DOMAIN;
+ }
+ }
+
+ pwdProperties = samdb_result_uint(res[0], "pwdProperties", 0);
+ pwdHistoryLength = samdb_result_uint(res[0], "pwdHistoryLength", 0);
+ minPwdLength = samdb_result_uint(res[0], "minPwdLength", 0);
+ minPwdAge = samdb_result_int64(res[0], "minPwdAge", 0);
+
+ if (_dominfo) {
+ struct samr_DomInfo1 *dominfo;
+ /* on failure we need to fill in the reject reasons */
+ dominfo = talloc(mem_ctx, struct samr_DomInfo1);
+ if (dominfo == NULL) {
+ return NT_STATUS_NO_MEMORY;
+ }
+ dominfo->min_password_length = minPwdLength;
+ dominfo->password_properties = pwdProperties;
+ dominfo->password_history_length = pwdHistoryLength;
+ dominfo->max_password_age = minPwdAge;
+ dominfo->min_password_age = minPwdAge;
+ *_dominfo = dominfo;
+ }
+
+ if (new_pass) {
+ /* check the various password restrictions */
+ if (restrictions && minPwdLength > strlen_m(new_pass)) {
+ if (reject_reason) {
+ *reject_reason = SAMR_REJECT_TOO_SHORT;
+ }
+ return NT_STATUS_PASSWORD_RESTRICTION;
+ }
+
+ /* possibly check password complexity */
+ if (restrictions && pwdProperties & DOMAIN_PASSWORD_COMPLEX &&
+ !samdb_password_complexity_ok(new_pass)) {
+ if (reject_reason) {
+ *reject_reason = SAMR_REJECT_COMPLEXITY;
+ }
+ return NT_STATUS_PASSWORD_RESTRICTION;
+ }
+
+ /* compute the new nt and lm hashes */
+ if (E_deshash(new_pass, local_lmNewHash.hash)) {
+ lmNewHash = &local_lmNewHash;
+ }
+ E_md4hash(new_pass, local_ntNewHash.hash);
+ ntNewHash = &local_ntNewHash;
+ }
+
+ if (restrictions && user_change) {
+ /* are all password changes disallowed? */
+ if (pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) {
+ if (reject_reason) {
+ *reject_reason = SAMR_REJECT_OTHER;
+ }
+ return NT_STATUS_PASSWORD_RESTRICTION;
+ }
+
+ /* can this user change password? */
+ if (userAccountControl & UF_PASSWD_CANT_CHANGE) {
+ if (reject_reason) {
+ *reject_reason = SAMR_REJECT_OTHER;
+ }
+ return NT_STATUS_PASSWORD_RESTRICTION;
+ }
+
+ /* yes, this is a minus. The ages are in negative 100nsec units! */
+ if (pwdLastSet - minPwdAge > now_nt) {
+ if (reject_reason) {
+ *reject_reason = SAMR_REJECT_OTHER;
+ }
+ return NT_STATUS_PASSWORD_RESTRICTION;
+ }
+
+ /* check the immediately past password */
+ if (pwdHistoryLength > 0) {
+ if (lmNewHash && lmPwdHash && memcmp(lmNewHash->hash, lmPwdHash->hash, 16) == 0) {
+ if (reject_reason) {
+ *reject_reason = SAMR_REJECT_COMPLEXITY;
+ }
+ return NT_STATUS_PASSWORD_RESTRICTION;
+ }
+ if (ntNewHash && ntPwdHash && memcmp(ntNewHash->hash, ntPwdHash->hash, 16) == 0) {
+ if (reject_reason) {
+ *reject_reason = SAMR_REJECT_COMPLEXITY;
+ }
+ return NT_STATUS_PASSWORD_RESTRICTION;
+ }
+ }
+
+ /* check the password history */
+ sambaLMPwdHistory_len = MIN(sambaLMPwdHistory_len, pwdHistoryLength);
+ sambaNTPwdHistory_len = MIN(sambaNTPwdHistory_len, pwdHistoryLength);
+
+ for (i=0; lmNewHash && i<sambaLMPwdHistory_len;i++) {
+ if (memcmp(lmNewHash->hash, sambaLMPwdHistory[i].hash, 16) == 0) {
+ if (reject_reason) {
+ *reject_reason = SAMR_REJECT_COMPLEXITY;
+ }
+ return NT_STATUS_PASSWORD_RESTRICTION;
+ }
+ }
+ for (i=0; ntNewHash && i<sambaNTPwdHistory_len;i++) {
+ if (memcmp(ntNewHash->hash, sambaNTPwdHistory[i].hash, 16) == 0) {
+ if (reject_reason) {
+ *reject_reason = SAMR_REJECT_COMPLEXITY;
+ }
+ return NT_STATUS_PASSWORD_RESTRICTION;
+ }
+ }
+ }
+
+#define CHECK_RET(x) do { if (x != 0) return NT_STATUS_NO_MEMORY; } while(0)
+
+ /* the password is acceptable. Start forming the new fields */
+ if (new_pass) {
+ /* if we know the cleartext, then only set it.
+ * Modules in ldb will set all the appropriate
+ * hashes */
+ CHECK_RET(samdb_msg_add_string(ctx, mem_ctx, mod,
+ "sambaPassword", new_pass));
+ } else {
+ /* We don't have the cleartext, so delete the old one
+ * and set what we have of the hashes */
+ CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "sambaPassword"));
+
+ if (lmNewHash) {
+ CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "lmPwdHash", lmNewHash));
+ } else {
+ CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "lmPwdHash"));
+ }
+
+ if (ntNewHash) {
+ CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "ntPwdHash", ntNewHash));
+ } else {
+ CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "ntPwdHash"));
+ }
+ }
+
+ return NT_STATUS_OK;
+}
+
+
+/*
+ set the user password using plaintext, obeying any user or domain
+ password restrictions
+
+ This wrapper function takes a SID as input, rather than a user DN,
+ and actually performs the password change
+
+*/
+_PUBLIC_ NTSTATUS samdb_set_password_sid(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
+ const struct dom_sid *user_sid,
+ const char *new_pass,
+ struct samr_Password *lmNewHash,
+ struct samr_Password *ntNewHash,
+ BOOL user_change,
+ BOOL restrictions,
+ enum samr_RejectReason *reject_reason,
+ struct samr_DomInfo1 **_dominfo)
+{
+ NTSTATUS nt_status;
+ struct ldb_dn *user_dn;
+ struct ldb_message *msg;
+ int ret;
+
+ ret = ldb_transaction_start(ctx);
+ if (ret) {
+ DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(ctx)));
+ return NT_STATUS_TRANSACTION_ABORTED;
+ }
+
+ user_dn = samdb_search_dn(ctx, mem_ctx, NULL,
+ "(&(objectSid=%s)(objectClass=user))",
+ ldap_encode_ndr_dom_sid(mem_ctx, user_sid));
+ if (!user_dn) {
+ ldb_transaction_cancel(ctx);
+ DEBUG(3, ("samdb_set_password_sid: SID %s not found in samdb, returning NO_SUCH_USER\n",
+ dom_sid_string(mem_ctx, user_sid)));
+ return NT_STATUS_NO_SUCH_USER;
+ }
+
+ msg = ldb_msg_new(mem_ctx);
+ if (msg == NULL) {
+ ldb_transaction_cancel(ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ msg->dn = ldb_dn_copy(msg, user_dn);
+ if (!msg->dn) {
+ ldb_transaction_cancel(ctx);
+ return NT_STATUS_NO_MEMORY;
+ }
+
+ nt_status = samdb_set_password(ctx, mem_ctx,
+ user_dn, NULL,
+ msg, new_pass,
+ lmNewHash, ntNewHash,
+ user_change, /* This is a password set, not change */
+ restrictions, /* run restriction tests */
+ reject_reason, _dominfo);
+ if (!NT_STATUS_IS_OK(nt_status)) {
+ ldb_transaction_cancel(ctx);
+ return nt_status;
+ }
+
+ /* modify the samdb record */
+ ret = samdb_replace(ctx, mem_ctx, msg);
+ if (ret != 0) {
+ ldb_transaction_cancel(ctx);
+ return NT_STATUS_ACCESS_DENIED;
+ }
+
+ ret = ldb_transaction_commit(ctx);
+ if (ret != 0) {
+ DEBUG(0,("Failed to commit transaction to change password on %s: %s\n",
+ ldb_dn_linearize(mem_ctx, msg->dn),
+ ldb_errstring(ctx)));
+ return NT_STATUS_TRANSACTION_ABORTED;
+ }
+ return NT_STATUS_OK;
+}
diff --git a/source4/dsdb/samdb/samdb.h b/source4/dsdb/samdb/samdb.h
index 292307f423..36bff2f7ff 100644
--- a/source4/dsdb/samdb/samdb.h
+++ b/source4/dsdb/samdb/samdb.h
@@ -28,6 +28,7 @@ struct drsuapi_DsNameInfo1;
#include "librpc/gen_ndr/security.h"
#include "lib/ldb/include/ldb.h"
+#include "librpc/gen_ndr/samr.h"
#include "dsdb/samdb/samdb_proto.h"
#endif /* __SAMDB_H__ */
diff --git a/source4/rpc_server/samr/samr_password.c b/source4/rpc_server/samr/samr_password.c
index 07a2d678fe..1235d0c769 100644
--- a/source4/rpc_server/samr/samr_password.c
+++ b/source4/rpc_server/samr/samr_password.c
@@ -505,237 +505,6 @@ NTSTATUS samr_ChangePasswordUser2(struct dcesrv_call_state *dce_call, TALLOC_CTX
/*
- check that a password is sufficiently complex
-*/
-static BOOL samdb_password_complexity_ok(const char *pass)
-{
- return check_password_quality(pass);
-}
-
-/*
- set the user password using plaintext, obeying any user or domain
- password restrictions
-
- note that this function doesn't actually store the result in the
- database, it just fills in the "mod" structure with ldb modify
- elements to setup the correct change when samdb_replace() is
- called. This allows the caller to combine the change with other
- changes (as is needed by some of the set user info levels)
-
- The caller should probably have a transaction wrapping this
-*/
-NTSTATUS samdb_set_password(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
- const struct ldb_dn *user_dn,
- const struct ldb_dn *domain_dn,
- struct ldb_message *mod,
- const char *new_pass,
- struct samr_Password *lmNewHash,
- struct samr_Password *ntNewHash,
- BOOL user_change,
- BOOL restrictions,
- enum samr_RejectReason *reject_reason,
- struct samr_DomInfo1 **_dominfo)
-{
- const char * const user_attrs[] = { "userAccountControl", "sambaLMPwdHistory",
- "sambaNTPwdHistory",
- "lmPwdHash", "ntPwdHash",
- "objectSid",
- "pwdLastSet", NULL };
- const char * const domain_attrs[] = { "pwdProperties", "pwdHistoryLength",
- "maxPwdAge", "minPwdAge",
- "minPwdLength", NULL };
- NTTIME pwdLastSet;
- int64_t minPwdAge;
- uint_t minPwdLength, pwdProperties, pwdHistoryLength;
- uint_t userAccountControl;
- struct samr_Password *sambaLMPwdHistory, *sambaNTPwdHistory, *lmPwdHash, *ntPwdHash;
- struct samr_Password local_lmNewHash, local_ntNewHash;
- int sambaLMPwdHistory_len, sambaNTPwdHistory_len;
- struct dom_sid *domain_sid;
- struct ldb_message **res;
- int count;
- time_t now = time(NULL);
- NTTIME now_nt;
- int i;
-
- /* we need to know the time to compute password age */
- unix_to_nt_time(&now_nt, now);
-
- /* pull all the user parameters */
- count = gendb_search_dn(ctx, mem_ctx, user_dn, &res, user_attrs);
- if (count != 1) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
- userAccountControl = samdb_result_uint(res[0], "userAccountControl", 0);
- sambaLMPwdHistory_len = samdb_result_hashes(mem_ctx, res[0],
- "sambaLMPwdHistory", &sambaLMPwdHistory);
- sambaNTPwdHistory_len = samdb_result_hashes(mem_ctx, res[0],
- "sambaNTPwdHistory", &sambaNTPwdHistory);
- lmPwdHash = samdb_result_hash(mem_ctx, res[0], "lmPwdHash");
- ntPwdHash = samdb_result_hash(mem_ctx, res[0], "ntPwdHash");
- pwdLastSet = samdb_result_uint64(res[0], "pwdLastSet", 0);
-
- if (domain_dn) {
- /* pull the domain parameters */
- count = gendb_search_dn(ctx, mem_ctx, domain_dn, &res, domain_attrs);
- if (count != 1) {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- } else {
- /* work out the domain sid, and pull the domain from there */
- domain_sid = samdb_result_sid_prefix(mem_ctx, res[0], "objectSid");
- if (domain_sid == NULL) {
- return NT_STATUS_INTERNAL_DB_CORRUPTION;
- }
-
- count = gendb_search(ctx, mem_ctx, NULL, &res, domain_attrs,
- "(objectSid=%s)",
- ldap_encode_ndr_dom_sid(mem_ctx, domain_sid));
- if (count != 1) {
- return NT_STATUS_NO_SUCH_DOMAIN;
- }
- }
-
- pwdProperties = samdb_result_uint(res[0], "pwdProperties", 0);
- pwdHistoryLength = samdb_result_uint(res[0], "pwdHistoryLength", 0);
- minPwdLength = samdb_result_uint(res[0], "minPwdLength", 0);
- minPwdAge = samdb_result_int64(res[0], "minPwdAge", 0);
-
- if (_dominfo) {
- struct samr_DomInfo1 *dominfo;
- /* on failure we need to fill in the reject reasons */
- dominfo = talloc(mem_ctx, struct samr_DomInfo1);
- if (dominfo == NULL) {
- return NT_STATUS_NO_MEMORY;
- }
- dominfo->min_password_length = minPwdLength;
- dominfo->password_properties = pwdProperties;
- dominfo->password_history_length = pwdHistoryLength;
- dominfo->max_password_age = minPwdAge;
- dominfo->min_password_age = minPwdAge;
- *_dominfo = dominfo;
- }
-
- if (new_pass) {
- /* check the various password restrictions */
- if (restrictions && minPwdLength > strlen_m(new_pass)) {
- if (reject_reason) {
- *reject_reason = SAMR_REJECT_TOO_SHORT;
- }
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
-
- /* possibly check password complexity */
- if (restrictions && pwdProperties & DOMAIN_PASSWORD_COMPLEX &&
- !samdb_password_complexity_ok(new_pass)) {
- if (reject_reason) {
- *reject_reason = SAMR_REJECT_COMPLEXITY;
- }
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
-
- /* compute the new nt and lm hashes */
- if (E_deshash(new_pass, local_lmNewHash.hash)) {
- lmNewHash = &local_lmNewHash;
- }
- E_md4hash(new_pass, local_ntNewHash.hash);
- ntNewHash = &local_ntNewHash;
- }
-
- if (restrictions && user_change) {
- /* are all password changes disallowed? */
- if (pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) {
- if (reject_reason) {
- *reject_reason = SAMR_REJECT_OTHER;
- }
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
-
- /* can this user change password? */
- if (userAccountControl & UF_PASSWD_CANT_CHANGE) {
- if (reject_reason) {
- *reject_reason = SAMR_REJECT_OTHER;
- }
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
-
- /* yes, this is a minus. The ages are in negative 100nsec units! */
- if (pwdLastSet - minPwdAge > now_nt) {
- if (reject_reason) {
- *reject_reason = SAMR_REJECT_OTHER;
- }
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
-
- /* check the immediately past password */
- if (pwdHistoryLength > 0) {
- if (lmNewHash && lmPwdHash && memcmp(lmNewHash->hash, lmPwdHash->hash, 16) == 0) {
- if (reject_reason) {
- *reject_reason = SAMR_REJECT_COMPLEXITY;
- }
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
- if (ntNewHash && ntPwdHash && memcmp(ntNewHash->hash, ntPwdHash->hash, 16) == 0) {
- if (reject_reason) {
- *reject_reason = SAMR_REJECT_COMPLEXITY;
- }
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
- }
-
- /* check the password history */
- sambaLMPwdHistory_len = MIN(sambaLMPwdHistory_len, pwdHistoryLength);
- sambaNTPwdHistory_len = MIN(sambaNTPwdHistory_len, pwdHistoryLength);
-
- for (i=0; lmNewHash && i<sambaLMPwdHistory_len;i++) {
- if (memcmp(lmNewHash->hash, sambaLMPwdHistory[i].hash, 16) == 0) {
- if (reject_reason) {
- *reject_reason = SAMR_REJECT_COMPLEXITY;
- }
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
- }
- for (i=0; ntNewHash && i<sambaNTPwdHistory_len;i++) {
- if (memcmp(ntNewHash->hash, sambaNTPwdHistory[i].hash, 16) == 0) {
- if (reject_reason) {
- *reject_reason = SAMR_REJECT_COMPLEXITY;
- }
- return NT_STATUS_PASSWORD_RESTRICTION;
- }
- }
- }
-
-#define CHECK_RET(x) do { if (x != 0) return NT_STATUS_NO_MEMORY; } while(0)
-
- /* the password is acceptable. Start forming the new fields */
- if (new_pass) {
- /* if we know the cleartext, then only set it.
- * Modules in ldb will set all the appropriate
- * hashes */
- CHECK_RET(samdb_msg_add_string(ctx, mem_ctx, mod,
- "sambaPassword", new_pass));
- } else {
- /* We don't have the cleartext, so delete the old one
- * and set what we have of the hashes */
- CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "sambaPassword"));
-
- if (lmNewHash) {
- CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "lmPwdHash", lmNewHash));
- } else {
- CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "lmPwdHash"));
- }
-
- if (ntNewHash) {
- CHECK_RET(samdb_msg_add_hash(ctx, mem_ctx, mod, "ntPwdHash", ntNewHash));
- } else {
- CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "ntPwdHash"));
- }
- }
-
- return NT_STATUS_OK;
-}
-
-/*
set password via a samr_CryptPassword buffer
this will in the 'msg' with modify operations that will update the user
password when applied
@@ -830,82 +599,4 @@ NTSTATUS samr_set_password_ex(struct dcesrv_call_state *dce_call,
NULL, NULL);
}
-/*
- set the user password using plaintext, obeying any user or domain
- password restrictions
-
- This wrapper function takes a SID as input, rather than a user DN,
- and actually performs the password change
-
-*/
-NTSTATUS samdb_set_password_sid(struct ldb_context *ctx, TALLOC_CTX *mem_ctx,
- const struct dom_sid *user_sid,
- const char *new_pass,
- struct samr_Password *lmNewHash,
- struct samr_Password *ntNewHash,
- BOOL user_change,
- BOOL restrictions,
- enum samr_RejectReason *reject_reason,
- struct samr_DomInfo1 **_dominfo)
-{
- NTSTATUS nt_status;
- struct ldb_dn *user_dn;
- struct ldb_message *msg;
- int ret;
- ret = ldb_transaction_start(ctx);
- if (ret) {
- DEBUG(1, ("Failed to start transaction: %s\n", ldb_errstring(ctx)));
- return NT_STATUS_TRANSACTION_ABORTED;
- }
-
- user_dn = samdb_search_dn(ctx, mem_ctx, NULL,
- "(&(objectSid=%s)(objectClass=user))",
- ldap_encode_ndr_dom_sid(mem_ctx, user_sid));
- if (!user_dn) {
- ldb_transaction_cancel(ctx);
- DEBUG(3, ("samdb_set_password_sid: SID %s not found in samdb, returning NO_SUCH_USER\n",
- dom_sid_string(mem_ctx, user_sid)));
- return NT_STATUS_NO_SUCH_USER;
- }
-
- msg = ldb_msg_new(mem_ctx);
- if (msg == NULL) {
- ldb_transaction_cancel(ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- msg->dn = ldb_dn_copy(msg, user_dn);
- if (!msg->dn) {
- ldb_transaction_cancel(ctx);
- return NT_STATUS_NO_MEMORY;
- }
-
- nt_status = samdb_set_password(ctx, mem_ctx,
- user_dn, NULL,
- msg, new_pass,
- lmNewHash, ntNewHash,
- user_change, /* This is a password set, not change */
- restrictions, /* run restriction tests */
- reject_reason, _dominfo);
- if (!NT_STATUS_IS_OK(nt_status)) {
- ldb_transaction_cancel(ctx);
- return nt_status;
- }
-
- /* modify the samdb record */
- ret = samdb_replace(ctx, mem_ctx, msg);
- if (ret != 0) {
- ldb_transaction_cancel(ctx);
- return NT_STATUS_ACCESS_DENIED;
- }
-
- ret = ldb_transaction_commit(ctx);
- if (ret != 0) {
- DEBUG(0,("Failed to commit transaction to change password on %s: %s\n",
- ldb_dn_linearize(mem_ctx, msg->dn),
- ldb_errstring(ctx)));
- return NT_STATUS_TRANSACTION_ABORTED;
- }
- return NT_STATUS_OK;
-}