dpward / rpms / sssd

Forked from rpms/sssd 3 years ago
Clone

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

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