diff options
author | Andrew Tridgell <tridge@samba.org> | 2004-05-24 05:35:59 +0000 |
---|---|---|
committer | Gerald (Jerry) Carter <jerry@samba.org> | 2007-10-10 12:53:54 -0500 |
commit | 934f6fda20fd35c5ff34a2289d9d587ff3938634 (patch) | |
tree | 08ce59d17e2c086ab8c80f673f5aa9fa0a2c4e23 /source4/rpc_server/samr/samdb.c | |
parent | b63cd185b921d2c248e99cb3eea7dfc882c92c90 (diff) | |
download | samba-934f6fda20fd35c5ff34a2289d9d587ff3938634.tar.gz samba-934f6fda20fd35c5ff34a2289d9d587ff3938634.tar.bz2 samba-934f6fda20fd35c5ff34a2289d9d587ff3938634.zip |
r839: password set/change in the samr server is complex enough that it
deserves its own C module
(This used to be commit 2ba7ff824c32b3db037263ddcff9c876293ea284)
Diffstat (limited to 'source4/rpc_server/samr/samdb.c')
-rw-r--r-- | source4/rpc_server/samr/samdb.c | 222 |
1 files changed, 0 insertions, 222 deletions
diff --git a/source4/rpc_server/samr/samdb.c b/source4/rpc_server/samr/samdb.c index a0591af451..c7a2f770c0 100644 --- a/source4/rpc_server/samr/samdb.c +++ b/source4/rpc_server/samr/samdb.c @@ -872,225 +872,3 @@ int samdb_replace(void *ctx, TALLOC_CTX *mem_ctx, struct ldb_message *msg) return samdb_modify(ctx, mem_ctx, msg); } -/* - 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 -*/ -NTSTATUS samdb_set_password(void *ctx, TALLOC_CTX *mem_ctx, - const char *user_dn, const char *domain_dn, - struct ldb_message *mod, - const char *new_pass, - struct samr_Hash *lmNewHash, - struct samr_Hash *ntNewHash, - BOOL user_change) -{ - const char * const user_attrs[] = { "userAccountControl", "lmPwdHistory", - "ntPwdHistory", "unicodePwd", - "lmPwdHash", "ntPwdHash", "badPwdCount", - NULL }; - const char * const domain_attrs[] = { "pwdProperties", "pwdHistoryLength", - "maxPwdAge", "minPwdAge", - "minPwdLength", "pwdLastSet", NULL }; - const char *unicodePwd; - double minPwdAge, pwdLastSet; - uint_t minPwdLength, pwdProperties, pwdHistoryLength; - uint_t userAccountControl, badPwdCount; - struct samr_Hash *lmPwdHistory, *ntPwdHistory, lmPwdHash, ntPwdHash; - struct samr_Hash *new_lmPwdHistory, *new_ntPwdHistory; - struct samr_Hash local_lmNewHash, local_ntNewHash; - int lmPwdHistory_len, ntPwdHistory_len; - struct ldb_message **res; - int count; - time_t now = time(NULL); - NTTIME now_nt; - double now_double; - int i; - - /* we need to know the time to compute password age */ - unix_to_nt_time(&now_nt, now); - now_double = nttime_to_double_nt(now_nt); - - /* pull all the user parameters */ - count = samdb_search(ctx, mem_ctx, NULL, &res, user_attrs, "dn=%s", user_dn); - if (count != 1) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - unicodePwd = samdb_result_string(res[0], "unicodePwd", NULL); - userAccountControl = samdb_result_uint(res[0], "userAccountControl", 0); - badPwdCount = samdb_result_uint(res[0], "badPwdCount", 0); - lmPwdHistory_len = samdb_result_hashes(mem_ctx, res[0], - "lmPwdHistory", &lmPwdHistory); - ntPwdHistory_len = samdb_result_hashes(mem_ctx, res[0], - "ntPwdHistory", &ntPwdHistory); - lmPwdHash = samdb_result_hash(res[0], "lmPwdHash"); - ntPwdHash = samdb_result_hash(res[0], "ntPwdHash"); - pwdLastSet = samdb_result_double(res[0], "pwdLastSet", 0); - - /* pull the domain parameters */ - count = samdb_search(ctx, mem_ctx, NULL, &res, domain_attrs, "dn=%s", domain_dn); - if (count != 1) { - return NT_STATUS_INTERNAL_DB_CORRUPTION; - } - 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_double(res[0], "minPwdAge", 0); - - if (new_pass) { - /* check the various password restrictions */ - if (minPwdLength > str_charnum(new_pass)) { - return NT_STATUS_PASSWORD_RESTRICTION; - } - - /* possibly check password complexity */ - if (pwdProperties & DOMAIN_PASSWORD_COMPLEX && - !samdb_password_complexity_ok(new_pass)) { - 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 (user_change) { - /* are all password changes disallowed? */ - if (pwdProperties & DOMAIN_REFUSE_PASSWORD_CHANGE) { - return NT_STATUS_PASSWORD_RESTRICTION; - } - - /* can this user change password? */ - if (userAccountControl & UF_PASSWD_CANT_CHANGE) { - return NT_STATUS_PASSWORD_RESTRICTION; - } - - /* yes, this is a minus. The ages are in negative 100nsec units! */ - if (pwdLastSet - minPwdAge > now_double) { - return NT_STATUS_PASSWORD_RESTRICTION; - } - - /* check the immediately past password */ - if (pwdHistoryLength > 0) { - if (lmNewHash && memcmp(lmNewHash->hash, lmPwdHash.hash, 16) == 0) { - return NT_STATUS_PASSWORD_RESTRICTION; - } - if (ntNewHash && memcmp(ntNewHash->hash, ntPwdHash.hash, 16) == 0) { - return NT_STATUS_PASSWORD_RESTRICTION; - } - } - - /* check the password history */ - lmPwdHistory_len = MIN(lmPwdHistory_len, pwdHistoryLength); - ntPwdHistory_len = MIN(ntPwdHistory_len, pwdHistoryLength); - - if (pwdHistoryLength > 0) { - if (unicodePwd && new_pass && strcmp(unicodePwd, new_pass) == 0) { - return NT_STATUS_PASSWORD_RESTRICTION; - } - if (lmNewHash && memcmp(lmNewHash->hash, lmPwdHash.hash, 16) == 0) { - return NT_STATUS_PASSWORD_RESTRICTION; - } - if (ntNewHash && memcmp(ntNewHash->hash, ntPwdHash.hash, 16) == 0) { - return NT_STATUS_PASSWORD_RESTRICTION; - } - } - - for (i=0; lmNewHash && i<lmPwdHistory_len;i++) { - if (memcmp(lmNewHash->hash, lmPwdHistory[i].hash, 16) == 0) { - return NT_STATUS_PASSWORD_RESTRICTION; - } - } - for (i=0; ntNewHash && i<ntPwdHistory_len;i++) { - if (memcmp(ntNewHash->hash, ntPwdHistory[i].hash, 16) == 0) { - 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 (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")); - } - - if (new_pass && (pwdProperties & DOMAIN_PASSWORD_STORE_CLEARTEXT) && - (userAccountControl & UF_ENCRYPTED_TEXT_PASSWORD_ALLOWED)) { - CHECK_RET(samdb_msg_add_string(ctx, mem_ctx, mod, - "unicodePwd", new_pass)); - } else { - CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "unicodePwd")); - } - - CHECK_RET(samdb_msg_add_double(ctx, mem_ctx, mod, "pwdLastSet", now_double)); - - if (pwdHistoryLength == 0) { - CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "lmPwdHistory")); - CHECK_RET(samdb_msg_add_delete(ctx, mem_ctx, mod, "ntPwdHistory")); - return NT_STATUS_OK; - } - - /* store the password history */ - new_lmPwdHistory = talloc_array_p(mem_ctx, struct samr_Hash, - pwdHistoryLength); - if (!new_lmPwdHistory) { - return NT_STATUS_NO_MEMORY; - } - new_ntPwdHistory = talloc_array_p(mem_ctx, struct samr_Hash, - pwdHistoryLength); - if (!new_ntPwdHistory) { - return NT_STATUS_NO_MEMORY; - } - for (i=0;i<MIN(pwdHistoryLength-1, lmPwdHistory_len);i++) { - new_lmPwdHistory[i+1] = lmPwdHistory[i]; - } - for (i=0;i<MIN(pwdHistoryLength-1, ntPwdHistory_len);i++) { - new_ntPwdHistory[i+1] = ntPwdHistory[i]; - } - - /* Don't store 'long' passwords in the LM history, - but make sure to 'expire' one password off the other end */ - if (lmNewHash) { - new_lmPwdHistory[0] = *lmNewHash; - } else { - ZERO_STRUCT(new_lmPwdHistory[0]); - } - lmPwdHistory_len = MIN(lmPwdHistory_len + 1, pwdHistoryLength); - - if (ntNewHash) { - new_ntPwdHistory[0] = *ntNewHash; - } else { - ZERO_STRUCT(new_ntPwdHistory[0]); - } - ntPwdHistory_len = MIN(ntPwdHistory_len + 1, pwdHistoryLength); - - CHECK_RET(samdb_msg_add_hashes(ctx, mem_ctx, mod, - "lmPwdHistory", - new_lmPwdHistory, - lmPwdHistory_len)); - - CHECK_RET(samdb_msg_add_hashes(ctx, mem_ctx, mod, - "ntPwdHistory", - new_ntPwdHistory, - ntPwdHistory_len)); - return NT_STATUS_OK; -} |