diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c index 93563536c..eace90735 100644 --- a/daemons/ipa-kdb/ipa_kdb.c +++ b/daemons/ipa-kdb/ipa_kdb.c @@ -839,7 +839,7 @@ kdb_vftabl kdb_function_table = { .check_allowed_to_delegate = ipadb_check_allowed_to_delegate, .free_principal_e_data = ipadb_free_principal_e_data, .get_s4u_x509_principal = NULL, - .allowed_to_delegate_from = NULL, + .allowed_to_delegate_from = ipadb_allowed_to_delegate_from, .issue_pac = ipadb_v9_issue_pac, }; #endif diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h index 7aa5be494..d4d8656e4 100644 --- a/daemons/ipa-kdb/ipa_kdb.h +++ b/daemons/ipa-kdb/ipa_kdb.h @@ -222,6 +222,16 @@ int ipadb_ldap_attr_has_value(LDAP *lcontext, LDAPMessage *le, int ipadb_ldap_deref_results(LDAP *lcontext, LDAPMessage *le, LDAPDerefRes **results); +krb5_error_code ipadb_get_tl_data(krb5_db_entry *entry, + krb5_int16 type, + krb5_ui_2 length, + krb5_octet *data); + +krb5_error_code ipadb_set_tl_data(krb5_db_entry *entry, + krb5_int16 type, + krb5_ui_2 length, + const krb5_octet *data); + struct ipadb_multires; krb5_error_code ipadb_multires_init(LDAP *lcontext, struct ipadb_multires **r); void ipadb_multires_free(struct ipadb_multires *r); @@ -374,6 +384,12 @@ krb5_error_code ipadb_check_allowed_to_delegate(krb5_context kcontext, const krb5_db_entry *server, krb5_const_principal proxy); +krb5_error_code ipadb_allowed_to_delegate_from(krb5_context context, + krb5_const_principal client, + krb5_const_principal server, + krb5_pac server_pac, + const krb5_db_entry *proxy); + /* AS AUDIT */ void ipadb_audit_as_req(krb5_context kcontext, diff --git a/daemons/ipa-kdb/ipa_kdb_delegation.c b/daemons/ipa-kdb/ipa_kdb_delegation.c index 212046e01..ce5409d2b 100644 --- a/daemons/ipa-kdb/ipa_kdb_delegation.c +++ b/daemons/ipa-kdb/ipa_kdb_delegation.c @@ -292,3 +292,44 @@ done: ldap_msgfree(res); return kerr; } + + +krb5_error_code ipadb_allowed_to_delegate_from(krb5_context context, + krb5_const_principal client, + krb5_const_principal server, + krb5_pac server_pac, + const krb5_db_entry *proxy) +{ + char **acl_list = NULL; + krb5_error_code kerr; + size_t i; + + kerr = ipadb_get_tl_data((krb5_db_entry *) proxy, KRB5_TL_CONSTRAINED_DELEGATION_ACL, + sizeof(acl_list), (krb5_octet *)&acl_list); + + if (kerr != 0 && kerr != ENOENT) { + return KRB5KDC_ERR_BADOPTION; + } + + if (kerr == ENOENT) { + return KRB5_PLUGIN_OP_NOTSUPP; + } + + kerr = KRB5KDC_ERR_BADOPTION; + if (acl_list != NULL) { + krb5_principal acl; + for (i = 0; acl_list[i] != NULL; i++) { + if (krb5_parse_name(context, acl_list[i], &acl) != 0) + continue; + if ((server == NULL) || + (krb5_principal_compare(context, server, acl) == TRUE)) { + kerr = 0; + krb5_free_principal(context, acl); + break; + } + krb5_free_principal(context, acl); + } + } + + return kerr; +} diff --git a/daemons/ipa-kdb/ipa_kdb_principals.c b/daemons/ipa-kdb/ipa_kdb_principals.c index e95cb453c..15ef287d2 100644 --- a/daemons/ipa-kdb/ipa_kdb_principals.c +++ b/daemons/ipa-kdb/ipa_kdb_principals.c @@ -82,6 +82,7 @@ static char *std_principal_attrs[] = { "krbAuthIndMaxRenewableAge", "ipaNTSecurityIdentifier", "ipaUniqueID", + "memberPrincipal", "objectClass", NULL @@ -178,10 +179,10 @@ done: return ret; } -static krb5_error_code ipadb_set_tl_data(krb5_db_entry *entry, - krb5_int16 type, - krb5_ui_2 length, - const krb5_octet *data) +krb5_error_code ipadb_set_tl_data(krb5_db_entry *entry, + krb5_int16 type, + krb5_ui_2 length, + const krb5_octet *data) { krb5_error_code kerr; krb5_tl_data *new_td = NULL; @@ -633,6 +634,7 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext, char *uidstring; char **authz_data_list; char *princ_sid; + char **acl_list; krb5_timestamp restime; bool resbool; int result; @@ -1029,6 +1031,30 @@ static krb5_error_code ipadb_parse_ldap_entry(krb5_context kcontext, ied->has_sid = true; } + /* check if it has the serviceDelegation objectclass */ + ret = ipadb_ldap_attr_has_value(lcontext, lentry, + "objectClass", "resourceDelegation"); + if (ret != 0 && ret != ENOENT) { + kerr = ret; + goto done; + } + if (ret == 0) { + ret = ipadb_ldap_attr_to_strlist(lcontext, lentry, + "memberPrincipal", &acl_list); + if (ret != 0 && ret != ENOENT) { + kerr = KRB5_KDB_INTERNAL_ERROR; + goto done; + } + if (ret == 0) { + kerr = ipadb_set_tl_data(entry, KRB5_TL_CONSTRAINED_DELEGATION_ACL, + sizeof(acl_list), + (const krb5_octet *) &acl_list); + if (kerr) { + goto done; + } + } + } + kerr = 0; done: @@ -1682,12 +1708,20 @@ void ipadb_free_principal_e_data(krb5_context kcontext, krb5_octet *e_data) void ipadb_free_principal(krb5_context kcontext, krb5_db_entry *entry) { krb5_tl_data *prev, *next; + size_t i; if (entry) { krb5_free_principal(kcontext, entry->princ); prev = entry->tl_data; while(prev) { next = prev->tl_data_next; + /* Handle RBCD ACL type */ + if (prev->tl_data_type == KRB5_TL_CONSTRAINED_DELEGATION_ACL) { + char **acl_list = (char **) prev->tl_data_contents; + for (i = 0; (acl_list != NULL) && (acl_list[i] != NULL); i++) { + free(acl_list[i]); + } + } free(prev->tl_data_contents); free(prev); prev = next; @@ -1702,10 +1736,10 @@ void ipadb_free_principal(krb5_context kcontext, krb5_db_entry *entry) } } -static krb5_error_code ipadb_get_tl_data(krb5_db_entry *entry, - krb5_int16 type, - krb5_ui_2 length, - krb5_octet *data) +krb5_error_code ipadb_get_tl_data(krb5_db_entry *entry, + krb5_int16 type, + krb5_ui_2 length, + krb5_octet *data) { krb5_tl_data *td;