diff options
Diffstat (limited to 'source4/rpc_server')
-rw-r--r-- | source4/rpc_server/samr/samr_password.c | 309 |
1 files changed, 0 insertions, 309 deletions
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; -} |