From 27a3c0cf354bf2e85f50d7b4650d8a22120a5691 Mon Sep 17 00:00:00 2001 From: Sumit Bose Date: Apr 03 2020 09:26:21 +0000 Subject: sysdb: sanitize certmap rule name before using it in DN 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 --- diff --git a/src/db/sysdb_certmap.c b/src/db/sysdb_certmap.c index 0bcc54c..4cc5b5b 100644 --- a/src/db/sysdb_certmap.c +++ b/src/db/sysdb_certmap.c @@ -71,6 +71,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) { @@ -93,10 +117,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 88c9737..8e84d18 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[])