Blame SOURCES/0121-PAM-check-matching-certificates-from-all-domains.patch

ecf709
From 52514960f5b0609cd9f31f3c4455b61fbe4c04c5 Mon Sep 17 00:00:00 2001
ecf709
From: Sumit Bose <sbose@redhat.com>
ecf709
Date: Wed, 26 Apr 2017 17:16:19 +0200
ecf709
Subject: [PATCH 121/121] PAM: check matching certificates from all domains
ecf709
ecf709
Although the cache_req lookup found matching in multiple domains only
ecf709
the results from the first domain were used. With this patch the results
ecf709
from all domains are checked.
ecf709
ecf709
Resolves https://pagure.io/SSSD/sssd/issue/3385
ecf709
ecf709
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
ecf709
(cherry picked from commit 92d8b072f8c521e1b4effe109b5caedabd36ed6f)
ecf709
---
ecf709
 src/responder/pam/pamsrv_cmd.c | 69 ++++++++++++++++++++++++++++++++++++++----
ecf709
 1 file changed, 63 insertions(+), 6 deletions(-)
ecf709
ecf709
diff --git a/src/responder/pam/pamsrv_cmd.c b/src/responder/pam/pamsrv_cmd.c
ecf709
index f2b3c74b483e527932dda42279d14a9ac184b475..10a178f839ec011c09a6da4575efbb026f3f7700 100644
ecf709
--- a/src/responder/pam/pamsrv_cmd.c
ecf709
+++ b/src/responder/pam/pamsrv_cmd.c
ecf709
@@ -1352,15 +1352,71 @@ done:
ecf709
     pam_check_user_done(preq, ret);
ecf709
 }
ecf709
 
ecf709
+static errno_t get_results_from_all_domains(TALLOC_CTX *mem_ctx,
ecf709
+                                            struct cache_req_result **results,
ecf709
+                                            struct ldb_result **ldb_results)
ecf709
+{
ecf709
+    int ret;
ecf709
+    size_t count = 0;
ecf709
+    size_t c;
ecf709
+    size_t d;
ecf709
+    size_t r = 0;
ecf709
+    struct ldb_result *res;
ecf709
+
ecf709
+    for (d = 0; results != NULL && results[d] != NULL; d++) {
ecf709
+        count += results[d]->count;
ecf709
+    }
ecf709
+
ecf709
+    res = talloc_zero(mem_ctx, struct ldb_result);
ecf709
+    if (res == NULL) {
ecf709
+        DEBUG(SSSDBG_OP_FAILURE, "talloc_zero failed.\n");
ecf709
+        return ENOMEM;
ecf709
+    }
ecf709
+
ecf709
+    if (count == 0) {
ecf709
+        *ldb_results = res;
ecf709
+        return EOK;
ecf709
+    }
ecf709
+
ecf709
+    res->msgs = talloc_zero_array(res, struct ldb_message *, count);
ecf709
+    if (res->msgs == NULL) {
ecf709
+        DEBUG(SSSDBG_OP_FAILURE, "talloc_zero_array failed.\n");
ecf709
+        return ENOMEM;
ecf709
+    }
ecf709
+    res->count = count;
ecf709
+
ecf709
+    for (d = 0; results != NULL && results[d] != NULL; d++) {
ecf709
+        for (c = 0; c < results[d]->count; c++) {
ecf709
+            if (r >= count) {
ecf709
+                DEBUG(SSSDBG_CRIT_FAILURE,
ecf709
+                      "More results found then counted before.\n");
ecf709
+                ret = EINVAL;
ecf709
+                goto done;
ecf709
+            }
ecf709
+            res->msgs[r++] = talloc_steal(res->msgs, results[d]->msgs[c]);
ecf709
+        }
ecf709
+    }
ecf709
+
ecf709
+    *ldb_results = res;
ecf709
+    ret = EOK;
ecf709
+
ecf709
+done:
ecf709
+    if (ret != EOK) {
ecf709
+        talloc_free(res);
ecf709
+    }
ecf709
+
ecf709
+    return ret;
ecf709
+}
ecf709
+
ecf709
 static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
ecf709
 {
ecf709
     int ret;
ecf709
-    struct cache_req_result *result;
ecf709
+    struct cache_req_result **results;
ecf709
     struct pam_auth_req *preq = tevent_req_callback_data(req,
ecf709
                                                          struct pam_auth_req);
ecf709
     const char *cert_user;
ecf709
 
ecf709
-    ret = cache_req_user_by_cert_recv(preq, req, &result);
ecf709
+    ret = cache_req_recv(preq, req, &results);
ecf709
     talloc_zfree(req);
ecf709
     if (ret != EOK && ret != ENOENT) {
ecf709
         DEBUG(SSSDBG_OP_FAILURE, "cache_req_user_by_cert request failed.\n");
ecf709
@@ -1368,12 +1424,13 @@ static void pam_forwarder_lookup_by_cert_done(struct tevent_req *req)
ecf709
     }
ecf709
 
ecf709
     if (ret == EOK) {
ecf709
-        if (preq->domain == NULL) {
ecf709
-            preq->domain = result->domain;
ecf709
+        ret = get_results_from_all_domains(preq, results,
ecf709
+                                           &preq->cert_user_objs);
ecf709
+        if (ret != EOK) {
ecf709
+            DEBUG(SSSDBG_OP_FAILURE, "get_results_from_all_domains failed.\n");
ecf709
+            goto done;
ecf709
         }
ecf709
 
ecf709
-        preq->cert_user_objs = talloc_steal(preq, result->ldb_result);
ecf709
-
ecf709
         if (preq->pd->logon_name == NULL) {
ecf709
             if (preq->pd->cmd != SSS_PAM_PREAUTH) {
ecf709
                 DEBUG(SSSDBG_CRIT_FAILURE,
ecf709
-- 
ecf709
2.9.3
ecf709