diff options
author | Sumit Bose <sbose@redhat.com> | 2017-02-02 16:34:32 +0100 |
---|---|---|
committer | Jakub Hrozek <jhrozek@redhat.com> | 2017-03-23 17:19:14 +0100 |
commit | b341ee51cffd98b642b9c68a417f8a7504e303a1 (patch) | |
tree | bc1a2f70566cf587376bf38db7c49ded080b9090 | |
parent | 81c564a0692aa4b719af2219f52894e6cd4bdf9f (diff) | |
download | sssd-b341ee51cffd98b642b9c68a417f8a7504e303a1.tar.gz sssd-b341ee51cffd98b642b9c68a417f8a7504e303a1.tar.xz sssd-b341ee51cffd98b642b9c68a417f8a7504e303a1.zip |
sss_cert_derb64_to_ldap_filter: add sss_certmap support
Use certificate mapping library if available to lookup a user by
certificate in LDAP.
Related to https://pagure.io/SSSD/sssd/issue/3050
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
-rw-r--r-- | Makefile.am | 1 | ||||
-rw-r--r-- | src/db/sysdb_ops.c | 2 | ||||
-rw-r--r-- | src/db/sysdb_views.c | 4 | ||||
-rw-r--r-- | src/providers/ipa/ipa_views.c | 2 | ||||
-rw-r--r-- | src/providers/ldap/ldap_id.c | 2 | ||||
-rw-r--r-- | src/tests/cmocka/test_cert_utils.c | 4 | ||||
-rw-r--r-- | src/util/cert.h | 3 | ||||
-rw-r--r-- | src/util/cert/cert_common.c | 76 |
8 files changed, 76 insertions, 18 deletions
diff --git a/Makefile.am b/Makefile.am index 7947b7a5f..f262cc248 100644 --- a/Makefile.am +++ b/Makefile.am @@ -952,6 +952,7 @@ libsss_cert_la_LIBADD = \ $(TALLOC_LIBS) \ libsss_crypt.la \ libsss_debug.la \ + libsss_certmap.la \ $(NULL) libsss_cert_la_LDFLAGS = \ -avoid-version \ diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c index 8ae257644..919f22370 100644 --- a/src/db/sysdb_ops.c +++ b/src/db/sysdb_ops.c @@ -4661,7 +4661,7 @@ errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx, char *user_filter; ret = sss_cert_derb64_to_ldap_filter(mem_ctx, cert, SYSDB_USER_MAPPED_CERT, - &user_filter); + NULL, NULL, &user_filter); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n"); return ret; diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c index 9dc48f5b6..1c416dd14 100644 --- a/src/db/sysdb_views.c +++ b/src/db/sysdb_views.c @@ -862,8 +862,8 @@ errno_t sysdb_search_override_by_cert(TALLOC_CTX *mem_ctx, goto done; } - ret = sss_cert_derb64_to_ldap_filter(tmp_ctx, cert, SYSDB_USER_CERT, - &cert_filter); + ret = sss_cert_derb64_to_ldap_filter(tmp_ctx, cert, SYSDB_USER_CERT, NULL, + NULL, &cert_filter); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n"); diff --git a/src/providers/ipa/ipa_views.c b/src/providers/ipa/ipa_views.c index 29f589ec1..5b6fcbc9b 100644 --- a/src/providers/ipa/ipa_views.c +++ b/src/providers/ipa/ipa_views.c @@ -156,7 +156,7 @@ static errno_t dp_id_data_to_override_filter(TALLOC_CTX *mem_ctx, if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_BY_CERT) { ret = sss_cert_derb64_to_ldap_filter(mem_ctx, ar->filter_value, ipa_opts->override_map[IPA_AT_OVERRIDE_USER_CERT].name, - &cert_filter); + NULL, NULL, &cert_filter); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n"); diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c index a8b4bc2cf..8e60769d0 100644 --- a/src/providers/ldap/ldap_id.c +++ b/src/providers/ldap/ldap_id.c @@ -247,7 +247,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx, } ret = sss_cert_derb64_to_ldap_filter(state, filter_value, attr_name, - &user_filter); + NULL, NULL, &user_filter); if (ret != EOK) { DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n"); diff --git a/src/tests/cmocka/test_cert_utils.c b/src/tests/cmocka/test_cert_utils.c index 35e8cb751..583013175 100644 --- a/src/tests/cmocka/test_cert_utils.c +++ b/src/tests/cmocka/test_cert_utils.c @@ -297,11 +297,11 @@ void test_sss_cert_derb64_to_ldap_filter(void **state) struct test_state *ts = talloc_get_type_abort(*state, struct test_state); assert_non_null(ts); - ret = sss_cert_derb64_to_ldap_filter(ts, NULL, NULL, NULL); + ret = sss_cert_derb64_to_ldap_filter(ts, NULL, NULL, NULL, NULL, NULL); assert_int_equal(ret, EINVAL); ret = sss_cert_derb64_to_ldap_filter(ts, "AAECAwQFBgcICQ==", "attrName", - &filter); + NULL, NULL, &filter); assert_int_equal(ret, EOK); assert_string_equal(filter, "(attrName=\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09)"); diff --git a/src/util/cert.h b/src/util/cert.h index bb64d0d7a..4598aa8df 100644 --- a/src/util/cert.h +++ b/src/util/cert.h @@ -21,6 +21,7 @@ #include <talloc.h> #include "util/util.h" +#include "lib/certmap/sss_certmap.h" #ifndef __CERT_H__ #define __CERT_H__ @@ -39,6 +40,8 @@ errno_t sss_cert_pem_to_derb64(TALLOC_CTX *mem_ctx, const char *pem, errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64, const char *attr_name, + struct sss_certmap_ctx *certmap_ctx, + struct sss_domain_info *dom, char **ldap_filter); errno_t bin_to_ldap_filter_value(TALLOC_CTX *mem_ctx, diff --git a/src/util/cert/cert_common.c b/src/util/cert/cert_common.c index a29696ed3..766877089 100644 --- a/src/util/cert/cert_common.c +++ b/src/util/cert/cert_common.c @@ -72,12 +72,17 @@ errno_t sss_cert_pem_to_derb64(TALLOC_CTX *mem_ctx, const char *pem, errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64, const char *attr_name, + struct sss_certmap_ctx *certmap_ctx, + struct sss_domain_info *dom, char **ldap_filter) { int ret; unsigned char *der; size_t der_size; char *val; + char *filter = NULL; + char **domains = NULL; + size_t c; if (derb64 == NULL || attr_name == NULL) { return EINVAL; @@ -89,18 +94,67 @@ errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64, return EINVAL; } - ret = bin_to_ldap_filter_value(mem_ctx, der, der_size, &val); - talloc_free(der); - if (ret != EOK) { - DEBUG(SSSDBG_OP_FAILURE, "bin_to_ldap_filter_value failed.\n"); - return ret; - } + if (certmap_ctx == NULL) { + ret = bin_to_ldap_filter_value(mem_ctx, der, der_size, &val); + talloc_free(der); + if (ret != EOK) { + DEBUG(SSSDBG_OP_FAILURE, "bin_to_ldap_filter_value failed.\n"); + return ret; + } - *ldap_filter = talloc_asprintf(mem_ctx, "(%s=%s)", attr_name, val); - talloc_free(val); - if (*ldap_filter == NULL) { - DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); - return ENOMEM; + *ldap_filter = talloc_asprintf(mem_ctx, "(%s=%s)", attr_name, val); + talloc_free(val); + if (*ldap_filter == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n"); + return ENOMEM; + } + } else { + ret = sss_certmap_get_search_filter(certmap_ctx, der, der_size, + &filter, &domains); + talloc_free(der); + if (ret != 0) { + if (ret == ENOENT) { + DEBUG(SSSDBG_OP_FAILURE, + "Certificate does not match matching-rules.\n"); + } else { + DEBUG(SSSDBG_OP_FAILURE, + "sss_certmap_get_search_filter failed.\n"); + } + } else { + if (domains == NULL) { + if (IS_SUBDOMAIN(dom)) { + DEBUG(SSSDBG_TRACE_FUNC, + "Rule applies only to local domain.\n"); + ret = ENOENT; + } + } else { + for (c = 0; domains[c] != NULL; c++) { + if (strcasecmp(dom->name, domains[c]) == 0) { + DEBUG(SSSDBG_TRACE_FUNC, + "Rule applies to current domain [%s].\n", + dom->name); + ret = EOK; + break; + } + } + if (domains[c] == NULL) { + DEBUG(SSSDBG_TRACE_FUNC, + "Rule does not apply to current domain [%s].\n", + dom->name); + ret = ENOENT; + } + } + } + + if (ret == EOK) { + *ldap_filter = talloc_strdup(mem_ctx, filter); + if (*ldap_filter == NULL) { + DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n"); + ret = ENOMEM; + } + } + sss_certmap_free_filter_and_domains(filter, domains); + return ret; } return EOK; |