|
|
ac7d03 |
From 0956c8149f11921ed427d67b10bb9b6c4b97df48 Mon Sep 17 00:00:00 2001
|
|
|
ac7d03 |
From: Sumit Bose <sbose@redhat.com>
|
|
|
ac7d03 |
Date: Thu, 2 Feb 2017 12:32:13 +0100
|
|
|
ac7d03 |
Subject: [PATCH] IPA certauth plugin
|
|
|
ac7d03 |
|
|
|
ac7d03 |
This patch add a certauth plugin which allows the IPA server to support
|
|
|
ac7d03 |
PKINIT for certificates which do not include a special SAN extension
|
|
|
ac7d03 |
which contains a Kerberos principal but allow other mappings with the
|
|
|
ac7d03 |
help of SSSD's certmap library.
|
|
|
ac7d03 |
|
|
|
ac7d03 |
Related to https://pagure.io/freeipa/issue/4905
|
|
|
ac7d03 |
|
|
|
ac7d03 |
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
|
|
|
ac7d03 |
Reviewed-By: David Kupka <dkupka@redhat.com>
|
|
|
ac7d03 |
---
|
|
|
ac7d03 |
daemons/ipa-kdb/Makefile.am | 24 ++-
|
|
|
ac7d03 |
daemons/ipa-kdb/ipa-certauth.in | 5 +
|
|
|
ac7d03 |
daemons/ipa-kdb/ipa_kdb.c | 2 +
|
|
|
ac7d03 |
daemons/ipa-kdb/ipa_kdb.exports | 1 +
|
|
|
ac7d03 |
daemons/ipa-kdb/ipa_kdb.h | 5 +
|
|
|
ac7d03 |
daemons/ipa-kdb/ipa_kdb_certauth.c | 398 +++++++++++++++++++++++++++++++++++++
|
|
|
ac7d03 |
freeipa.spec.in | 2 +
|
|
|
ac7d03 |
server.m4 | 13 ++
|
|
|
ac7d03 |
8 files changed, 449 insertions(+), 1 deletion(-)
|
|
|
ac7d03 |
create mode 100644 daemons/ipa-kdb/ipa-certauth.in
|
|
|
ac7d03 |
create mode 100644 daemons/ipa-kdb/ipa_kdb_certauth.c
|
|
|
ac7d03 |
|
|
|
ac7d03 |
diff --git a/daemons/ipa-kdb/Makefile.am b/daemons/ipa-kdb/Makefile.am
|
|
|
ac7d03 |
index 6a2caa0637bf076c796b50efc92412062524f35f..715666e779a4fa64c2c0f71767f09efb19b5f908 100644
|
|
|
ac7d03 |
--- a/daemons/ipa-kdb/Makefile.am
|
|
|
ac7d03 |
+++ b/daemons/ipa-kdb/Makefile.am
|
|
|
ac7d03 |
@@ -18,6 +18,7 @@ AM_CPPFLAGS = \
|
|
|
ac7d03 |
$(WARN_CFLAGS) \
|
|
|
ac7d03 |
$(NDRPAC_CFLAGS) \
|
|
|
ac7d03 |
$(NSS_CFLAGS) \
|
|
|
ac7d03 |
+ $(SSSCERTMAP_CFLAGS) \
|
|
|
ac7d03 |
$(NULL)
|
|
|
ac7d03 |
|
|
|
ac7d03 |
plugindir = $(libdir)/krb5/plugins/kdb
|
|
|
ac7d03 |
@@ -39,6 +40,20 @@ ipadb_la_SOURCES = \
|
|
|
ac7d03 |
ipa_kdb_audit_as.c \
|
|
|
ac7d03 |
$(NULL)
|
|
|
ac7d03 |
|
|
|
ac7d03 |
+if BUILD_IPA_CERTAUTH_PLUGIN
|
|
|
ac7d03 |
+ipadb_la_SOURCES += ipa_kdb_certauth.c
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+%: %.in
|
|
|
ac7d03 |
+ sed \
|
|
|
ac7d03 |
+ -e 's|@plugindir@|$(plugindir)|g' \
|
|
|
ac7d03 |
+ '$(srcdir)/$@.in' >$@
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+krb5confdir = $(sysconfdir)/krb5.conf.d
|
|
|
ac7d03 |
+krb5conf_DATA = ipa-certauth
|
|
|
ac7d03 |
+CLEANFILES = $(krb5conf_DATA)
|
|
|
ac7d03 |
+endif
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
ipadb_la_LDFLAGS = \
|
|
|
ac7d03 |
-avoid-version \
|
|
|
ac7d03 |
-module \
|
|
|
ac7d03 |
@@ -50,6 +65,7 @@ ipadb_la_LIBADD = \
|
|
|
ac7d03 |
$(NDRPAC_LIBS) \
|
|
|
ac7d03 |
$(UNISTRING_LIBS) \
|
|
|
ac7d03 |
$(NSS_LIBS) \
|
|
|
ac7d03 |
+ $(SSSCERTMAP_LIBS) \
|
|
|
ac7d03 |
$(top_builddir)/util/libutil.la \
|
|
|
ac7d03 |
$(NULL)
|
|
|
ac7d03 |
|
|
|
ac7d03 |
@@ -70,6 +86,11 @@ ipa_kdb_tests_SOURCES = \
|
|
|
ac7d03 |
ipa_kdb_delegation.c \
|
|
|
ac7d03 |
ipa_kdb_audit_as.c \
|
|
|
ac7d03 |
$(NULL)
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+if BUILD_IPA_CERTAUTH_PLUGIN
|
|
|
ac7d03 |
+ipa_kdb_tests_SOURCES += ipa_kdb_certauth.c
|
|
|
ac7d03 |
+endif
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
ipa_kdb_tests_CFLAGS = $(CMOCKA_CFLAGS)
|
|
|
ac7d03 |
ipa_kdb_tests_LDADD = \
|
|
|
ac7d03 |
$(CMOCKA_LIBS) \
|
|
|
ac7d03 |
@@ -78,12 +99,13 @@ ipa_kdb_tests_LDADD = \
|
|
|
ac7d03 |
$(NDRPAC_LIBS) \
|
|
|
ac7d03 |
$(UNISTRING_LIBS) \
|
|
|
ac7d03 |
$(NSS_LIBS) \
|
|
|
ac7d03 |
+ $(SSSCERTMAP_LIBS) \
|
|
|
ac7d03 |
$(top_builddir)/util/libutil.la \
|
|
|
ac7d03 |
-lkdb5 \
|
|
|
ac7d03 |
-lsss_idmap \
|
|
|
ac7d03 |
$(NULL)
|
|
|
ac7d03 |
|
|
|
ac7d03 |
-dist_noinst_DATA = ipa_kdb.exports
|
|
|
ac7d03 |
+dist_noinst_DATA = ipa_kdb.exports ipa-certauth.in
|
|
|
ac7d03 |
|
|
|
ac7d03 |
clean-local:
|
|
|
ac7d03 |
rm -f tests/.dirstamp
|
|
|
ac7d03 |
diff --git a/daemons/ipa-kdb/ipa-certauth.in b/daemons/ipa-kdb/ipa-certauth.in
|
|
|
ac7d03 |
new file mode 100644
|
|
|
ac7d03 |
index 0000000000000000000000000000000000000000..eda89a26f02fbea449eb754b232b8115904acd21
|
|
|
ac7d03 |
--- /dev/null
|
|
|
ac7d03 |
+++ b/daemons/ipa-kdb/ipa-certauth.in
|
|
|
ac7d03 |
@@ -0,0 +1,5 @@
|
|
|
ac7d03 |
+[plugins]
|
|
|
ac7d03 |
+ certauth = {
|
|
|
ac7d03 |
+ module = ipakdb:@plugindir@/ipadb.so
|
|
|
ac7d03 |
+ enable_only = ipakdb
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
diff --git a/daemons/ipa-kdb/ipa_kdb.c b/daemons/ipa-kdb/ipa_kdb.c
|
|
|
ac7d03 |
index c19b7c40e2e88173ab8367a3ef1d7f46245fd174..a961e4e57cf5379eb237551d56e3bc8dc82d952d 100644
|
|
|
ac7d03 |
--- a/daemons/ipa-kdb/ipa_kdb.c
|
|
|
ac7d03 |
+++ b/daemons/ipa-kdb/ipa_kdb.c
|
|
|
ac7d03 |
@@ -67,6 +67,8 @@ static void ipadb_context_free(krb5_context kcontext,
|
|
|
ac7d03 |
}
|
|
|
ac7d03 |
free(cfg->authz_data);
|
|
|
ac7d03 |
|
|
|
ac7d03 |
+ ipa_certauth_free_moddata(&((*ctx)->certauth_moddata));
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
free(*ctx);
|
|
|
ac7d03 |
*ctx = NULL;
|
|
|
ac7d03 |
}
|
|
|
ac7d03 |
diff --git a/daemons/ipa-kdb/ipa_kdb.exports b/daemons/ipa-kdb/ipa_kdb.exports
|
|
|
ac7d03 |
index d2c3f30246cc7ebcba02a9ec5d134e604fa0dbb9..27ce92d2edd741245061a5f4ee9275169440c932 100644
|
|
|
ac7d03 |
--- a/daemons/ipa-kdb/ipa_kdb.exports
|
|
|
ac7d03 |
+++ b/daemons/ipa-kdb/ipa_kdb.exports
|
|
|
ac7d03 |
@@ -3,6 +3,7 @@ EXPORTED {
|
|
|
ac7d03 |
# public symbols
|
|
|
ac7d03 |
global:
|
|
|
ac7d03 |
kdb_function_table;
|
|
|
ac7d03 |
+ certauth_ipakdb_initvt;
|
|
|
ac7d03 |
|
|
|
ac7d03 |
# everything else is local
|
|
|
ac7d03 |
local:
|
|
|
ac7d03 |
diff --git a/daemons/ipa-kdb/ipa_kdb.h b/daemons/ipa-kdb/ipa_kdb.h
|
|
|
ac7d03 |
index 72f2675809a3267cce30bc06c77335697c7287ad..632c1979d15e88aec86d5e408ed6c7017d8362b8 100644
|
|
|
ac7d03 |
--- a/daemons/ipa-kdb/ipa_kdb.h
|
|
|
ac7d03 |
+++ b/daemons/ipa-kdb/ipa_kdb.h
|
|
|
ac7d03 |
@@ -40,6 +40,7 @@
|
|
|
ac7d03 |
#include <arpa/inet.h>
|
|
|
ac7d03 |
#include <endian.h>
|
|
|
ac7d03 |
#include <unistd.h>
|
|
|
ac7d03 |
+#include <krb5/certauth_plugin.h>
|
|
|
ac7d03 |
|
|
|
ac7d03 |
#include "ipa_krb5.h"
|
|
|
ac7d03 |
#include "ipa_pwd.h"
|
|
|
ac7d03 |
@@ -111,6 +112,7 @@ struct ipadb_context {
|
|
|
ac7d03 |
krb5_key_salt_tuple *def_encs;
|
|
|
ac7d03 |
int n_def_encs;
|
|
|
ac7d03 |
struct ipadb_mspac *mspac;
|
|
|
ac7d03 |
+ krb5_certauth_moddata certauth_moddata;
|
|
|
ac7d03 |
|
|
|
ac7d03 |
/* Don't access this directly, use ipadb_get_global_config(). */
|
|
|
ac7d03 |
struct ipadb_global_config config;
|
|
|
ac7d03 |
@@ -331,3 +333,6 @@ ipadb_get_global_config(struct ipadb_context *ipactx);
|
|
|
ac7d03 |
int ipadb_get_enc_salt_types(struct ipadb_context *ipactx, LDAPMessage *entry,
|
|
|
ac7d03 |
char *attr, krb5_key_salt_tuple **enc_salt_types,
|
|
|
ac7d03 |
int *n_enc_salt_types);
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+/* CERTAUTH PLUGIN */
|
|
|
ac7d03 |
+void ipa_certauth_free_moddata(krb5_certauth_moddata *moddata);
|
|
|
ac7d03 |
diff --git a/daemons/ipa-kdb/ipa_kdb_certauth.c b/daemons/ipa-kdb/ipa_kdb_certauth.c
|
|
|
ac7d03 |
new file mode 100644
|
|
|
ac7d03 |
index 0000000000000000000000000000000000000000..a53a2ce4e7ceb06ec8de117cdbca2666fdb5a97a
|
|
|
ac7d03 |
--- /dev/null
|
|
|
ac7d03 |
+++ b/daemons/ipa-kdb/ipa_kdb_certauth.c
|
|
|
ac7d03 |
@@ -0,0 +1,398 @@
|
|
|
ac7d03 |
+/** BEGIN COPYRIGHT BLOCK
|
|
|
ac7d03 |
+ * This program is free software; you can redistribute it and/or modify
|
|
|
ac7d03 |
+ * it under the terms of the GNU General Public License as published by
|
|
|
ac7d03 |
+ * the Free Software Foundation, either version 3 of the License, or
|
|
|
ac7d03 |
+ * (at your option) any later version.
|
|
|
ac7d03 |
+ *
|
|
|
ac7d03 |
+ * This program is distributed in the hope that it will be useful,
|
|
|
ac7d03 |
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
|
ac7d03 |
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
|
ac7d03 |
+ * GNU General Public License for more details.
|
|
|
ac7d03 |
+ *
|
|
|
ac7d03 |
+ * You should have received a copy of the GNU General Public License
|
|
|
ac7d03 |
+ * along with this program. If not, see <http://www.gnu.org/licenses/>.
|
|
|
ac7d03 |
+ *
|
|
|
ac7d03 |
+ * Additional permission under GPLv3 section 7:
|
|
|
ac7d03 |
+ *
|
|
|
ac7d03 |
+ * In the following paragraph, "GPL" means the GNU General Public
|
|
|
ac7d03 |
+ * License, version 3 or any later version, and "Non-GPL Code" means
|
|
|
ac7d03 |
+ * code that is governed neither by the GPL nor a license
|
|
|
ac7d03 |
+ * compatible with the GPL.
|
|
|
ac7d03 |
+ *
|
|
|
ac7d03 |
+ * You may link the code of this Program with Non-GPL Code and convey
|
|
|
ac7d03 |
+ * linked combinations including the two, provided that such Non-GPL
|
|
|
ac7d03 |
+ * Code only links to the code of this Program through those well
|
|
|
ac7d03 |
+ * defined interfaces identified in the file named EXCEPTION found in
|
|
|
ac7d03 |
+ * the source code files (the "Approved Interfaces"). The files of
|
|
|
ac7d03 |
+ * Non-GPL Code may instantiate templates or use macros or inline
|
|
|
ac7d03 |
+ * functions from the Approved Interfaces without causing the resulting
|
|
|
ac7d03 |
+ * work to be covered by the GPL. Only the copyright holders of this
|
|
|
ac7d03 |
+ * Program may make changes or additions to the list of Approved
|
|
|
ac7d03 |
+ * Interfaces.
|
|
|
ac7d03 |
+ *
|
|
|
ac7d03 |
+ * Authors:
|
|
|
ac7d03 |
+ * Sumit Bose <sbose@redhat.com>
|
|
|
ac7d03 |
+ *
|
|
|
ac7d03 |
+ * Copyright (C) 2017 Red Hat, Inc.
|
|
|
ac7d03 |
+ * All rights reserved.
|
|
|
ac7d03 |
+ * END COPYRIGHT BLOCK **/
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+#include <errno.h>
|
|
|
ac7d03 |
+//#include <krb5/certauth_plugin.h>
|
|
|
ac7d03 |
+#include <syslog.h>
|
|
|
ac7d03 |
+#include <sss_certmap.h>
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+#include "util/ipa_krb5.h"
|
|
|
ac7d03 |
+#include "ipa_kdb.h"
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+#define IPA_OC_CERTMAP_RULE "ipaCertMapRule"
|
|
|
ac7d03 |
+#define IPA_CERTMAP_MAPRULE "ipaCertMapMapRule"
|
|
|
ac7d03 |
+#define IPA_CERTMAP_MATCHRULE "ipaCertMapMatchRule"
|
|
|
ac7d03 |
+#define IPA_CERTMAP_PRIORITY "ipaCertMapPriority"
|
|
|
ac7d03 |
+#define IPA_ENABLED_FLAG "ipaEnabledFlag"
|
|
|
ac7d03 |
+#define IPA_TRUE_VALUE "TRUE"
|
|
|
ac7d03 |
+#define IPA_ASSOCIATED_DOMAIN "associatedDomain"
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+#define OBJECTCLASS "objectClass"
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+#define CERTMAP_FILTER "(&("OBJECTCLASS"="IPA_OC_CERTMAP_RULE")" \
|
|
|
ac7d03 |
+ "("IPA_ENABLED_FLAG"="IPA_TRUE_VALUE"))"
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+#ifndef discard_const
|
|
|
ac7d03 |
+#define discard_const(ptr) ((void *)((uintptr_t)(ptr)))
|
|
|
ac7d03 |
+#endif
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+struct krb5_certauth_moddata_st {
|
|
|
ac7d03 |
+ char *local_domain;
|
|
|
ac7d03 |
+ struct sss_certmap_ctx *sss_certmap_ctx;
|
|
|
ac7d03 |
+ struct ipadb_context *ipactx;
|
|
|
ac7d03 |
+};
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+void ipa_certmap_debug(void *private,
|
|
|
ac7d03 |
+ const char *file, long line,
|
|
|
ac7d03 |
+ const char *function,
|
|
|
ac7d03 |
+ const char *format, ...)
|
|
|
ac7d03 |
+{
|
|
|
ac7d03 |
+ va_list ap;
|
|
|
ac7d03 |
+ char str[255] = { 0 };
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ va_start(ap, format);
|
|
|
ac7d03 |
+ vsnprintf(str, sizeof(str)-1, format, ap);
|
|
|
ac7d03 |
+ va_end(ap);
|
|
|
ac7d03 |
+ krb5_klog_syslog(LOG_INFO, str);
|
|
|
ac7d03 |
+}
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+void ipa_certauth_free_moddata(krb5_certauth_moddata *moddata)
|
|
|
ac7d03 |
+{
|
|
|
ac7d03 |
+ if (moddata == NULL || *moddata == NULL) {
|
|
|
ac7d03 |
+ return;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ free((*moddata)->local_domain);
|
|
|
ac7d03 |
+ (*moddata)->local_domain = NULL;
|
|
|
ac7d03 |
+ sss_certmap_free_ctx((*moddata)->sss_certmap_ctx);
|
|
|
ac7d03 |
+ (*moddata)->sss_certmap_ctx = NULL;
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ free(*moddata);
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ return;
|
|
|
ac7d03 |
+}
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+static krb5_error_code ipa_get_init_data(krb5_context kcontext,
|
|
|
ac7d03 |
+ krb5_certauth_moddata moddata_out)
|
|
|
ac7d03 |
+{
|
|
|
ac7d03 |
+ int ret;
|
|
|
ac7d03 |
+ struct sss_certmap_ctx *ctx = NULL;
|
|
|
ac7d03 |
+ struct ipadb_context *ipactx;
|
|
|
ac7d03 |
+ krb5_error_code kerr;
|
|
|
ac7d03 |
+ char *basedn = NULL;
|
|
|
ac7d03 |
+ LDAPMessage *result = NULL;
|
|
|
ac7d03 |
+ LDAPMessage *le;
|
|
|
ac7d03 |
+ LDAP *lc;
|
|
|
ac7d03 |
+ size_t c;
|
|
|
ac7d03 |
+ uint32_t prio;
|
|
|
ac7d03 |
+ char *map_rule = NULL;
|
|
|
ac7d03 |
+ char *match_rule = NULL;
|
|
|
ac7d03 |
+ char **domains = NULL;
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ const char *certmap_attrs[] = { OBJECTCLASS,
|
|
|
ac7d03 |
+ IPA_CERTMAP_PRIORITY,
|
|
|
ac7d03 |
+ IPA_CERTMAP_MATCHRULE,
|
|
|
ac7d03 |
+ IPA_CERTMAP_MAPRULE,
|
|
|
ac7d03 |
+ IPA_ASSOCIATED_DOMAIN,
|
|
|
ac7d03 |
+ IPA_ENABLED_FLAG,
|
|
|
ac7d03 |
+ NULL};
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ krb5_klog_syslog(LOG_INFO, "Initializing IPA certauth plugin.");
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ ipactx = ipadb_get_context(kcontext);
|
|
|
ac7d03 |
+ if (ipactx == NULL) {
|
|
|
ac7d03 |
+ return KRB5_KDB_DBNOTINITED;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ if (ipactx->certauth_moddata == NULL) {
|
|
|
ac7d03 |
+ ret = asprintf(&basedn, "cn=certmap,%s", ipactx->base);
|
|
|
ac7d03 |
+ if (ret == -1) {
|
|
|
ac7d03 |
+ return ENOMEM;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ kerr = ipadb_simple_search(ipactx,basedn, LDAP_SCOPE_SUBTREE,
|
|
|
ac7d03 |
+ CERTMAP_FILTER, discard_const(certmap_attrs),
|
|
|
ac7d03 |
+ &result);
|
|
|
ac7d03 |
+ if (kerr != 0 && kerr != KRB5_KDB_NOENTRY) {
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ ret = sss_certmap_init(NULL, ipa_certmap_debug, NULL, &ctx;;
|
|
|
ac7d03 |
+ if (ret != 0) {
|
|
|
ac7d03 |
+ return ret;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ if (kerr == KRB5_KDB_NOENTRY) {
|
|
|
ac7d03 |
+ ret = sss_certmap_add_rule(ctx, SSS_CERTMAP_MIN_PRIO,
|
|
|
ac7d03 |
+ NULL, NULL, NULL);
|
|
|
ac7d03 |
+ if (ret != 0) {
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ } else {
|
|
|
ac7d03 |
+ lc = ipactx->lcontext;
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ for (le = ldap_first_entry(lc, result); le;
|
|
|
ac7d03 |
+ le = ldap_next_entry(lc, le)) {
|
|
|
ac7d03 |
+ prio = SSS_CERTMAP_MIN_PRIO;
|
|
|
ac7d03 |
+ ret = ipadb_ldap_attr_to_uint32(lc, le, IPA_CERTMAP_PRIORITY,
|
|
|
ac7d03 |
+ &prio;;
|
|
|
ac7d03 |
+ if (ret != 0 && ret != ENOENT) {
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ free(map_rule);
|
|
|
ac7d03 |
+ map_rule = NULL;
|
|
|
ac7d03 |
+ ret = ipadb_ldap_attr_to_str(lc, le, IPA_CERTMAP_MAPRULE,
|
|
|
ac7d03 |
+ &map_rule);
|
|
|
ac7d03 |
+ if (ret != 0 && ret != ENOENT) {
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ free(match_rule);
|
|
|
ac7d03 |
+ match_rule = NULL;
|
|
|
ac7d03 |
+ ret = ipadb_ldap_attr_to_str(lc, le, IPA_CERTMAP_MATCHRULE,
|
|
|
ac7d03 |
+ &match_rule);
|
|
|
ac7d03 |
+ if (ret != 0 && ret != ENOENT) {
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ if (domains != NULL) {
|
|
|
ac7d03 |
+ for (c = 0; domains[c] != NULL; c++) {
|
|
|
ac7d03 |
+ free(domains[c]);
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ free(domains);
|
|
|
ac7d03 |
+ domains = NULL;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ ret = ipadb_ldap_attr_to_strlist(lc, le, IPA_ASSOCIATED_DOMAIN,
|
|
|
ac7d03 |
+ &domains);
|
|
|
ac7d03 |
+ if (ret != 0 && ret != ENOENT) {
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ ret = sss_certmap_add_rule(ctx, prio, match_rule, map_rule,
|
|
|
ac7d03 |
+ (const char **) domains);
|
|
|
ac7d03 |
+ if (ret != 0) {
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ ipactx->certauth_moddata = moddata_out;
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ if (ipactx->realm != NULL) {
|
|
|
ac7d03 |
+ ipactx->certauth_moddata->local_domain = strdup(ipactx->realm);
|
|
|
ac7d03 |
+ if (ipactx->certauth_moddata->local_domain == NULL) {
|
|
|
ac7d03 |
+ free(ipactx->certauth_moddata);
|
|
|
ac7d03 |
+ ipactx->certauth_moddata = NULL;
|
|
|
ac7d03 |
+ ret = ENOMEM;
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ ipactx->certauth_moddata->sss_certmap_ctx = ctx;
|
|
|
ac7d03 |
+ ipactx->certauth_moddata->ipactx = ipactx;
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ ret = 0;
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+done:
|
|
|
ac7d03 |
+ ldap_msgfree(result);
|
|
|
ac7d03 |
+ free(basedn);
|
|
|
ac7d03 |
+ free(map_rule);
|
|
|
ac7d03 |
+ free(match_rule);
|
|
|
ac7d03 |
+ if (domains != NULL) {
|
|
|
ac7d03 |
+ for (c = 0; domains[c] != NULL; c++) {
|
|
|
ac7d03 |
+ free(domains[c]);
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ free(domains);
|
|
|
ac7d03 |
+ domains = NULL;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ if (ret != 0) {
|
|
|
ac7d03 |
+ sss_certmap_free_ctx(ctx);
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ return ret;
|
|
|
ac7d03 |
+}
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+static krb5_error_code ipa_certauth_authorize(krb5_context context,
|
|
|
ac7d03 |
+ krb5_certauth_moddata moddata,
|
|
|
ac7d03 |
+ const uint8_t *cert,
|
|
|
ac7d03 |
+ size_t cert_len,
|
|
|
ac7d03 |
+ krb5_const_principal princ,
|
|
|
ac7d03 |
+ const void *opts,
|
|
|
ac7d03 |
+ const krb5_db_entry *db_entry,
|
|
|
ac7d03 |
+ char ***authinds_out)
|
|
|
ac7d03 |
+{
|
|
|
ac7d03 |
+ char *cert_filter = NULL;
|
|
|
ac7d03 |
+ char **domains = NULL;
|
|
|
ac7d03 |
+ int ret;
|
|
|
ac7d03 |
+ size_t c;
|
|
|
ac7d03 |
+ char *principal = NULL;
|
|
|
ac7d03 |
+ LDAPMessage *res = NULL;
|
|
|
ac7d03 |
+ krb5_error_code kerr;
|
|
|
ac7d03 |
+ LDAPMessage *lentry;
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ if (moddata == NULL) {
|
|
|
ac7d03 |
+ return KRB5_PLUGIN_NO_HANDLE;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ if (moddata->sss_certmap_ctx == NULL) {
|
|
|
ac7d03 |
+ kerr = ipa_get_init_data(context, moddata);
|
|
|
ac7d03 |
+ if (kerr != 0) {
|
|
|
ac7d03 |
+ krb5_klog_syslog(LOG_ERR, "Failed to init certmapping data");
|
|
|
ac7d03 |
+ return KRB5_PLUGIN_NO_HANDLE;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ ret = krb5_unparse_name(context, princ, &principal);
|
|
|
ac7d03 |
+ if (ret != 0) {
|
|
|
ac7d03 |
+ ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ krb5_klog_syslog(LOG_INFO, "Doing certauth authorize for [%s]", principal);
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ ret = sss_certmap_get_search_filter(moddata->sss_certmap_ctx,
|
|
|
ac7d03 |
+ cert, cert_len,
|
|
|
ac7d03 |
+ &cert_filter, &domains);
|
|
|
ac7d03 |
+ if (ret != 0) {
|
|
|
ac7d03 |
+ if (ret == ENOENT) {
|
|
|
ac7d03 |
+ ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ krb5_klog_syslog(LOG_INFO, "Got cert filter [%s]", cert_filter);
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ /* If there are no domains assigned the rule will apply to the local
|
|
|
ac7d03 |
+ * domain only. */
|
|
|
ac7d03 |
+ if (domains != NULL) {
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ if (moddata->local_domain == NULL) {
|
|
|
ac7d03 |
+ /* We don't know our own domain name, in general this should not
|
|
|
ac7d03 |
+ * happen. But to be fault tolerant we allow matching rule which
|
|
|
ac7d03 |
+ * do not have a domain assigned. */
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ for (c = 0; domains[c] != NULL; c++) {
|
|
|
ac7d03 |
+ if (strcasecmp(domains[c], moddata->local_domain) == 0) {
|
|
|
ac7d03 |
+ break;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ /* Our domain was not in the list */
|
|
|
ac7d03 |
+ if (domains[c] == NULL) {
|
|
|
ac7d03 |
+ ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ kerr = ipadb_fetch_principals_with_extra_filter(moddata->ipactx,
|
|
|
ac7d03 |
+ KRB5_KDB_FLAG_ALIAS_OK,
|
|
|
ac7d03 |
+ principal,
|
|
|
ac7d03 |
+ cert_filter,
|
|
|
ac7d03 |
+ &res;;
|
|
|
ac7d03 |
+ if (kerr != 0) {
|
|
|
ac7d03 |
+ krb5_klog_syslog(LOG_ERR, "Search failed [%d]", kerr);
|
|
|
ac7d03 |
+ ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ kerr = ipadb_find_principal(context, KRB5_KDB_FLAG_ALIAS_OK, res,
|
|
|
ac7d03 |
+ &principal, &lentry);
|
|
|
ac7d03 |
+ if (kerr == KRB5_KDB_NOENTRY) {
|
|
|
ac7d03 |
+ krb5_klog_syslog(LOG_INFO, "No matching entry found");
|
|
|
ac7d03 |
+ ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ } else if (kerr != 0) {
|
|
|
ac7d03 |
+ krb5_klog_syslog(LOG_ERR, "ipadb_find_principal failed [%d]", kerr);
|
|
|
ac7d03 |
+ ret = KRB5KDC_ERR_CERTIFICATE_MISMATCH;
|
|
|
ac7d03 |
+ goto done;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ /* TODO: add more tests ? */
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ ret = 0;
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+done:
|
|
|
ac7d03 |
+ sss_certmap_free_filter_and_domains(cert_filter, domains);
|
|
|
ac7d03 |
+ krb5_free_unparsed_name(context, principal);
|
|
|
ac7d03 |
+ ldap_msgfree(res);
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ return ret;
|
|
|
ac7d03 |
+}
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+static krb5_error_code ipa_certauth_init(krb5_context kcontext,
|
|
|
ac7d03 |
+ krb5_certauth_moddata *moddata_out)
|
|
|
ac7d03 |
+{
|
|
|
ac7d03 |
+ struct krb5_certauth_moddata_st *certauth_moddata;
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ certauth_moddata = calloc(1, sizeof(struct krb5_certauth_moddata_st));
|
|
|
ac7d03 |
+ if (certauth_moddata == NULL) {
|
|
|
ac7d03 |
+ return ENOMEM;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ *moddata_out = certauth_moddata;
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ return 0;
|
|
|
ac7d03 |
+}
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+static void ipa_certauth_fini(krb5_context context,
|
|
|
ac7d03 |
+ krb5_certauth_moddata moddata_out)
|
|
|
ac7d03 |
+{
|
|
|
ac7d03 |
+ krb5_klog_syslog(LOG_INFO, "IPA certauth plugin un-loaded.");
|
|
|
ac7d03 |
+ return;
|
|
|
ac7d03 |
+}
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+krb5_error_code certauth_ipakdb_initvt(krb5_context context,
|
|
|
ac7d03 |
+ int maj_ver, int min_ver,
|
|
|
ac7d03 |
+ krb5_plugin_vtable vtable)
|
|
|
ac7d03 |
+{
|
|
|
ac7d03 |
+ krb5_certauth_vtable vt;
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ if (maj_ver != 1) {
|
|
|
ac7d03 |
+ return KRB5_PLUGIN_VER_NOTSUPP;
|
|
|
ac7d03 |
+ }
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ vt = (krb5_certauth_vtable) vtable;
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
+ vt->name = "ipakdb";
|
|
|
ac7d03 |
+ vt->authorize = ipa_certauth_authorize;
|
|
|
ac7d03 |
+ vt->init = ipa_certauth_init;
|
|
|
ac7d03 |
+ vt->fini = ipa_certauth_fini;
|
|
|
ac7d03 |
+ /* currently we do not return authentication indicators */
|
|
|
ac7d03 |
+ vt->free_ind = NULL;
|
|
|
ac7d03 |
+ return 0;
|
|
|
ac7d03 |
+}
|
|
|
ac7d03 |
diff --git a/freeipa.spec.in b/freeipa.spec.in
|
|
|
ac7d03 |
index f776b34af88cc8ccd02da0713cb6eaca161c99f5..18291a5793a6b69dcd719f42e80e1652169e5e1d 100644
|
|
|
ac7d03 |
--- a/freeipa.spec.in
|
|
|
ac7d03 |
+++ b/freeipa.spec.in
|
|
|
ac7d03 |
@@ -120,6 +120,7 @@ BuildRequires: libtalloc-devel
|
|
|
ac7d03 |
BuildRequires: libtevent-devel
|
|
|
ac7d03 |
BuildRequires: libuuid-devel
|
|
|
ac7d03 |
BuildRequires: libsss_idmap-devel
|
|
|
ac7d03 |
+BuildRequires: libsss_certmap-devel
|
|
|
ac7d03 |
# 1.14.0: sss_nss_getnamebycert (https://fedorahosted.org/sssd/ticket/2897)
|
|
|
ac7d03 |
BuildRequires: libsss_nss_idmap-devel >= 1.14.0
|
|
|
ac7d03 |
BuildRequires: rhino
|
|
|
ac7d03 |
@@ -1164,6 +1165,7 @@ fi
|
|
|
ac7d03 |
%attr(0755,root,root) %{_libexecdir}/ipa/oddjob/org.freeipa.server.conncheck
|
|
|
ac7d03 |
%config(noreplace) %{_sysconfdir}/dbus-1/system.d/org.freeipa.server.conf
|
|
|
ac7d03 |
%config(noreplace) %{_sysconfdir}/oddjobd.conf.d/ipa-server.conf
|
|
|
ac7d03 |
+%config(noreplace) %{_sysconfdir}/krb5.conf.d/ipa-certauth
|
|
|
ac7d03 |
%dir %{_libexecdir}/ipa/certmonger
|
|
|
ac7d03 |
%attr(755,root,root) %{_libexecdir}/ipa/certmonger/*
|
|
|
ac7d03 |
# NOTE: systemd specific section
|
|
|
ac7d03 |
diff --git a/server.m4 b/server.m4
|
|
|
ac7d03 |
index 92b5cdd3a6ff90b70a9002360ff3d3aec5053392..7b2e94df91a4803849e496142788a4ed87ef487d 100644
|
|
|
ac7d03 |
--- a/server.m4
|
|
|
ac7d03 |
+++ b/server.m4
|
|
|
ac7d03 |
@@ -30,6 +30,19 @@ dnl -- sss_idmap is needed by the extdom exop --
|
|
|
ac7d03 |
PKG_CHECK_MODULES([SSSIDMAP], [sss_idmap])
|
|
|
ac7d03 |
PKG_CHECK_MODULES([SSSNSSIDMAP], [sss_nss_idmap >= 1.13.90])
|
|
|
ac7d03 |
|
|
|
ac7d03 |
+dnl -- sss_certmap and certauth.h are needed by the IPA KDB certauth plugin --
|
|
|
ac7d03 |
+PKG_CHECK_EXISTS([sss_certmap],
|
|
|
ac7d03 |
+ [PKG_CHECK_MODULES([SSSCERTMAP], [sss_certmap])],
|
|
|
ac7d03 |
+ [AC_MSG_NOTICE([sss_certmap not found])])
|
|
|
ac7d03 |
+AC_CHECK_HEADER([krb5/certauth_plugin.h],
|
|
|
ac7d03 |
+ [have_certauth_plugin=yes],
|
|
|
ac7d03 |
+ [have_certauth_plugin=no])
|
|
|
ac7d03 |
+AM_CONDITIONAL([BUILD_IPA_CERTAUTH_PLUGIN],
|
|
|
ac7d03 |
+ [test x$have_certauth_plugin = xyes -a x"$SSSCERTMAP_LIBS" != x])
|
|
|
ac7d03 |
+AM_COND_IF([BUILD_IPA_CERTAUTH_PLUGIN],
|
|
|
ac7d03 |
+ [AC_MSG_NOTICE([Build IPA KDB certauth plugin])],
|
|
|
ac7d03 |
+ [AC_MSG_WARN([Cannot build IPA KDB certauth plugin])])
|
|
|
ac7d03 |
+
|
|
|
ac7d03 |
dnl ---------------------------------------------------------------------------
|
|
|
ac7d03 |
dnl - Check for KRB5 krad
|
|
|
ac7d03 |
dnl ---------------------------------------------------------------------------
|
|
|
ac7d03 |
--
|
|
|
ac7d03 |
2.12.1
|
|
|
ac7d03 |
|