From 5043215f219f90a899a8dc75518540a04b93301f Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Thu, 28 Feb 2008 08:50:00 +1100 Subject: Generate ACB_PW_EXPIRED correctly More correctly handle expired passwords, and do not expire machine accounts. Test that the behaviour is consistant with windows, using the RPC-SAMR test. Change NETLOGON to directly query the userAccountControl, just because we don't want to do the extra expiry processing here. Andrew Bartlett (This used to be commit acda1f69bc9b9c43e157e254d0bae54d11363661) --- source4/auth/auth_sam.c | 4 +++- source4/auth/sam.c | 36 +++++++++++++++++++----------------- 2 files changed, 22 insertions(+), 18 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/auth_sam.c b/source4/auth/auth_sam.c index 9189640150..4cb8d2b304 100644 --- a/source4/auth/auth_sam.c +++ b/source4/auth/auth_sam.c @@ -226,7 +226,9 @@ static NTSTATUS authsam_authenticate(struct auth_context *auth_context, { struct samr_Password *lm_pwd, *nt_pwd; NTSTATUS nt_status; - uint16_t acct_flags = samdb_result_acct_flags(msgs[0], "userAccountControl"); + struct ldb_dn *domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msgs_domain_ref[0], "nCName", NULL); + + uint16_t acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msgs[0], domain_dn); /* Quit if the account was locked out. */ if (acct_flags & ACB_AUTOLOCK) { diff --git a/source4/auth/sam.c b/source4/auth/sam.c index fdd7de7c71..abcb72f292 100644 --- a/source4/auth/sam.c +++ b/source4/auth/sam.c @@ -156,7 +156,7 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, NTTIME now; DEBUG(4,("authsam_account_ok: Checking SMB password for user %s\n", name_for_logs)); - acct_flags = samdb_result_acct_flags(msg, "userAccountControl"); + acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn); acct_expiry = samdb_result_nttime(msg, "accountExpires", 0); must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx, @@ -186,22 +186,20 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, return NT_STATUS_ACCOUNT_EXPIRED; } - if (!(acct_flags & ACB_PWNOEXP)) { - /* check for immediate expiry "must change at next logon" */ - if (must_change_time == 0 && last_set_time != 0) { - DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n", - name_for_logs)); - return NT_STATUS_PASSWORD_MUST_CHANGE; - } + /* check for immediate expiry "must change at next logon" */ + if (!(acct_flags & ACB_PWNOEXP) && (must_change_time == 0 && last_set_time != 0)) { + DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n", + name_for_logs)); + return NT_STATUS_PASSWORD_MUST_CHANGE; + } - /* check for expired password */ - if ((must_change_time != 0) && (must_change_time < now)) { - DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n", - name_for_logs)); - DEBUG(1,("sam_account_ok: Password expired at '%s' unix time.\n", - nt_time_string(mem_ctx, must_change_time))); - return NT_STATUS_PASSWORD_EXPIRED; - } + /* check for expired password (dynamicly gnerated in samdb_result_acct_flags) */ + if (acct_flags & ACB_PW_EXPIRED) { + DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n", + name_for_logs)); + DEBUG(1,("sam_account_ok: Password expired at '%s' unix time.\n", + nt_time_string(mem_ctx, must_change_time))); + return NT_STATUS_PASSWORD_EXPIRED; } /* Test workstation. Workstation list is comma separated. */ @@ -267,6 +265,7 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte struct dom_sid **groupSIDs = NULL; struct dom_sid *account_sid; struct dom_sid *primary_group_sid; + struct ldb_dn *domain_dn; const char *str; struct ldb_dn *ncname; int i; @@ -368,7 +367,10 @@ _PUBLIC_ NTSTATUS authsam_make_server_info(TALLOC_CTX *mem_ctx, struct ldb_conte server_info->logon_count = samdb_result_uint(msg, "logonCount", 0); server_info->bad_password_count = samdb_result_uint(msg, "badPwdCount", 0); - server_info->acct_flags = samdb_result_acct_flags(msg, "userAccountControl"); + domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", NULL); + + server_info->acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, + msg, domain_dn); server_info->user_session_key = user_sess_key; server_info->lm_session_key = lm_sess_key; -- cgit From 3abf47fe87e72b18c94157c3f993b7f2fca8c248 Mon Sep 17 00:00:00 2001 From: Andrew Bartlett Date: Fri, 29 Feb 2008 08:47:42 +1100 Subject: Simplify the 'password must change' logic This takes the previous patches further, so we catch all the cases (the KDC looked at the time directly). Andrew Bartlett (This used to be commit cda4642a937d249399e25eaa6e5e20a0d440bcbf) --- source4/auth/sam.c | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) (limited to 'source4/auth') diff --git a/source4/auth/sam.c b/source4/auth/sam.c index abcb72f292..9a8045f62d 100644 --- a/source4/auth/sam.c +++ b/source4/auth/sam.c @@ -149,7 +149,6 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, const char *workstation_list; NTTIME acct_expiry; NTTIME must_change_time; - NTTIME last_set_time; struct ldb_dn *domain_dn = samdb_result_dn(sam_ctx, mem_ctx, msg_domain_ref, "nCName", ldb_dn_new(mem_ctx, sam_ctx, NULL)); @@ -159,9 +158,11 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, acct_flags = samdb_result_acct_flags(sam_ctx, mem_ctx, msg, domain_dn); acct_expiry = samdb_result_nttime(msg, "accountExpires", 0); + + /* Check for when we must change this password, taking the + * userAccountControl flags into account */ must_change_time = samdb_result_force_password_change(sam_ctx, mem_ctx, domain_dn, msg); - last_set_time = samdb_result_nttime(msg, "pwdLastSet", 0); workstation_list = samdb_result_string(msg, "userWorkstations", NULL); @@ -187,14 +188,14 @@ _PUBLIC_ NTSTATUS authsam_account_ok(TALLOC_CTX *mem_ctx, } /* check for immediate expiry "must change at next logon" */ - if (!(acct_flags & ACB_PWNOEXP) && (must_change_time == 0 && last_set_time != 0)) { + if (must_change_time == 0) { DEBUG(1,("sam_account_ok: Account for user '%s' password must change!.\n", name_for_logs)); return NT_STATUS_PASSWORD_MUST_CHANGE; } - /* check for expired password (dynamicly gnerated in samdb_result_acct_flags) */ - if (acct_flags & ACB_PW_EXPIRED) { + /* check for expired password */ + if (must_change_time < now) { DEBUG(1,("sam_account_ok: Account for user '%s' password expired!.\n", name_for_logs)); DEBUG(1,("sam_account_ok: Password expired at '%s' unix time.\n", -- cgit