Blame SOURCES/0006-ipa-kdb-PAC-consistency-checker-needs-to-handle-child-domains-as-well_rhbz#2166324.patch

f17082
From 2a0868fccbc9f4dfc540a7d3bb5dfa22c0bdce4e Mon Sep 17 00:00:00 2001
f17082
From: Alexander Bokovoy <abokovoy@redhat.com>
f17082
Date: Mon, 30 Jan 2023 14:22:30 +0200
f17082
Subject: [PATCH 1/2] ipa-kdb: PAC consistency checker needs to handle child
f17082
 domains as well
f17082
f17082
When PAC check is performed, we might get a signing TGT instead of the
f17082
client DB entry. This means it is a principal from a trusted domain but
f17082
we don't know which one exactly because we only have a krbtgt for the
f17082
forest root. This happens in MIT Kerberos 1.20 or later where KDB's
f17082
issue_pac() callback never gets the original client principal directly.
f17082
f17082
Look into known child domains as well and make pass the check if both
f17082
NetBIOS name and SID correspond to one of the trusted domains under this
f17082
forest root. Move check for the SID before NetBIOS name check because we
f17082
can use SID of the domain in PAC to find out the right child domain in
f17082
our trusted domains' topology list.
f17082
f17082
Fixes: https://pagure.io/freeipa/issue/9316
f17082
f17082
Signed-off-by: Alexander Bokovoy <abokovoy@redhat.com>
f17082
---
f17082
 daemons/ipa-kdb/ipa_kdb_mspac.c | 51 +++++++++++++++++++++------------
f17082
 1 file changed, 32 insertions(+), 19 deletions(-)
f17082
f17082
diff --git a/daemons/ipa-kdb/ipa_kdb_mspac.c b/daemons/ipa-kdb/ipa_kdb_mspac.c
f17082
index a15050e2166..476d1cb558a 100644
f17082
--- a/daemons/ipa-kdb/ipa_kdb_mspac.c
f17082
+++ b/daemons/ipa-kdb/ipa_kdb_mspac.c
f17082
@@ -1827,11 +1827,43 @@ krb5_error_code filter_logon_info(krb5_context context,
f17082
     bool result;
f17082
     char *domstr = NULL;
f17082
 
f17082
+    ipactx = ipadb_get_context(context);
f17082
+    if (!ipactx || !ipactx->mspac) {
f17082
+        return KRB5_KDB_DBNOTINITED;
f17082
+    }
f17082
+
f17082
     domain = get_domain_from_realm_update(context, realm);
f17082
     if (!domain) {
f17082
         return EINVAL;
f17082
     }
f17082
 
f17082
+    /* check exact sid */
f17082
+    result = dom_sid_check(&domain->domsid, info->info->info3.base.domain_sid, true);
f17082
+    if (!result) {
f17082
+        struct ipadb_mspac *mspac_ctx = ipactx->mspac;
f17082
+        result = FALSE;
f17082
+        /* Didn't match but perhaps the original PAC was issued by a child domain's DC? */
f17082
+        for (k = 0; k < mspac_ctx->num_trusts; k++) {
f17082
+            result = dom_sid_check(&mspac_ctx->trusts[k].domsid,
f17082
+                             info->info->info3.base.domain_sid, true);
f17082
+            if (result) {
f17082
+                domain = &mspac_ctx->trusts[k];
f17082
+                break;
f17082
+            }
f17082
+        }
f17082
+        if (!result) {
f17082
+            domstr = dom_sid_string(NULL, info->info->info3.base.domain_sid);
f17082
+            krb5_klog_syslog(LOG_ERR, "PAC Info mismatch: domain = %s, "
f17082
+                                      "expected domain SID = %s, "
f17082
+                                      "found domain SID = %s",
f17082
+                                      domain->domain_name, domain->domain_sid,
f17082
+                                      domstr ? domstr : "<failed to display>");
f17082
+            talloc_free(domstr);
f17082
+            return EINVAL;
f17082
+        }
f17082
+    }
f17082
+
f17082
+    /* At this point we may have changed the domain we look at, */
f17082
     /* check netbios/flat name */
f17082
     if (strcasecmp(info->info->info3.base.logon_domain.string,
f17082
                    domain->flat_name) != 0) {
f17082
@@ -1843,21 +1875,6 @@ krb5_error_code filter_logon_info(krb5_context context,
f17082
         return EINVAL;
f17082
     }
f17082
 
f17082
-    /* check exact sid */
f17082
-    result = dom_sid_check(&domain->domsid, info->info->info3.base.domain_sid, true);
f17082
-    if (!result) {
f17082
-        domstr = dom_sid_string(NULL, info->info->info3.base.domain_sid);
f17082
-        if (!domstr) {
f17082
-            return EINVAL;
f17082
-        }
f17082
-        krb5_klog_syslog(LOG_ERR, "PAC Info mismatch: domain = %s, "
f17082
-                                  "expected domain SID = %s, "
f17082
-                                  "found domain SID = %s",
f17082
-                                  domain->domain_name, domain->domain_sid, domstr);
f17082
-        talloc_free(domstr);
f17082
-        return EINVAL;
f17082
-    }
f17082
-
f17082
     /* Check if this domain has been filtered out by the trust itself*/
f17082
     if (domain->parent != NULL) {
f17082
         for(k = 0; k < domain->parent->len_sid_blocklist_incoming; k++) {
f17082
@@ -1944,10 +1961,6 @@ krb5_error_code filter_logon_info(krb5_context context,
f17082
      * should include different possibilities into account
f17082
      * */
f17082
     if (info->info->info3.sidcount != 0) {
f17082
-        ipactx = ipadb_get_context(context);
f17082
-        if (!ipactx || !ipactx->mspac) {
f17082
-            return KRB5_KDB_DBNOTINITED;
f17082
-        }
f17082
         count = info->info->info3.sidcount;
f17082
         i = 0;
f17082
         j = 0;
f17082
f17082
From 1a4f2597253c750696f6cd34613b375dc30fe456 Mon Sep 17 00:00:00 2001
f17082
From: Anuja More <amore@redhat.com>
f17082
Date: Mon, 30 Jan 2023 19:27:49 +0530
f17082
Subject: [PATCH 2/2] Add test for SSH with GSSAPI auth.
f17082
f17082
Added test for aduser with GSSAPI authentication.
f17082
f17082
Related : https://pagure.io/freeipa/issue/9316
f17082
f17082
Signed-off-by: Anuja More <amore@redhat.com>
f17082
---
f17082
 ipatests/test_integration/test_trust.py | 46 +++++++++++++++++++++++++
f17082
 1 file changed, 46 insertions(+)
f17082
f17082
diff --git a/ipatests/test_integration/test_trust.py b/ipatests/test_integration/test_trust.py
f17082
index 21c814ff1a9..a1ed906c6ae 100644
f17082
--- a/ipatests/test_integration/test_trust.py
f17082
+++ b/ipatests/test_integration/test_trust.py
f17082
@@ -527,6 +527,35 @@ def test_subordinate_suffix(self):
f17082
                    .format(self.ad_domain, subordinate_suffix))
f17082
             self.ad.run_command(['powershell', '-c', cmd])
f17082
 
f17082
+    def test_ssh_aduser(self):
f17082
+        """Test ssh with GSSAPI is working with aduser
f17082
+
f17082
+        When kerberos ticket is obtained for child domain user
f17082
+        and ssh with this ticket should be successful
f17082
+        with no password prompt.
f17082
+
f17082
+        Related : https://pagure.io/freeipa/issue/9316
f17082
+        """
f17082
+        testuser = 'testuser@{0}'.format(self.ad_domain)
f17082
+        testusersub = 'subdomaintestuser@{0}'.format(self.ad_subdomain)
f17082
+
f17082
+        def sshuser(host, user):
f17082
+            tasks.kdestroy_all(host)
f17082
+            try:
f17082
+                tasks.kinit_as_user(host, user,
f17082
+                                    host.config.ad_admin_password
f17082
+                                    )
f17082
+                ssh_cmd = "ssh -q -K -l {user} {host} hostname"
f17082
+                valid_ssh = host.run_command(
f17082
+                    ssh_cmd.format(user=user, host=host.hostname)
f17082
+                )
f17082
+                assert host.hostname in valid_ssh.stdout_text
f17082
+            finally:
f17082
+                tasks.kdestroy_all(host)
f17082
+
f17082
+        sshuser(self.master, testuser)
f17082
+        sshuser(self.master, testusersub)
f17082
+
f17082
     def test_remove_nonposix_trust(self):
f17082
         self.remove_trust(self.ad)
f17082
         tasks.unconfigure_dns_for_trust(self.master, self.ad)
f17082
@@ -784,6 +813,23 @@ def test_user_gid_uid_resolution_in_external_treedomain_trust(self):
f17082
         assert re.search(
f17082
             testuser_regex, result.stdout_text), result.stdout_text
f17082
 
f17082
+    def test_ssh_adtreeuser(self):
f17082
+        testuser = 'treetestuser@{0}'.format(self.ad_treedomain)
f17082
+        self.master.run_command(["id", testuser])
f17082
+        tasks.clear_sssd_cache(self.master)
f17082
+        tasks.kdestroy_all(self.master)
f17082
+        try:
f17082
+            tasks.kinit_as_user(self.master, testuser,
f17082
+                                password="Secret123456"
f17082
+                                )
f17082
+            ssh_cmd = "ssh -q -K -l {user} {host} hostname"
f17082
+            valid_ssh = self.master.run_command(
f17082
+                ssh_cmd.format(user=testuser, host=self.master.hostname)
f17082
+            )
f17082
+            assert self.master.hostname in valid_ssh.stdout_text
f17082
+        finally:
f17082
+            tasks.kdestroy_all(self.master)
f17082
+
f17082
     def test_remove_external_treedomain_trust(self):
f17082
         self.remove_trust(self.tree_ad)
f17082
         tasks.unconfigure_dns_for_trust(self.master, self.ad, self.tree_ad)