[SSSD] [PATCHES] IFP: add FindByCertificate method for User objects
Sumit Bose
sbose at redhat.com
Thu Jun 11 11:08:53 UTC 2015
On Thu, Jun 04, 2015 at 12:31:34PM +0200, Pavel Březina wrote:
> On 06/04/2015 11:06 AM, Sumit Bose wrote:
> >Hi,
> >
> >this patch-set aims to solve https://fedorahosted.org/sssd/ticket/2596.
> >The first patch is unrelated but needed to make the changes in the
> >second patch properly aligned.
> >
> >Patches 3,4 and 6 add some certificate related utilities while patch 5
> >adds the backend changes and patch 7 the changes for InfoPipe.
> >
> >bye,
> >Sumit
Hi Pavel,
thank you for the review.
>
> >+errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx,
> >+ struct sss_domain_info *domain,
> >+ const char *cert,
> >+ const char **attrs,
> >+ struct ldb_result **res)
> >+{
> >+ int ret;
> >+ char *user_filter;
> >+
> >+ ret = sss_cert_derb64_to_ldap_filter(mem_ctx, cert, SYSDB_USER_CERT,
> >+ &user_filter);
> >+ if (ret != EOK) {
> >+ DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n");
> >+ return ret;
> >+ }
> >+
> vv two spaces here
fixed
> >+ ret = sysdb_search_object_by_str_attr(mem_ctx, domain,
> >+ SYSDB_USER_CERT_FILTER,
> >+ user_filter, attrs, res);
> >+ talloc_free(user_filter);
> >+
> >+ return ret;
> >+}
> >+
> >+errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx,
> >+ struct sss_domain_info *domain,
> >+ const char *cert,
> >+ struct ldb_result **res)
> >+{
> >+ const char *user_attrs[] = SYSDB_PW_ATTRS;
> >+
> >+ return sysdb_search_object_by_cert(mem_ctx, domain, cert, user_attrs, res);
> ^^ two spaces here
fixed
> >+}
>
> cache_req:
> >search_str = state->input->type == CACHE_REQ_USER_BY_CERT ?
> > state->input->orig_name : state->input->dom_objname;
>
> I think it will be better to create a new field in cache_req_input, say
> 'cert', to not abuse fields that resemble object names. The code will be
> cleaner and you can get rid of few parts like:
I added cert.
>
> > if (state->input->orig_name != NULL && domain == NULL
> > && (input->type == CACHE_REQ_USER_BY_NAME
> > || input->type == CACHE_REQ_GROUP_BY_NAME
> > || input->type == CACHE_REQ_INITGROUPS))
new version attached.
bye,
Sumit
>
> _______________________________________________
> sssd-devel mailing list
> sssd-devel at lists.fedorahosted.org
> https://lists.fedorahosted.org/mailman/listinfo/sssd-devel
-------------- next part --------------
From 278de9ff7a12eabdeabbeb6cae10f724442c58c2 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Thu, 7 May 2015 10:58:33 +0200
Subject: [PATCH 1/7] adding ldap_user_auth_type where missing
---
src/config/SSSDConfig/__init__.py.in | 2 ++
src/config/etc/sssd.api.d/sssd-ad.conf | 1 +
src/config/etc/sssd.api.d/sssd-ipa.conf | 1 +
src/config/etc/sssd.api.d/sssd-ldap.conf | 1 +
4 files changed, 5 insertions(+)
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index af7f1bffbd910c0dee177eb64996233ac18fff19..0654cb63bd93c616c85261555e4f38d9fc02ccb2 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -307,6 +307,8 @@ option_strings = {
'ldap_user_nds_login_expiration_time' : _('loginExpirationTime attribute of NDS'),
'ldap_user_nds_login_allowed_time_map' : _('loginAllowedTimeMap attribute of NDS'),
'ldap_user_ssh_public_key' : _('SSH public key attribute'),
+ 'ldap_user_auth_type' : _('attribute listing allowed authentication types for a user'),
+
'ldap_user_extra_attrs' : _('A list of extra attributes to download along with the user entry'),
'ldap_group_search_base' : _('Base DN for group lookups'),
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index c46f3a7cb50db519d113e15f425c7f746d34ad81..23194d38a35fcc9ae2134c3dbbc7cef1aefcf079 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -93,6 +93,7 @@ ldap_user_krb_last_pwd_change = str, None, false
ldap_user_krb_password_expiration = str, None, false
ldap_pwd_attribute = str, None, false
ldap_user_ssh_public_key = str, None, false
+ldap_user_auth_type = str, None, false
ldap_group_search_base = str, None, false
ldap_group_search_scope = str, None, false
ldap_group_search_filter = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 6bae609fa9ff57e70c195b858eeea4eca680f62f..075a74e3aabe4ff664814b8a1aef8117496e9273 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -89,6 +89,7 @@ ldap_user_krb_last_pwd_change = str, None, false
ldap_user_krb_password_expiration = str, None, false
ldap_pwd_attribute = str, None, false
ldap_user_ssh_public_key = str, None, false
+ldap_user_auth_type = str, None, false
ldap_group_search_base = str, None, false
ldap_group_search_scope = str, None, false
ldap_group_search_filter = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index ba5f56f1942da552fc6ab8f82851714756683a8f..e27d570b8cdf8ad765d16b8f8befe5c25fbebc28 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -83,6 +83,7 @@ ldap_user_nds_login_disabled = str, None, false
ldap_user_nds_login_expiration_time = str, None, false
ldap_user_nds_login_allowed_time_map = str, None, false
ldap_user_ssh_public_key = str, None, false
+ldap_user_auth_type = str, None, false
ldap_group_search_base = str, None, false
ldap_group_search_scope = str, None, false
ldap_group_search_filter = str, None, false
--
2.1.0
-------------- next part --------------
From 3f7fe04eeb54238896162a43986477f7598021f1 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Thu, 7 May 2015 10:59:10 +0200
Subject: [PATCH 2/7] LDAP: add ldap_user_certificate option
Related to https://fedorahosted.org/sssd/ticket/2596
---
src/config/SSSDConfig/__init__.py.in | 1 +
src/config/etc/sssd.api.d/sssd-ad.conf | 1 +
src/config/etc/sssd.api.d/sssd-ipa.conf | 1 +
src/config/etc/sssd.api.d/sssd-ldap.conf | 1 +
src/db/sysdb.h | 1 +
src/man/sssd-ldap.5.xml | 14 ++++++++++++++
src/providers/ad/ad_opts.h | 1 +
src/providers/ipa/ipa_opts.h | 1 +
src/providers/ldap/ldap_opts.h | 3 +++
src/providers/ldap/sdap.h | 1 +
10 files changed, 25 insertions(+)
diff --git a/src/config/SSSDConfig/__init__.py.in b/src/config/SSSDConfig/__init__.py.in
index 0654cb63bd93c616c85261555e4f38d9fc02ccb2..f2d9bf0190745d4a5296c56212e5ff97681db59c 100644
--- a/src/config/SSSDConfig/__init__.py.in
+++ b/src/config/SSSDConfig/__init__.py.in
@@ -308,6 +308,7 @@ option_strings = {
'ldap_user_nds_login_allowed_time_map' : _('loginAllowedTimeMap attribute of NDS'),
'ldap_user_ssh_public_key' : _('SSH public key attribute'),
'ldap_user_auth_type' : _('attribute listing allowed authentication types for a user'),
+ 'ldap_user_certificate' : _('attribute containing the X509 certificate of the user'),
'ldap_user_extra_attrs' : _('A list of extra attributes to download along with the user entry'),
diff --git a/src/config/etc/sssd.api.d/sssd-ad.conf b/src/config/etc/sssd.api.d/sssd-ad.conf
index 23194d38a35fcc9ae2134c3dbbc7cef1aefcf079..faab3a51e54d6d498392021a8945501120870f70 100644
--- a/src/config/etc/sssd.api.d/sssd-ad.conf
+++ b/src/config/etc/sssd.api.d/sssd-ad.conf
@@ -94,6 +94,7 @@ ldap_user_krb_password_expiration = str, None, false
ldap_pwd_attribute = str, None, false
ldap_user_ssh_public_key = str, None, false
ldap_user_auth_type = str, None, false
+ldap_user_certificate = str, None, false
ldap_group_search_base = str, None, false
ldap_group_search_scope = str, None, false
ldap_group_search_filter = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ipa.conf b/src/config/etc/sssd.api.d/sssd-ipa.conf
index 075a74e3aabe4ff664814b8a1aef8117496e9273..cfcc00f6f7ca768df861e8cf7face065f90e9e83 100644
--- a/src/config/etc/sssd.api.d/sssd-ipa.conf
+++ b/src/config/etc/sssd.api.d/sssd-ipa.conf
@@ -90,6 +90,7 @@ ldap_user_krb_password_expiration = str, None, false
ldap_pwd_attribute = str, None, false
ldap_user_ssh_public_key = str, None, false
ldap_user_auth_type = str, None, false
+ldap_user_certificate = str, None, false
ldap_group_search_base = str, None, false
ldap_group_search_scope = str, None, false
ldap_group_search_filter = str, None, false
diff --git a/src/config/etc/sssd.api.d/sssd-ldap.conf b/src/config/etc/sssd.api.d/sssd-ldap.conf
index e27d570b8cdf8ad765d16b8f8befe5c25fbebc28..c10290217b1b133792b893d9b80e2599969838a6 100644
--- a/src/config/etc/sssd.api.d/sssd-ldap.conf
+++ b/src/config/etc/sssd.api.d/sssd-ldap.conf
@@ -84,6 +84,7 @@ ldap_user_nds_login_expiration_time = str, None, false
ldap_user_nds_login_allowed_time_map = str, None, false
ldap_user_ssh_public_key = str, None, false
ldap_user_auth_type = str, None, false
+ldap_user_certificate = str, None, false
ldap_group_search_base = str, None, false
ldap_group_search_scope = str, None, false
ldap_group_search_filter = str, None, false
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 4035a39d3cd37390259cda79e6fcafe688bfd360..361d26d37481c521e93584b23af48a0861296e1f 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -132,6 +132,7 @@
#define SYSDB_SSH_PUBKEY "sshPublicKey"
#define SYSDB_AUTH_TYPE "authType"
+#define SYSDB_USER_CERT "userCertificate"
#define SYSDB_SUBDOMAIN_REALM "realmName"
#define SYSDB_SUBDOMAIN_FLAT "flatName"
diff --git a/src/man/sssd-ldap.5.xml b/src/man/sssd-ldap.5.xml
index 1b7a2609ac4ebd0bccfd15a04d041e283bcf9cab..f14090843fd32141ad4f491b69868aa7b2412301 100644
--- a/src/man/sssd-ldap.5.xml
+++ b/src/man/sssd-ldap.5.xml
@@ -814,6 +814,20 @@
</varlistentry>
<varlistentry>
+ <term>ldap_user_certificate (string)</term>
+ <listitem>
+ <para>
+ Name of the LDAP attribute containing the X509
+ certificate of the user.
+ </para>
+ <para>
+ Default: no set in the general case, userCertificate
+ for IPA
+ </para>
+ </listitem>
+ </varlistentry>
+
+ <varlistentry>
<term>ldap_group_object_class (string)</term>
<listitem>
<para>
diff --git a/src/providers/ad/ad_opts.h b/src/providers/ad/ad_opts.h
index 0f03d33839affe1381fd5eb72bfeba6e5b1dcc68..cb4c05d846d9abe5eedb28013ad13fff6476d431 100644
--- a/src/providers/ad/ad_opts.h
+++ b/src/providers/ad/ad_opts.h
@@ -216,6 +216,7 @@ struct sdap_attr_map ad_2008r2_user_map[] = {
{ "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
{ "ldap_user_ssh_public_key", NULL, SYSDB_SSH_PUBKEY, NULL },
{ "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL },
+ { "ldap_user_certificate", NULL, SYSDB_USER_CERT, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ipa/ipa_opts.h b/src/providers/ipa/ipa_opts.h
index 34e9e167eb46f290d017b5af817571122b359b4f..253c0715355536cc181c57beed5326a77e87e464 100644
--- a/src/providers/ipa/ipa_opts.h
+++ b/src/providers/ipa/ipa_opts.h
@@ -203,6 +203,7 @@ struct sdap_attr_map ipa_user_map[] = {
{ "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
{ "ldap_user_ssh_public_key", "ipaSshPubKey", SYSDB_SSH_PUBKEY, NULL },
{ "ldap_user_auth_type", "ipaUserAuthType", SYSDB_AUTH_TYPE, NULL },
+ { "ldap_user_certificate", "userCertificate", SYSDB_USER_CERT, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ldap/ldap_opts.h b/src/providers/ldap/ldap_opts.h
index f449ec7c309a5f664941cdefbb3c45a2fab10c99..c1b9bf688ef0a92046195c13a11d2c17b2419d67 100644
--- a/src/providers/ldap/ldap_opts.h
+++ b/src/providers/ldap/ldap_opts.h
@@ -180,6 +180,7 @@ struct sdap_attr_map rfc2307_user_map[] = {
{ "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
{ "ldap_user_ssh_public_key", "sshPublicKey", SYSDB_SSH_PUBKEY, NULL },
{ "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL },
+ { "ldap_user_certificate", NULL, SYSDB_USER_CERT, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
@@ -235,6 +236,7 @@ struct sdap_attr_map rfc2307bis_user_map[] = {
{ "ldap_user_nds_login_allowed_time_map", "loginAllowedTimeMap", SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
{ "ldap_user_ssh_public_key", "sshPublicKey", SYSDB_SSH_PUBKEY, NULL },
{ "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL },
+ { "ldap_user_certificate", NULL, SYSDB_USER_CERT, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
@@ -290,6 +292,7 @@ struct sdap_attr_map gen_ad2008r2_user_map[] = {
{ "ldap_user_nds_login_allowed_time_map", NULL, SYSDB_NDS_LOGIN_ALLOWED_TIME_MAP, NULL },
{ "ldap_user_ssh_public_key", NULL, SYSDB_SSH_PUBKEY, NULL },
{ "ldap_user_auth_type", NULL, SYSDB_AUTH_TYPE, NULL },
+ { "ldap_user_certificate", NULL, SYSDB_USER_CERT, NULL },
SDAP_ATTR_MAP_TERMINATOR
};
diff --git a/src/providers/ldap/sdap.h b/src/providers/ldap/sdap.h
index 6612ab200d7ee34be29512ba8df2744ab2a7ecd8..d9b2d18637bdb3e7823af9d1de2c042c8134780f 100644
--- a/src/providers/ldap/sdap.h
+++ b/src/providers/ldap/sdap.h
@@ -281,6 +281,7 @@ enum sdap_user_attrs {
SDAP_AT_NDS_LOGIN_ALLOWED_TIME_MAP,
SDAP_AT_USER_SSH_PUBLIC_KEY,
SDAP_AT_USER_AUTH_TYPE,
+ SDAP_AT_USER_CERT,
SDAP_OPTS_USER /* attrs counter */
};
--
2.1.0
-------------- next part --------------
From a6136a1e40520784e1e9755c81df20bdae03e581 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Fri, 8 May 2015 09:02:26 +0200
Subject: [PATCH 3/7] certs: add PEM/DER conversion utilities
Related to https://fedorahosted.org/sssd/ticket/2596
---
Makefile.am | 33 ++++
configure.ac | 5 +-
src/tests/cmocka/test_cert_utils.c | 361 +++++++++++++++++++++++++++++++++++++
src/util/cert.h | 47 +++++
src/util/cert/cert_common.c | 154 ++++++++++++++++
src/util/cert/libcrypto/cert.c | 168 +++++++++++++++++
6 files changed, 765 insertions(+), 3 deletions(-)
create mode 100644 src/tests/cmocka/test_cert_utils.c
create mode 100644 src/util/cert.h
create mode 100644 src/util/cert/cert_common.c
create mode 100644 src/util/cert/libcrypto/cert.c
diff --git a/Makefile.am b/Makefile.am
index 34c18ebbf8f75abee0200892c395c9601b570472..303dd44e1e0e3e66c8d2739051a9d5d63bf8e075 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -225,6 +225,7 @@ if HAVE_CMOCKA
test_sbus_opath \
test_fo_srv \
pam-srv-tests \
+ test_cert_utils \
$(NULL)
if HAVE_LIBRESOLV
@@ -495,6 +496,7 @@ endif
dist_noinst_HEADERS = \
src/monitor/monitor.h \
src/util/crypto/sss_crypto.h \
+ src/util/cert.h \
src/util/dlinklist.h \
src/util/util.h \
src/util/io.h \
@@ -716,6 +718,23 @@ libsss_crypt_la_LIBADD = \
libsss_crypt_la_LDFLAGS = \
-avoid-version
+pkglib_LTLIBRARIES += libsss_cert.la
+
+libsss_cert_la_SOURCES = \
+ src/util/cert/cert_common.c \
+ src/util/cert/libcrypto/cert.c \
+ $(NULL)
+libsss_cert_la_CFLAGS = \
+ $(CRYPTO_CFLAGS) \
+ $(NULL)
+libsss_cert_la_LIBADD = \
+ $(CRYPTO_LIBS) \
+ libsss_crypt.la \
+ $(NULL)
+libsss_cert_la_LDFLAGS = \
+ -avoid-version \
+ $(NULL)
+
pkglib_LTLIBRARIES += libsss_util.la
libsss_util_la_SOURCES = \
src/confdb/confdb.c \
@@ -2405,6 +2424,20 @@ test_fo_srv_LDADD = \
libsss_test_common.la \
$(NULL)
+test_cert_utils_SOURCES = \
+ src/tests/cmocka/test_cert_utils.c \
+ $(NULL)
+test_cert_utils_CFLAGS = \
+ $(AM_CFLAGS) \
+ $(NULL)
+test_cert_utils_LDADD = \
+ $(CMOCKA_LIBS) \
+ $(POPT_LIBS) \
+ $(TALLOC_LIBS) \
+ libsss_debug.la \
+ libsss_test_common.la \
+ libsss_cert.la \
+ $(NULL)
endif # HAVE_CMOCKA
noinst_PROGRAMS = pam_test_client
diff --git a/configure.ac b/configure.ac
index a127d0bd57ee4149f664e193a65271d50d95f83b..d1c6ba35f6deed327ca8305cc567b77b9a9be5d6 100644
--- a/configure.ac
+++ b/configure.ac
@@ -339,9 +339,8 @@ fi
if test x$cryptolib = xnss; then
AM_CHECK_NSS
fi
-if test x$cryptolib = xlibcrypto; then
- AM_CHECK_LIBCRYPTO
-fi
+
+AM_CHECK_LIBCRYPTO
AM_CHECK_INOTIFY
diff --git a/src/tests/cmocka/test_cert_utils.c b/src/tests/cmocka/test_cert_utils.c
new file mode 100644
index 0000000000000000000000000000000000000000..5bcbafb27dbdff596c07b8aad10ca15a35ff4ef5
--- /dev/null
+++ b/src/tests/cmocka/test_cert_utils.c
@@ -0,0 +1,361 @@
+/*
+ SSSD
+
+ Certificates - Utilities tests
+
+ Authors:
+ Sumit Bose <sbose at redhat.com>
+
+ Copyright (C) 2015 Red Hat
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <popt.h>
+#include <openssl/objects.h>
+
+#include "util/cert.h"
+#include "tests/cmocka/common_mock.h"
+#include "util/crypto/nss/nss_util.h"
+
+
+/* TODO: create a certificate for this test */
+const uint8_t test_cert_der[] = {
+0x30, 0x82, 0x04, 0x09, 0x30, 0x82, 0x02, 0xf1, 0xa0, 0x03, 0x02, 0x01, 0x02, 0x02, 0x01, 0x09,
+0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x30,
+0x34, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a, 0x0c, 0x09, 0x49, 0x50, 0x41, 0x2e,
+0x44, 0x45, 0x56, 0x45, 0x4c, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03, 0x55, 0x04, 0x03, 0x0c, 0x15,
+0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65, 0x20, 0x41, 0x75, 0x74, 0x68,
+0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1e, 0x17, 0x0d, 0x31, 0x35, 0x30, 0x34, 0x32, 0x38, 0x31,
+0x30, 0x32, 0x31, 0x31, 0x31, 0x5a, 0x17, 0x0d, 0x31, 0x37, 0x30, 0x34, 0x32, 0x38, 0x31, 0x30,
+0x32, 0x31, 0x31, 0x31, 0x5a, 0x30, 0x32, 0x31, 0x12, 0x30, 0x10, 0x06, 0x03, 0x55, 0x04, 0x0a,
+0x0c, 0x09, 0x49, 0x50, 0x41, 0x2e, 0x44, 0x45, 0x56, 0x45, 0x4c, 0x31, 0x1c, 0x30, 0x1a, 0x06,
+0x03, 0x55, 0x04, 0x03, 0x0c, 0x13, 0x69, 0x70, 0x61, 0x2d, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x2e,
+0x69, 0x70, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x30, 0x82, 0x01, 0x22, 0x30, 0x0d, 0x06,
+0x09, 0x2a, 0x86, 0x48, 0x86, 0xf7, 0x0d, 0x01, 0x01, 0x01, 0x05, 0x00, 0x03, 0x82, 0x01, 0x0f,
+0x00, 0x30, 0x82, 0x01, 0x0a, 0x02, 0x82, 0x01, 0x01, 0x00, 0xb2, 0x32, 0x92, 0xab, 0x47, 0xb8,
+0x0c, 0x13, 0x54, 0x4a, 0x1f, 0x1e, 0x29, 0x06, 0xff, 0xd0, 0x50, 0xcb, 0xf7, 0x5f, 0x79, 0x91,
+0x65, 0xb1, 0x39, 0x01, 0x83, 0x6a, 0xad, 0x9e, 0x77, 0x3b, 0xf3, 0x0d, 0xd7, 0xb9, 0xf6, 0xdc,
+0x9e, 0x4a, 0x49, 0xa7, 0xd0, 0x66, 0x72, 0xcc, 0xbf, 0x77, 0xd6, 0xde, 0xa9, 0xfe, 0x67, 0x96,
+0xcc, 0x49, 0xf1, 0x37, 0x23, 0x2e, 0xc4, 0x50, 0xf4, 0xeb, 0xba, 0x62, 0xd4, 0x23, 0x4d, 0xf3,
+0x37, 0x38, 0x82, 0xee, 0x3b, 0x3f, 0x2c, 0xd0, 0x80, 0x9b, 0x17, 0xaa, 0x9b, 0xeb, 0xa6, 0xdd,
+0xf6, 0x15, 0xff, 0x06, 0xb2, 0xce, 0xff, 0xdf, 0x8a, 0x9e, 0x95, 0x85, 0x49, 0x1f, 0x84, 0xfd,
+0x81, 0x26, 0xce, 0x06, 0x32, 0x0d, 0x36, 0xca, 0x7c, 0x15, 0x81, 0x68, 0x6b, 0x8f, 0x3e, 0xb3,
+0xa2, 0xfc, 0xae, 0xaf, 0xc2, 0x44, 0x58, 0x15, 0x95, 0x40, 0xfc, 0x56, 0x19, 0x91, 0x80, 0xed,
+0x42, 0x11, 0x66, 0x04, 0xef, 0x3c, 0xe0, 0x76, 0x33, 0x4b, 0x83, 0xfa, 0x7e, 0xb4, 0x47, 0xdc,
+0xfb, 0xed, 0x46, 0xa5, 0x8d, 0x0a, 0x66, 0x87, 0xa5, 0xef, 0x7b, 0x74, 0x62, 0xac, 0xbe, 0x73,
+0x36, 0xc9, 0xb4, 0xfe, 0x20, 0xc4, 0x81, 0xf3, 0xfe, 0x78, 0x19, 0xa8, 0xd0, 0xaf, 0x7f, 0x81,
+0x72, 0x24, 0x61, 0xd9, 0x76, 0x93, 0xe3, 0x0b, 0xd2, 0x4f, 0x19, 0x17, 0x33, 0x57, 0xd4, 0x82,
+0xb0, 0xf1, 0xa8, 0x03, 0xf6, 0x01, 0x99, 0xa9, 0xb8, 0x8c, 0x83, 0xc9, 0xba, 0x19, 0x87, 0xea,
+0xd6, 0x3b, 0x06, 0xeb, 0x4c, 0xf7, 0xf1, 0xe5, 0x28, 0xa9, 0x10, 0xb6, 0x46, 0xde, 0xe1, 0xe1,
+0x3f, 0xc1, 0xcc, 0x72, 0xbe, 0x2a, 0x43, 0xc6, 0xf6, 0xd0, 0xb5, 0xa0, 0xc4, 0x24, 0x6e, 0x4f,
+0xbd, 0xec, 0x22, 0x8a, 0x07, 0x11, 0x3d, 0xf9, 0xd3, 0x15, 0x02, 0x03, 0x01, 0x00, 0x01, 0xa3,
+0x82, 0x01, 0x26, 0x30, 0x82, 0x01, 0x22, 0x30, 0x1f, 0x06, 0x03, 0x55, 0x1d, 0x23, 0x04, 0x18,
+0x30, 0x16, 0x80, 0x14, 0xf2, 0x9d, 0x42, 0x4e, 0x0f, 0xc4, 0x48, 0x25, 0x58, 0x2f, 0x1c, 0xce,
+0x0f, 0xa1, 0x3f, 0x22, 0xc8, 0x55, 0xc8, 0x91, 0x30, 0x3b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+0x05, 0x07, 0x01, 0x01, 0x04, 0x2f, 0x30, 0x2d, 0x30, 0x2b, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+0x05, 0x07, 0x30, 0x01, 0x86, 0x1f, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x70, 0x61,
+0x2d, 0x63, 0x61, 0x2e, 0x69, 0x70, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x2f, 0x63, 0x61,
+0x2f, 0x6f, 0x63, 0x73, 0x70, 0x30, 0x0e, 0x06, 0x03, 0x55, 0x1d, 0x0f, 0x01, 0x01, 0xff, 0x04,
+0x04, 0x03, 0x02, 0x04, 0xf0, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d, 0x25, 0x04, 0x16, 0x30, 0x14,
+0x06, 0x08, 0x2b, 0x06, 0x01, 0x05, 0x05, 0x07, 0x03, 0x01, 0x06, 0x08, 0x2b, 0x06, 0x01, 0x05,
+0x05, 0x07, 0x03, 0x02, 0x30, 0x74, 0x06, 0x03, 0x55, 0x1d, 0x1f, 0x04, 0x6d, 0x30, 0x6b, 0x30,
+0x69, 0xa0, 0x31, 0xa0, 0x2f, 0x86, 0x2d, 0x68, 0x74, 0x74, 0x70, 0x3a, 0x2f, 0x2f, 0x69, 0x70,
+0x61, 0x2d, 0x63, 0x61, 0x2e, 0x69, 0x70, 0x61, 0x2e, 0x64, 0x65, 0x76, 0x65, 0x6c, 0x2f, 0x69,
+0x70, 0x61, 0x2f, 0x63, 0x72, 0x6c, 0x2f, 0x4d, 0x61, 0x73, 0x74, 0x65, 0x72, 0x43, 0x52, 0x4c,
+0x2e, 0x62, 0x69, 0x6e, 0xa2, 0x34, 0xa4, 0x32, 0x30, 0x30, 0x31, 0x0e, 0x30, 0x0c, 0x06, 0x03,
+0x55, 0x04, 0x0a, 0x0c, 0x05, 0x69, 0x70, 0x61, 0x63, 0x61, 0x31, 0x1e, 0x30, 0x1c, 0x06, 0x03,
+0x55, 0x04, 0x03, 0x0c, 0x15, 0x43, 0x65, 0x72, 0x74, 0x69, 0x66, 0x69, 0x63, 0x61, 0x74, 0x65,
+0x20, 0x41, 0x75, 0x74, 0x68, 0x6f, 0x72, 0x69, 0x74, 0x79, 0x30, 0x1d, 0x06, 0x03, 0x55, 0x1d,
+0x0e, 0x04, 0x16, 0x04, 0x14, 0x2d, 0x2b, 0x3f, 0xcb, 0xf5, 0xb2, 0xff, 0x32, 0x2c, 0xa8, 0xc2,
+0x1c, 0xdd, 0xbd, 0x8c, 0x80, 0x1e, 0xdd, 0x31, 0x82, 0x30, 0x0d, 0x06, 0x09, 0x2a, 0x86, 0x48,
+0x86, 0xf7, 0x0d, 0x01, 0x01, 0x0b, 0x05, 0x00, 0x03, 0x82, 0x01, 0x01, 0x00, 0x9a, 0x47, 0x2e,
+0x50, 0xa7, 0x4d, 0x1d, 0x53, 0x0f, 0xc9, 0x71, 0x42, 0x0c, 0xe5, 0xda, 0x7d, 0x49, 0x64, 0xe7,
+0xab, 0xc8, 0xdf, 0xdf, 0x02, 0xc1, 0x87, 0xd1, 0x5b, 0xde, 0xda, 0x6f, 0x2b, 0xe4, 0xf0, 0xbe,
+0xba, 0x09, 0xdf, 0x02, 0x85, 0x0b, 0x8a, 0xe6, 0x9b, 0x06, 0x7d, 0x69, 0x38, 0x6c, 0x72, 0xff,
+0x4c, 0x7b, 0x2a, 0x0d, 0x3f, 0x23, 0x2f, 0x16, 0x46, 0xff, 0x05, 0x93, 0xb0, 0xea, 0x24, 0x28,
+0xd7, 0x12, 0xa1, 0x57, 0xb8, 0x59, 0x19, 0x25, 0xf3, 0x43, 0x0a, 0xd3, 0xfd, 0x0f, 0x37, 0x8d,
+0xb8, 0xca, 0x15, 0xe7, 0x48, 0x8a, 0xa0, 0xc7, 0xc7, 0x4b, 0x7f, 0x01, 0x3c, 0x58, 0xd7, 0x37,
+0xe5, 0xff, 0x7d, 0x2b, 0x01, 0xac, 0x0d, 0x9f, 0x51, 0x6a, 0xe5, 0x40, 0x24, 0xe6, 0x5e, 0x55,
+0x0d, 0xf7, 0xb8, 0x2f, 0x42, 0xac, 0x6d, 0xe5, 0x29, 0x6b, 0xc6, 0x0b, 0xa4, 0xbf, 0x19, 0xbd,
+0x39, 0x27, 0xee, 0xfe, 0xc5, 0xb3, 0xdb, 0x62, 0xd4, 0xbe, 0xd2, 0x47, 0xba, 0x96, 0x30, 0x5a,
+0xfd, 0x62, 0x00, 0xb8, 0x27, 0x5d, 0x2f, 0x3a, 0x94, 0x0b, 0x95, 0x35, 0x85, 0x40, 0x2c, 0xbc,
+0x67, 0xdf, 0x8a, 0xf9, 0xf1, 0x7b, 0x19, 0x96, 0x3e, 0x42, 0x48, 0x13, 0x23, 0x04, 0x95, 0xa9,
+0x6b, 0x11, 0x33, 0x81, 0x47, 0x5a, 0x83, 0x72, 0xf6, 0x20, 0xfa, 0x8e, 0x41, 0x7b, 0x8f, 0x77,
+0x47, 0x7c, 0xc7, 0x5d, 0x46, 0xf4, 0x4f, 0xfd, 0x81, 0x0a, 0xae, 0x39, 0x27, 0xb6, 0x6a, 0x26,
+0x63, 0xb1, 0xd3, 0xbf, 0x55, 0x83, 0x82, 0x9b, 0x36, 0x6c, 0x33, 0x64, 0x0f, 0x50, 0xc0, 0x55,
+0x94, 0x13, 0xc3, 0x85, 0xf4, 0xd5, 0x71, 0x65, 0xd0, 0xc0, 0xdd, 0xfc, 0xe6, 0xec, 0x9c, 0x5b,
+0xf0, 0x11, 0xb5, 0x2c, 0xf3, 0x48, 0xc1, 0x36, 0x8c, 0xa2, 0x96, 0x48, 0x84};
+
+#define TEST_CERT_PEM "-----BEGIN CERTIFICATE-----\n" \
+"MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu\n" \
+"REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA0Mjgx\n" \
+"MDIxMTFaFw0xNzA0MjgxMDIxMTFaMDIxEjAQBgNVBAoMCUlQQS5ERVZFTDEcMBoG\n" \
+"A1UEAwwTaXBhLWRldmVsLmlwYS5kZXZlbDCCASIwDQYJKoZIhvcNAQEBBQADggEP\n" \
+"ADCCAQoCggEBALIykqtHuAwTVEofHikG/9BQy/dfeZFlsTkBg2qtnnc78w3Xufbc\n" \
+"nkpJp9Bmcsy/d9beqf5nlsxJ8TcjLsRQ9Ou6YtQjTfM3OILuOz8s0ICbF6qb66bd\n" \
+"9hX/BrLO/9+KnpWFSR+E/YEmzgYyDTbKfBWBaGuPPrOi/K6vwkRYFZVA/FYZkYDt\n" \
+"QhFmBO884HYzS4P6frRH3PvtRqWNCmaHpe97dGKsvnM2ybT+IMSB8/54GajQr3+B\n" \
+"ciRh2XaT4wvSTxkXM1fUgrDxqAP2AZmpuIyDyboZh+rWOwbrTPfx5SipELZG3uHh\n" \
+"P8HMcr4qQ8b20LWgxCRuT73sIooHET350xUCAwEAAaOCASYwggEiMB8GA1UdIwQY\n" \
+"MBaAFPKdQk4PxEglWC8czg+hPyLIVciRMDsGCCsGAQUFBwEBBC8wLTArBggrBgEF\n" \
+"BQcwAYYfaHR0cDovL2lwYS1jYS5pcGEuZGV2ZWwvY2Evb2NzcDAOBgNVHQ8BAf8E\n" \
+"BAMCBPAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHQGA1UdHwRtMGsw\n" \
+"aaAxoC+GLWh0dHA6Ly9pcGEtY2EuaXBhLmRldmVsL2lwYS9jcmwvTWFzdGVyQ1JM\n" \
+"LmJpbqI0pDIwMDEOMAwGA1UECgwFaXBhY2ExHjAcBgNVBAMMFUNlcnRpZmljYXRl\n" \
+"IEF1dGhvcml0eTAdBgNVHQ4EFgQULSs/y/Wy/zIsqMIc3b2MgB7dMYIwDQYJKoZI\n" \
+"hvcNAQELBQADggEBAJpHLlCnTR1TD8lxQgzl2n1JZOeryN/fAsGH0Vve2m8r5PC+\n" \
+"ugnfAoULiuabBn1pOGxy/0x7Kg0/Iy8WRv8Fk7DqJCjXEqFXuFkZJfNDCtP9DzeN\n" \
+"uMoV50iKoMfHS38BPFjXN+X/fSsBrA2fUWrlQCTmXlUN97gvQqxt5Slrxgukvxm9\n" \
+"OSfu/sWz22LUvtJHupYwWv1iALgnXS86lAuVNYVALLxn34r58XsZlj5CSBMjBJWp\n" \
+"axEzgUdag3L2IPqOQXuPd0d8x11G9E/9gQquOSe2aiZjsdO/VYOCmzZsM2QPUMBV\n" \
+"lBPDhfTVcWXQwN385uycW/ARtSzzSME2jKKWSIQ=\n" \
+"-----END CERTIFICATE-----\n"
+
+#define TEST_CERT_DERB64 \
+"MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEu" \
+"REVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA0Mjgx" \
+"MDIxMTFaFw0xNzA0MjgxMDIxMTFaMDIxEjAQBgNVBAoMCUlQQS5ERVZFTDEcMBoG" \
+"A1UEAwwTaXBhLWRldmVsLmlwYS5kZXZlbDCCASIwDQYJKoZIhvcNAQEBBQADggEP" \
+"ADCCAQoCggEBALIykqtHuAwTVEofHikG/9BQy/dfeZFlsTkBg2qtnnc78w3Xufbc" \
+"nkpJp9Bmcsy/d9beqf5nlsxJ8TcjLsRQ9Ou6YtQjTfM3OILuOz8s0ICbF6qb66bd" \
+"9hX/BrLO/9+KnpWFSR+E/YEmzgYyDTbKfBWBaGuPPrOi/K6vwkRYFZVA/FYZkYDt" \
+"QhFmBO884HYzS4P6frRH3PvtRqWNCmaHpe97dGKsvnM2ybT+IMSB8/54GajQr3+B" \
+"ciRh2XaT4wvSTxkXM1fUgrDxqAP2AZmpuIyDyboZh+rWOwbrTPfx5SipELZG3uHh" \
+"P8HMcr4qQ8b20LWgxCRuT73sIooHET350xUCAwEAAaOCASYwggEiMB8GA1UdIwQY" \
+"MBaAFPKdQk4PxEglWC8czg+hPyLIVciRMDsGCCsGAQUFBwEBBC8wLTArBggrBgEF" \
+"BQcwAYYfaHR0cDovL2lwYS1jYS5pcGEuZGV2ZWwvY2Evb2NzcDAOBgNVHQ8BAf8E" \
+"BAMCBPAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHQGA1UdHwRtMGsw" \
+"aaAxoC+GLWh0dHA6Ly9pcGEtY2EuaXBhLmRldmVsL2lwYS9jcmwvTWFzdGVyQ1JM" \
+"LmJpbqI0pDIwMDEOMAwGA1UECgwFaXBhY2ExHjAcBgNVBAMMFUNlcnRpZmljYXRl" \
+"IEF1dGhvcml0eTAdBgNVHQ4EFgQULSs/y/Wy/zIsqMIc3b2MgB7dMYIwDQYJKoZI" \
+"hvcNAQELBQADggEBAJpHLlCnTR1TD8lxQgzl2n1JZOeryN/fAsGH0Vve2m8r5PC+" \
+"ugnfAoULiuabBn1pOGxy/0x7Kg0/Iy8WRv8Fk7DqJCjXEqFXuFkZJfNDCtP9DzeN" \
+"uMoV50iKoMfHS38BPFjXN+X/fSsBrA2fUWrlQCTmXlUN97gvQqxt5Slrxgukvxm9" \
+"OSfu/sWz22LUvtJHupYwWv1iALgnXS86lAuVNYVALLxn34r58XsZlj5CSBMjBJWp" \
+"axEzgUdag3L2IPqOQXuPd0d8x11G9E/9gQquOSe2aiZjsdO/VYOCmzZsM2QPUMBV" \
+"lBPDhfTVcWXQwN385uycW/ARtSzzSME2jKKWSIQ="
+
+struct test_state {
+ void *dummy;
+};
+
+static int setup(void **state)
+{
+ struct test_state *ts = NULL;
+
+ assert_true(leak_check_setup());
+
+ ts = talloc(global_talloc_context, struct test_state);
+ assert_non_null(ts);
+
+ check_leaks_push(ts);
+ *state = (void *)ts;
+ return 0;
+}
+
+static int teardown(void **state)
+{
+ struct test_state *ts = talloc_get_type_abort(*state, struct test_state);
+
+ assert_non_null(ts);
+
+ assert_true(check_leaks_pop(ts));
+ talloc_free(ts);
+ assert_true(leak_check_teardown());
+ return 0;
+}
+
+void test_sss_cert_der_to_pem(void **state)
+{
+ int ret;
+ char *pem_str;
+ size_t pem_size;
+ struct test_state *ts = talloc_get_type_abort(*state, struct test_state);
+ assert_non_null(ts);
+
+ ret = sss_cert_der_to_pem(NULL, NULL, 0, NULL, NULL);
+ assert_int_equal(ret, EINVAL);
+
+ ret = sss_cert_der_to_pem(ts, test_cert_der, sizeof(test_cert_der),
+ &pem_str, &pem_size);
+ assert_int_equal(ret, EOK);
+ assert_int_equal(sizeof(TEST_CERT_PEM) - 1, pem_size);
+ assert_string_equal(pem_str, TEST_CERT_PEM);
+
+ talloc_free(pem_str);
+}
+
+void test_sss_cert_pem_to_der(void **state)
+{
+ int ret;
+ uint8_t *der;
+ size_t der_size;
+ struct test_state *ts = talloc_get_type_abort(*state, struct test_state);
+ assert_non_null(ts);
+
+ ret = sss_cert_pem_to_der(NULL, NULL, NULL, NULL);
+ assert_int_equal(ret, EINVAL);
+
+ ret = sss_cert_pem_to_der(ts, TEST_CERT_PEM, &der, &der_size);
+ assert_int_equal(ret, EOK);
+ assert_int_equal(sizeof(test_cert_der), der_size);
+ assert_memory_equal(der, test_cert_der, der_size);
+
+ talloc_free(der);
+}
+
+void test_sss_cert_derb64_to_pem(void **state)
+{
+ int ret;
+ char *pem_str;
+ size_t pem_size;
+ struct test_state *ts = talloc_get_type_abort(*state, struct test_state);
+ assert_non_null(ts);
+
+ ret = sss_cert_derb64_to_pem(NULL, NULL, NULL, NULL);
+ assert_int_equal(ret, EINVAL);
+
+ ret = sss_cert_derb64_to_pem(ts, TEST_CERT_DERB64, &pem_str, &pem_size);
+ assert_int_equal(ret, EOK);
+ assert_int_equal(sizeof(TEST_CERT_PEM) - 1, pem_size);
+ assert_string_equal(pem_str, TEST_CERT_PEM);
+
+ talloc_free(pem_str);
+}
+
+void test_sss_cert_pem_to_derb64(void **state)
+{
+ int ret;
+ char *derb64;
+ struct test_state *ts = talloc_get_type_abort(*state, struct test_state);
+ assert_non_null(ts);
+
+ ret = sss_cert_pem_to_derb64(NULL, NULL, NULL);
+ assert_int_equal(ret, EINVAL);
+
+ ret = sss_cert_pem_to_derb64(ts, TEST_CERT_PEM, &derb64);
+ assert_int_equal(ret, EOK);
+ assert_string_equal(derb64, TEST_CERT_DERB64);
+
+ talloc_free(derb64);
+}
+
+void test_bin_to_ldap_filter_value(void **state)
+{
+ int ret;
+ size_t c;
+ char *str;
+ struct test_state *ts = talloc_get_type_abort(*state, struct test_state);
+ assert_non_null(ts);
+
+ struct test_data {
+ uint8_t blob[5];
+ const char *str;
+ } test_data[] = {
+ {{0x01, 0x02, 0x03, 0x04, 0x05}, "\\01\\02\\03\\04\\05"},
+ {{0x00, 0x00, 0x00, 0x00, 0x00}, "\\00\\00\\00\\00\\00"},
+ {{0xff, 0xff, 0xff, 0xff, 0xff}, "\\ff\\ff\\ff\\ff\\ff"},
+ {{0xca, 0xfe, 0xc0, 0xff, 0xee}, "\\ca\\fe\\c0\\ff\\ee"},
+ {{0}, NULL}
+ };
+
+ ret = bin_to_ldap_filter_value(ts, NULL, 0, NULL);
+ assert_int_equal(ret, EINVAL);
+
+ for (c = 0; test_data[c].str != NULL; c++) {
+ ret = bin_to_ldap_filter_value(ts, test_data[c].blob, 5, &str);
+ assert_int_equal(ret, EOK);
+ assert_string_equal(str, test_data[c].str);
+
+ talloc_free(str);
+ }
+
+}
+
+void test_sss_cert_derb64_to_ldap_filter(void **state)
+{
+ int ret;
+ char *filter;
+
+ 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);
+ assert_int_equal(ret, EINVAL);
+
+ ret = sss_cert_derb64_to_ldap_filter(ts, "AAECAwQFBgcICQ==", "attrName",
+ &filter);
+ assert_int_equal(ret, EOK);
+ assert_string_equal(filter,
+ "(attrName=\\00\\01\\02\\03\\04\\05\\06\\07\\08\\09)");
+
+ talloc_free(filter);
+}
+
+int main(int argc, const char *argv[])
+{
+ poptContext pc;
+ int opt;
+ int ret;
+ struct poptOption long_options[] = {
+ POPT_AUTOHELP
+ SSSD_DEBUG_OPTS
+ POPT_TABLEEND
+ };
+
+ const struct CMUnitTest tests[] = {
+ cmocka_unit_test_setup_teardown(test_sss_cert_der_to_pem,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(test_sss_cert_pem_to_der,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(test_sss_cert_derb64_to_pem,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(test_sss_cert_pem_to_derb64,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(test_bin_to_ldap_filter_value,
+ setup, teardown),
+ cmocka_unit_test_setup_teardown(test_sss_cert_derb64_to_ldap_filter,
+ setup, teardown),
+ };
+
+ /* Set debug level to invalid value so we can deside if -d 0 was used. */
+ debug_level = SSSDBG_INVALID;
+
+ pc = poptGetContext(argv[0], argc, argv, long_options, 0);
+ while((opt = poptGetNextOpt(pc)) != -1) {
+ switch(opt) {
+ default:
+ fprintf(stderr, "\nInvalid option %s: %s\n\n",
+ poptBadOption(pc, 0), poptStrerror(opt));
+ poptPrintUsage(pc, stderr, 0);
+ return 1;
+ }
+ }
+ poptFreeContext(pc);
+
+ DEBUG_CLI_INIT(debug_level);
+
+ ret = cmocka_run_group_tests(tests, NULL, NULL);
+
+ CRYPTO_cleanup_all_ex_data(); /* to make valgrind happy */
+
+#ifdef HAVE_NSS
+ /* Cleanup NSS and NSPR to make valgrind happy. */
+ nspr_nss_cleanup();
+#endif
+
+
+ return ret;
+}
diff --git a/src/util/cert.h b/src/util/cert.h
new file mode 100644
index 0000000000000000000000000000000000000000..79ea1a4ab58149a312bece265798ab3a3f459114
--- /dev/null
+++ b/src/util/cert.h
@@ -0,0 +1,47 @@
+/*
+ SSSD - certificate handling utils - openssl version
+
+ Copyright (C) Sumit Bose <sbose at redhat.com> 2015
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <stdint.h>
+#include <talloc.h>
+
+#include "util/util.h"
+
+#ifndef __CERT_H__
+#define __CERT_H__
+
+errno_t sss_cert_der_to_pem(TALLOC_CTX *mem_ctx, const uint8_t *der_blob,
+ size_t der_size, char **pem, size_t *pem_size);
+
+errno_t sss_cert_pem_to_der(TALLOC_CTX *mem_ctx, const char *pem,
+ uint8_t **der_blob, size_t *der_size);
+
+errno_t sss_cert_derb64_to_pem(TALLOC_CTX *mem_ctx, const char *derb64,
+ char **pem, size_t *pem_size);
+
+errno_t sss_cert_pem_to_derb64(TALLOC_CTX *mem_ctx, const char *pem,
+ char **derb64);
+
+errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64,
+ const char *attr_name,
+ char **ldap_filter);
+
+errno_t bin_to_ldap_filter_value(TALLOC_CTX *mem_ctx,
+ const uint8_t *blob, size_t blob_size,
+ char **_str);
+#endif /* __CERT_H__ */
diff --git a/src/util/cert/cert_common.c b/src/util/cert/cert_common.c
new file mode 100644
index 0000000000000000000000000000000000000000..a29696ed3cd9f2168f47323fac97d44e9b49f921
--- /dev/null
+++ b/src/util/cert/cert_common.c
@@ -0,0 +1,154 @@
+/*
+ SSSD - certificate handling utils
+
+ Copyright (C) Sumit Bose <sbose at redhat.com> 2015
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include "util/util.h"
+#include "util/cert.h"
+#include "util/crypto/sss_crypto.h"
+
+errno_t sss_cert_derb64_to_pem(TALLOC_CTX *mem_ctx, const char *derb64,
+ char **pem, size_t *pem_size)
+{
+ int ret;
+ unsigned char *der;
+ size_t der_size;
+
+ if (derb64 == NULL) {
+ return EINVAL;
+ }
+
+ der = sss_base64_decode(mem_ctx, derb64, &der_size);
+ if (der == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n");
+ return EINVAL;
+ }
+
+ ret = sss_cert_der_to_pem(mem_ctx, der, der_size, pem, pem_size);
+ talloc_free(der);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_cert_der_to_pem failed.\n");
+ }
+
+ return ret;
+}
+
+errno_t sss_cert_pem_to_derb64(TALLOC_CTX *mem_ctx, const char *pem,
+ char **derb64)
+{
+ int ret;
+ uint8_t *der;
+ size_t der_size;
+
+ ret = sss_cert_pem_to_der(mem_ctx, pem, &der, &der_size);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_cert_pem_to_der failed.\n");
+ return ret;
+ }
+
+ *derb64 = sss_base64_encode(mem_ctx, der, der_size);
+ talloc_free(der);
+ if (*derb64 == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_encode failed.\n");
+ return EINVAL;
+ }
+
+ return EOK;
+}
+
+errno_t sss_cert_derb64_to_ldap_filter(TALLOC_CTX *mem_ctx, const char *derb64,
+ const char *attr_name,
+ char **ldap_filter)
+{
+ int ret;
+ unsigned char *der;
+ size_t der_size;
+ char *val;
+
+ if (derb64 == NULL || attr_name == NULL) {
+ return EINVAL;
+ }
+
+ der = sss_base64_decode(mem_ctx, derb64, &der_size);
+ if (der == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_base64_decode failed.\n");
+ 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;
+ }
+
+ *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;
+ }
+
+ return EOK;
+}
+
+errno_t bin_to_ldap_filter_value(TALLOC_CTX *mem_ctx,
+ const uint8_t *blob, size_t blob_size,
+ char **_str)
+{
+ int ret;
+ size_t c;
+ size_t len;
+ char *str = NULL;
+ char *p;
+
+ if (blob == NULL || blob_size == 0 || _str == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "Missing input parameter.\n");
+ return EINVAL;
+ }
+
+ len = (blob_size * 3) + 1;
+ str = talloc_size(mem_ctx, len);
+ if (str == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n");
+ return ENOMEM;
+ }
+ str[len - 1] = '\0';
+
+ p = str;
+ for (c = 0; c < blob_size; c++) {
+ ret = snprintf(p, 4, "\\%02x", blob[c]);
+ if (ret != 3) {
+ DEBUG(SSSDBG_OP_FAILURE, "snprintf failed.\n");
+ ret = EIO;
+ goto done;
+ }
+
+ p += 3;
+ }
+
+ ret = EOK;
+
+done:
+ if (ret == EOK) {
+ *_str = str;
+ } else {
+ talloc_free(str);
+ }
+
+ return ret;
+}
diff --git a/src/util/cert/libcrypto/cert.c b/src/util/cert/libcrypto/cert.c
new file mode 100644
index 0000000000000000000000000000000000000000..1a250f60d1a7dfd5c883ec7e9b1f9491fb74c9b0
--- /dev/null
+++ b/src/util/cert/libcrypto/cert.c
@@ -0,0 +1,168 @@
+/*
+ SSSD - certificate handling utils - openssl version
+
+ Copyright (C) Sumit Bose <sbose at redhat.com> 2015
+
+ This program is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+
+#include <openssl/x509.h>
+#include <openssl/bio.h>
+#include <openssl/pem.h>
+
+#include "util/util.h"
+
+errno_t sss_cert_der_to_pem(TALLOC_CTX *mem_ctx, const uint8_t *der_blob,
+ size_t der_size, char **pem, size_t *pem_size)
+{
+ X509 *x509 = NULL;
+ BIO *bio_mem = NULL;
+ const unsigned char *d;
+ int ret;
+ long p_size;
+ char *p;
+
+ if (der_blob == NULL || der_size == 0) {
+ return EINVAL;
+ }
+
+ d = (const unsigned char *) der_blob;
+
+ x509 = d2i_X509(NULL, &d, (int) der_size);
+ if (x509 == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "d2i_X509 failed.\n");
+ return EINVAL;
+ }
+
+ bio_mem = BIO_new(BIO_s_mem());
+ if (bio_mem == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "BIO_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = PEM_write_bio_X509(bio_mem, x509);
+ if (ret != 1) {
+ DEBUG(SSSDBG_OP_FAILURE, "PEM_write_bio_X509 failed.\n");
+ ret = EIO;
+ goto done;
+ }
+
+ p_size = BIO_get_mem_data(bio_mem, &p);
+ if (p_size == 0) {
+ DEBUG(SSSDBG_OP_FAILURE, "Unexpected PEM size [%ld].\n", p_size);
+ ret = EINVAL;
+ goto done;
+ }
+
+ if (pem != NULL) {
+ *pem = talloc_strndup(mem_ctx, p, p_size);
+ if (*pem == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_memdup failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
+ if (pem_size != NULL) {
+ *pem_size = p_size;
+ }
+
+ ret = EOK;
+
+done:
+ X509_free(x509);
+ BIO_free_all(bio_mem);
+
+ return ret;
+}
+
+errno_t sss_cert_pem_to_der(TALLOC_CTX *mem_ctx, const char *pem,
+ uint8_t **_der_blob, size_t *_der_size)
+{
+ X509 *x509 = NULL;
+ BIO *bio_mem = NULL;
+ int ret;
+ unsigned char *buf;
+ int buf_size;
+ uint8_t *der_blob;
+ size_t der_size;
+
+ if (pem == NULL) {
+ return EINVAL;
+ }
+
+ bio_mem = BIO_new(BIO_s_mem());
+ if (bio_mem == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "BIO_new failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ ret = BIO_puts(bio_mem, pem);
+ if (ret <= 0) {
+ DEBUG(SSSDBG_OP_FAILURE, "BIO_puts failed.\n");
+ ret = EIO;
+ goto done;
+ }
+
+ x509 = PEM_read_bio_X509(bio_mem, NULL, NULL, NULL);
+ if (x509 == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "PEM_read_bio_X509 failed.\n");
+ ret = EIO;
+ goto done;
+ }
+
+ buf_size = i2d_X509(x509, NULL);
+ if (buf_size <= 0) {
+ DEBUG(SSSDBG_OP_FAILURE, "i2d_X509 failed.\n");
+ ret = EIO;
+ goto done;
+ }
+
+ if (_der_blob != NULL) {
+ buf = talloc_size(mem_ctx, buf_size);
+ if (buf == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_size failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+
+ der_blob = buf;
+
+ der_size = i2d_X509(x509, &buf);
+ if (der_size != buf_size) {
+ talloc_free(der_blob);
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "i2d_X509 size mismatch between two calls.\n");
+ ret = EIO;
+ goto done;
+ }
+
+ *_der_blob = der_blob;
+ }
+
+ if (_der_size != NULL) {
+ *_der_size = buf_size;
+ }
+
+ ret = EOK;
+
+done:
+ X509_free(x509);
+ BIO_free_all(bio_mem);
+
+ return ret;
+
+}
--
2.1.0
-------------- next part --------------
From 257972b79d9a7710c2c45c4e30e7dc96798269e9 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Wed, 27 May 2015 11:22:20 +0200
Subject: [PATCH 4/7] sysdb: add sysdb_search_user_by_cert() and
sysdb_search_object_by_cert()
Related to https://fedorahosted.org/sssd/ticket/2596
---
Makefile.am | 1 +
src/db/sysdb.h | 14 ++++++++++++
src/db/sysdb_ops.c | 35 ++++++++++++++++++++++++++++++
src/tests/cwrap/Makefile.am | 2 ++
src/tests/sysdb-tests.c | 53 +++++++++++++++++++++++++++++++++++++++++++++
5 files changed, 105 insertions(+)
diff --git a/Makefile.am b/Makefile.am
index 303dd44e1e0e3e66c8d2739051a9d5d63bf8e075..9e68c37826776b52c4b18bd75108f56638158ef4 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -804,6 +804,7 @@ libsss_util_la_LIBADD = \
libsss_debug.la \
libsss_child.la \
libsss_crypt.la \
+ libsss_cert.la \
$(NULL)
if BUILD_SUDO
libsss_util_la_SOURCES += src/db/sysdb_sudo.c
diff --git a/src/db/sysdb.h b/src/db/sysdb.h
index 361d26d37481c521e93584b23af48a0861296e1f..9759642c4953bfc2e67599193f7846189fbdfa59 100644
--- a/src/db/sysdb.h
+++ b/src/db/sysdb.h
@@ -193,6 +193,7 @@
#define SYSDB_SID_FILTER "(&(|("SYSDB_UC")("SYSDB_GC"))("SYSDB_SID_STR"=%s))"
#define SYSDB_UUID_FILTER "(&(|("SYSDB_UC")("SYSDB_GC"))("SYSDB_UUID"=%s))"
+#define SYSDB_USER_CERT_FILTER "(&("SYSDB_UC")%s)"
#define SYSDB_HAS_ENUMERATED "has_enumerated"
@@ -1060,6 +1061,19 @@ errno_t sysdb_search_object_by_uuid(TALLOC_CTX *mem_ctx,
const char **attrs,
struct ldb_result **res);
+errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *cert,
+ const char **attrs,
+ struct ldb_result **res);
+
+errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *cert,
+ struct ldb_result **res);
+
+
+
/* === Functions related to GPOs === */
#define SYSDB_GPO_CONTAINER "cn=gpos,cn=ad,cn=custom"
diff --git a/src/db/sysdb_ops.c b/src/db/sysdb_ops.c
index b86cf490e84ab35562f14333fff6f0cd21890e41..ce569c5d554e8c8c041e940834af6f48f723e672 100644
--- a/src/db/sysdb_ops.c
+++ b/src/db/sysdb_ops.c
@@ -24,6 +24,7 @@
#include "db/sysdb_services.h"
#include "db/sysdb_autofs.h"
#include "util/crypto/sss_crypto.h"
+#include "util/cert.h"
#include <time.h>
int add_string(struct ldb_message *msg, int flags,
@@ -3713,6 +3714,40 @@ errno_t sysdb_search_object_by_uuid(TALLOC_CTX *mem_ctx,
uuid_str, attrs, res);
}
+errno_t sysdb_search_object_by_cert(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *cert,
+ const char **attrs,
+ struct ldb_result **res)
+{
+ int ret;
+ char *user_filter;
+
+ ret = sss_cert_derb64_to_ldap_filter(mem_ctx, cert, SYSDB_USER_CERT,
+ &user_filter);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_cert_derb64_to_ldap_filter failed.\n");
+ return ret;
+ }
+
+ ret = sysdb_search_object_by_str_attr(mem_ctx, domain,
+ SYSDB_USER_CERT_FILTER,
+ user_filter, attrs, res);
+ talloc_free(user_filter);
+
+ return ret;
+}
+
+errno_t sysdb_search_user_by_cert(TALLOC_CTX *mem_ctx,
+ struct sss_domain_info *domain,
+ const char *cert,
+ struct ldb_result **res)
+{
+ const char *user_attrs[] = SYSDB_PW_ATTRS;
+
+ return sysdb_search_object_by_cert(mem_ctx, domain, cert, user_attrs, res);
+}
+
errno_t sysdb_get_sids_of_members(TALLOC_CTX *mem_ctx,
struct sss_domain_info *dom,
const char *group_name,
diff --git a/src/tests/cwrap/Makefile.am b/src/tests/cwrap/Makefile.am
index b805e834977f60d6ba2efdf0f700061bb5e0e264..dc92192928a55abb247096ef310251098d16038f 100644
--- a/src/tests/cwrap/Makefile.am
+++ b/src/tests/cwrap/Makefile.am
@@ -109,6 +109,7 @@ server_tests_LDADD = \
$(abs_top_builddir)/libsss_debug.la \
$(abs_top_builddir)/libsss_crypt.la \
$(abs_top_builddir)/libsss_test_common.la \
+ $(abs_top_builddir)/libsss_cert.la \
$(NULL)
usertools_tests_SOURCES = \
@@ -143,6 +144,7 @@ usertools_tests_LDADD = \
$(abs_top_builddir)/libsss_debug.la \
$(abs_top_builddir)/libsss_crypt.la \
$(abs_top_builddir)/libsss_test_common.la \
+ $(abs_top_builddir)/libsss_cert.la \
$(NULL)
responder_common_tests_SOURCES =\
diff --git a/src/tests/sysdb-tests.c b/src/tests/sysdb-tests.c
index 6a77c6eebc4d8e29c09d67f9b1de17939591410a..b892f5ad9ab39567ccf379e27ead3ce9a42a5ddd 100644
--- a/src/tests/sysdb-tests.c
+++ b/src/tests/sysdb-tests.c
@@ -5201,6 +5201,56 @@ START_TEST(test_sysdb_search_object_by_uuid)
}
END_TEST
+/* For simple searches the content of the certificate does not matter */
+#define TEST_USER_CERT_DERB64 "gJznJT7L0aETU5CMk+n+1Q=="
+START_TEST(test_sysdb_search_user_by_cert)
+{
+ errno_t ret;
+ struct sysdb_test_ctx *test_ctx;
+ struct ldb_result *res;
+ struct sysdb_attrs *attrs = NULL;
+ struct ldb_val val;
+
+ /* Setup */
+ ret = setup_sysdb_tests(&test_ctx);
+ fail_if(ret != EOK, "Could not set up the test");
+
+ val.data = sss_base64_decode(test_ctx, TEST_USER_CERT_DERB64, &val.length);
+ fail_unless(val.data != NULL, "sss_base64_decode failed.");
+
+ attrs = sysdb_new_attrs(test_ctx);
+ fail_unless(attrs != NULL, "sysdb_new_attrs failed");
+
+ ret = sysdb_attrs_add_val(attrs, SYSDB_USER_CERT, &val);
+ fail_unless(ret == EOK, "sysdb_attrs_add_val failed with [%d][%s].",
+ ret, strerror(ret));
+
+ ret = sysdb_add_user(test_ctx->domain, "certuser",
+ 234567, 0, "cert user", "/home/certuser", "/bin/bash",
+ NULL, attrs, 0, 0);
+ fail_unless(ret == EOK, "sysdb_add_user failed with [%d][%s].",
+ ret, strerror(ret));
+
+ ret = sysdb_search_user_by_cert(test_ctx, test_ctx->domain, "ABC", &res);
+ fail_unless(ret == ENOENT,
+ "Unexpected return code from sysdb_search_user_by_cert for "
+ "missing object, expected [%d], got [%d].", ENOENT, ret);
+
+ ret = sysdb_search_user_by_cert(test_ctx, test_ctx->domain,
+ TEST_USER_CERT_DERB64, &res);
+ fail_unless(ret == EOK, "sysdb_search_user_by_cert failed with [%d][%s].",
+ ret, strerror(ret));
+ fail_unless(res->count == 1, "Unexpected number of results, " \
+ "expected [%u], get [%u].", 1, res->count);
+ fail_unless(strcmp(ldb_msg_find_attr_as_string(res->msgs[0],
+ SYSDB_NAME, ""),
+ "certuser") == 0, "Unexpected object found, " \
+ "expected [%s], got [%s].", "certuser",
+ ldb_msg_find_attr_as_string(res->msgs[0],SYSDB_NAME, ""));
+ talloc_free(test_ctx);
+}
+END_TEST
+
START_TEST(test_sysdb_delete_by_sid)
{
errno_t ret;
@@ -6370,6 +6420,9 @@ Suite *create_sysdb_suite(void)
/* Test UUID string searches */
tcase_add_test(tc_sysdb, test_sysdb_search_object_by_uuid);
+ /* Test user by certificate searches */
+ tcase_add_test(tc_sysdb, test_sysdb_search_user_by_cert);
+
/* Test canonicalizing names */
tcase_add_test(tc_sysdb, test_sysdb_get_real_name);
--
2.1.0
-------------- next part --------------
From c40d3d421febf00a36209c8b8ac0f5939ecd9a9c Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Wed, 27 May 2015 18:23:49 +0200
Subject: [PATCH 5/7] LDAP/IPA: add user lookup by certificate
Related to https://fedorahosted.org/sssd/ticket/2596
---
src/providers/data_provider.h | 6 +++-
src/providers/data_provider_be.c | 5 ++++
src/providers/ipa/ipa_subdomains_id.c | 14 +++++++++
src/providers/ldap/ldap_id.c | 55 +++++++++++++++++++++++++++++++----
4 files changed, 73 insertions(+), 7 deletions(-)
diff --git a/src/providers/data_provider.h b/src/providers/data_provider.h
index 657d2b798cf28fa59c9f644e343f2a2482609bad..13a700308e9c9d1a80c0310dbb1c17de33607498 100644
--- a/src/providers/data_provider.h
+++ b/src/providers/data_provider.h
@@ -128,6 +128,7 @@
#define BE_FILTER_ENUM 3
#define BE_FILTER_SECID 4
#define BE_FILTER_UUID 5
+#define BE_FILTER_CERT 6
#define BE_REQ_USER 0x0001
#define BE_REQ_GROUP 0x0002
@@ -140,14 +141,17 @@
#define BE_REQ_HOST 0x0010
#define BE_REQ_BY_SECID 0x0011
#define BE_REQ_USER_AND_GROUP 0x0012
-#define BE_REQ_BY_UUID 0x0013
+#define BE_REQ_BY_UUID 0x0013
+#define BE_REQ_BY_CERT 0x0014
#define BE_REQ_TYPE_MASK 0x00FF
#define BE_REQ_FAST 0x1000
#define DP_SEC_ID "secid"
+#define DP_CERT "cert"
/* sizeof() counts the trailing \0 so we must substract 1 for the string
* length */
#define DP_SEC_ID_LEN (sizeof(DP_SEC_ID) - 1)
+#define DP_CERT_LEN (sizeof(DP_CERT) - 1)
#define EXTRA_NAME_IS_UPN "U"
#define EXTRA_INPUT_MAYBE_WITH_VIEW "V"
diff --git a/src/providers/data_provider_be.c b/src/providers/data_provider_be.c
index 34c7b2c766ee4072ee980ad43f1e1d33ee7c8a5a..f5bdfb676011975defa4c5a734d420c8694f3bdd 100644
--- a/src/providers/data_provider_be.c
+++ b/src/providers/data_provider_be.c
@@ -1199,6 +1199,11 @@ static int be_get_account_info(struct sbus_request *dbus_req, void *user_data)
ret = split_name_extended(req, &filter[DP_SEC_ID_LEN + 1],
&req->filter_value,
&req->extra_value);
+ } else if (strncmp(filter, DP_CERT"=", DP_CERT_LEN + 1) == 0) {
+ req->filter_type = BE_FILTER_CERT;
+ ret = split_name_extended(req, &filter[DP_CERT_LEN + 1],
+ &req->filter_value,
+ &req->extra_value);
} else if (strcmp(filter, ENUM_INDICATOR) == 0) {
req->filter_type = BE_FILTER_ENUM;
req->filter_value = NULL;
diff --git a/src/providers/ipa/ipa_subdomains_id.c b/src/providers/ipa/ipa_subdomains_id.c
index 617c091d3abc4808da4a279213ffc3e1119001bf..74773def113553ccf011d2c99a6ef3fd2b3150a9 100644
--- a/src/providers/ipa/ipa_subdomains_id.c
+++ b/src/providers/ipa/ipa_subdomains_id.c
@@ -918,6 +918,20 @@ errno_t get_object_from_cache(TALLOC_CTX *mem_ctx,
ret = EOK;
goto done;
+ } else if (ar->filter_type == BE_FILTER_CERT) {
+ ret = sysdb_search_object_by_cert(mem_ctx, dom, ar->filter_value, attrs,
+ &res);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "Failed to make request to our cache: [%d]: [%s]\n",
+ ret, sss_strerror(ret));
+ goto done;
+ }
+
+ *_msg = res->msgs[0];
+
+ ret = EOK;
+ goto done;
} else if (ar->filter_type == BE_FILTER_IDNUM) {
errno = 0;
id = strtouint32(ar->filter_value, NULL, 10);
diff --git a/src/providers/ldap/ldap_id.c b/src/providers/ldap/ldap_id.c
index d4f46f1dcd69898e5883d21be07f895fd198cf50..ff117d82957b3b23d9cedc5e513255804103f916 100644
--- a/src/providers/ldap/ldap_id.c
+++ b/src/providers/ldap/ldap_id.c
@@ -28,6 +28,7 @@
#include "util/util.h"
#include "util/strtonum.h"
+#include "util/cert.h"
#include "db/sysdb.h"
#include "providers/ldap/ldap_common.h"
#include "providers/ldap/sdap_async.h"
@@ -78,12 +79,13 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
struct tevent_req *req;
struct users_get_state *state;
const char *attr_name = NULL;
- char *clean_name;
+ char *clean_name = NULL;
char *endptr;
int ret;
uid_t uid;
enum idmap_error_code err;
char *sid;
+ char *user_filter = NULL;
req = tevent_req_create(memctx, &state, struct users_get_state);
if (!req) return NULL;
@@ -194,6 +196,23 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
goto done;
}
break;
+ case BE_FILTER_CERT:
+ attr_name = ctx->opts->user_map[SDAP_AT_USER_CERT].name;
+ if (attr_name == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ "Certificate search not configured for this backend.\n");
+ ret = EINVAL;
+ goto done;
+ }
+
+ ret = sss_cert_derb64_to_ldap_filter(state, name, attr_name,
+ &user_filter);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE,
+ "sss_cert_derb64_to_ldap_filter failed.\n");
+ goto done;
+ }
+ break;
default:
ret = EINVAL;
goto done;
@@ -205,29 +224,39 @@ struct tevent_req *users_get_send(TALLOC_CTX *memctx,
goto done;
}
+ if (user_filter == NULL) {
+ user_filter = talloc_asprintf(state, "(%s=%s)", attr_name, clean_name);
+ talloc_free(clean_name);
+ if (user_filter == NULL) {
+ DEBUG(SSSDBG_OP_FAILURE, "talloc_asprintf failed.\n");
+ ret = ENOMEM;
+ goto done;
+ }
+ }
+
if (state->use_id_mapping || filter_type == BE_FILTER_SECID) {
/* When mapping IDs or looking for SIDs, we don't want to limit
* ourselves to users with a UID value. But there must be a SID to map
* from.
*/
state->filter = talloc_asprintf(state,
- "(&(%s=%s)(objectclass=%s)(%s=*)(%s=*))",
- attr_name, clean_name,
+ "(&%s(objectclass=%s)(%s=*)(%s=*))",
+ user_filter,
ctx->opts->user_map[SDAP_OC_USER].name,
ctx->opts->user_map[SDAP_AT_USER_NAME].name,
ctx->opts->user_map[SDAP_AT_USER_OBJECTSID].name);
} else {
/* When not ID-mapping, make sure there is a non-NULL UID */
state->filter = talloc_asprintf(state,
- "(&(%s=%s)(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))",
- attr_name, clean_name,
+ "(&%s(objectclass=%s)(%s=*)(&(%s=*)(!(%s=0))))",
+ user_filter,
ctx->opts->user_map[SDAP_OC_USER].name,
ctx->opts->user_map[SDAP_AT_USER_NAME].name,
ctx->opts->user_map[SDAP_AT_USER_UID].name,
ctx->opts->user_map[SDAP_AT_USER_UID].name);
}
- talloc_zfree(clean_name);
+ talloc_zfree(user_filter);
if (!state->filter) {
DEBUG(SSSDBG_OP_FAILURE, "Failed to build the base filter\n");
ret = ENOMEM;
@@ -1537,6 +1566,16 @@ sdap_handle_acct_req_send(TALLOC_CTX *mem_ctx,
noexist_delete);
break;
+ case BE_REQ_BY_CERT:
+ subreq = users_get_send(state, be_ctx->ev, id_ctx,
+ sdom, conn,
+ ar->filter_value,
+ ar->filter_type,
+ ar->extra_value,
+ ar->attr_type,
+ noexist_delete);
+ break;
+
default: /*fail*/
ret = EINVAL;
state->err = "Invalid request type";
@@ -1602,6 +1641,10 @@ sdap_handle_acct_req_done(struct tevent_req *subreq)
ret = sdap_get_user_and_group_recv(subreq, &state->dp_error,
&state->sdap_ret);
break;
+ case BE_REQ_BY_CERT:
+ err = "User lookup by certificate failed";
+ ret = users_get_recv(subreq, &state->dp_error, &state->sdap_ret);
+ break;
default: /*fail*/
ret = EINVAL;
break;
--
2.1.0
-------------- next part --------------
From b866832420ec53a2f466151ec0cd37c27ba62cd7 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Wed, 3 Jun 2015 16:18:05 +0200
Subject: [PATCH 6/7] ncache: add calls for certificate based searches
Related to https://fedorahosted.org/sssd/ticket/2596
---
src/responder/common/negcache.c | 31 +++++++++++++++++++++++++++++
src/responder/common/negcache.h | 3 +++
src/tests/cmocka/test_negcache.c | 42 ++++++++++++++++++++++++++++++++++++++++
3 files changed, 76 insertions(+)
diff --git a/src/responder/common/negcache.c b/src/responder/common/negcache.c
index cf70dc52fe122328810064ebd112aec501f892a4..64270f4672f81fcd71f60acb83728d82dd4a1965 100644
--- a/src/responder/common/negcache.c
+++ b/src/responder/common/negcache.c
@@ -35,6 +35,7 @@
#define NC_UID_PREFIX NC_ENTRY_PREFIX"UID"
#define NC_GID_PREFIX NC_ENTRY_PREFIX"GID"
#define NC_SID_PREFIX NC_ENTRY_PREFIX"SID"
+#define NC_CERT_PREFIX NC_ENTRY_PREFIX"CERT"
struct sss_nc_ctx {
struct tdb_context *tdb;
@@ -417,6 +418,21 @@ int sss_ncache_check_sid(struct sss_nc_ctx *ctx, int ttl, const char *sid)
return ret;
}
+int sss_ncache_check_cert(struct sss_nc_ctx *ctx, int ttl, const char *cert)
+{
+ char *str;
+ int ret;
+
+ str = talloc_asprintf(ctx, "%s/%s", NC_CERT_PREFIX, cert);
+ if (!str) return ENOMEM;
+
+ ret = sss_ncache_check_str(ctx, str, ttl);
+
+ talloc_free(str);
+ return ret;
+}
+
+
static int sss_ncache_set_user_int(struct sss_nc_ctx *ctx, bool permanent,
const char *domain, const char *name)
{
@@ -548,6 +564,21 @@ int sss_ncache_set_sid(struct sss_nc_ctx *ctx, bool permanent, const char *sid)
return ret;
}
+int sss_ncache_set_cert(struct sss_nc_ctx *ctx, bool permanent,
+ const char *cert)
+{
+ char *str;
+ int ret;
+
+ str = talloc_asprintf(ctx, "%s/%s", NC_CERT_PREFIX, cert);
+ if (!str) return ENOMEM;
+
+ ret = sss_ncache_set_str(ctx, str, permanent);
+
+ talloc_free(str);
+ return ret;
+}
+
static int delete_permanent(struct tdb_context *tdb,
TDB_DATA key, TDB_DATA data, void *state)
{
diff --git a/src/responder/common/negcache.h b/src/responder/common/negcache.h
index b96fbfda5a63ce32c42b31bcfe517d2369f06138..e7cbfe11451399a639d8e77b3479e74968e72921 100644
--- a/src/responder/common/negcache.h
+++ b/src/responder/common/negcache.h
@@ -37,6 +37,7 @@ int sss_ncache_check_netgr(struct sss_nc_ctx *ctx, int ttl,
int sss_ncache_check_uid(struct sss_nc_ctx *ctx, int ttl, uid_t uid);
int sss_ncache_check_gid(struct sss_nc_ctx *ctx, int ttl, gid_t gid);
int sss_ncache_check_sid(struct sss_nc_ctx *ctx, int ttl, const char *sid);
+int sss_ncache_check_cert(struct sss_nc_ctx *ctx, int ttl, const char *cert);
int sss_ncache_check_service(struct sss_nc_ctx *ctx, int ttl,
struct sss_domain_info *dom,
@@ -60,6 +61,8 @@ int sss_ncache_set_netgr(struct sss_nc_ctx *ctx, bool permanent,
int sss_ncache_set_uid(struct sss_nc_ctx *ctx, bool permanent, uid_t uid);
int sss_ncache_set_gid(struct sss_nc_ctx *ctx, bool permanent, gid_t gid);
int sss_ncache_set_sid(struct sss_nc_ctx *ctx, bool permanent, const char *sid);
+int sss_ncache_set_cert(struct sss_nc_ctx *ctx, bool permanent,
+ const char *cert);
int sss_ncache_set_service_name(struct sss_nc_ctx *ctx, bool permanent,
struct sss_domain_info *dom,
const char *name, const char *proto);
diff --git a/src/tests/cmocka/test_negcache.c b/src/tests/cmocka/test_negcache.c
index 6f9802a38c44adfc41688ce1a9297a8636c5d616..fa07ea2481e2040e3e83eecfb5c69dbec17e26fa 100644
--- a/src/tests/cmocka/test_negcache.c
+++ b/src/tests/cmocka/test_negcache.c
@@ -45,6 +45,7 @@
#define PORT 21
#define SID "S-1-2-3-4-5"
+#define CERT "MIIECTCCAvGgAwIBAgIBCTANBgkqhkiG9w0BAQsFADA0MRIwEAYDVQQKDAlJUEEuREVWRUwxHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAeFw0xNTA0MjgxMDIxMTFaFw0xNzA0MjgxMDIxMTFaMDIxEjAQBgNVBAoMCUlQQS5ERVZFTDEcMBoGA1UEAwwTaXBhLWRldmVsLmlwYS5kZXZlbDCCASIwDQYJKoZIhvcNAQEBBQADggEPADCCAQoCggEBALIykqtHuAwTVEofHikG/9BQy/dfeZFlsTkBg2qtnnc78w3XufbcnkpJp9Bmcsy/d9beqf5nlsxJ8TcjLsRQ9Ou6YtQjTfM3OILuOz8s0ICbF6qb66bd9hX/BrLO/9+KnpWFSR+E/YEmzgYyDTbKfBWBaGuPPrOi/K6vwkRYFZVA/FYZkYDtQhFmBO884HYzS4P6frRH3PvtRqWNCmaHpe97dGKsvnM2ybT+IMSB8/54GajQr3+BciRh2XaT4wvSTxkXM1fUgrDxqAP2AZmpuIyDyboZh+rWOwbrTPfx5SipELZG3uHhP8HMcr4qQ8b20LWgxCRuT73sIooHET350xUCAwEAAaOCASYwggEiMB8GA1UdIwQYMBaAFPKdQk4PxEglWC8czg+hPyLIVciRMDsGCCsGAQUFBwEBBC8wLTArBggrBgEFBQcwAYYfaHR0cDovL2lwYS1jYS5pcGEuZGV2ZWwvY2Evb2NzcDAOBgNVHQ8BAf8EBAMCBPAwHQYDVR0lBBYwFAYIKwYBBQUHAwEGCCsGAQUFBwMCMHQGA1UdHwRtMGswaaAxoC+GLWh0dHA6Ly9pcGEtY2EuaXBhLmRldmVsL2lwYS9jcmwvTWFzdGVyQ1JMLmJpbqI0pDIwMDEOMAwGA1UECgwFaXBhY2ExHjAcBgNVBAMMFUNlcnRpZmljYXRlIEF1dGhvcml0eTAdBgNVHQ4EFgQULSs/y/Wy/zIsqMIc3b2MgB7dMYIwDQYJKoZIhvcNAQELBQADggEBAJpHLlCnTR1TD8lxQgzl2n1JZOeryN/fAsGH0Vve2m8r5PC+ugnfAoULiuabBn1pOGxy/0x7Kg0/Iy8WRv8Fk7DqJCjXEqFXuFkZJfNDCtP9DzeNuMoV50iKoMfHS38BPFjXN+X/fSsBrA2fUWrlQCTmXlUN97gvQqxt5Slrxgukvxm9OSfu/sWz22LUvtJHupYwWv1iALgnXS86lAuVNYVALLxn34r58XsZlj5CSBMjBJWpaxEzgUdag3L2IPqOQXuPd0d8x11G9E/9gQquOSe2aiZjsdO/VYOCmzZsM2QPUMBVlBPDhfTVcWXQwN385uycW/ARtSzzSME2jKKWSIQ="
#define PROTO "TCP"
#define LIFETIME 200
#define SHORTSPAN 1
@@ -317,6 +318,46 @@ static void test_sss_ncache_sid(void **state)
assert_int_equal(ret, EEXIST);
}
+/* @test_sss_ncache_cert : test following functions
+ * sss_ncache_set_cert
+ * sss_ncache_check_cert_
+ */
+static void test_sss_ncache_cert(void **state)
+{
+ int ret, ttl;
+ bool permanent;
+ const char *cert = NULL;
+ struct test_state *ts;
+
+ ttl = LIFETIME;
+ cert = CERT;
+ ts = talloc_get_type_abort(*state, struct test_state);
+
+ /*test when cert in not present in database */
+ ret = sss_ncache_check_cert(ts->ctx, ttl, cert);
+ assert_int_equal(ret, ENOENT);
+
+ /* test when cert is present in database */
+ permanent = true;
+ ret = sss_ncache_set_cert(ts->ctx, permanent, cert);
+ assert_int_equal(ret, EOK);
+
+ ret = sss_ncache_check_cert(ts->ctx, ttl, cert);
+ assert_int_equal(ret, EEXIST);
+
+ permanent = false;
+ ret = sss_ncache_set_cert(ts->ctx, permanent, cert);
+ assert_int_equal(ret, EOK);
+
+ ret = sss_ncache_check_cert(ts->ctx, ttl, cert);
+ assert_int_equal(ret, EEXIST);
+
+ /* test when ttl is -1 with cert present in database*/
+ ttl = -1;
+ ret = sss_ncache_check_cert(ts->ctx, ttl, cert);
+ assert_int_equal(ret, EEXIST);
+}
+
/* @test_sss_ncache_user : test following functions
* sss_ncache_check_user
* sss_ncache_set_user
@@ -809,6 +850,7 @@ int main(void)
cmocka_unit_test_setup_teardown(test_sss_ncache_uid, setup, teardown),
cmocka_unit_test_setup_teardown(test_sss_ncache_gid, setup, teardown),
cmocka_unit_test_setup_teardown(test_sss_ncache_sid, setup, teardown),
+ cmocka_unit_test_setup_teardown(test_sss_ncache_cert, setup, teardown),
cmocka_unit_test_setup_teardown(test_sss_ncache_user, setup, teardown),
cmocka_unit_test_setup_teardown(test_sss_ncache_group, setup, teardown),
cmocka_unit_test_setup_teardown(test_sss_ncache_netgr, setup, teardown),
--
2.1.0
-------------- next part --------------
From 4b5b4324ddbe2509d23e164097f617cfee757b89 Mon Sep 17 00:00:00 2001
From: Sumit Bose <sbose at redhat.com>
Date: Tue, 26 May 2015 14:29:17 +0200
Subject: [PATCH 7/7] IFP: add FindByCertificate method for User objects
Related to https://fedorahosted.org/sssd/ticket/2596
---
Makefile.am | 4 +-
src/responder/common/responder.h | 3 +-
src/responder/common/responder_cache_req.c | 64 +++++++++++++++++++++-
src/responder/common/responder_cache_req.h | 16 +++++-
src/responder/common/responder_dp.c | 11 ++++
src/responder/ifp/ifp_iface.c | 1 +
src/responder/ifp/ifp_iface.xml | 4 ++
src/responder/ifp/ifp_iface_generated.c | 26 +++++++++
src/responder/ifp/ifp_iface_generated.h | 5 ++
src/responder/ifp/ifp_users.c | 87 ++++++++++++++++++++++++++++++
src/responder/ifp/ifp_users.h | 4 ++
src/sbus/sssd_dbus_errors.h | 1 +
12 files changed, 221 insertions(+), 5 deletions(-)
diff --git a/Makefile.am b/Makefile.am
index 9e68c37826776b52c4b18bd75108f56638158ef4..b1a41eb8ac230f30fa2925fe766fdb45a51d8494 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -1127,7 +1127,9 @@ sssd_ifp_CFLAGS = \
$(AM_CFLAGS)
sssd_ifp_LDADD = \
$(SSSD_LIBS) \
- $(SSSD_INTERNAL_LTLIBS)
+ $(SSSD_INTERNAL_LTLIBS) \
+ libsss_cert.la \
+ $(NULL)
dist_dbuspolicy_DATA = \
src/responder/ifp/org.freedesktop.sssd.infopipe.conf
dist_dbusservice_DATA = \
diff --git a/src/responder/common/responder.h b/src/responder/common/responder.h
index 9c7a73809a3de8859aa546c2a7d31620fea39ac9..bd0250d52aae1efdac3bc0847f692542c6cfb6d2 100644
--- a/src/responder/common/responder.h
+++ b/src/responder/common/responder.h
@@ -281,7 +281,8 @@ enum sss_dp_acct_type {
SSS_DP_NETGR,
SSS_DP_SERVICES,
SSS_DP_SECID,
- SSS_DP_USER_AND_GROUP
+ SSS_DP_USER_AND_GROUP,
+ SSS_DP_CERT
};
struct tevent_req *
diff --git a/src/responder/common/responder_cache_req.c b/src/responder/common/responder_cache_req.c
index 7ba257276b064d923b6144f45ade59cac48849d5..eae6f7823dfa96c4b0fa4b8da034913629ba91d9 100644
--- a/src/responder/common/responder_cache_req.c
+++ b/src/responder/common/responder_cache_req.c
@@ -34,6 +34,7 @@ struct cache_req_input {
/* Provided input. */
const char *orig_name;
uint32_t id;
+ const char *cert;
/* Data Provider request type resolved from @type.
* FIXME: This is currently needed for data provider calls. We should
@@ -82,6 +83,17 @@ cache_req_input_create(TALLOC_CTX *mem_ctx,
goto fail;
}
break;
+ case CACHE_REQ_USER_BY_CERT:
+ if (name == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Bug: certificate cannot be NULL!\n");
+ goto fail;
+ }
+
+ input->cert = talloc_strdup(input, name);
+ if (input->cert == NULL) {
+ goto fail;
+ }
+ break;
case CACHE_REQ_USER_BY_ID:
case CACHE_REQ_GROUP_BY_ID:
if (id == 0) {
@@ -108,6 +120,9 @@ cache_req_input_create(TALLOC_CTX *mem_ctx,
case CACHE_REQ_INITGROUPS:
input->dp_type = SSS_DP_INITGROUPS;
break;
+ case CACHE_REQ_USER_BY_CERT:
+ input->dp_type = SSS_DP_CERT;
+ break;
}
return input;
@@ -192,6 +207,13 @@ cache_req_input_set_domain(struct cache_req_input *input,
goto done;
}
break;
+ case CACHE_REQ_USER_BY_CERT:
+ fqn = talloc_asprintf(tmp_ctx, "CERT:%s@%s", input->cert, domain->name);
+ if (fqn == NULL) {
+ ret = ENOMEM;
+ goto done;
+ }
+ break;
}
input->domain = domain;
@@ -227,6 +249,9 @@ static errno_t cache_req_check_ncache(struct cache_req_input *input,
case CACHE_REQ_GROUP_BY_ID:
ret = sss_ncache_check_gid(ncache, neg_timeout, input->id);
break;
+ case CACHE_REQ_USER_BY_CERT:
+ ret = sss_ncache_check_cert(ncache, neg_timeout, input->cert);
+ break;
}
if (ret == EEXIST) {
@@ -254,6 +279,7 @@ static void cache_req_add_to_ncache(struct cache_req_input *input,
break;
case CACHE_REQ_USER_BY_ID:
case CACHE_REQ_GROUP_BY_ID:
+ case CACHE_REQ_USER_BY_CERT:
/* Nothing to do. Those types must be unique among all domains so
* the don't contain domain part. Therefore they must be set only
* if all domains are search and the entry is not found. */
@@ -290,6 +316,9 @@ static void cache_req_add_to_ncache_global(struct cache_req_input *input,
case CACHE_REQ_GROUP_BY_ID:
ret = sss_ncache_set_gid(ncache, false, input->id);
break;
+ case CACHE_REQ_USER_BY_CERT:
+ ret = sss_ncache_set_cert(ncache, false, input->cert);
+ break;
}
if (ret != EOK) {
@@ -338,6 +367,11 @@ static errno_t cache_req_get_object(TALLOC_CTX *mem_ctx,
ret = sysdb_initgroups_with_views(mem_ctx, input->domain,
input->dom_objname, &result);
break;
+ case CACHE_REQ_USER_BY_CERT:
+ one_item_only = true;
+ ret = sysdb_search_user_by_cert(mem_ctx, input->domain,
+ input->cert, &result);
+ break;
}
if (ret != EOK) {
@@ -461,6 +495,7 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
const char *extra_flag = NULL;
uint64_t cache_expire = 0;
errno_t ret;
+ const char *search_str;
state = tevent_req_data(req, struct cache_req_cache_state);
@@ -479,6 +514,8 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
state->cache_refresh_percent, cache_expire);
}
+ search_str = (state->input->type == CACHE_REQ_USER_BY_CERT) ?
+ state->input->cert : state->input->dom_objname;
switch (ret) {
case EOK:
DEBUG(SSSDBG_TRACE_FUNC, "Cached entry is valid, returning...\n");
@@ -492,7 +529,7 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
subreq = sss_dp_get_account_send(state, state->rctx,
state->input->domain, true,
state->input->dp_type,
- state->input->dom_objname,
+ search_str,
state->input->id, NULL);
if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory sending out-of-band "
@@ -514,7 +551,7 @@ static errno_t cache_req_cache_check(struct tevent_req *req)
subreq = sss_dp_get_account_send(state, state->rctx,
state->input->domain, true,
state->input->dp_type,
- state->input->dom_objname,
+ search_str,
state->input->id, extra_flag);
if (subreq == NULL) {
DEBUG(SSSDBG_CRIT_FAILURE,
@@ -923,6 +960,29 @@ cache_req_user_by_id_send(TALLOC_CTX *mem_ctx,
}
struct tevent_req *
+cache_req_user_by_cert_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct resp_ctx *rctx,
+ struct sss_nc_ctx *ncache,
+ int neg_timeout,
+ int cache_refresh_percent,
+ const char *domain,
+ const char *pem_cert)
+{
+ struct cache_req_input *input;
+
+ input = cache_req_input_create(mem_ctx, CACHE_REQ_USER_BY_CERT,
+ pem_cert, 0);
+ if (input == NULL) {
+ return NULL;
+ }
+
+ return cache_req_steal_input_and_send(mem_ctx, ev, rctx, ncache,
+ neg_timeout, cache_refresh_percent,
+ domain, input);
+}
+
+struct tevent_req *
cache_req_group_by_name_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct resp_ctx *rctx,
diff --git a/src/responder/common/responder_cache_req.h b/src/responder/common/responder_cache_req.h
index 088e8efe0ceefe49510bc5eab37e7825b667e5f3..9b862a8b7751bfd938205184b4d6452a75f2684e 100644
--- a/src/responder/common/responder_cache_req.h
+++ b/src/responder/common/responder_cache_req.h
@@ -32,7 +32,8 @@ enum cache_req_type {
CACHE_REQ_USER_BY_ID,
CACHE_REQ_GROUP_BY_NAME,
CACHE_REQ_GROUP_BY_ID,
- CACHE_REQ_INITGROUPS
+ CACHE_REQ_INITGROUPS,
+ CACHE_REQ_USER_BY_CERT
};
struct cache_req_input;
@@ -90,6 +91,19 @@ cache_req_user_by_id_send(TALLOC_CTX *mem_ctx,
cache_req_recv(mem_ctx, req, _result, _domain, NULL)
struct tevent_req *
+cache_req_user_by_cert_send(TALLOC_CTX *mem_ctx,
+ struct tevent_context *ev,
+ struct resp_ctx *rctx,
+ struct sss_nc_ctx *ncache,
+ int neg_timeout,
+ int cache_refresh_percent,
+ const char *domain,
+ const char *pem_cert);
+
+#define cache_req_user_by_cert_recv(mem_ctx, req, _result, _domain, _name) \
+ cache_req_recv(mem_ctx, req, _result, _domain, _name)
+
+struct tevent_req *
cache_req_group_by_name_send(TALLOC_CTX *mem_ctx,
struct tevent_context *ev,
struct resp_ctx *rctx,
diff --git a/src/responder/common/responder_dp.c b/src/responder/common/responder_dp.c
index 853b3eae3877a8b6b2ffb310a0fb9ccf017498ae..f752c94c37fd0efa0d072ef8c567bd875a08e6f7 100644
--- a/src/responder/common/responder_dp.c
+++ b/src/responder/common/responder_dp.c
@@ -548,6 +548,9 @@ sss_dp_get_account_msg(void *pvt)
case SSS_DP_USER_AND_GROUP:
be_type = BE_REQ_USER_AND_GROUP;
break;
+ case SSS_DP_CERT:
+ be_type = BE_REQ_BY_CERT;
+ break;
}
if (info->fast_reply) {
@@ -563,6 +566,14 @@ sss_dp_get_account_msg(void *pvt)
filter = talloc_asprintf(info, "%s=%s", DP_SEC_ID,
info->opt_name);
}
+ } else if (info->type == SSS_DP_CERT) {
+ if (info->extra) {
+ filter = talloc_asprintf(info, "%s=%s:%s", DP_CERT,
+ info->opt_name, info->extra);
+ } else {
+ filter = talloc_asprintf(info, "%s=%s", DP_CERT,
+ info->opt_name);
+ }
} else {
if (info->extra) {
filter = talloc_asprintf(info, "name=%s:%s",
diff --git a/src/responder/ifp/ifp_iface.c b/src/responder/ifp/ifp_iface.c
index 015c66dc5323e237dd21575162e434b11acd8ed7..86d8d338c3d18c22a8dc449b6520f65f8968e26b 100644
--- a/src/responder/ifp/ifp_iface.c
+++ b/src/responder/ifp/ifp_iface.c
@@ -82,6 +82,7 @@ struct iface_ifp_users iface_ifp_users = {
{ &iface_ifp_users_meta, 0 },
.FindByName = ifp_users_find_by_name,
.FindByID = ifp_users_find_by_id,
+ .FindByCertificate = ifp_users_find_by_cert,
.ListByName = ifp_users_list_by_name,
.ListByDomainAndName = ifp_users_list_by_domain_and_name
};
diff --git a/src/responder/ifp/ifp_iface.xml b/src/responder/ifp/ifp_iface.xml
index 340eb6d23ebfebb508e12118b9ac6c9a71fed099..612a5b5a2817231d5793346778b49cc5a132fc73 100644
--- a/src/responder/ifp/ifp_iface.xml
+++ b/src/responder/ifp/ifp_iface.xml
@@ -136,6 +136,10 @@
<arg name="id" type="u" direction="in" />
<arg name="result" type="o" direction="out" />
</method>
+ <method name="FindByCertificate">
+ <arg name="pem_cert" type="s" direction="in" />
+ <arg name="result" type="o" direction="out" />
+ </method>
<method name="ListByName">
<arg name="name_filter" type="s" direction="in" />
<arg name="limit" type="u" direction="in" />
diff --git a/src/responder/ifp/ifp_iface_generated.c b/src/responder/ifp/ifp_iface_generated.c
index 8255cbea729d9b2c0696cbfdef5c0daf9d958631..a4fdd5d12cd5c82e7832de9d07f55ea6eb621fba 100644
--- a/src/responder/ifp/ifp_iface_generated.c
+++ b/src/responder/ifp/ifp_iface_generated.c
@@ -685,6 +685,25 @@ int iface_ifp_users_FindByID_finish(struct sbus_request *req, const char *arg_re
DBUS_TYPE_INVALID);
}
+/* arguments for org.freedesktop.sssd.infopipe.Users.FindByCertificate */
+const struct sbus_arg_meta iface_ifp_users_FindByCertificate__in[] = {
+ { "pem_cert", "s" },
+ { NULL, }
+};
+
+/* arguments for org.freedesktop.sssd.infopipe.Users.FindByCertificate */
+const struct sbus_arg_meta iface_ifp_users_FindByCertificate__out[] = {
+ { "result", "o" },
+ { NULL, }
+};
+
+int iface_ifp_users_FindByCertificate_finish(struct sbus_request *req, const char *arg_result)
+{
+ return sbus_request_return_and_finish(req,
+ DBUS_TYPE_OBJECT_PATH, &arg_result,
+ DBUS_TYPE_INVALID);
+}
+
/* arguments for org.freedesktop.sssd.infopipe.Users.ListByName */
const struct sbus_arg_meta iface_ifp_users_ListByName__in[] = {
{ "name_filter", "s" },
@@ -743,6 +762,13 @@ const struct sbus_method_meta iface_ifp_users__methods[] = {
invoke_u_method,
},
{
+ "FindByCertificate", /* name */
+ iface_ifp_users_FindByCertificate__in,
+ iface_ifp_users_FindByCertificate__out,
+ offsetof(struct iface_ifp_users, FindByCertificate),
+ invoke_s_method,
+ },
+ {
"ListByName", /* name */
iface_ifp_users_ListByName__in,
iface_ifp_users_ListByName__out,
diff --git a/src/responder/ifp/ifp_iface_generated.h b/src/responder/ifp/ifp_iface_generated.h
index d2e5cdd3a689d42509e63adde70237cbde627ee2..4dfe61ddff3763b1d3ee165b9098efd667037663 100644
--- a/src/responder/ifp/ifp_iface_generated.h
+++ b/src/responder/ifp/ifp_iface_generated.h
@@ -68,6 +68,7 @@
#define IFACE_IFP_USERS "org.freedesktop.sssd.infopipe.Users"
#define IFACE_IFP_USERS_FINDBYNAME "FindByName"
#define IFACE_IFP_USERS_FINDBYID "FindByID"
+#define IFACE_IFP_USERS_FINDBYCERTIFICATE "FindByCertificate"
#define IFACE_IFP_USERS_LISTBYNAME "ListByName"
#define IFACE_IFP_USERS_LISTBYDOMAINANDNAME "ListByDomainAndName"
@@ -235,6 +236,7 @@ struct iface_ifp_users {
struct sbus_vtable vtable; /* derive from sbus_vtable */
int (*FindByName)(struct sbus_request *req, void *data, const char *arg_name);
int (*FindByID)(struct sbus_request *req, void *data, uint32_t arg_id);
+ int (*FindByCertificate)(struct sbus_request *req, void *data, const char *arg_pem_cert);
int (*ListByName)(struct sbus_request *req, void *data, const char *arg_name_filter, uint32_t arg_limit);
int (*ListByDomainAndName)(struct sbus_request *req, void *data, const char *arg_domain_name, const char *arg_name_filter, uint32_t arg_limit);
};
@@ -245,6 +247,9 @@ int iface_ifp_users_FindByName_finish(struct sbus_request *req, const char *arg_
/* finish function for FindByID */
int iface_ifp_users_FindByID_finish(struct sbus_request *req, const char *arg_result);
+/* finish function for FindByCertificate */
+int iface_ifp_users_FindByCertificate_finish(struct sbus_request *req, const char *arg_result);
+
/* finish function for ListByName */
int iface_ifp_users_ListByName_finish(struct sbus_request *req, const char *arg_result[], int len_result);
diff --git a/src/responder/ifp/ifp_users.c b/src/responder/ifp/ifp_users.c
index fa6f47f0d2f7ce52c3f0069b8ebf0bf1c98dbf22..e661b8b1b886fed922df7ea286b8756c5ad429de 100644
--- a/src/responder/ifp/ifp_users.c
+++ b/src/responder/ifp/ifp_users.c
@@ -25,6 +25,7 @@
#include "db/sysdb.h"
#include "util/util.h"
#include "util/strtonum.h"
+#include "util/cert.h"
#include "sbus/sssd_dbus_errors.h"
#include "responder/common/responder.h"
#include "responder/common/responder_cache_req.h"
@@ -222,6 +223,92 @@ done:
return;
}
+static void ifp_users_find_by_cert_done(struct tevent_req *req);
+
+int ifp_users_find_by_cert(struct sbus_request *sbus_req, void *data,
+ const char *pem_cert)
+{
+ struct ifp_ctx *ctx;
+ struct tevent_req *req;
+ int ret;
+ char *derb64;
+ DBusError *error;
+
+ ctx = talloc_get_type(data, struct ifp_ctx);
+ if (ctx == NULL) {
+ DEBUG(SSSDBG_CRIT_FAILURE, "Invalid pointer!\n");
+ return ERR_INTERNAL;
+ }
+
+ ret = sss_cert_pem_to_derb64(sbus_req, pem_cert, &derb64);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_OP_FAILURE, "sss_cert_pem_to_derb64 failed.\n");
+
+ if (ret == ENOMEM) {
+ return ret;
+ }
+
+ error = sbus_error_new(sbus_req, SBUS_ERROR_EINVAL,
+ "Invalid certificate format");
+ sbus_request_fail_and_finish(sbus_req, error);
+ /* the connection is already terminated with an error message, hence
+ * we have to return EOK to not terminate the connection twice. */
+ return EOK;
+ }
+
+ req = cache_req_user_by_cert_send(sbus_req, ctx->rctx->ev, ctx->rctx,
+ ctx->ncache, ctx->neg_timeout, 0,
+ NULL, derb64);
+ if (req == NULL) {
+ return ENOMEM;
+ }
+
+ tevent_req_set_callback(req, ifp_users_find_by_cert_done, sbus_req);
+
+ return EOK;
+}
+
+static void ifp_users_find_by_cert_done(struct tevent_req *req)
+{
+ DBusError *error;
+ struct sbus_request *sbus_req;
+ struct sss_domain_info *domain;
+ struct ldb_result *result;
+ char *object_path;
+ errno_t ret;
+
+ sbus_req = tevent_req_callback_data(req, struct sbus_request);
+
+ ret = cache_req_user_by_cert_recv(sbus_req, req, &result, &domain, NULL);
+ talloc_zfree(req);
+ if (ret == ENOENT) {
+ error = sbus_error_new(sbus_req, SBUS_ERROR_NOT_FOUND,
+ "User not found");
+ goto done;
+ } else if (ret != EOK) {
+ error = sbus_error_new(sbus_req, DBUS_ERROR_FAILED, "Failed to fetch "
+ "user [%d]: %s\n", ret, sss_strerror(ret));
+ goto done;
+ }
+
+ object_path = ifp_users_build_path_from_msg(sbus_req, domain,
+ result->msgs[0]);
+ if (object_path == NULL) {
+ error = sbus_error_new(sbus_req, SBUS_ERROR_INTERNAL,
+ "Failed to compose object path");
+ goto done;
+ }
+
+done:
+ if (ret != EOK) {
+ sbus_request_fail_and_finish(sbus_req, error);
+ return;
+ }
+
+ iface_ifp_users_FindByCertificate_finish(sbus_req, object_path);
+ return;
+}
+
int ifp_users_list_by_name(struct sbus_request *sbus_req,
void *data,
const char *filter,
diff --git a/src/responder/ifp/ifp_users.h b/src/responder/ifp/ifp_users.h
index 4da0a734752a2a1bd11b0e21c532a1302c9126f1..471c3fb019c7cd0858b2928969b045091f370446 100644
--- a/src/responder/ifp/ifp_users.h
+++ b/src/responder/ifp/ifp_users.h
@@ -43,6 +43,10 @@ int ifp_users_find_by_id(struct sbus_request *sbus_req,
void *data,
uint32_t id);
+int ifp_users_find_by_cert(struct sbus_request *sbus_req,
+ void *data,
+ const char *pem_cert);
+
int ifp_users_list_by_name(struct sbus_request *sbus_req,
void *data,
const char *filter,
diff --git a/src/sbus/sssd_dbus_errors.h b/src/sbus/sssd_dbus_errors.h
index b2b2b233be4d2839d59cb32389505de2b393ba57..7f1656a274f3d2fd52ccd4cb1575ace78bc6d0d1 100644
--- a/src/sbus/sssd_dbus_errors.h
+++ b/src/sbus/sssd_dbus_errors.h
@@ -25,5 +25,6 @@
#define SBUS_ERROR_INTERNAL "org.freedesktop.sssd.Error.Internal"
#define SBUS_ERROR_NOT_FOUND "org.freedesktop.sssd.Error.NotFound"
+#define SBUS_ERROR_EINVAL "org.freedesktop.sssd.Error.InvalidArgument"
#endif /* SSSD_DBUS_ERRORS_H_ */
--
2.1.0
More information about the sssd-devel
mailing list