diff options
-rw-r--r-- | daemons/ipa-kdb/ipa_kdb_principals.c | 73 | ||||
-rw-r--r-- | install/share/61kerberos-ipav3.ldif | 3 | ||||
-rw-r--r-- | install/share/Makefile.am | 1 | ||||
-rw-r--r-- | install/updates/10-60basev3.update | 2 | ||||
-rw-r--r-- | ipalib/plugins/service.py | 7 | ||||
-rw-r--r-- | ipaserver/install/dsinstance.py | 1 |
6 files changed, 65 insertions, 22 deletions
diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c index 139741291..d87d6fe9f 100644 --- a/daemons/ipa-kdb/ipa_kdb_principals.c +++ b/daemons/ipa-kdb/ipa_kdb_principals.c @@ -22,6 +22,16 @@ #include "ipa_kdb.h" +/* + * During TGS request search by ipaKrbPrincipalName (case-insensitive) + * and krbPrincipalName (case-sensitive) + */ +#define PRINC_TGS_SEARCH_FILTER "(&(|(objectclass=krbprincipalaux)" \ + "(objectclass=krbprincipal)" \ + "(objectclass=ipakrbprincipal))" \ + "(|(ipakrbprincipalalias=%s)" \ + "(krbprincipalname=%s)))" + #define PRINC_SEARCH_FILTER "(&(|(objectclass=krbprincipalaux)" \ "(objectclass=krbprincipal))" \ "(krbprincipalname=%s))" @@ -29,6 +39,7 @@ static char *std_principal_attrs[] = { "krbPrincipalName", "krbCanonicalName", + "ipaKrbPrincipalAlias", "krbUPEnabled", "krbPrincipalKey", "krbTicketPolicyReference", @@ -73,6 +84,7 @@ static char *std_principal_obj_classes[] = { "krbprincipal", "krbprincipalaux", "krbTicketPolicyAux", + "ipakrbprincipal", NULL }; @@ -637,13 +649,14 @@ done: } static krb5_error_code ipadb_fetch_principals(struct ipadb_context *ipactx, - char *search_expr, + unsigned int flags, + char *principal, LDAPMessage **result) { krb5_error_code kerr; char *src_filter = NULL; - char *esc_search_expr = NULL; - int ret; + char *esc_original_princ = NULL; + int ret, i; if (!ipactx->lcontext) { ret = ipadb_get_connection(ipactx); @@ -655,13 +668,19 @@ static krb5_error_code ipadb_fetch_principals(struct ipadb_context *ipactx, /* escape filter but do not touch '*' as this function accepts * wildcards in names */ - esc_search_expr = ipadb_filter_escape(search_expr, false); - if (!esc_search_expr) { + esc_original_princ = ipadb_filter_escape(principal, false); + if (!esc_original_princ) { kerr = KRB5_KDB_INTERNAL_ERROR; goto done; } - ret = asprintf(&src_filter, PRINC_SEARCH_FILTER, esc_search_expr); + if (flags & KRB5_KDB_FLAG_ALIAS_OK) { + ret = asprintf(&src_filter, PRINC_TGS_SEARCH_FILTER, + esc_original_princ, esc_original_princ); + } else { + ret = asprintf(&src_filter, PRINC_SEARCH_FILTER, esc_original_princ); + } + if (ret == -1) { kerr = KRB5_KDB_INTERNAL_ERROR; goto done; @@ -674,7 +693,7 @@ static krb5_error_code ipadb_fetch_principals(struct ipadb_context *ipactx, done: free(src_filter); - free(esc_search_expr); + free(esc_original_princ); return kerr; } @@ -714,9 +733,12 @@ static krb5_error_code ipadb_find_principal(krb5_context kcontext, /* we need to check for a strict match as a '*' in the name may have * caused the ldap server to return multiple entries */ for (i = 0; vals[i]; i++) { - /* FIXME: use case insensitive compare and tree as alias ?? */ - if (strcmp(vals[i]->bv_val, (*principal)) == 0) { - found = true; + /* KDC will accept aliases when doing TGT lookup (ref_tgt_again in do_tgs_req.c */ + /* Use case-insensitive comparison in such cases */ + if ((flags & KRB5_KDB_FLAG_ALIAS_OK) != 0) { + found = (strcasecmp(vals[i]->bv_val, (*principal)) == 0); + } else { + found = (strcmp(vals[i]->bv_val, (*principal)) == 0); } } @@ -732,11 +754,15 @@ static krb5_error_code ipadb_find_principal(krb5_context kcontext, continue; } - /* FIXME: use case insensitive compare and treat as alias ?? */ - if (strcmp(vals[0]->bv_val, (*principal)) != 0 && - !(flags & KRB5_KDB_FLAG_ALIAS_OK)) { + /* Again, if aliases are accepted by KDC, use case-insensitive comparison */ + if ((flags & KRB5_KDB_FLAG_ALIAS_OK) != 0) { + found = (strcasecmp(vals[0]->bv_val, (*principal)) == 0); + } else { + found = (strcmp(vals[0]->bv_val, (*principal)) == 0); + } + + if (!found) { /* search does not allow aliases */ - found = false; ldap_value_free_len(vals); continue; } @@ -884,7 +910,7 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext, goto done; } - kerr = ipadb_fetch_principals(ipactx, principal, &res); + kerr = ipadb_fetch_principals(ipactx, flags, principal, &res); if (kerr != 0) { goto done; } @@ -1399,6 +1425,11 @@ static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext, if (kerr) { goto done; } + kerr = ipadb_get_ldap_mod_str(imods, "ipaKrbPrincipalAlias", + principal, mod_op); + if (kerr) { + goto done; + } } /* KADM5_PRINC_EXPIRE_TIME */ @@ -1736,13 +1767,13 @@ static krb5_error_code ipadb_add_principal(krb5_context kcontext, goto done; } - kerr = ipadb_entry_to_mods(kcontext, imods, - entry, principal, LDAP_MOD_ADD); + kerr = ipadb_entry_default_attrs(imods); if (kerr != 0) { goto done; } - kerr = ipadb_entry_default_attrs(imods); + kerr = ipadb_entry_to_mods(kcontext, imods, + entry, principal, LDAP_MOD_ADD); if (kerr != 0) { goto done; } @@ -1780,7 +1811,7 @@ static krb5_error_code ipadb_modify_principal(krb5_context kcontext, goto done; } - kerr = ipadb_fetch_principals(ipactx, principal, &res); + kerr = ipadb_fetch_principals(ipactx, 0, principal, &res); if (kerr != 0) { goto done; } @@ -1931,7 +1962,7 @@ krb5_error_code ipadb_delete_principal(krb5_context kcontext, goto done; } - kerr = ipadb_fetch_principals(ipactx, principal, &res); + kerr = ipadb_fetch_principals(ipactx, 0, principal, &res); if (kerr != 0) { goto done; } @@ -1983,7 +2014,7 @@ krb5_error_code ipadb_iterate(krb5_context kcontext, } /* fetch list of principal matching filter */ - kerr = ipadb_fetch_principals(ipactx, match_entry, &res); + kerr = ipadb_fetch_principals(ipactx, 0, match_entry, &res); if (kerr != 0) { goto done; } diff --git a/install/share/61kerberos-ipav3.ldif b/install/share/61kerberos-ipav3.ldif new file mode 100644 index 000000000..dcdaa5d08 --- /dev/null +++ b/install/share/61kerberos-ipav3.ldif @@ -0,0 +1,3 @@ +dn: cn=schema +attributeTypes: (2.16.840.1.113730.3.8.11.32 NAME 'ipaKrbPrincipalAlias' DESC 'IPA principal alias' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v3') +objectClasses: (2.16.840.1.113730.3.8.12.8 NAME 'ipaKrbPrincipal' SUP krbPrincipalAux AUXILIARY MUST ( krbPrincipalName $ ipaKrbPrincipalAlias ) X-ORIGIN 'IPA v3' ) diff --git a/install/share/Makefile.am b/install/share/Makefile.am index 81fd0dc15..68c98e05a 100644 --- a/install/share/Makefile.am +++ b/install/share/Makefile.am @@ -9,6 +9,7 @@ app_DATA = \ 60basev2.ldif \ 60basev3.ldif \ 60ipadns.ldif \ + 61kerberos-ipav3.ldif \ 65ipasudo.ldif \ anonymous-vlv.ldif \ bootstrap-template.ldif \ diff --git a/install/updates/10-60basev3.update b/install/updates/10-60basev3.update index 796eb16ff..96d012c14 100644 --- a/install/updates/10-60basev3.update +++ b/install/updates/10-60basev3.update @@ -4,3 +4,5 @@ add:attributeTypes: ( 2.16.840.1.113730.3.8.11.21 NAME 'ipaAllowToImpersonate' D add:attributeTypes: ( 2.16.840.1.113730.3.8.11.22 NAME 'ipaAllowedTarget' DESC 'Target principals alowed to get a ticket for' SUP distinguishedName X-ORIGIN 'IPA-v3') add:objectClasses: (2.16.840.1.113730.3.8.12.6 NAME 'groupOfPrincipals' SUP top AUXILIARY MUST ( cn ) MAY ( memberPrincipal ) X-ORIGIN 'IPA v3' ) add:objectClasses: (2.16.840.1.113730.3.8.12.7 NAME 'ipaKrb5DelegationACL' SUP groupOfPrincipals STRUCTURAL MAY ( ipaAllowToImpersonate $$ ipaAllowedTarget ) X-ORIGIN 'IPA v3' ) +add:attributeTypes: (2.16.840.1.113730.3.8.11.32 NAME 'ipaKrbPrincipalAlias' DESC 'IPA principal alias' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v3') +add:objectClasses: (2.16.840.1.113730.3.8.12.8 NAME 'ipaKrbPrincipal' SUP krbPrincipalAux AUXILIARY MUST ( krbPrincipalName $$ ipaKrbPrincipalAlias ) X-ORIGIN 'IPA v3' ) diff --git a/ipalib/plugins/service.py b/ipalib/plugins/service.py index 24a0a0f87..60035bf6d 100644 --- a/ipalib/plugins/service.py +++ b/ipalib/plugins/service.py @@ -221,7 +221,7 @@ class service(LDAPObject): object_name_plural = _('services') object_class = [ 'krbprincipal', 'krbprincipalaux', 'krbticketpolicyaux', 'ipaobject', - 'ipaservice', 'pkiuser' + 'ipaservice', 'pkiuser', 'ipakrbprincipal' ] search_attributes = ['krbprincipalname', 'managedby'] default_attributes = ['krbprincipalname', 'usercertificate', 'managedby'] @@ -293,6 +293,11 @@ class service_add(LDAPCreate): if not 'managedby' in entry_attrs: entry_attrs['managedby'] = hostresult['dn'] + # Enforce ipaKrbPrincipalAlias to aid case-insensitive searches + # as krbPrincipalName/krbCanonicalName are case-sensitive in Kerberos + # schema + entry_attrs['ipakrbprincipalalias'] = keys[-1] + return dn api.register(service_add) diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index 359d76664..fb620a82e 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -389,6 +389,7 @@ class DsInstance(service.Service): "60basev2.ldif", "60basev3.ldif", "60ipadns.ldif", + "61kerberos-ipav3.ldif", "65ipasudo.ldif"): target_fname = schema_dirname(self.serverid) + schema_fname shutil.copyfile(ipautil.SHARE_DIR + schema_fname, target_fname) |