mirror of
https://salsa.debian.org/freeipa-team/freeipa.git
synced 2025-02-25 18:55:28 -06:00
kdb: implement RBCD handling in KDB driver
Resource-based constrained delegation (RBCD) is implemented with a new callback used by the KDC. This callback is called when a server asks for S4U2Proxy TGS request and passes a ticket that contains RBCD PAC options. The callback is supposed to take a client and a server principals, a PAC and a target service database entry. Using the target service database entry it then needs to decide whether a server principal is allowed to delegate the client credentials to the target service. The callback can also cross-check whether the client principal can be limited in delegating own tickets but this is not implemented in the current version. Fixes: https://pagure.io/freeipa/issue/9354 Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com> Reviewed-By: Rob Crittenden <rcritten@redhat.com>
This commit is contained in:
committed by
Rob Crittenden
parent
4239b77a6d
commit
f78dc0b163
@@ -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
|
||||
|
||||
@@ -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,
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
|
||||
Reference in New Issue
Block a user