[Freeipa-devel] [PATCH] 116 Add PAC to master host TGTs

Sumit Bose sbose at redhat.com
Wed Jul 3 12:53:55 UTC 2013


On Wed, Jul 03, 2013 at 01:00:43PM +0300, Alexander Bokovoy wrote:
> On Mon, 01 Jul 2013, Sumit Bose wrote:
> >Hi,
> >
> >this patch fixes https://fedorahosted.org/freeipa/ticket/3651 but only
> >to allow SSSD running on a FreeIPA server to access the AD LDAP server.
> >In the ticket a more generic solution is described but since there is no
> >other use case so far I think this patch is sufficient for the time
> >being.
> >
> >bye,
> >Sumit
> 
> >From a707d8f9d771dfe4fb8487e051519dba0ef72449 Mon Sep 17 00:00:00 2001
> >From: Sumit Bose <sbose at redhat.com>
> >Date: Mon, 1 Jul 2013 13:47:22 +0200
> >Subject: [PATCH] Add PAC to master host TGTs
> >
> >For a proper SALS bind with GSSAPI against an AD LDAP server a PAC is
> >needed. To allow SSSD in ipa_server_mode to access the LDAP or GC server
> >of a trusted domain with the credentials of a FreeIPA server host a
> >PAC must be added to the TGT for the host.
> s/SALS/SASL/

Thank you for the review, I've fixed the typo and added the numerical
values for the well-known RIDs to the commit message.

> 
> 
> >To determine if a host is a FreeIPA server or not it is checked if there
> >is an entry for the host in cn=master,cn=ipa,cn=etc,$base. Unfortunately
> >this requires an additional LDAP lookup. But since TGS-REQs for hosts
> >should be rare I think it is acceptable for the time being.
> I think it is better to change this lookup to
> "cn=ADTRUST,cn=$FQDN,cn=masters,cn=ipa,cn=etc,$SUFFIX", it would
> explicitly limit us to the IPA masters running AD trusts.

I'm not sure if this restriction is needed. With SSSD's ipa_server_mode
any IPA master (which networkwise can access an AD server of the trusted
domain) can read AD user and group data, no running smbd or winbind is
required. So it would be possible to run the extdom plugin or the compat
plugin for the legacy clients on any IPA server which would allow a much
better load balancing.

If there are other concerns I'm happy to add the restriction.

bye,
Sumit

> 
> >+static bool is_master_host(struct ipadb_context *ipactx, const char *fqdn)
> >+{
> >+    int ret;
> >+    char *master_host_base = NULL;
> >+    LDAPMessage *result = NULL;
> >+    krb5_error_code err;
> >+
> >+    ret = asprintf(&master_host_base, "cn=%s,cn=masters,cn=ipa,cn=etc,%s",
> >+                                      fqdn, ipactx->base);
> here: "cn=ADTRUST,cn=%s,cn=masters,cn=ipa,cn=etc,%s"
> 
> >+    if (is_host) {
> >+        prigid = 515; /* Well known RID for domain computers group */
> Could you please mention this fact in the commit message as well?
> 
> >+    if (is_host) {
> >+        /* Well know RID of domain controllers group */
> >+        info3->base.rid = 516;
> Same here.
> 
> 
> 
> -- 
> / Alexander Bokovoy
-------------- next part --------------
From 76b1be5d8331c92e5837e6e0f7f19fab2876be9b Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Mon, 1 Jul 2013 13:47:22 +0200
Subject: [PATCH] Add PAC to master host TGTs

For a proper SASL bind with GSSAPI against an AD LDAP server a PAC is
needed. To allow SSSD in ipa_server_mode to access the LDAP or GC server
of a trusted domain with the credentials of a FreeIPA server host a
PAC must be added to the TGT for the host.

We use the well know RID of the Domain Computers group (515) for the
primary gid element of the PAC, this is the same as AD uses for host
tickets.  The rid element of the PAC is set to the well know RID of the
Domain Controllers group (516). This is working for the SSSD use case
but might be improved later for more general use cases.

To determine if a host is a FreeIPA server or not it is checked if there
is an entry for the host in cn=master,cn=ipa,cn=etc,$base. Unfortunately
this requires an additional LDAP lookup. But since TGS-REQs for hosts
should be rare I think it is acceptable for the time being.

Fixes https://fedorahosted.org/freeipa/ticket/3651
---
 daemons/ipa-kdb/ipa_kdb_mspac.c | 154 ++++++++++++++++++++++++++++++----------
 1 file changed, 115 insertions(+), 39 deletions(-)

diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
index 2662b947bd589074faa1acf6a9bb97748161cb05..92dc8dd7fa6c51d9edfc4d73cef23b3129c01192 100644
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
@@ -58,6 +58,7 @@ static char *user_pac_attrs[] = {
     "objectClass",
     "uid",
     "cn",
+    "fqdn",
     "gidNumber",
     "krbPrincipalName",
     "krbCanonicalName",
@@ -358,6 +359,29 @@ static int sid_split_rid(struct dom_sid *sid, uint32_t *rid)
     return 0;
 }
 
+static bool is_master_host(struct ipadb_context *ipactx, const char *fqdn)
+{
+    int ret;
+    char *master_host_base = NULL;
+    LDAPMessage *result = NULL;
+    krb5_error_code err;
+
+    ret = asprintf(&master_host_base, "cn=%s,cn=masters,cn=ipa,cn=etc,%s",
+                                      fqdn, ipactx->base);
+    if (ret == -1) {
+        return false;
+    }
+    err = ipadb_simple_search(ipactx, master_host_base, LDAP_SCOPE_BASE,
+                              NULL, NULL, &result);
+    free(master_host_base);
+    ldap_msgfree(result);
+    if (err == 0) {
+        return true;
+    }
+
+    return false;
+}
+
 static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
                                         LDAPMessage *lentry,
                                         TALLOC_CTX *memctx,
@@ -371,13 +395,65 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
     char *strres;
     int intres;
     int ret;
+    char **objectclasses = NULL;
+    size_t c;
+    bool is_host = false;
+    bool is_user = false;
 
-    ret = ipadb_ldap_attr_to_int(lcontext, lentry, "gidNumber", &intres);
-    if (ret) {
-        /* gidNumber is mandatory */
-        return ret;
+    ret = ipadb_ldap_attr_to_strlist(lcontext, lentry, "objectClass",
+                                     &objectclasses);
+    if (ret == 0 && objectclasses != NULL) {
+        for (c = 0; objectclasses[c] != NULL; c++) {
+            if (strcasecmp(objectclasses[c], "ipaHost") == 0) {
+                is_host = true;
+            }
+            if (strcasecmp(objectclasses[c], "ipaNTUserAttrs") == 0) {
+                is_user = true;
+            }
+            free(objectclasses[c]);
+        }
+    }
+    free(objectclasses);
+
+    if (!is_host && !is_user) {
+        /* We only handle users and hosts */
+        return ENOENT;
+    }
+
+    if (is_host) {
+        ret = ipadb_ldap_attr_to_str(lcontext, lentry, "fqdn", &strres);
+        if (ret) {
+            /* fqdn is mandatory for hosts */
+            return ret;
+        }
+
+        /* Currently we only add a PAC to TGTs for IPA servers to allow SSSD in
+         * ipa_server_mode to access the AD LDAP server */
+        if (!is_master_host(ipactx, strres)) {
+            free(strres);
+            return ENOENT;
+        }
+    } else {
+        ret = ipadb_ldap_attr_to_str(lcontext, lentry, "uid", &strres);
+        if (ret) {
+            /* uid is mandatory */
+            return ret;
+        }
+    }
+
+    info3->base.account_name.string = talloc_strdup(memctx, strres);
+    free(strres);
+
+    if (is_host) {
+        prigid = 515; /* Well known RID for domain computers group */
+    } else {
+        ret = ipadb_ldap_attr_to_int(lcontext, lentry, "gidNumber", &intres);
+        if (ret) {
+            /* gidNumber is mandatory */
+            return ret;
+        }
+        prigid = intres;
     }
-    prigid = intres;
 
 
     info3->base.logon_time = 0; /* do not have this info yet */
@@ -419,15 +495,6 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
     info3->base.allow_password_change = 0;
     info3->base.force_password_change = -1;
 
-    /* FIXME: handle computer accounts they do not use 'uid' */
-    ret = ipadb_ldap_attr_to_str(lcontext, lentry, "uid", &strres);
-    if (ret) {
-        /* uid is mandatory */
-        return ret;
-    }
-    info3->base.account_name.string = talloc_strdup(memctx, strres);
-    free(strres);
-
     ret = ipadb_ldap_attr_to_str(lcontext, lentry, "cn", &strres);
     switch (ret) {
     case 0:
@@ -500,21 +567,25 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
     info3->base.logon_count = 0; /* we do not have this info yet */
     info3->base.bad_password_count = 0; /* we do not have this info yet */
 
-    ret = ipadb_ldap_attr_to_str(lcontext, lentry,
-                                 "ipaNTSecurityIdentifier", &strres);
-    if (ret) {
-        /* SID is mandatory */
-        return ret;
-    }
-    ret = string_to_sid(strres, &sid);
-    free(strres);
-    if (ret) {
-        return ret;
-    }
-
-    ret = sid_split_rid(&sid, &info3->base.rid);
-    if (ret) {
-        return ret;
+    if (is_host) {
+        /* Well know RID of domain controllers group */
+        info3->base.rid = 516;
+    } else {
+        ret = ipadb_ldap_attr_to_str(lcontext, lentry,
+                                     "ipaNTSecurityIdentifier", &strres);
+        if (ret) {
+            /* SID is mandatory */
+            return ret;
+        }
+        ret = string_to_sid(strres, &sid);
+        free(strres);
+        if (ret) {
+            return ret;
+        }
+        ret = sid_split_rid(&sid, &info3->base.rid);
+        if (ret) {
+            return ret;
+        }
     }
 
     ret = ipadb_ldap_deref_results(lcontext, lentry, &deref_results);
@@ -587,11 +658,15 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
     }
 
     if (info3->base.primary_gid == 0) {
-        if (ipactx->mspac->fallback_rid) {
-            info3->base.primary_gid = ipactx->mspac->fallback_rid;
+        if (is_host) {
+            info3->base.primary_gid = 515;  /* Well known RID for domain computers group */
         } else {
-            /* can't give a pack without a primary group rid */
-            return ENOENT;
+            if (ipactx->mspac->fallback_rid) {
+                info3->base.primary_gid = ipactx->mspac->fallback_rid;
+            } else {
+                /* can't give a pack without a primary group rid */
+                return ENOENT;
+            }
         }
     }
 
@@ -623,8 +698,13 @@ static krb5_error_code ipadb_fill_info3(struct ipadb_context *ipactx,
         return ENOENT;
     }
 
-    /* we got the domain SID for the user sid */
-    info3->base.domain_sid = talloc_memdup(memctx, &sid, sizeof(sid));
+    if (is_host) {
+        info3->base.domain_sid = talloc_memdup(memctx, &ipactx->mspac->domsid,
+                                               sizeof(ipactx->mspac->domsid));
+    } else {
+        /* we got the domain SID for the user sid */
+        info3->base.domain_sid = talloc_memdup(memctx, &sid, sizeof(sid));
+    }
 
     /* always zero out, not used for Krb, only NTLM */
     memset(&info3->base.LMSessKey, '\0', sizeof(info3->base.key));
@@ -666,10 +746,6 @@ static krb5_error_code ipadb_get_pac(krb5_context kcontext,
         return EINVAL;
     }
 
-    if (!ied->ipa_user) {
-        return 0;
-    }
-
     tmpctx = talloc_new(NULL);
     if (!tmpctx) {
         return ENOMEM;
-- 
1.8.1.4



More information about the Freeipa-devel mailing list