Blob Blame History Raw
From f68b4dae7faea871b925fd551aefd6c428200cc4 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose@redhat.com>
Date: Fri, 27 Mar 2020 17:05:14 +0100
Subject: [PATCH 7/7] sysdb: sanitize certmap rule name before using it in DN
MIME-Version: 1.0
Content-Type: text/plain; charset=UTF-8
Content-Transfer-Encoding: 8bit

The name of a certificate mapping and matching rule might contain
characters which are not allowed in RDNs an must be escaped before if
can be used in the DN of the cached certmap object.

Resolves: https://pagure.io/SSSD/sssd/issue/3721

Reviewed-by: Pavel Březina <pbrezina@redhat.com>
(cherry picked from commit 27a3c0cf354bf2e85f50d7b4650d8a22120a5691)
---
 src/db/sysdb_certmap.c                | 29 ++++++++++++++++++++++++---
 src/tests/cmocka/test_sysdb_certmap.c | 25 +++++++++++++++++++++--
 2 files changed, 49 insertions(+), 5 deletions(-)

diff --git a/src/db/sysdb_certmap.c b/src/db/sysdb_certmap.c
index 6d83ba088..eda20f5a7 100644
--- a/src/db/sysdb_certmap.c
+++ b/src/db/sysdb_certmap.c
@@ -70,6 +70,30 @@ done:
     return ret;
 }
 
+static struct ldb_dn *sysdb_certmap_dn(TALLOC_CTX *mem_ctx,
+                                       struct sysdb_ctx *sysdb,
+                                       const char *name)
+{
+    int ret;
+    char *clean_name;
+    struct ldb_dn *dn = NULL;
+
+    ret = sysdb_dn_sanitize(mem_ctx, name, &clean_name);
+    if (ret != EOK) {
+        DEBUG(SSSDBG_OP_FAILURE, "sysdb_dn_sanitize failed.\n");
+        return NULL;
+    }
+
+    dn = ldb_dn_new_fmt(mem_ctx, sysdb->ldb, SYSDB_TMPL_CERTMAP, clean_name);
+    talloc_free(clean_name);
+    if (dn == NULL) {
+        DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n");
+        return NULL;
+    }
+
+    return dn;
+}
+
 static errno_t sysdb_certmap_add(struct sysdb_ctx *sysdb,
                                  struct certmap_info *certmap)
 {
@@ -92,10 +116,9 @@ static errno_t sysdb_certmap_add(struct sysdb_ctx *sysdb,
         goto done;
     }
 
-    msg->dn = ldb_dn_new_fmt(tmp_ctx, sysdb->ldb,
-                             SYSDB_TMPL_CERTMAP, certmap->name);
+    msg->dn = sysdb_certmap_dn(tmp_ctx, sysdb, certmap->name);
     if (msg->dn == NULL) {
-        DEBUG(SSSDBG_OP_FAILURE, "ldb_dn_new_fmt failed.\n");
+        DEBUG(SSSDBG_OP_FAILURE, "sysdb_certmap_dn failed.\n");
         ret = ENOMEM;
         goto done;
     }
diff --git a/src/tests/cmocka/test_sysdb_certmap.c b/src/tests/cmocka/test_sysdb_certmap.c
index e78ea8504..57b28bd6c 100644
--- a/src/tests/cmocka/test_sysdb_certmap.c
+++ b/src/tests/cmocka/test_sysdb_certmap.c
@@ -133,12 +133,20 @@ static void test_sysdb_update_certmap(void **state)
 {
     int ret;
     const char *domains[] = { "dom1.test", "dom2.test", "dom3.test", NULL };
-    struct certmap_info map_a = { discard_const("map_a"), 11, discard_const("abc"), discard_const("def"), NULL };
-    struct certmap_info map_b = { discard_const("map_b"), UINT_MAX, discard_const("abc"), NULL, domains };
+    struct certmap_info map_a = { discard_const("map_a"), 11,
+                                  discard_const("abc"), discard_const("def"),
+                                  NULL };
+    struct certmap_info map_b = { discard_const("map_b"), UINT_MAX,
+                                  discard_const("abc"), NULL, domains };
+    struct certmap_info map_c = { discard_const("cn=map_c,dc=sssd,dc=org"),
+                                  UINT_MAX, discard_const("abc"), NULL,
+                                  domains };
+
     struct certmap_info *certmap_empty[] = { NULL };
     struct certmap_info *certmap_a[] = { &map_a, NULL };
     struct certmap_info *certmap_b[] = { &map_b, NULL };
     struct certmap_info *certmap_ab[] = { &map_a, &map_b, NULL };
+    struct certmap_info *certmap_c[] = { &map_c, NULL };
     struct certmap_info **certmap;
     struct certmap_test_ctx *ctctx = talloc_get_type(*state,
                                                      struct certmap_test_ctx);
@@ -207,6 +215,19 @@ static void test_sysdb_update_certmap(void **state)
         check_certmap(certmap[1], &map_a, 0);
     }
     talloc_free(certmap);
+
+    ret = sysdb_update_certmap(ctctx->tctx->sysdb, certmap_c, false);
+    assert_int_equal(ret, EOK);
+
+    ret = sysdb_get_certmap(ctctx, ctctx->tctx->sysdb, &certmap,
+                            &user_name_hint);
+    assert_int_equal(ret, EOK);
+    assert_false(user_name_hint);
+    assert_non_null(certmap);
+    assert_non_null(certmap[0]);
+    check_certmap(certmap[0], &map_c, 3);
+    assert_null(certmap[1]);
+    talloc_free(certmap);
 }
 
 int main(int argc, const char *argv[])
-- 
2.21.1