diff options
| author | Greg Hudson <ghudson@mit.edu> | 2010-10-05 14:53:09 +0000 |
|---|---|---|
| committer | Greg Hudson <ghudson@mit.edu> | 2010-10-05 14:53:09 +0000 |
| commit | 96f2a016991c199be477b6abd48824ec1cb6641f (patch) | |
| tree | c1d70a4b27bf8befad040b06c4831e842506fd51 /src/plugins | |
| parent | 0ce5cb2e9dc040f35a91bca8dcad68d10ed7ea8a (diff) | |
| download | krb5-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.c | 15 | ||||
| -rw-r--r-- | src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif | 12 | ||||
| -rw-r--r-- | src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema | 9 | ||||
| -rw-r--r-- | src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c | 14 | ||||
| -rw-r--r-- | src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c | 2 | ||||
| -rw-r--r-- | src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.h | 2 | ||||
| -rw-r--r-- | src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c | 23 | ||||
| -rw-r--r-- | src/plugins/kdb/ldap/libkdb_ldap/ldap_service_rights.c | 6 | ||||
| -rw-r--r-- | src/plugins/kdb/ldap/libkdb_ldap/lockout.c | 15 |
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 */ |
