summaryrefslogtreecommitdiffstats
path: root/src/plugins
diff options
context:
space:
mode:
authorGreg Hudson <ghudson@mit.edu>2010-10-05 14:53:09 +0000
committerGreg Hudson <ghudson@mit.edu>2010-10-05 14:53:09 +0000
commit96f2a016991c199be477b6abd48824ec1cb6641f (patch)
treec1d70a4b27bf8befad040b06c4831e842506fd51 /src/plugins
parent0ce5cb2e9dc040f35a91bca8dcad68d10ed7ea8a (diff)
downloadkrb5-96f2a016991c199be477b6abd48824ec1cb6641f.tar.gz
krb5-96f2a016991c199be477b6abd48824ec1cb6641f.tar.xz
krb5-96f2a016991c199be477b6abd48824ec1cb6641f.zip
Propagate modprinc -unlock from master to slave KDCs
Create a new tl-data type to hold the time of the last administrative unlock, and factor it into decisions about account lockout. Since tl-data values are propagated from master to slave, this will cause modprinc -unlock operations to reach slave KDCs on the next propagation. ticket: 6795 git-svn-id: svn://anonsvn.mit.edu/krb5/trunk@24424 dc483132-0cff-0310-8789-dd5450dbe970
Diffstat (limited to 'src/plugins')
-rw-r--r--src/plugins/kdb/db2/lockout.c15
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif12
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema9
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c14
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c2
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.h2
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c23
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/ldap_service_rights.c6
-rw-r--r--src/plugins/kdb/ldap/libkdb_ldap/lockout.c15
9 files changed, 93 insertions, 5 deletions
diff --git a/src/plugins/kdb/db2/lockout.c b/src/plugins/kdb/db2/lockout.c
index 3ba53d214..b47361124 100644
--- a/src/plugins/kdb/db2/lockout.c
+++ b/src/plugins/kdb/db2/lockout.c
@@ -100,6 +100,13 @@ locked_check_p(krb5_context context,
krb5_timestamp lockout_duration,
krb5_db_entry *entry)
{
+ krb5_timestamp unlock_time;
+
+ /* If the entry was unlocked since the last failure, it's not locked. */
+ if (krb5_dbe_lookup_last_admin_unlock(context, entry, &unlock_time) == 0 &&
+ entry->last_failed <= unlock_time)
+ return FALSE;
+
if (max_fail == 0 || entry->fail_auth_count < max_fail)
return FALSE;
@@ -147,6 +154,7 @@ krb5_db2_lockout_audit(krb5_context context,
krb5_deltat lockout_duration = 0;
krb5_db2_context *db_ctx = context->dal_handle->db_context;
krb5_boolean need_update = FALSE;
+ krb5_timestamp unlock_time;
switch (status) {
case 0:
@@ -182,6 +190,13 @@ krb5_db2_lockout_audit(krb5_context context,
} else if (!db_ctx->disable_lockout &&
(status == KRB5KDC_ERR_PREAUTH_FAILED ||
status == KRB5KRB_AP_ERR_BAD_INTEGRITY)) {
+ if (krb5_dbe_lookup_last_admin_unlock(context, entry,
+ &unlock_time) == 0 &&
+ entry->last_failed <= unlock_time) {
+ /* Reset fail_auth_count after administrative unlock. */
+ entry->fail_auth_count = 0;
+ }
+
if (failcnt_interval != 0 &&
stamp > entry->last_failed + failcnt_interval) {
/* Reset fail_auth_count after failcnt_interval. */
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif b/src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif
index 886f8b435..33a236564 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif
+++ b/src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif
@@ -550,6 +550,16 @@ attributetypes: ( 2.16.840.1.113719.1.301.4.45.1
SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
SINGLE-VALUE)
+##### The time at which the principal was last administratively unlocked.
+
+dn: cn=schema
+changetype: modify
+add: attributetypes
+attributetypes: ( 1.3.6.1.4.1.5322.21.2.5
+ NAME 'krbLastAdminUnlock'
+ EQUALITY generalizedTimeMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
+ SINGLE-VALUE)
##### This attribute holds the kerberos master key.
##### This can be used to encrypt principal keys.
@@ -754,7 +764,7 @@ add: objectclasses
objectClasses: ( 2.16.840.1.113719.1.301.6.8.1
NAME 'krbPrincipalAux'
AUXILIARY
- MAY ( krbPrincipalName $ krbCanonicalName $ krbUPEnabled $ krbPrincipalKey $ krbTicketPolicyReference $ krbPrincipalExpiration $ krbPasswordExpiration $ krbPwdPolicyReference $ krbPrincipalType $ krbPwdHistory $ krbLastPwdChange $ krbPrincipalAliases $ krbLastSuccessfulAuth $ krbLastFailedAuth $ krbLoginFailedCount $ krbExtraData $ krbAllowedToDelegateTo ) )
+ MAY ( krbPrincipalName $ krbCanonicalName $ krbUPEnabled $ krbPrincipalKey $ krbTicketPolicyReference $ krbPrincipalExpiration $ krbPasswordExpiration $ krbPwdPolicyReference $ krbPrincipalType $ krbPwdHistory $ krbLastPwdChange $ krbLastAdminUnlock $ krbPrincipalAliases $ krbLastSuccessfulAuth $ krbLastFailedAuth $ krbLoginFailedCount $ krbExtraData $ krbAllowedToDelegateTo ) )
###### This class is used to create additional principals and stand alone principals.
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema b/src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema
index 65e07d6cd..f4f8aca3f 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema
+++ b/src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema
@@ -445,6 +445,13 @@ attributetype ( 2.16.840.1.113719.1.301.4.45.1
SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
SINGLE-VALUE)
+##### The time at which the principal was last administratively unlocked.
+
+attributetype ( 1.3.6.1.4.1.5322.21.2.5
+ NAME 'krbLastAdminUnlock'
+ EQUALITY generalizedTimeMatch
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.24
+ SINGLE-VALUE)
##### This attribute holds the kerberos master key.
##### This can be used to encrypt principal keys.
@@ -609,7 +616,7 @@ objectclass ( 2.16.840.1.113719.1.301.6.8.1
NAME 'krbPrincipalAux'
SUP top
AUXILIARY
- MAY ( krbPrincipalName $ krbCanonicalName $ krbUPEnabled $ krbPrincipalKey $ krbTicketPolicyReference $ krbPrincipalExpiration $ krbPasswordExpiration $ krbPwdPolicyReference $ krbPrincipalType $ krbPwdHistory $ krbLastPwdChange $ krbPrincipalAliases $ krbLastSuccessfulAuth $ krbLastFailedAuth $ krbLoginFailedCount $ krbExtraData $ krbAllowedToDelegateTo ) )
+ MAY ( krbPrincipalName $ krbCanonicalName $ krbUPEnabled $ krbPrincipalKey $ krbTicketPolicyReference $ krbPrincipalExpiration $ krbPasswordExpiration $ krbPwdPolicyReference $ krbPrincipalType $ krbPwdHistory $ krbLastPwdChange $ krbLastAdminUnlock $ krbPrincipalAliases $ krbLastSuccessfulAuth $ krbLastFailedAuth $ krbLoginFailedCount $ krbExtraData $ krbAllowedToDelegateTo ) )
###### This class is used to create additional principals and stand alone principals.
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
index e9d50196d..86fa4d1e5 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c
@@ -1997,6 +1997,20 @@ populate_krb5_db_entry(krb5_context context, krb5_ldap_context *ldap_context,
}
}
+ /* LAST ADMIN UNLOCK */
+ {
+ krb5_timestamp unlock_time=0;
+ if ((st=krb5_ldap_get_time(ld, ent, "krbLastAdminUnlock",
+ &unlock_time, &attr_present)) != 0)
+ goto cleanup;
+ if (attr_present == TRUE) {
+ if ((st=krb5_dbe_update_last_admin_unlock(context, entry,
+ unlock_time)))
+ goto cleanup;
+ mask |= KDB_LAST_ADMIN_UNLOCK_ATTR;
+ }
+ }
+
/* ALLOWED TO DELEGATE TO */
{
char **a2d2 = NULL;
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
index 68b08c512..0805019db 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c
@@ -60,6 +60,7 @@ char *principal_attributes[] = { "krbprincipalname",
"logindisabled",
#endif
"krbLastPwdChange",
+ "krbLastAdminUnlock",
"krbExtraData",
"krbObjectReferences",
"krbAllowedToDelegateTo",
@@ -80,6 +81,7 @@ static char *attributes_set[] = { "krbmaxticketlife",
"krbLastSuccessfulAuth",
"krbLastFailedAuth",
"krbLoginFailedCount",
+ "krbLastAdminUnlock",
NULL };
void
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.h b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.h
index 3942e3f42..7a7a8067f 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.h
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.h
@@ -82,7 +82,7 @@
#define KDB_LAST_SUCCESS_ATTR 0x000800
#define KDB_LAST_FAILED_ATTR 0x001000
#define KDB_FAIL_AUTH_COUNT_ATTR 0x002000
-#define KDB_LOCKED_TIME_ATTR 0x004000
+#define KDB_LAST_ADMIN_UNLOCK_ATTR 0x004000
/*
* This is a private contract between krb5_ldap_lockout_audit()
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
index 27a3a6441..140db1a47 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c
@@ -1051,6 +1051,7 @@ krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry,
int count = 0;
struct berval **ber_tl_data = NULL;
krb5_tl_data *ptr;
+ krb5_timestamp unlock_time;
for (ptr = entry->tl_data; ptr != NULL; ptr = ptr->tl_data_next) {
if (ptr->tl_data_type == KRB5_TL_LAST_PWD_CHANGE
#ifdef SECURID
@@ -1058,7 +1059,8 @@ krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry,
#endif
|| ptr->tl_data_type == KRB5_TL_KADM_DATA
|| ptr->tl_data_type == KDB_TL_USER_INFO
- || ptr->tl_data_type == KRB5_TL_CONSTRAINED_DELEGATION_ACL)
+ || ptr->tl_data_type == KRB5_TL_CONSTRAINED_DELEGATION_ACL
+ || ptr->tl_data_type == KRB5_TL_LAST_ADMIN_UNLOCK)
continue;
count++;
}
@@ -1079,7 +1081,8 @@ krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry,
#endif
|| ptr->tl_data_type == KRB5_TL_KADM_DATA
|| ptr->tl_data_type == KDB_TL_USER_INFO
- || ptr->tl_data_type == KRB5_TL_CONSTRAINED_DELEGATION_ACL)
+ || ptr->tl_data_type == KRB5_TL_CONSTRAINED_DELEGATION_ACL
+ || ptr->tl_data_type == KRB5_TL_LAST_ADMIN_UNLOCK)
continue;
if ((st = tl_data2berval (ptr, &ber_tl_data[j])) != 0)
break;
@@ -1099,6 +1102,22 @@ krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry,
ber_tl_data)) != 0)
goto cleanup;
}
+ if ((st=krb5_dbe_lookup_last_admin_unlock(context, entry,
+ &unlock_time)) != 0)
+ goto cleanup;
+ if (unlock_time != 0) {
+ /* Update last admin unlock */
+ memset(strval, 0, sizeof(strval));
+ if ((strval[0] = getstringtime(unlock_time)) == NULL)
+ goto cleanup;
+
+ if ((st=krb5_add_str_mem_ldap_mod(&mods, "krbLastAdminUnlock",
+ LDAP_MOD_REPLACE, strval)) != 0) {
+ free (strval[0]);
+ goto cleanup;
+ }
+ free (strval[0]);
+ }
}
/* Directory specific attribute */
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_rights.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_rights.c
index be01f394a..ce697a438 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_rights.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_service_rights.c
@@ -54,6 +54,7 @@ static char *kdcrights_subtree[][2] = {
{"2#subtree#","#krbMaxPwdLife"},
{"2#subtree#","#krbObjectReferences"},
{"2#subtree#","#krbLastPwdChange"},
+ {"2#subtree#","#krbLastAdminUnlock"},
{"6#subtree#","#krbExtraData"},
{"2#subtree#","#krbPasswordExpiration"},
{"6#subtree#","#krbLastFailedAuth"},
@@ -82,6 +83,7 @@ static char *adminrights_subtree[][2]={
{"6#subtree#","#krbPwdMinLength"},
{"6#subtree#","#krbPwdPolicyReference"},
{"6#subtree#","#krbLastPwdChange"},
+ {"6#subtree#","#krbLastAdminUnlock"},
{"6#subtree#","#krbObjectReferences"},
{"6#subtree#","#krbExtraData"},
{"6#subtree#","#krbPasswordExpiration"},
@@ -114,6 +116,7 @@ static char *pwdrights_subtree[][2] = {
{"2#subtree#","#krbPwdMinLength"},
{"2#subtree#","#krbPwdPolicyReference"},
{"6#subtree#","#krbLastPwdChange"},
+ {"6#subtree#","#krbLastAdminUnlock"},
{"2#subtree#","#krbObjectReferences"},
{"6#subtree#","#krbExtraData"},
{"6#subtree#","#krbPasswordExpiration"},
@@ -150,6 +153,7 @@ static char *kdcrights_realmcontainer[][2]={
{"2#subtree#","#krbMaxPwdLife"},
{"2#subtree#","#krbObjectReferences"},
{"2#subtree#","#krbLastPwdChange"},
+ {"2#subtree#","#krbLastAdminUnlock"},
{"6#subtree#","#krbExtraData"},
{"2#subtree#","#krbPasswordExpiration"},
{"2#subtree#","#krbDefaultEncSaltTypes"},
@@ -187,6 +191,7 @@ static char *adminrights_realmcontainer[][2]={
{"6#subtree#","#krbPwdMinLength"},
{"6#subtree#","#krbPwdPolicyReference"},
{"6#subtree#","#krbLastPwdChange"},
+ {"6#subtree#","#krbLastAdminUnlock"},
{"6#subtree#","#krbObjectReferences"},
{"6#subtree#","#krbExtraData"},
{"6#subtree#","#krbPasswordExpiration"},
@@ -228,6 +233,7 @@ static char *pwdrights_realmcontainer[][2]={
{"2#subtree#","#krbPwdMinLength"},
{"2#subtree#","#krbPwdPolicyReference"},
{"2#subtree#","#krbLastPwdChange"},
+ {"2#subtree#","#krbLastAdminUnlock"},
{"2#subtree#","#krbObjectReferences"},
{"6#subtree#","#krbExtraData"},
{"6#subtree#","#krbPasswordExpiration"},
diff --git a/src/plugins/kdb/ldap/libkdb_ldap/lockout.c b/src/plugins/kdb/ldap/libkdb_ldap/lockout.c
index c1a4d7ebe..509c692e6 100644
--- a/src/plugins/kdb/ldap/libkdb_ldap/lockout.c
+++ b/src/plugins/kdb/ldap/libkdb_ldap/lockout.c
@@ -96,6 +96,13 @@ locked_check_p(krb5_context context,
krb5_timestamp lockout_duration,
krb5_db_entry *entry)
{
+ krb5_timestamp unlock_time;
+
+ /* If the entry was unlocked since the last failure, it's not locked. */
+ if (krb5_dbe_lookup_last_admin_unlock(context, entry, &unlock_time) == 0 &&
+ entry->last_failed <= unlock_time)
+ return FALSE;
+
if (max_fail == 0 || entry->fail_auth_count < max_fail)
return FALSE;
@@ -145,6 +152,7 @@ krb5_ldap_lockout_audit(krb5_context context,
krb5_kvno max_fail = 0;
krb5_deltat failcnt_interval = 0;
krb5_deltat lockout_duration = 0;
+ krb5_timestamp unlock_time;
SETUP_CONTEXT();
@@ -183,6 +191,13 @@ krb5_ldap_lockout_audit(krb5_context context,
} else if (!ldap_context->disable_lockout &&
(status == KRB5KDC_ERR_PREAUTH_FAILED ||
status == KRB5KRB_AP_ERR_BAD_INTEGRITY)) {
+ if (krb5_dbe_lookup_last_admin_unlock(context, entry,
+ &unlock_time) == 0 &&
+ entry->last_failed <= unlock_time) {
+ /* Reset fail_auth_count after administrative unlock. */
+ entry->fail_auth_count = 0;
+ }
+
if (failcnt_interval != 0 &&
stamp > entry->last_failed + failcnt_interval) {
/* Reset fail_auth_count after failcnt_interval */