|
|
bb7cd1 |
From 2e12cbdc8e2676b045a972045e9dae75b232dc76 Mon Sep 17 00:00:00 2001
|
|
|
bb7cd1 |
From: Sumit Bose <sbose@redhat.com>
|
|
|
bb7cd1 |
Date: Thu, 2 Feb 2017 16:34:32 +0100
|
|
|
bb7cd1 |
Subject: [PATCH 09/15] sss_cert_derb64_to_ldap_filter: add sss_certmap support
|
|
|
bb7cd1 |
MIME-Version: 1.0
|
|
|
bb7cd1 |
Content-Type: text/plain; charset=UTF-8
|
|
|
bb7cd1 |
Content-Transfer-Encoding: 8bit
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
Use certificate mapping library if available to lookup a user by
|
|
|
bb7cd1 |
certificate in LDAP.
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
Related to https://pagure.io/SSSD/sssd/issue/3050
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
Reviewed-by: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
bb7cd1 |
Reviewed-by: Lukáš Slebodník <lslebodn@redhat.com>
|
|
|
bb7cd1 |
---
|
|
|
bb7cd1 |
Makefile.am | 1 +
|
|
|
bb7cd1 |
src/db/sysdb_ops.c | 2 +-
|
|
|
bb7cd1 |
src/db/sysdb_views.c | 4 +-
|
|
|
bb7cd1 |
src/providers/ipa/ipa_views.c | 2 +-
|
|
|
bb7cd1 |
src/providers/ldap/ldap_id.c | 2 +-
|
|
|
bb7cd1 |
src/tests/cmocka/test_cert_utils.c | 4 +-
|
|
|
bb7cd1 |
src/util/cert.h | 3 ++
|
|
|
bb7cd1 |
src/util/cert/cert_common.c | 76 ++++++++++++++++++++++++++++++++------
|
|
|
bb7cd1 |
8 files changed, 76 insertions(+), 18 deletions(-)
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
diff --git a/Makefile.am b/Makefile.am
|
|
|
bb7cd1 |
index 7947b7a5fbe3ca1034baac1c13c53300994b1bf8..f262cc24832358910dbb92ccd46f93c9eda8a295 100644
|
|
|
bb7cd1 |
--- a/Makefile.am
|
|
|
bb7cd1 |
+++ b/Makefile.am
|
|
|
bb7cd1 |
@@ -952,6 +952,7 @@ libsss_cert_la_LIBADD = \
|
|
|
bb7cd1 |
$(TALLOC_LIBS) \
|
|
|
bb7cd1 |
libsss_crypt.la \
|
|
|
bb7cd1 |
libsss_debug.la \
|
|
|
bb7cd1 |
+ libsss_certmap.la \
|
|
|
bb7cd1 |
$(NULL)
|
|
|
bb7cd1 |
libsss_cert_la_LDFLAGS = \
|
|
|
bb7cd1 |
-avoid-version \
|
|
|
bb7cd1 |
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
|
|
|
bb7cd1 |
index 8ae25764478e522255b177f9e8de1d3ca1ad43fd..919f22370ff87eff2bf0bb569ca90f1ee699a61e 100644
|
|
|
bb7cd1 |
--- a/src/db/sysdb_ops.c
|
|
|
bb7cd1 |
+++ b/src/db/sysdb_ops.c
|
|
|
bb7cd1 |
@@ -4661,7 +4661,7 @@ errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx,
|
|
|
bb7cd1 |
char *user_filter;
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
ret = sss_cert_derb64_to_ldap_filter(mem_ctx, cert, SYSDB_USER_MAPPED_CERT,
|
|
|
bb7cd1 |
- &user_filter);
|
|
|
bb7cd1 |
+ NULL, NULL, &user_filter);
|
|
|
bb7cd1 |
if (ret != EOK) {
|
|
|
bb7cd1 |
DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n");
|
|
|
bb7cd1 |
return ret;
|
|
|
bb7cd1 |
diff --git a/src/db/sysdb_views.c b/src/db/sysdb_views.c
|
|
|
bb7cd1 |
index 9dc48f5b6c414bbc7c64bcd1fe73553f388588bd..1c416dd14049237e9f35d52f154035e3ff861469 100644
|
|
|
bb7cd1 |
--- a/src/db/sysdb_views.c
|
|
|
bb7cd1 |
+++ b/src/db/sysdb_views.c
|
|
|
bb7cd1 |
@@ -862,8 +862,8 @@ errno_t sysdb_search_override_by_cert(TALLOC_CTX *mem_ctx,
|
|
|
bb7cd1 |
goto done;
|
|
|
bb7cd1 |
}
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
- ret = sss_cert_derb64_to_ldap_filter(tmp_ctx, cert, SYSDB_USER_CERT,
|
|
|
bb7cd1 |
- &cert_filter);
|
|
|
bb7cd1 |
+ ret = sss_cert_derb64_to_ldap_filter(tmp_ctx, cert, SYSDB_USER_CERT, NULL,
|
|
|
bb7cd1 |
+ NULL, &cert_filter);
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
if (ret != EOK) {
|
|
|
bb7cd1 |
DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n");
|
|
|
bb7cd1 |
diff --git a/src/providers/ipa/ipa_views.c b/src/providers/ipa/ipa_views.c
|
|
|
bb7cd1 |
index 29f589ec1fd05f59175dcc4592e6395941e6e034..5b6fcbc9b7c6f2ea7dbeecb01a5a3fd11b8a6854 100644
|
|
|
bb7cd1 |
--- a/src/providers/ipa/ipa_views.c
|
|
|
bb7cd1 |
+++ b/src/providers/ipa/ipa_views.c
|
|
|
bb7cd1 |
@@ -156,7 +156,7 @@ static errno_t dp_id_data_to_override_filter(TALLOC_CTX *mem_ctx,
|
|
|
bb7cd1 |
if ((ar->entry_type & BE_REQ_TYPE_MASK) == BE_REQ_BY_CERT) {
|
|
|
bb7cd1 |
ret = sss_cert_derb64_to_ldap_filter(mem_ctx, ar->filter_value,
|
|
|
bb7cd1 |
ipa_opts->override_map[IPA_AT_OVERRIDE_USER_CERT].name,
|
|
|
bb7cd1 |
- &cert_filter);
|
|
|
bb7cd1 |
+ NULL, NULL, &cert_filter);
|
|
|
bb7cd1 |
if (ret != EOK) {
|
|
|
bb7cd1 |
DEBUG(SSSDBG_OP_FAILURE,
|
|
|
bb7cd1 |
"sss_cert_derb64_to_ldap_filter failed.\n");
|
|
|
bb7cd1 |
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
|
|
|
bb7cd1 |
index a8b4bc2cfc6e9d4e0d74b0e3e036afbcbf7eb26e..8e60769d09383ac8ebe33e5f64fd4fd9788e82cd 100644
|
|
|
bb7cd1 |
--- a/src/providers/ldap/ldap_id.c
|
|
|
bb7cd1 |
+++ b/src/providers/ldap/ldap_id.c
|
|
|
bb7cd1 |
@@ -247,7 +247,7 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
|
|
|
bb7cd1 |
}
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
ret = sss_cert_derb64_to_ldap_filter(state, filter_value, attr_name,
|
|
|
bb7cd1 |
- &user_filter);
|
|
|
bb7cd1 |
+ NULL, NULL, &user_filter);
|
|
|
bb7cd1 |
if (ret != EOK) {
|
|
|
bb7cd1 |
DEBUG(SSSDBG_OP_FAILURE,
|
|
|
bb7cd1 |
"sss_cert_derb64_to_ldap_filter failed.\n");
|
|
|
bb7cd1 |
diff --git a/src/tests/cmocka/test_cert_utils.c b/src/tests/cmocka/test_cert_utils.c
|
|
|
bb7cd1 |
index 35e8cb7513968079861048a7e8b0631229f202c0..5830131754e4cf318273151b586ef36d6a349829 100644
|
|
|
bb7cd1 |
--- a/src/tests/cmocka/test_cert_utils.c
|
|
|
bb7cd1 |
+++ b/src/tests/cmocka/test_cert_utils.c
|
|
|
bb7cd1 |
@@ -297,11 +297,11 @@ void test_sss_cert_derb64_to_ldap_filter(void **state)
|
|
|
bb7cd1 |
struct test_state *ts = talloc_get_type_abort(*state, struct test_state);
|
|
|
bb7cd1 |
assert_non_null(ts);
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
- ret = sss_cert_derb64_to_ldap_filter(ts, NULL, NULL, NULL);
|
|
|
bb7cd1 |
+ ret = sss_cert_derb64_to_ldap_filter(ts, NULL, NULL, NULL, NULL, NULL);
|
|
|
bb7cd1 |
assert_int_equal(ret, EINVAL);
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
ret = sss_cert_derb64_to_ldap_filter(ts, "AAECAwQFBgcICQ==", "attrName",
|
|
|
bb7cd1 |
- &filter);
|
|
|
bb7cd1 |
+ NULL, NULL, &filter);
|
|
|
bb7cd1 |
assert_int_equal(ret, EOK);
|
|
|
bb7cd1 |
assert_string_equal(filter,
|
|
|
bb7cd1 |
"(attrName=\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09)");
|
|
|
bb7cd1 |
diff --git a/src/util/cert.h b/src/util/cert.h
|
|
|
bb7cd1 |
index bb64d0d7a0a48207df60f6e6e554da5e16a16b03..4598aa8df0cd860fed71d9cd2e4beec7f1910578 100644
|
|
|
bb7cd1 |
--- a/src/util/cert.h
|
|
|
bb7cd1 |
+++ b/src/util/cert.h
|
|
|
bb7cd1 |
@@ -21,6 +21,7 @@
|
|
|
bb7cd1 |
#include <talloc.h>
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
#include "util/util.h"
|
|
|
bb7cd1 |
+#include "lib/certmap/sss_certmap.h"
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
#ifndef __CERT_H__
|
|
|
bb7cd1 |
#define __CERT_H__
|
|
|
bb7cd1 |
@@ -39,6 +40,8 @@ errno_t sss_cert_pem_to_derb64(TALLOC_CTX *mem_ctx, const char *pem,
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64,
|
|
|
bb7cd1 |
const char *attr_name,
|
|
|
bb7cd1 |
+ struct sss_certmap_ctx *certmap_ctx,
|
|
|
bb7cd1 |
+ struct sss_domain_info *dom,
|
|
|
bb7cd1 |
char **ldap_filter);
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
errno_t bin_to_ldap_filter_value(TALLOC_CTX *mem_ctx,
|
|
|
bb7cd1 |
diff --git a/src/util/cert/cert_common.c b/src/util/cert/cert_common.c
|
|
|
bb7cd1 |
index a29696ed3cd9f2168f47323fac97d44e9b49f921..766877089429ff1c01000a3986316c74583e3fa4 100644
|
|
|
bb7cd1 |
--- a/src/util/cert/cert_common.c
|
|
|
bb7cd1 |
+++ b/src/util/cert/cert_common.c
|
|
|
bb7cd1 |
@@ -72,12 +72,17 @@ errno_t sss_cert_pem_to_derb64(TALLOC_CTX *mem_ctx, const char *pem,
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64,
|
|
|
bb7cd1 |
const char *attr_name,
|
|
|
bb7cd1 |
+ struct sss_certmap_ctx *certmap_ctx,
|
|
|
bb7cd1 |
+ struct sss_domain_info *dom,
|
|
|
bb7cd1 |
char **ldap_filter)
|
|
|
bb7cd1 |
{
|
|
|
bb7cd1 |
int ret;
|
|
|
bb7cd1 |
unsigned char *der;
|
|
|
bb7cd1 |
size_t der_size;
|
|
|
bb7cd1 |
char *val;
|
|
|
bb7cd1 |
+ char *filter = NULL;
|
|
|
bb7cd1 |
+ char **domains = NULL;
|
|
|
bb7cd1 |
+ size_t c;
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
if (derb64 == NULL || attr_name == NULL) {
|
|
|
bb7cd1 |
return EINVAL;
|
|
|
bb7cd1 |
@@ -89,18 +94,67 @@ errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64,
|
|
|
bb7cd1 |
return EINVAL;
|
|
|
bb7cd1 |
}
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
- ret = bin_to_ldap_filter_value(mem_ctx, der, der_size, &val;;
|
|
|
bb7cd1 |
- talloc_free(der);
|
|
|
bb7cd1 |
- if (ret != EOK) {
|
|
|
bb7cd1 |
- DEBUG(SSSDBG_OP_FAILURE, "bin_to_ldap_filter_value failed.\n");
|
|
|
bb7cd1 |
- return ret;
|
|
|
bb7cd1 |
- }
|
|
|
bb7cd1 |
+ if (certmap_ctx == NULL) {
|
|
|
bb7cd1 |
+ ret = bin_to_ldap_filter_value(mem_ctx, der, der_size, &val;;
|
|
|
bb7cd1 |
+ talloc_free(der);
|
|
|
bb7cd1 |
+ if (ret != EOK) {
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_OP_FAILURE, "bin_to_ldap_filter_value failed.\n");
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
- *ldap_filter = talloc_asprintf(mem_ctx, "(%s=%s)", attr_name, val);
|
|
|
bb7cd1 |
- talloc_free(val);
|
|
|
bb7cd1 |
- if (*ldap_filter == NULL) {
|
|
|
bb7cd1 |
- DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
|
|
|
bb7cd1 |
- return ENOMEM;
|
|
|
bb7cd1 |
+ *ldap_filter = talloc_asprintf(mem_ctx, "(%s=%s)", attr_name, val);
|
|
|
bb7cd1 |
+ talloc_free(val);
|
|
|
bb7cd1 |
+ if (*ldap_filter == NULL) {
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
|
|
|
bb7cd1 |
+ return ENOMEM;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ } else {
|
|
|
bb7cd1 |
+ ret = sss_certmap_get_search_filter(certmap_ctx, der, der_size,
|
|
|
bb7cd1 |
+ &filter, &domains);
|
|
|
bb7cd1 |
+ talloc_free(der);
|
|
|
bb7cd1 |
+ if (ret != 0) {
|
|
|
bb7cd1 |
+ if (ret == ENOENT) {
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
bb7cd1 |
+ "Certificate does not match matching-rules.\n");
|
|
|
bb7cd1 |
+ } else {
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
bb7cd1 |
+ "sss_certmap_get_search_filter failed.\n");
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ } else {
|
|
|
bb7cd1 |
+ if (domains == NULL) {
|
|
|
bb7cd1 |
+ if (IS_SUBDOMAIN(dom)) {
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_TRACE_FUNC,
|
|
|
bb7cd1 |
+ "Rule applies only to local domain.\n");
|
|
|
bb7cd1 |
+ ret = ENOENT;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ } else {
|
|
|
bb7cd1 |
+ for (c = 0; domains[c] != NULL; c++) {
|
|
|
bb7cd1 |
+ if (strcasecmp(dom->name, domains[c]) == 0) {
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_TRACE_FUNC,
|
|
|
bb7cd1 |
+ "Rule applies to current domain [%s].\n",
|
|
|
bb7cd1 |
+ dom->name);
|
|
|
bb7cd1 |
+ ret = EOK;
|
|
|
bb7cd1 |
+ break;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ if (domains[c] == NULL) {
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_TRACE_FUNC,
|
|
|
bb7cd1 |
+ "Rule does not apply to current domain [%s].\n",
|
|
|
bb7cd1 |
+ dom->name);
|
|
|
bb7cd1 |
+ ret = ENOENT;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+
|
|
|
bb7cd1 |
+ if (ret == EOK) {
|
|
|
bb7cd1 |
+ *ldap_filter = talloc_strdup(mem_ctx, filter);
|
|
|
bb7cd1 |
+ if (*ldap_filter == NULL) {
|
|
|
bb7cd1 |
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_strdup failed.\n");
|
|
|
bb7cd1 |
+ ret = ENOMEM;
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ }
|
|
|
bb7cd1 |
+ sss_certmap_free_filter_and_domains(filter, domains);
|
|
|
bb7cd1 |
+ return ret;
|
|
|
bb7cd1 |
}
|
|
|
bb7cd1 |
|
|
|
bb7cd1 |
return EOK;
|
|
|
bb7cd1 |
--
|
|
|
bb7cd1 |
2.9.3
|
|
|
bb7cd1 |
|