On Fri, 2011-12-02 at 09:27 -0500, Rob Crittenden wrote:
> Simo Sorce wrote:
> > Hello all,
> >
> > with this set of patches it is possible to allow constrained delegation
> > of credentials so that a service can impersonate a user when

[..]

> In the third patch in ipadb_get_delegation_acl() you can just fall 
> through to the return.

Removed useless check.
I also noticed I had added the prototype declaration for the new vtable
function in the 2nd patch instead of the 3rd where it belongs by
mistake.

So I fixed that too.

> I think the content of this e-mail should be added as a README to the 
> source tree.

Ok, I dumped and adapted the email content into a README file and added
it to the third patch.

I also fixed the patch names as per policy.

Simo.

-- 
Simo Sorce * Red Hat, Inc * New York
>From 6361de2b8a08a2ca8787300bd4672af1c855a857 Mon Sep 17 00:00:00 2001
From: Simo Sorce <sso...@redhat.com>
Date: Sun, 20 Nov 2011 17:04:05 -0500
Subject: [PATCH 1/3] ipa-kdb: Delegation ACL schema

---
 install/share/60basev3.ldif |    5 +++++
 1 files changed, 5 insertions(+), 0 deletions(-)

diff --git a/install/share/60basev3.ldif b/install/share/60basev3.ldif
index f518541586b2df9ed08718098a7f170563aa4e1d..b31a3d4dd77be57adcc0d97d24e23ecf71025756 100644
--- a/install/share/60basev3.ldif
+++ b/install/share/60basev3.ldif
@@ -14,7 +14,12 @@ attributeTypes: (2.16.840.1.113730.3.8.11.7 NAME 'ipaNTProfilePath' DESC 'User P
 attributeTypes: (2.16.840.1.113730.3.8.11.8 NAME 'ipaNTHomeDirectory' DESC 'User Home Directory Path' EQUALITY caseIgnoreMatch OREDRING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v3' )
 attributeTypes: (2.16.840.1.113730.3.8.11.9 NAME 'ipaNTHomeDirectoryDrive' DESC 'User Home Drive Letter' EQUALITY caseIgnoreMatch OREDRING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 SINGLE-VALUE X-ORIGIN 'IPA v3' )
 attributeTypes: (2.16.840.1.113730.3.8.11.10 NAME 'ipaNTDomainGUID' DESC 'NT Domain GUID' EQUALITY caseIgnoreIA5Match OREDRING caseIgnoreIA5OrderingMatch SUBSTR caseIgnoreIA5SubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.26 SINGLE-VALUE X-ORIGIN 'IPA v3' )
+attributeTypes: ( 2.16.840.1.113730.3.8.11.20 NAME 'memberPrincipal' DESC 'Principal names member of a groupOfPrincipals group' EQUALITY caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 1.3.6.1.4.1.1466.115.121.1.15 X-ORIGIN 'IPA-v3')
+attributeTypes: ( 2.16.840.1.113730.3.8.11.21 NAME 'ipaAllowToImpersonate' DESC 'Principals that can be impersonated' SUP distinguishedName X-ORIGIN 'IPA-v3')
+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')
 objectClasses: (2.16.840.1.113730.3.8.12.1 NAME 'ipaExternalGroup' SUP top STRUCTURAL MUST ( cn ) MAY ( ipaExternalMember $ memberOf $ description $ owner) X-ORIGIN 'IPA v3' )
 objectClasses: (2.16.840.1.113730.3.8.12.2 NAME 'ipaNTUserAttrs' SUP top AUXILIARY MUST ( ipaNTSecurityIdentifier ) MAY ( ipaNTHash $ ipaNTLogonScript $ ipaNTProfilePath $ ipaNTHomeDirectory $ ipaNTHomeDirectoryDrive ) X-ORIGIN 'IPA v3' )
 objectClasses: (2.16.840.1.113730.3.8.12.3 NAME 'ipaNTGroupAttrs' SUP top AUXILIARY MUST ( ipaNTSecurityIdentifier ) X-ORIGIN 'IPA v3' )
 objectClasses: (2.16.840.1.113730.3.8.12.4 NAME 'ipaNTDomainAttrs' SUP top AUXILIARY MUST ( ipaNTSecurityIdentifier $ ipaNTFlatName $ ipaNTDomainGUID ) MAY ( ipaNTFallbackPrimaryGroup ) X-ORIGIN 'IPA v3' )
+objectClasses: (2.16.840.1.113730.3.8.12.6 NAME 'groupOfPrincipals' SUP top AUXILIARY MUST ( cn ) MAY ( memberPrincipal ) X-ORIGIN 'IPA v3' )
+objectClasses: (2.16.840.1.113730.3.8.12.7 NAME 'ipaKrb5DelegationACL' SUP groupOfPrincipals STRUCTURAL MAY ( ipaAllowToImpersonate $ ipaAllowedTarget ) X-ORIGIN 'IPA v3' )
-- 
1.7.7.1

>From 3a15f52a95aae218f66d6aba06dfa1ce874aa855 Mon Sep 17 00:00:00 2001
From: Simo Sorce <sso...@redhat.com>
Date: Sun, 20 Nov 2011 20:50:27 -0500
Subject: [PATCH 2/3] ipa-kdb: enhance deref searches

Allow to deref more than one attribute.
The attrs searched are the same for all deref attributes at this time.
---
 daemons/ipa-kdb/ipa_kdb.h        |    7 +++++--
 daemons/ipa-kdb/ipa_kdb_common.c |   34 +++++++++++++++++++++++++---------
 daemons/ipa-kdb/ipa_kdb_mspac.c  |   11 +++++++++--
 3 files changed, 39 insertions(+), 13 deletions(-)

diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
index 8c907c448d0f497786f7b66fb4e17e6590d4cc29..33b74a28ab9a283d635b050e93ee3760c1a55ec6 100644
--- a/daemons/ipa-kdb/ipa_kdb.h
+++ b/daemons/ipa-kdb/ipa_kdb.h
@@ -123,8 +123,11 @@ krb5_error_code ipadb_simple_modify(struct ipadb_context *ipactx,
 krb5_error_code ipadb_simple_delete_val(struct ipadb_context *ipactx,
                                         char *dn, char *attr, char *value);
 krb5_error_code ipadb_deref_search(struct ipadb_context *ipactx,
-                                   char *entry_dn, char **entry_attrs,
-                                   char *deref_attr_name, char **deref_attrs,
+                                   char *base_dn, int scope,
+                                   char *filter,
+                                   char **entry_attrs,
+                                   char **deref_attr_names,
+                                   char **deref_attrs,
                                    LDAPMessage **res);
 
 int ipadb_ldap_attr_to_int(LDAP *lcontext, LDAPMessage *le,
diff --git a/daemons/ipa-kdb/ipa_kdb_common.c b/daemons/ipa-kdb/ipa_kdb_common.c
index d3e8e9c4cb5438cd9c918daf5a19fc736fc698cb..6f5ac1d74f04c03bccdb19187a34d07b9784fa59 100644
--- a/daemons/ipa-kdb/ipa_kdb_common.c
+++ b/daemons/ipa-kdb/ipa_kdb_common.c
@@ -265,24 +265,39 @@ done:
 }
 
 krb5_error_code ipadb_deref_search(struct ipadb_context *ipactx,
-                                   char *entry_dn, char **entry_attrs,
-                                   char *deref_attr_name, char **deref_attrs,
+                                   char *base_dn, int scope,
+                                   char *filter,
+                                   char **entry_attrs,
+                                   char **deref_attr_names,
+                                   char **deref_attrs,
                                    LDAPMessage **res)
 {
     struct berval derefval = { 0, NULL };
     LDAPControl *ctrl[2] = { NULL, NULL };
-    LDAPDerefSpec ds[2];
+    LDAPDerefSpec *ds;
     krb5_error_code kerr;
     int times;
     int ret;
+    int c;
 
-    ds[0].derefAttr = deref_attr_name;
-    ds[0].attributes = deref_attrs;
-    ds[1].derefAttr = NULL;
+    for (c = 0; deref_attr_names[c]; c++) {
+        /* count */ ;
+    }
+
+    ds = calloc(c, sizeof(LDAPDerefSpec));
+    if (!ds) {
+        return ENOMEM;
+    }
+
+    for (c = 0; deref_attr_names[c]; c++) {
+        ds[c].derefAttr = deref_attr_names[c];
+        ds[c].attributes = deref_attrs;
+    }
 
     ret = ldap_create_deref_control_value(ipactx->lcontext, ds, &derefval);
     if (ret != LDAP_SUCCESS) {
-        return ENOMEM;
+        kerr = ENOMEM;
+        goto done;
     }
 
     ret = ldap_control_create(LDAP_CONTROL_X_DEREF,
@@ -297,8 +312,8 @@ krb5_error_code ipadb_deref_search(struct ipadb_context *ipactx,
     ret = LDAP_SUCCESS;
     while (!ipadb_need_retry(ipactx, ret) && times > 0) {
         times--;
-        ret = ldap_search_ext_s(ipactx->lcontext, entry_dn,
-                                LDAP_SCOPE_BASE, "(objectclass=*)",
+        ret = ldap_search_ext_s(ipactx->lcontext, base_dn,
+                                scope, filter,
                                 entry_attrs, 0,
                                 ctrl, NULL,
                                 &std_timeout, LDAP_NO_LIMIT,
@@ -309,6 +324,7 @@ krb5_error_code ipadb_deref_search(struct ipadb_context *ipactx,
 
 done:
     ldap_memfree(derefval.bv_val);
+    free(ds);
     return kerr;
 }
 
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index b435efeec0215d50694eeb668c0286b80056016f..160974ceb9cede21a3709316551fa5e1f1c5d5df 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -84,6 +84,11 @@ static char *user_pac_attrs[] = {
     NULL
 };
 
+char *deref_search_attrs[] = {
+    "memberOf",
+    NULL
+};
+
 static char *memberof_pac_attrs[] = {
     "gidNumber",
     "ipaNTSecurityIdentifier",
@@ -502,8 +507,10 @@ static krb5_error_code ipadb_get_pac(krb5_context kcontext,
 
 
     /* == Search PAC info == */
-    kerr = ipadb_deref_search(ipactx, ied->entry_dn, user_pac_attrs,
-                              "memberOf", memberof_pac_attrs, &results);
+    kerr = ipadb_deref_search(ipactx, ied->entry_dn, LDAP_SCOPE_BASE,
+                              "(objectclass=*)", user_pac_attrs,
+                              deref_search_attrs, memberof_pac_attrs,
+                              &results);
     if (kerr) {
         goto done;
     }
-- 
1.7.7.1

>From f1378c4cebb88e61e3ccc1ab68ee2bbedd9fd6da Mon Sep 17 00:00:00 2001
From: Simo Sorce <sso...@redhat.com>
Date: Sun, 20 Nov 2011 18:36:26 -0500
Subject: [PATCH] ipa-kdb: Add delgation access control support

---
 daemons/ipa-kdb/Makefile.am          |    1 +
 daemons/ipa-kdb/README.s4u2proxy.txt |  124 ++++++++++++++++++++
 daemons/ipa-kdb/ipa_kdb.c            |    2 +-
 daemons/ipa-kdb/ipa_kdb.h            |    7 +
 daemons/ipa-kdb/ipa_kdb_delegation.c |  209 ++++++++++++++++++++++++++++++++++
 5 files changed, 342 insertions(+), 1 deletions(-)
 create mode 100644 daemons/ipa-kdb/README.s4u2proxy.txt
 create mode 100644 daemons/ipa-kdb/ipa_kdb_delegation.c

diff --git a/daemons/ipa-kdb/Makefile.am b/daemons/ipa-kdb/Makefile.am
index c0a579bf4c74ac75a8da5d3f2dd774724e786bc8..77b92e8db865eb4bcc8ced50e0ef0352b6ea334f 100644
--- a/daemons/ipa-kdb/Makefile.am
+++ b/daemons/ipa-kdb/Makefile.am
@@ -34,6 +34,7 @@ ipadb_la_SOURCES = 		\
 	ipa_kdb_principals.c	\
 	ipa_kdb_pwdpolicy.c	\
 	ipa_kdb_mspac.c		\
+	ipa_kdb_delegation.c	\
 	$(KRB5_UTIL_SRCS)	\
 	$(NULL)
 
diff --git a/daemons/ipa-kdb/README.s4u2proxy.txt b/daemons/ipa-kdb/README.s4u2proxy.txt
new file mode 100644
index 0000000000000000000000000000000000000000..92d71bbd3e44c7a0ce97eb1443ce49c3b2f5e447
--- /dev/null
+++ b/daemons/ipa-kdb/README.s4u2proxy.txt
@@ -0,0 +1,124 @@
+It is now possible to allow constrained delegation of credentials so
+that a service can impersonate a user when communicating with another
+service w/o requiring the user to actually forward their TGT.
+This makes for a much better method of delegating credentials as it
+prevents exposure of the short term secret of the user.
+
+I added a relatively simple access control method that allow the KDC to
+decide exactly which services are allowed to impersonate which users
+against other services. A simple grouping mechanism is used so that in
+large environments, clusters and otherwise classes of services can be
+much more easily managed.
+
+The grouping mechanism has been built so that lookup is highly optimized
+and is basically reduced to a single search that uses the derefernce
+control. Speed is very important in this case because KDC operations
+time out very quickly and unless we add a caching layer in ipa-kdb we
+must keep the number of searches down to avoid client timeouts.
+
+The grouping mechanism is very simple a groupOfPrincipals object is
+introduced, this Auxiliary class have a single optional attribute called
+memberPrincipal which is a string containing a principal name.
+
+A separate objectclass is also introduced called ipaKrb5DelegationACL,
+it is a subclass of groupOfPrincipals and is a Structural class.
+
+It has 2 additional optional attributes: ipaAllowedTarget and
+ipaAllowToImpersonate. They are both DNs.
+
+The memberPrincipal attribute in this class contains the list of
+principals that are being considered proxies[1]. That is: the
+principals of the services that want to impersonate client principals
+against other services.
+
+The ipaAllowedToImpersonate must point to a groupOfPrincipal based
+object that contains the list of client principals (normally these are
+user principals) that can be impersonated by this service.
+If the attribute is missing than the service is allowed to impersonate
+*any* user.
+
+The ipaAllowedTarget DN must point to a groupOfPrincipal based object
+that contains the list of service principals that the proxy service is
+allowed target when impersonating users. A target must be specified in
+order to allow a service to access it impersonating another principal.
+
+
+At the moment no wildcarding is implemented so services have to be
+explicitly listed in their respective groups.
+I have some idea of adding wildcard support at least for the
+ipaAllowedToImpersonate group in order to separate user principals by
+REALM. So you can say all users of REALM1 can be impersonated by this
+service but no users of REALM2.
+
+It is unclear how this wildcarding may be implemented, but it must be
+simple to avoid potentially very expensive computations every time a
+ticket for the target services is requested.
+
+I have briefly tested this patch by manually creating a few objects then
+using the kvno command to test that I could get a ldap ticket just using
+the HTTP credentials (in order to do this I had to allow also s4u2self
+operations for the HTTP service, but this is *not* generally required
+and it is *not* desired in the IPA framework implementation).
+
+This patchset does not contain any CLI or UI nor installation changes to
+create ipaKrb5DelegationACL obujects. It is indeed yet unclear where we
+want to store them (suggestions are welcome) and how/when we may want to
+expose this mechanism through UI/CLI for general usage.
+
+The initial intended usage is to allow us to move away from using
+forwarded TGTs in the IPA framework and instead use S4U2Proxy in order
+to access the ldap service. In order to do this some changes will need
+to be made in installation scripts and replica management scripts later.
+
+How to test:
+
+Create 2 objects like these:
+
+dn: cn=ipa-http-delegation,...
+objectClass: ipaKrb5DelegationACL
+objectClass: groupOfPrincipals
+cn: ipa-http-delegation
+memberPrincipal: HTTP/ipaserver.example....@example.com
+ipaAllowedTarget: cn=ipa-ldap-delegation-targets,...
+
+dn: cn=ipa-ldap-delegation-targets,...
+objectClass: groupOfPrincipals
+cn: ipa-ldap-delegation-targets
+memberPrincipal: ldap/ipaserver.example....@example.com
+
+
+In order to test with kvno which pretend to do s4u2self too you will
+need to allow the HTTP service to impersonate arbitrary users.
+
+This is done with:
+kdamin.local
+modprinc +ok_to_auth_as_delegate HTTP/ipaserver.example.com
+
+Then run kvno as follows:
+
+# Init credntials as HTTP
+kinit -kt /etc/httpd/conf/ipa.keytab HTTP/ipaserver.example.com
+
+# Perform S4U2Self
+kvno -U admin HTTP/ipaserver.example.com
+
+# Perform S4U2Proxy
+kvno -k /etc/httpd/conf/ipa.keytab -U admin -P HTTP/ipaserver.example.com
+ldap/ipaserver.example.com
+
+
+If this works it means you successfully impersonated the admin user with
+the HTTP service against the ldap service.
+
+Simo.
+
+
+[1]
+Note that here I use the term proxy in a different way than it is used in
+the krb interfaces. It may seem a bit confusing but I think people will
+understand it better this way.
+
+In this document 'client' connects to 'proxy' which impersonates 'client'
+against 'service'.
+In the Code/API the 'client' connects to 'server' which impersonates
+'client' against 'proxy'.
diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c
index 05ee18720a11fc6b8579fd00206d1cbb9d5a1a34..ca266d546b9529778eec1b27bc10e0150c952b1f 100644
--- a/daemons/ipa-kdb/ipa_kdb.c
+++ b/daemons/ipa-kdb/ipa_kdb.c
@@ -458,6 +458,6 @@ kdb_vftabl kdb_function_table = {
     NULL,                               /* check_policy_tgs */
     NULL,                               /* audit_as_req */
     NULL,                               /* refresh_config */
-    NULL                                /* check_allowed_to_delegate */
+    ipadb_check_allowed_to_delegate     /* check_allowed_to_delegate */
 };
 
diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
index 33b74a28ab9a283d635b050e93ee3760c1a55ec6..2531d03281e899152b9418b545dd7f1122cf61bb 100644
--- a/daemons/ipa-kdb/ipa_kdb.h
+++ b/daemons/ipa-kdb/ipa_kdb.h
@@ -223,3 +223,10 @@ krb5_error_code ipadb_sign_authdata(krb5_context context,
                                     krb5_authdata ***signed_auth_data);
 
 krb5_error_code ipadb_reinit_mspac(struct ipadb_context *ipactx);
+
+/* DELEGATION CHECKS */
+
+krb5_error_code ipadb_check_allowed_to_delegate(krb5_context kcontext,
+                                                krb5_const_principal client,
+                                                const krb5_db_entry *server,
+                                                krb5_const_principal proxy);
diff --git a/daemons/ipa-kdb/ipa_kdb_delegation.c b/daemons/ipa-kdb/ipa_kdb_delegation.c
new file mode 100644
index 0000000000000000000000000000000000000000..428e214b7f6a5efff2797a76480746427d12d35e
--- /dev/null
+++ b/daemons/ipa-kdb/ipa_kdb_delegation.c
@@ -0,0 +1,209 @@
+/*
+ * MIT Kerberos KDC database backend for FreeIPA
+ *
+ * Authors: Simo Sorce <sso...@redhat.com>
+ *
+ * Copyright (C) 2011  Simo Sorce, Red Hat
+ * see file 'COPYING' for use and warranty information
+ *
+ * This program is free software you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation, either version 3 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.  If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include "ipa_kdb.h"
+
+static char *acl_attrs[] = {
+    "objectClass",
+    "memberPrincipal",
+    NULL
+};
+
+static char *search_attrs[] = {
+    "ipaAllowToImpersonate",
+    "ipaAllowedTarget",
+    NULL
+};
+
+static krb5_error_code ipadb_get_delegation_acl(krb5_context kcontext,
+                                                char *srv_principal,
+                                                LDAPMessage **results)
+{
+    struct ipadb_context *ipactx;
+    krb5_error_code kerr;
+    char *filter = NULL;
+    int ret;
+
+    ipactx = ipadb_get_context(kcontext);
+    if (!ipactx) {
+        return KRB5_KDB_DBNOTINITED;
+    }
+
+    ret = asprintf(&filter,
+                   "(&(objectclass=ipaKrb5DelegationACL)"
+                     "(memberPrincipal=%s))", srv_principal);
+    if (ret == -1) {
+        kerr = ENOMEM;
+        goto done;
+    }
+
+    /* == Search ACL info == */
+    kerr = ipadb_deref_search(ipactx, ipactx->base,
+                              LDAP_SCOPE_SUBTREE, filter, acl_attrs,
+                              search_attrs, acl_attrs, results);
+
+done:
+    free(filter);
+    return kerr;
+}
+
+static bool ipadb_match_member(char *princ, LDAPDerefRes *dres)
+{
+    LDAPDerefVal *dval;
+    int i;
+
+    for (dval = dres->attrVals; dval; dval = dval->next) {
+        if (strcasecmp(dval->type, "memberPrincipal") != 0) {
+            continue;
+        }
+
+        for (i = 0; dval->vals[i].bv_val != NULL; i++) {
+            /* FIXME: use utf8 aware comparison ? */
+            /* FIXME: support wildcards ? */
+            if (strncasecmp(princ, dval->vals[i].bv_val,
+                                    dval->vals[i].bv_len) == 0) {
+                return true;
+            }
+        }
+    }
+
+    return false;
+}
+
+static krb5_error_code ipadb_match_acl(krb5_context kcontext,
+                                       LDAPMessage *results,
+                                       krb5_const_principal client,
+                                       krb5_const_principal target)
+{
+    struct ipadb_context *ipactx;
+    krb5_error_code kerr = ENOENT;
+    LDAPMessage *lentry;
+    LDAPDerefRes *deref_results;
+    LDAPDerefRes *dres;
+    char *client_princ = NULL;
+    char *target_princ = NULL;
+    bool client_missing;
+    bool client_found;
+    bool target_found;
+    int ret;
+
+    ipactx = ipadb_get_context(kcontext);
+    if (!ipactx) {
+        return KRB5_KDB_DBNOTINITED;
+    }
+
+    kerr = krb5_unparse_name(kcontext, client, &client_princ);
+    if (kerr != 0) {
+        goto done;
+    }
+    kerr = krb5_unparse_name(kcontext, target, &target_princ);
+    if (kerr != 0) {
+        goto done;
+    }
+
+    lentry = ldap_first_entry(ipactx->lcontext, results);
+    if (!lentry) {
+        kerr = ENOENT;
+        goto done;
+    }
+
+    while (lentry) {
+        /* both client and target must be found in the same ACI */
+        client_missing = true;
+        client_found = false;
+        target_found = false;
+
+        ret = ipadb_ldap_deref_results(ipactx->lcontext, lentry,
+                                       &deref_results);
+        switch (ret) {
+        case 0:
+            for (dres = deref_results; dres; dres = dres->next) {
+                if (strcasecmp(dres->derefAttr, "ipaAllowToImpersonate") == 0) {
+                    /* NOTE: client_missing is used to signal that the
+                     * attribute was completely missing. This signals that
+                     * ANY client is allowed to be impersonated.
+                     * This logic is valid only for clients, not for targets */
+                    client_missing = false;
+                    client_found = ipadb_match_member(client_princ, dres);
+                }
+                if (strcasecmp(dres->derefAttr, "ipaAllowedTarget") == 0) {
+                    target_found = ipadb_match_member(target_princ, dres);
+                }
+            }
+
+            ldap_derefresponse_free(deref_results);
+            break;
+        case ENOENT:
+            break;
+        default:
+            kerr = ret;
+            goto done;
+        }
+
+        if ((client_found == true || client_missing == true) &&
+            target_found == true) {
+            kerr = 0;
+            goto done;
+        }
+
+        lentry = ldap_next_entry(ipactx->lcontext, lentry);
+    }
+
+done:
+    krb5_free_unparsed_name(kcontext, client_princ);
+    krb5_free_unparsed_name(kcontext, target_princ);
+    return kerr;
+}
+
+/* Ok terminology is confusing here so read carefully:
+ * here 'proxy' is the service for which 'server' wants a ticket on behalf of
+ * 'client' */
+
+krb5_error_code ipadb_check_allowed_to_delegate(krb5_context kcontext,
+                                                krb5_const_principal client,
+                                                const krb5_db_entry *server,
+                                                krb5_const_principal proxy)
+{
+    krb5_error_code kerr;
+    char *srv_principal = NULL;
+    LDAPMessage *res = NULL;
+
+    kerr = krb5_unparse_name(kcontext, server->princ, &srv_principal);
+    if (kerr) {
+        goto done;
+    }
+
+    kerr = ipadb_get_delegation_acl(kcontext, srv_principal, &res);
+    if (kerr) {
+        goto done;
+    }
+
+    kerr = ipadb_match_acl(kcontext, res, client, proxy);
+    if (kerr) {
+        goto done;
+    }
+
+done:
+    krb5_free_unparsed_name(kcontext, srv_principal);
+    ldap_msgfree(res);
+    return kerr;
+}
-- 
1.7.7.1

_______________________________________________
Freeipa-devel mailing list
Freeipa-devel@redhat.com
https://www.redhat.com/mailman/listinfo/freeipa-devel

Reply via email to