mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
Perform case-insensitive searches for principals on TGS requests
We want to always resolve TGS requests even if the user mistakenly sends a request for a service ticket where the fqdn part contain upper case letters. The actual implementation follows hints set by KDC. When AP_REQ is done, KDC sets KRB5_FLAG_ALIAS_OK and we obey it when looking for principals on TGS requests. https://fedorahosted.org/freeipa/ticket/1577
This commit is contained in:
committed by
Martin Kosek
parent
27517c2008
commit
cbb1d626b9
@@ -22,6 +22,16 @@
|
|||||||
|
|
||||||
#include "ipa_kdb.h"
|
#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)" \
|
#define PRINC_SEARCH_FILTER "(&(|(objectclass=krbprincipalaux)" \
|
||||||
"(objectclass=krbprincipal))" \
|
"(objectclass=krbprincipal))" \
|
||||||
"(krbprincipalname=%s))"
|
"(krbprincipalname=%s))"
|
||||||
@@ -29,6 +39,7 @@
|
|||||||
static char *std_principal_attrs[] = {
|
static char *std_principal_attrs[] = {
|
||||||
"krbPrincipalName",
|
"krbPrincipalName",
|
||||||
"krbCanonicalName",
|
"krbCanonicalName",
|
||||||
|
"ipaKrbPrincipalAlias",
|
||||||
"krbUPEnabled",
|
"krbUPEnabled",
|
||||||
"krbPrincipalKey",
|
"krbPrincipalKey",
|
||||||
"krbTicketPolicyReference",
|
"krbTicketPolicyReference",
|
||||||
@@ -73,6 +84,7 @@ static char *std_principal_obj_classes[] = {
|
|||||||
"krbprincipal",
|
"krbprincipal",
|
||||||
"krbprincipalaux",
|
"krbprincipalaux",
|
||||||
"krbTicketPolicyAux",
|
"krbTicketPolicyAux",
|
||||||
|
"ipakrbprincipal",
|
||||||
|
|
||||||
NULL
|
NULL
|
||||||
};
|
};
|
||||||
@@ -637,13 +649,14 @@ done:
|
|||||||
}
|
}
|
||||||
|
|
||||||
static krb5_error_code ipadb_fetch_principals(struct ipadb_context *ipactx,
|
static krb5_error_code ipadb_fetch_principals(struct ipadb_context *ipactx,
|
||||||
char *search_expr,
|
unsigned int flags,
|
||||||
|
char *principal,
|
||||||
LDAPMessage **result)
|
LDAPMessage **result)
|
||||||
{
|
{
|
||||||
krb5_error_code kerr;
|
krb5_error_code kerr;
|
||||||
char *src_filter = NULL;
|
char *src_filter = NULL;
|
||||||
char *esc_search_expr = NULL;
|
char *esc_original_princ = NULL;
|
||||||
int ret;
|
int ret, i;
|
||||||
|
|
||||||
if (!ipactx->lcontext) {
|
if (!ipactx->lcontext) {
|
||||||
ret = ipadb_get_connection(ipactx);
|
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
|
/* escape filter but do not touch '*' as this function accepts
|
||||||
* wildcards in names */
|
* wildcards in names */
|
||||||
esc_search_expr = ipadb_filter_escape(search_expr, false);
|
esc_original_princ = ipadb_filter_escape(principal, false);
|
||||||
if (!esc_search_expr) {
|
if (!esc_original_princ) {
|
||||||
kerr = KRB5_KDB_INTERNAL_ERROR;
|
kerr = KRB5_KDB_INTERNAL_ERROR;
|
||||||
goto done;
|
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) {
|
if (ret == -1) {
|
||||||
kerr = KRB5_KDB_INTERNAL_ERROR;
|
kerr = KRB5_KDB_INTERNAL_ERROR;
|
||||||
goto done;
|
goto done;
|
||||||
@@ -674,7 +693,7 @@ static krb5_error_code ipadb_fetch_principals(struct ipadb_context *ipactx,
|
|||||||
|
|
||||||
done:
|
done:
|
||||||
free(src_filter);
|
free(src_filter);
|
||||||
free(esc_search_expr);
|
free(esc_original_princ);
|
||||||
return kerr;
|
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
|
/* we need to check for a strict match as a '*' in the name may have
|
||||||
* caused the ldap server to return multiple entries */
|
* caused the ldap server to return multiple entries */
|
||||||
for (i = 0; vals[i]; i++) {
|
for (i = 0; vals[i]; i++) {
|
||||||
/* FIXME: use case insensitive compare and tree as alias ?? */
|
/* KDC will accept aliases when doing TGT lookup (ref_tgt_again in do_tgs_req.c */
|
||||||
if (strcmp(vals[i]->bv_val, (*principal)) == 0) {
|
/* Use case-insensitive comparison in such cases */
|
||||||
found = true;
|
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;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* FIXME: use case insensitive compare and treat as alias ?? */
|
/* Again, if aliases are accepted by KDC, use case-insensitive comparison */
|
||||||
if (strcmp(vals[0]->bv_val, (*principal)) != 0 &&
|
if ((flags & KRB5_KDB_FLAG_ALIAS_OK) != 0) {
|
||||||
!(flags & KRB5_KDB_FLAG_ALIAS_OK)) {
|
found = (strcasecmp(vals[0]->bv_val, (*principal)) == 0);
|
||||||
|
} else {
|
||||||
|
found = (strcmp(vals[0]->bv_val, (*principal)) == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!found) {
|
||||||
/* search does not allow aliases */
|
/* search does not allow aliases */
|
||||||
found = false;
|
|
||||||
ldap_value_free_len(vals);
|
ldap_value_free_len(vals);
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -884,7 +910,7 @@ krb5_error_code ipadb_get_principal(krb5_context kcontext,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
kerr = ipadb_fetch_principals(ipactx, principal, &res);
|
kerr = ipadb_fetch_principals(ipactx, flags, principal, &res);
|
||||||
if (kerr != 0) {
|
if (kerr != 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -1399,6 +1425,11 @@ static krb5_error_code ipadb_entry_to_mods(krb5_context kcontext,
|
|||||||
if (kerr) {
|
if (kerr) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
kerr = ipadb_get_ldap_mod_str(imods, "ipaKrbPrincipalAlias",
|
||||||
|
principal, mod_op);
|
||||||
|
if (kerr) {
|
||||||
|
goto done;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/* KADM5_PRINC_EXPIRE_TIME */
|
/* KADM5_PRINC_EXPIRE_TIME */
|
||||||
@@ -1736,13 +1767,13 @@ static krb5_error_code ipadb_add_principal(krb5_context kcontext,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
kerr = ipadb_entry_to_mods(kcontext, imods,
|
kerr = ipadb_entry_default_attrs(imods);
|
||||||
entry, principal, LDAP_MOD_ADD);
|
|
||||||
if (kerr != 0) {
|
if (kerr != 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
kerr = ipadb_entry_default_attrs(imods);
|
kerr = ipadb_entry_to_mods(kcontext, imods,
|
||||||
|
entry, principal, LDAP_MOD_ADD);
|
||||||
if (kerr != 0) {
|
if (kerr != 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -1780,7 +1811,7 @@ static krb5_error_code ipadb_modify_principal(krb5_context kcontext,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
kerr = ipadb_fetch_principals(ipactx, principal, &res);
|
kerr = ipadb_fetch_principals(ipactx, 0, principal, &res);
|
||||||
if (kerr != 0) {
|
if (kerr != 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -1931,7 +1962,7 @@ krb5_error_code ipadb_delete_principal(krb5_context kcontext,
|
|||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
kerr = ipadb_fetch_principals(ipactx, principal, &res);
|
kerr = ipadb_fetch_principals(ipactx, 0, principal, &res);
|
||||||
if (kerr != 0) {
|
if (kerr != 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
@@ -1983,7 +2014,7 @@ krb5_error_code ipadb_iterate(krb5_context kcontext,
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* fetch list of principal matching filter */
|
/* 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) {
|
if (kerr != 0) {
|
||||||
goto done;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|||||||
3
install/share/61kerberos-ipav3.ldif
Normal file
3
install/share/61kerberos-ipav3.ldif
Normal file
@@ -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' )
|
||||||
@@ -9,6 +9,7 @@ app_DATA = \
|
|||||||
60basev2.ldif \
|
60basev2.ldif \
|
||||||
60basev3.ldif \
|
60basev3.ldif \
|
||||||
60ipadns.ldif \
|
60ipadns.ldif \
|
||||||
|
61kerberos-ipav3.ldif \
|
||||||
65ipasudo.ldif \
|
65ipasudo.ldif \
|
||||||
anonymous-vlv.ldif \
|
anonymous-vlv.ldif \
|
||||||
bootstrap-template.ldif \
|
bootstrap-template.ldif \
|
||||||
|
|||||||
@@ -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: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.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: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' )
|
||||||
|
|||||||
@@ -221,7 +221,7 @@ class service(LDAPObject):
|
|||||||
object_name_plural = _('services')
|
object_name_plural = _('services')
|
||||||
object_class = [
|
object_class = [
|
||||||
'krbprincipal', 'krbprincipalaux', 'krbticketpolicyaux', 'ipaobject',
|
'krbprincipal', 'krbprincipalaux', 'krbticketpolicyaux', 'ipaobject',
|
||||||
'ipaservice', 'pkiuser'
|
'ipaservice', 'pkiuser', 'ipakrbprincipal'
|
||||||
]
|
]
|
||||||
search_attributes = ['krbprincipalname', 'managedby']
|
search_attributes = ['krbprincipalname', 'managedby']
|
||||||
default_attributes = ['krbprincipalname', 'usercertificate', 'managedby']
|
default_attributes = ['krbprincipalname', 'usercertificate', 'managedby']
|
||||||
@@ -293,6 +293,11 @@ class service_add(LDAPCreate):
|
|||||||
if not 'managedby' in entry_attrs:
|
if not 'managedby' in entry_attrs:
|
||||||
entry_attrs['managedby'] = hostresult['dn']
|
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
|
return dn
|
||||||
|
|
||||||
api.register(service_add)
|
api.register(service_add)
|
||||||
|
|||||||
@@ -389,6 +389,7 @@ class DsInstance(service.Service):
|
|||||||
"60basev2.ldif",
|
"60basev2.ldif",
|
||||||
"60basev3.ldif",
|
"60basev3.ldif",
|
||||||
"60ipadns.ldif",
|
"60ipadns.ldif",
|
||||||
|
"61kerberos-ipav3.ldif",
|
||||||
"65ipasudo.ldif"):
|
"65ipasudo.ldif"):
|
||||||
target_fname = schema_dirname(self.serverid) + schema_fname
|
target_fname = schema_dirname(self.serverid) + schema_fname
|
||||||
shutil.copyfile(ipautil.SHARE_DIR + schema_fname, target_fname)
|
shutil.copyfile(ipautil.SHARE_DIR + schema_fname, target_fname)
|
||||||
|
|||||||
Reference in New Issue
Block a user