diff options
author | Andrew Bartlett <abartlet@samba.org> | 2014-03-26 11:32:05 +1300 |
---|---|---|
committer | Stefan Metzmacher <metze@samba.org> | 2014-04-02 17:12:47 +0200 |
commit | 05c2f83f266db208982858067680f888e637378b (patch) | |
tree | 344fdd8562be9436deb4f509cf82f873aae6d779 | |
parent | 6ac62b30007d5b5870443f392d41f7ebfe52a5c3 (diff) | |
download | samba-05c2f83f266db208982858067680f888e637378b.tar.gz samba-05c2f83f266db208982858067680f888e637378b.tar.xz samba-05c2f83f266db208982858067680f888e637378b.zip |
dsdb: Allow SAMR server to return the computed, not actual badPwdCount
This matters after the lockout observation period has expired.
Note: that QueryUserInfo level 3 returns the raw badPwdCount value.
Andrew Bartlett
Change-Id: I7b304a50984072bc6cb1daf3315b4427443632a9
Signed-off-by: Andrew Bartlett <abartlet@samba.org>
Reviewed-by: Stefan Metzmacher <metze@samba.org>
-rw-r--r-- | source4/dsdb/common/util.c | 60 | ||||
-rw-r--r-- | source4/rpc_server/samr/dcesrv_samr.c | 11 |
2 files changed, 58 insertions, 13 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c index 9dbdbdd7b2..2aa6a6ccf7 100644 --- a/source4/dsdb/common/util.c +++ b/source4/dsdb/common/util.c @@ -4654,6 +4654,50 @@ _PUBLIC_ char *NS_GUID_string(TALLOC_CTX *mem_ctx, const struct GUID *guid) } /* + * Return the effective badPwdCount + * + * This requires that the user_msg have (if present): + * - badPasswordTime + * - badPwdCount + * + * This also requires that the domain_msg have (if present): + * - lockOutObservationWindow + */ +static int dsdb_effective_badPwdCount(struct ldb_message *user_msg, + int64_t lockOutObservationWindow, + NTTIME now) +{ + int64_t badPasswordTime; + badPasswordTime = ldb_msg_find_attr_as_int64(user_msg, "badPasswordTime", 0); + + if (badPasswordTime - lockOutObservationWindow >= now) { + return ldb_msg_find_attr_as_int(user_msg, "badPwdCount", 0); + } else { + return 0; + } +} + +/* + * Return the effective badPwdCount + * + * This requires that the user_msg have (if present): + * - badPasswordTime + * - badPwdCount + * + */ +int samdb_result_effective_badPwdCount(struct ldb_context *sam_ldb, + TALLOC_CTX *mem_ctx, + struct ldb_dn *domain_dn, + struct ldb_message *user_msg) +{ + struct timeval tv_now = timeval_current(); + NTTIME now = timeval_to_nttime(&tv_now); + int64_t lockOutObservationWindow = samdb_search_int64(sam_ldb, mem_ctx, 0, domain_dn, + "lockOutObservationWindow", NULL); + return dsdb_effective_badPwdCount(user_msg, lockOutObservationWindow, now); +} + +/* * Prepare an update to the badPwdCount and associated attributes. * * This requires that the user_msg have (if present): @@ -4673,7 +4717,7 @@ NTSTATUS dsdb_update_bad_pwd_count(TALLOC_CTX *mem_ctx, struct ldb_message **_mod_msg) { int i, ret, badPwdCount; - int64_t lockoutThreshold, lockOutObservationWindow, badPasswordTime; + int64_t lockoutThreshold, lockOutObservationWindow; struct dom_sid *sid; struct timeval tv_now = timeval_current(); NTTIME now = timeval_to_nttime(&tv_now); @@ -4710,11 +4754,6 @@ NTSTATUS dsdb_update_bad_pwd_count(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } - lockOutObservationWindow = ldb_msg_find_attr_as_int64(domain_msg, - "lockOutObservationWindow", 0); - - badPasswordTime = ldb_msg_find_attr_as_int64(user_msg, "badPasswordTime", 0); - mod_msg = ldb_msg_new(mem_ctx); if (mod_msg == NULL) { return NT_STATUS_NO_MEMORY; @@ -4725,11 +4764,10 @@ NTSTATUS dsdb_update_bad_pwd_count(TALLOC_CTX *mem_ctx, return NT_STATUS_NO_MEMORY; } - if (badPasswordTime - lockOutObservationWindow >= now) { - badPwdCount = ldb_msg_find_attr_as_int(user_msg, "badPwdCount", 0); - } else { - badPwdCount = 0; - } + lockOutObservationWindow = ldb_msg_find_attr_as_int64(domain_msg, + "lockOutObservationWindow", 0); + + badPwdCount = dsdb_effective_badPwdCount(user_msg, lockOutObservationWindow, now); badPwdCount++; diff --git a/source4/rpc_server/samr/dcesrv_samr.c b/source4/rpc_server/samr/dcesrv_samr.c index fb7ad52703..3e58a44fb8 100644 --- a/source4/rpc_server/samr/dcesrv_samr.c +++ b/source4/rpc_server/samr/dcesrv_samr.c @@ -57,6 +57,9 @@ #define QUERY_FPASSC(msg, field, attr) \ info->field = samdb_result_force_password_change(sam_ctx, mem_ctx, \ a_state->domain_state->domain_dn, msg); +#define QUERY_BPWDCT(msg, field, attr) \ + info->field = samdb_result_effective_badPwdCount(sam_ctx, mem_ctx, \ + a_state->domain_state->domain_dn, msg); #define QUERY_LHOURS(msg, field, attr) \ info->field = samdb_result_logon_hours(mem_ctx, msg, attr); #define QUERY_AFLAGS(msg, field, attr) \ @@ -2733,6 +2736,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA "pwdLastSet", "logonHours", "badPwdCount", + "badPasswordTime", "logonCount", "userAccountControl", "msDS-User-Account-Control-Computed", @@ -2763,6 +2767,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA "lastLogoff", "logonHours", "badPwdCount", + "badPasswordTime", "logonCount", "pwdLastSet", "accountExpires", @@ -2886,6 +2891,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA "msDS-User-Account-Control-Computed", "logonHours", "badPwdCount", + "badPasswordTime", "logonCount", "countryCode", "codePage", @@ -2955,6 +2961,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA QUERY_APASSC(msg, info3.allow_password_change, "pwdLastSet"); QUERY_FPASSC(msg, info3.force_password_change, "pwdLastSet"); QUERY_LHOURS(msg, info3.logon_hours, "logonHours"); + /* level 3 gives the raw badPwdCount value */ QUERY_UINT (msg, info3.bad_password_count, "badPwdCount"); QUERY_UINT (msg, info3.logon_count, "logonCount"); QUERY_AFLAGS(msg, info3.acct_flags, "msDS-User-Account-Control-Computed"); @@ -2978,7 +2985,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA QUERY_UINT64(msg, info5.last_logon, "lastLogon"); QUERY_UINT64(msg, info5.last_logoff, "lastLogoff"); QUERY_LHOURS(msg, info5.logon_hours, "logonHours"); - QUERY_UINT (msg, info5.bad_password_count, "badPwdCount"); + QUERY_BPWDCT(msg, info5.bad_password_count, "badPwdCount"); QUERY_UINT (msg, info5.logon_count, "logonCount"); QUERY_UINT64(msg, info5.last_password_change, "pwdLastSet"); QUERY_UINT64(msg, info5.acct_expiry, "accountExpires"); @@ -3057,7 +3064,7 @@ static NTSTATUS dcesrv_samr_QueryUserInfo(struct dcesrv_call_state *dce_call, TA QUERY_AFLAGS(msg, info21.acct_flags, "msDS-User-Account-Control-Computed"); info->info21.fields_present = 0x08FFFFFF; QUERY_LHOURS(msg, info21.logon_hours, "logonHours"); - QUERY_UINT (msg, info21.bad_password_count, "badPwdCount"); + QUERY_BPWDCT(msg, info21.bad_password_count, "badPwdCount"); QUERY_UINT (msg, info21.logon_count, "logonCount"); if ((info->info21.acct_flags & ACB_PW_EXPIRED) != 0) { info->info21.password_expired = PASS_MUST_CHANGE_AT_NEXT_LOGON; |