summaryrefslogtreecommitdiffstats
path: root/source4
diff options
context:
space:
mode:
authorAndrew Bartlett <abartlet@samba.org>2014-03-26 11:32:05 +1300
committerStefan Metzmacher <metze@samba.org>2014-04-02 17:12:47 +0200
commit05c2f83f266db208982858067680f888e637378b (patch)
tree344fdd8562be9436deb4f509cf82f873aae6d779 /source4
parent6ac62b30007d5b5870443f392d41f7ebfe52a5c3 (diff)
downloadsamba-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>
Diffstat (limited to 'source4')
-rw-r--r--source4/dsdb/common/util.c60
-rw-r--r--source4/rpc_server/samr/dcesrv_samr.c11
2 files changed, 58 insertions, 13 deletions
diff --git a/source4/dsdb/common/util.c b/source4/dsdb/common/util.c
index 9dbdbdd7b29..2aa6a6ccf77 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 fb7ad527039..3e58a44fb82 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;