From: Matt Rogers Date: Thu, 25 Feb 2016 19:55:44 +0000 (-0500) Subject: Add auth indicator handling to libkdb_ldap X-Git-Tag: krb5-1.15-beta1~242 X-Git-Url: http://git.ipfire.org/cgi-bin/gitweb.cgi?a=commitdiff_plain;h=0bdd3b8058ed4ec9acc050e316bea86f6830b15f;p=thirdparty%2Fkrb5.git Add auth indicator handling to libkdb_ldap Have krb5_ldap_put_principal() store individual auth indicator values in the new krbPrincipalAuthInd attribute, in addition to krbExtraData. krb5_ldap_get_principal() retrieves auth indicator values from krbPrincipalAuthInd, which takes precedence over any krbExtraData entries. ticket: 8379 (new) --- diff --git a/src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif b/src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif index eaf979c9a8..a742470043 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif +++ b/src/plugins/kdb/ldap/libkdb_ldap/kerberos.ldif @@ -720,6 +720,21 @@ attributetypes: ( 2.16.840.1.113719.1.301.4.53.1 EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12) + +##### A list of authentication indicator strings, one of which must be satisfied +##### to authenticate to the principal as a service. +##### FreeIPA OID: +##### joint-iso-ccitt(3) country(16) us(840) organization(1) netscape(113730) +##### ldap(3) freeipa(8) krb5(15) attributes(2) +dn: cn=schema +changetype: modify +add: attributetypes +attributetypes: ( 2.16.840.1.113730.3.8.15.2.1 + NAME 'krbPrincipalAuthInd' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15) + + ##### A list of services to which a service principal can delegate. dn: cn=schema changetype: modify @@ -812,7 +827,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 $ krbLastAdminUnlock $ 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 $ krbPrincipalAuthInd ) ) ###### 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 4052f160ac..52036a1785 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema +++ b/src/plugins/kdb/ldap/libkdb_ldap/kerberos.schema @@ -576,6 +576,18 @@ attributetype ( 2.16.840.1.113719.1.301.4.53.1 EQUALITY distinguishedNameMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.12) + +##### A list of authentication indicator strings, one of which must be satisfied +##### to authenticate to the principal as a service. +##### FreeIPA OID: +##### joint-iso-ccitt(3) country(16) us(840) organization(1) netscape(113730) +##### ldap(3) freeipa(8) krb5(15) attributes(2) +attributetype ( 2.16.840.1.113730.3.8.15.2.1 + NAME 'krbPrincipalAuthInd' + EQUALITY caseExactMatch + SYNTAX 1.3.6.1.4.1.1466.115.121.1.15) + + ##### A list of services to which a service principal can delegate. attributetype ( 1.3.6.1.4.1.5322.21.2.4 NAME 'krbAllowedToDelegateTo' @@ -652,7 +664,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 $ krbLastAdminUnlock $ 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 $ krbPrincipalAuthInd ) ) ###### 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 7ba44167da..b29a944ca5 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_misc.c @@ -1330,6 +1330,45 @@ free_princ_ent_contents(osa_princ_ent_t princ_ent) princ_ent->old_key_len = 0; } +/* Get any auth indicator values from LDAP and update the "require_auth" + * string. */ +static krb5_error_code +get_ldap_auth_ind(krb5_context context, LDAP *ld, LDAPMessage *ldap_ent, + krb5_db_entry *entry, unsigned int *mask) +{ + krb5_error_code ret; + int i; + char **auth_inds = NULL; + struct k5buf buf = EMPTY_K5BUF; + + auth_inds = ldap_get_values(ld, ldap_ent, "krbPrincipalAuthInd"); + if (auth_inds == NULL) + return 0; + + k5_buf_init_dynamic(&buf); + + /* Make a space seperated list of indicators. */ + for (i = 0; auth_inds[i] != NULL; i++) { + k5_buf_add(&buf, auth_inds[i]); + if (auth_inds[i + 1] != NULL) + k5_buf_add(&buf, " "); + } + + ret = k5_buf_status(&buf); + if (ret) + goto cleanup; + + ret = krb5_dbe_set_string(context, entry, KRB5_KDB_SK_REQUIRE_AUTH, + buf.data); + if (!ret) + *mask |= KDB_AUTH_IND_ATTR; + +cleanup: + k5_buf_free(&buf); + ldap_value_free(auth_inds); + return ret; +} + /* * Fill out a krb5_db_entry princ entry struct given a LDAP message containing * the results of a principal search of the directory. @@ -1569,6 +1608,12 @@ populate_krb5_db_entry(krb5_context context, krb5_ldap_context *ldap_context, mask |= KDB_EXTRA_DATA_ATTR; } + /* Auth indicators from krbPrincipalAuthInd will replace those from + * krbExtraData. */ + ret = get_ldap_auth_ind(context, ld, ent, entry, &mask); + if (ret) + goto cleanup; + /* Update the mask of attributes present on the directory object to the * tl_data. */ ret = store_tl_data(&userinfo_tl_data, KDB_TL_MASK, &mask); diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c index 2beb1d0e1f..d4802c5b0d 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.c @@ -56,6 +56,7 @@ char *principal_attributes[] = { "krbprincipalname", "krbLastSuccessfulAuth", "krbLastPwdChange", "krbLastAdminUnlock", + "krbPrincipalAuthInd", "krbExtraData", "krbObjectReferences", "krbAllowedToDelegateTo", @@ -68,7 +69,7 @@ static char *attributes_set[] = { "krbmaxticketlife", "krbticketflags", "krbprincipalexpiration", "krbticketpolicyreference", - "krbUpEnabled", + "krbPrincipalAuthInd", "krbpwdpolicyreference", "krbpasswordexpiration", "krbprincipalkey", diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.h b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.h index 78229b98d4..2e015927a1 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.h +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal.h @@ -73,7 +73,7 @@ #define KDB_TKT_FLAGS_ATTR 0x000004 #define KDB_PRINC_EXPIRE_TIME_ATTR 0x000008 #define KDB_POL_REF_ATTR 0x000010 -#define KDB_UP_FLAG_ATTR 0x000020 +#define KDB_AUTH_IND_ATTR 0x000020 #define KDB_PWD_POL_REF_ATTR 0x000040 #define KDB_PWD_EXPIRE_TIME_ATTR 0x000080 #define KDB_SECRET_KEY_ATTR 0x000100 diff --git a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c index 503acc8fa9..6e591e1974 100644 --- a/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c +++ b/src/plugins/kdb/ldap/libkdb_ldap/ldap_principal2.c @@ -618,6 +618,38 @@ tl_data2berval (krb5_tl_data *in, struct berval **out) return 0; } +/* Parse the "require_auth" string for auth indicators, adding them to the + * krbPrincipalAuthInd attribute. */ +static krb5_error_code +update_ldap_mod_auth_ind(krb5_context context, krb5_db_entry *entry, + LDAPMod ***mods) +{ + int i = 0; + krb5_error_code ret; + char *auth_ind = NULL; + char *strval[10] = {}; + char *ai, *ai_save = NULL; + int sv_num = sizeof(strval) / sizeof(*strval); + + ret = krb5_dbe_get_string(context, entry, KRB5_KDB_SK_REQUIRE_AUTH, + &auth_ind); + if (ret || auth_ind == NULL) + goto cleanup; + + ai = strtok_r(auth_ind, " ", &ai_save); + while (ai != NULL && i < sv_num) { + strval[i++] = ai; + ai = strtok_r(NULL, " ", &ai_save); + } + + ret = krb5_add_str_mem_ldap_mod(mods, "krbPrincipalAuthInd", + LDAP_MOD_REPLACE, strval); + +cleanup: + krb5_dbe_free_string(context, auth_ind); + return ret; +} + krb5_error_code krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry, char **db_args) @@ -1222,6 +1254,12 @@ krb5_ldap_put_principal(krb5_context context, krb5_db_entry *entry, } /* Modify Key data ends here */ + /* Auth indicators will also be stored in krbExtraData when processing + * tl_data. */ + st = update_ldap_mod_auth_ind(context, entry, &mods); + if (st != 0) + goto cleanup; + /* Set tl_data */ if (entry->tl_data != NULL) { int count = 0;