URL: https://github.com/SSSD/sssd/pull/522
Author: abbra
 Title: #522: Prepare SSSD to support IPA in trust to Samba AD
Action: synchronized

To pull the PR as Git branch:
git remote add ghsssd https://github.com/SSSD/sssd
git fetch ghsssd pull/522/head:pr522
git checkout pr522
From 150f410045944bfbb23830a912f0548e1b1bf6f2 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <aboko...@redhat.com>
Date: Thu, 22 Feb 2018 14:38:51 +0200
Subject: [PATCH 1/2] ipa provider: expand search base to cover trusted domain
 objects

In case of a two-way trust between FreeIPA and an Active Directory,
domain controller would use a TDO object in the trusting domain to
authenticate. Due to how trusted domain objects are used in Active
Directory, a domain controller from the trusted domain will synthesize
a Kerberos ticket for the TDO in the trusting domain. This ticket
will lack MS-PAC information because a trusted DC has no idea what
to put there. On IPA master smbd process will attempt to validate
successfully authenticated TDO principal by looking at its MS-PAC
structure, only to find it is missing. As result, smbd will revert
to a direct getpwnam().

Because TDO objects are stored under cn=trusts,$SUFFIX in FreeIPA,
they couldn't be found by SSSD which uses cn=accounts,$SUFFIX by
default. Add second search base to look up cn=trusts,$SUFFX to
allow TDO objects to be queried.

On FreeIPA side access controls are put in place so that only
AD trust agents are able to see a content of the cn=trusts,$SUFFIX
subtree.

Signed-of-by: Alexander Bokovoy <aboko...@redhat.com>
---
 src/providers/ipa/ipa_common.c | 36 +++++++++++++++++++++++++++++++-----
 1 file changed, 31 insertions(+), 5 deletions(-)

diff --git a/src/providers/ipa/ipa_common.c b/src/providers/ipa/ipa_common.c
index 2b81d7f3f..d91ba1c8e 100644
--- a/src/providers/ipa/ipa_common.c
+++ b/src/providers/ipa/ipa_common.c
@@ -176,9 +176,10 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
     TALLOC_CTX *tmpctx;
     char *basedn;
     char *realm;
-    char *value;
+    char *value, *user_base;
     int ret;
     int i;
+    bool server_mode;
 
     tmpctx = talloc_new(ipa_opts);
     if (!tmpctx) {
@@ -272,11 +273,36 @@ int ipa_get_id_options(struct ipa_options *ipa_opts,
     ipa_opts->id->schema_type = SDAP_SCHEMA_IPA_V1;
 
     /* set user/group search bases if they are not specified */
-    if (NULL == dp_opt_get_string(ipa_opts->id->basic,
-                                  SDAP_USER_SEARCH_BASE)) {
+    user_base = dp_opt_get_string(ipa_opts->id->basic, SDAP_USER_SEARCH_BASE);
+
+    /* In server mode we need to search both cn=accounts,$SUFFIX and
+     * cn=trusts,$SUFFIX to allow trusted domain object accounts to be found.
+     * Update user base if it wasn't set explicitly to multiple base DNs
+     */
+    server_mode = dp_opt_get_bool(ipa_opts->basic, IPA_SERVER_MODE);
+    if (server_mode != false) {
+        if ((NULL == user_base) || (NULL == strstr(user_base, "?cn=trusts,"))) {
+            /* Search both cn=accounts,$SUFFIX and cn=trusts,$SUFFIX.  This allows
+             * to catch trusted domain objects used by trusted AD DCs to talk to
+             * Samba on IPA master */
+            value = talloc_asprintf(tmpctx,
+                                    "%s?cn=trusts,%s??(objectclass=ipaIDObject)",
+                                    user_base ? user_base :
+                                    dp_opt_get_string(ipa_opts->id->basic,
+                                                      SDAP_SEARCH_BASE),
+                                    basedn);
+        }
+    } else {
+        value = dp_opt_get_string(ipa_opts->id->basic, SDAP_SEARCH_BASE);
+    }
+
+    if (NULL == user_base) {
+        if (!value) {
+            ret = ENOMEM;
+            goto done;
+        }
         ret = dp_opt_set_string(ipa_opts->id->basic, SDAP_USER_SEARCH_BASE,
-                                dp_opt_get_string(ipa_opts->id->basic,
-                                                  SDAP_SEARCH_BASE));
+                                value);
         if (ret != EOK) {
             goto done;
         }

From d311450a1e45f5123db6ccd3083391f607b540f6 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <aboko...@redhat.com>
Date: Thu, 22 Feb 2018 14:45:16 +0200
Subject: [PATCH 2/2] ipa provider: always use a special keytab to talk to a
 trusted DC

When FreeIPA is set up to trust an Active Directory forest, we should be
using trusted domain object credentials regardless of the trust
direction. Previously, SSSD relied on FreeIPA KDC issuing a cross-realm
referral towards a trusted domain. However, this does not work
currently with Samba AD and in general we want to move away to use
TDO in all cases as it is guaranteed to have correct permissions on AD
side.

Signed-of-by: Alexander Bokovoy <aboko...@redhat.com>
---
 src/providers/ipa/ipa_subdomains_server.c     | 24 ++++++---------
 src/tests/cmocka/test_ipa_subdomains_server.c | 44 +++++++++++++--------------
 2 files changed, 31 insertions(+), 37 deletions(-)

diff --git a/src/providers/ipa/ipa_subdomains_server.c b/src/providers/ipa/ipa_subdomains_server.c
index d670a156b..91c040d37 100644
--- a/src/providers/ipa/ipa_subdomains_server.c
+++ b/src/providers/ipa/ipa_subdomains_server.c
@@ -33,6 +33,7 @@
  */
 #define LSA_TRUST_DIRECTION_INBOUND  0x00000001
 #define LSA_TRUST_DIRECTION_OUTBOUND 0x00000002
+#define LSA_TRUST_DIRECTION_MASK (LSA_TRUST_DIRECTION_INBOUND | LSA_TRUST_DIRECTION_OUTBOUND)
 
 static char *forest_keytab(TALLOC_CTX *mem_ctx, const char *forest)
 {
@@ -182,15 +183,11 @@ static struct ad_options *ipa_ad_options_new(struct be_ctx *be_ctx,
         return NULL;
     }
 
-    if (direction & LSA_TRUST_DIRECTION_OUTBOUND) {
-        ad_options = ad_create_2way_trust_options(id_ctx,
-                                                  be_ctx->cdb,
-                                                  subdom_conf_path,
-                                                  id_ctx->server_mode->realm,
-                                                  subdom,
-                                                  id_ctx->server_mode->hostname,
-                                                  NULL);
-    } else if (direction & LSA_TRUST_DIRECTION_INBOUND) {
+    /* In both inbound and outbound trust cases we should be
+     * using trusted domain object in a trusted domain space,
+     * thus we always should be initializing principals/keytabs
+     * as if we are running one-way trust */
+    if (direction & LSA_TRUST_DIRECTION_MASK) {
         ad_options = ipa_create_1way_trust_ctx(id_ctx, be_ctx,
                                                subdom_conf_path, forest,
                                                forest_realm, subdom);
@@ -663,11 +660,10 @@ ipa_server_trusted_dom_setup_send(TALLOC_CTX *mem_ctx,
           subdom->name, state->forest,
           ipa_trust_dir2str(state->direction));
 
-    if (state->direction & LSA_TRUST_DIRECTION_OUTBOUND) {
-        /* Use system keytab, nothing to do here */
-        ret = EOK;
-        goto immediate;
-    } else if (state->direction & LSA_TRUST_DIRECTION_INBOUND) {
+    /* For both inbound and outbound trusts use a special keytab
+     * as this allows us to reuse the same logic in FreeIPA for
+     * both Microsoft AD and Samba AD */
+    if (state->direction & LSA_TRUST_DIRECTION_MASK) {
         /* Need special keytab */
         ret = ipa_server_trusted_dom_setup_1way(req);
         if (ret == EAGAIN) {
diff --git a/src/tests/cmocka/test_ipa_subdomains_server.c b/src/tests/cmocka/test_ipa_subdomains_server.c
index 65a13de7f..11cec6721 100644
--- a/src/tests/cmocka/test_ipa_subdomains_server.c
+++ b/src/tests/cmocka/test_ipa_subdomains_server.c
@@ -420,7 +420,7 @@ static void assert_trust_object(struct ipa_ad_server_ctx *trust,
         assert_null(s);
     }
 
-    /* the system keytab is always used with two-way trusts */
+    /* both one-way and two-way trust uses specialized keytab */
     s = dp_opt_get_string(trust->ad_id_ctx->ad_options->id->basic,
                           SDAP_KRB5_KEYTAB);
     if (keytab != NULL) {
@@ -474,23 +474,22 @@ static void test_ipa_server_create_trusts_twoway(struct tevent_req *req)
         s_trust = test_ctx->ipa_ctx->server_mode->trusts->next;
         c_trust = test_ctx->ipa_ctx->server_mode->trusts;
     }
-    /* Two-way trusts should use the system realm */
     assert_trust_object(c_trust,
                         CHILD_NAME,
-                        DOM_REALM,
+                        CHILD_REALM,
                         CHILD_SID,
-                        NULL,
-                        TEST_AUTHID,
-                        DOM_REALM);
+                        ONEWAY_KEYTAB,
+                        ONEWAY_PRINC,
+                        SUBDOM_REALM);
 
 
     assert_trust_object(s_trust,
                         SUBDOM_NAME,
-                        DOM_REALM,
+                        SUBDOM_REALM,
                         SUBDOM_SID,
-                        NULL,
-                        TEST_AUTHID,
-                        DOM_REALM);
+                        ONEWAY_KEYTAB,
+                        ONEWAY_PRINC,
+                        SUBDOM_REALM);
 
     /* No more trust objects */
     assert_null(test_ctx->ipa_ctx->server_mode->trusts->next->next);
@@ -505,11 +504,11 @@ static void test_ipa_server_create_trusts_twoway(struct tevent_req *req)
 
     assert_trust_object(test_ctx->ipa_ctx->server_mode->trusts,
                         SUBDOM_NAME,
-                        DOM_REALM,
+                        SUBDOM_REALM,
                         SUBDOM_SID,
-                        NULL,
-                        TEST_AUTHID,
-                        DOM_REALM);
+                        ONEWAY_KEYTAB,
+                        ONEWAY_PRINC,
+                        SUBDOM_REALM);
     assert_null(test_ctx->ipa_ctx->server_mode->trusts->next);
 
     test_ev_done(test_ctx->tctx, EOK);
@@ -562,22 +561,21 @@ static void test_ipa_server_trust_init(void **state)
         c_trust = test_ctx->ipa_ctx->server_mode->trusts;
     }
 
-    /* Two-way trusts should use the system realm */
     assert_trust_object(c_trust,
                         CHILD_NAME,
-                        DOM_REALM,
+                        CHILD_REALM,
                         CHILD_SID,
-                        NULL,
-                        TEST_AUTHID,
-                        DOM_REALM);
+                        ONEWAY_KEYTAB,
+                        ONEWAY_PRINC,
+                        SUBDOM_REALM);
 
     assert_trust_object(s_trust,
                         SUBDOM_NAME,
-                        DOM_REALM,
+                        SUBDOM_REALM,
                         SUBDOM_SID,
-                        NULL,
-                        TEST_AUTHID,
-                        DOM_REALM);
+                        ONEWAY_KEYTAB,
+                        ONEWAY_PRINC,
+                        SUBDOM_REALM);
 
     /* No more trust objects */
     assert_null(test_ctx->ipa_ctx->server_mode->trusts->next->next);
_______________________________________________
sssd-devel mailing list -- sssd-devel@lists.fedorahosted.org
To unsubscribe send an email to sssd-devel-le...@lists.fedorahosted.org

Reply via email to