Users that can rename the token (such as admins) can also create non-UUID token names.
https://fedorahosted.org/freeipa/ticket/4456 NOTE: this patch is an alternate approach to my patch 0065. This version has two main advantages compared to 0065: 1. Permissions are more flexible (not tied to the admin group). 2. Enforcement occurs at the DS-level It should also be noted that this patch does not enforce UUID randomness, only syntax. Users can still specify a token ID so long as it is in UUID format. Nathaniel
From aed2d3705a050d24119d2b5124088dfcb76b81d7 Mon Sep 17 00:00:00 2001 From: Nathaniel McCallum <npmccal...@redhat.com> Date: Sun, 21 Sep 2014 14:58:32 -0400 Subject: [PATCH] Adds 389DS plugin to enforce UUID token IDs Users that can rename the token (such as admins) can also create non-UUID token names. https://fedorahosted.org/freeipa/ticket/4456 --- daemons/configure.ac | 1 + daemons/ipa-slapi-plugins/Makefile.am | 1 + .../ipa-slapi-plugins/ipa-otp-tokenid/Makefile.am | 25 +++ .../ipa-otp-tokenid/ipa-otp-tokenid.sym | 1 + .../ipa-otp-tokenid/ipa_otp_tokenid.c | 206 +++++++++++++++++++++ .../ipa-otp-tokenid/otp-tokenid-conf.ldif | 15 ++ freeipa.spec.in | 2 + ipaserver/install/dsinstance.py | 4 + 8 files changed, 255 insertions(+) create mode 100644 daemons/ipa-slapi-plugins/ipa-otp-tokenid/Makefile.am create mode 100644 daemons/ipa-slapi-plugins/ipa-otp-tokenid/ipa-otp-tokenid.sym create mode 100644 daemons/ipa-slapi-plugins/ipa-otp-tokenid/ipa_otp_tokenid.c create mode 100644 daemons/ipa-slapi-plugins/ipa-otp-tokenid/otp-tokenid-conf.ldif diff --git a/daemons/configure.ac b/daemons/configure.ac index b4507a6d972f854331925e72869898576bdfd76f..55636c9dd62985e54b6bb4599211d96001582d1e 100644 --- a/daemons/configure.ac +++ b/daemons/configure.ac @@ -315,6 +315,7 @@ AC_CONFIG_FILES([ ipa-slapi-plugins/ipa-enrollment/Makefile ipa-slapi-plugins/ipa-lockout/Makefile ipa-slapi-plugins/ipa-otp-lasttoken/Makefile + ipa-slapi-plugins/ipa-otp-tokenid/Makefile ipa-slapi-plugins/ipa-pwd-extop/Makefile ipa-slapi-plugins/ipa-extdom-extop/Makefile ipa-slapi-plugins/ipa-winsync/Makefile diff --git a/daemons/ipa-slapi-plugins/Makefile.am b/daemons/ipa-slapi-plugins/Makefile.am index 06e6ee8b86f138cce05f2184ac98c39ffaf9757f..08ce230686ca4dd16c15f08c40826aefd7023bd8 100644 --- a/daemons/ipa-slapi-plugins/Makefile.am +++ b/daemons/ipa-slapi-plugins/Makefile.am @@ -8,6 +8,7 @@ SUBDIRS = \ ipa-lockout \ ipa-modrdn \ ipa-otp-lasttoken \ + ipa-otp-tokenid \ ipa-pwd-extop \ ipa-extdom-extop \ ipa-uuid \ diff --git a/daemons/ipa-slapi-plugins/ipa-otp-tokenid/Makefile.am b/daemons/ipa-slapi-plugins/ipa-otp-tokenid/Makefile.am new file mode 100644 index 0000000000000000000000000000000000000000..4889af554c001433b41f7b9e08aa2628e38b6bc7 --- /dev/null +++ b/daemons/ipa-slapi-plugins/ipa-otp-tokenid/Makefile.am @@ -0,0 +1,25 @@ +MAINTAINERCLEANFILES = *~ Makefile.in +PLUGIN_COMMON_DIR = ../common +AM_CPPFLAGS = \ + -I. \ + -I$(srcdir) \ + -I$(PLUGIN_COMMON_DIR) \ + -I/usr/include/dirsrv \ + -DPREFIX=\""$(prefix)"\" \ + -DBINDIR=\""$(bindir)"\" \ + -DLIBDIR=\""$(libdir)"\" \ + -DLIBEXECDIR=\""$(libexecdir)"\" \ + -DDATADIR=\""$(datadir)"\" \ + $(AM_CFLAGS) \ + $(LDAP_CFLAGS) \ + $(WARN_CFLAGS) + +plugindir = $(libdir)/dirsrv/plugins +plugin_LTLIBRARIES = libipa_otp_tokenid.la +libipa_otp_tokenid_la_SOURCES = ipa_otp_tokenid.c +libipa_otp_tokenid_la_LDFLAGS = -avoid-version -export-symbols ipa-otp-tokenid.sym +libipa_otp_tokenid_la_LIBADD = $(LDAP_LIBS) + +appdir = $(IPA_DATA_DIR) +app_DATA = otp-tokenid-conf.ldif +EXTRA_DIST = $(app_DATA) diff --git a/daemons/ipa-slapi-plugins/ipa-otp-tokenid/ipa-otp-tokenid.sym b/daemons/ipa-slapi-plugins/ipa-otp-tokenid/ipa-otp-tokenid.sym new file mode 100644 index 0000000000000000000000000000000000000000..ed6aaa999928c833cfe13f95a3bd0d273b5fcd86 --- /dev/null +++ b/daemons/ipa-slapi-plugins/ipa-otp-tokenid/ipa-otp-tokenid.sym @@ -0,0 +1 @@ +ipa_otp_tokenid_init diff --git a/daemons/ipa-slapi-plugins/ipa-otp-tokenid/ipa_otp_tokenid.c b/daemons/ipa-slapi-plugins/ipa-otp-tokenid/ipa_otp_tokenid.c new file mode 100644 index 0000000000000000000000000000000000000000..8778ed3aadda98e5beef51b3d06b047b01821f6c --- /dev/null +++ b/daemons/ipa-slapi-plugins/ipa-otp-tokenid/ipa_otp_tokenid.c @@ -0,0 +1,206 @@ +/** BEGIN COPYRIGHT BLOCK + * 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/>. + * + * Additional permission under GPLv3 section 7: + * + * In the following paragraph, "GPL" means the GNU General Public + * License, version 3 or any later version, and "Non-GPL Code" means + * code that is governed neither by the GPL nor a license + * compatible with the GPL. + * + * You may link the code of this Program with Non-GPL Code and convey + * linked combinations including the two, provided that such Non-GPL + * Code only links to the code of this Program through those well + * defined interfaces identified in the file named EXCEPTION found in + * the source code files (the "Approved Interfaces"). The files of + * Non-GPL Code may instantiate templates or use macros or inline + * functions from the Approved Interfaces without causing the resulting + * work to be covered by the GPL. Only the copyright holders of this + * Program may make changes or additions to the list of Approved + * Interfaces. + * + * Authors: + * Nathaniel McCallum <npmccal...@redhat.com> + * + * Copyright (C) 2014 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <slapi-plugin.h> +#include <stdbool.h> +#include <plstr.h> + +static int +send_error(Slapi_PBlock *pb, int rc, char *msg) +{ + slapi_send_ldap_result(pb, rc, NULL, msg, 0, NULL); + slapi_pblock_set(pb, SLAPI_RESULT_CODE, &rc); + return rc; +} + +static bool +is_token(Slapi_Entry *entry) +{ + char **clsses = slapi_entry_attr_get_charray(entry, "objectClass"); + for (size_t i = 0; clsses != NULL && clsses[i] != NULL; i++) { + if (PL_strcasecmp("ipaToken", clsses[i]) == 0) + return true; + } + + slapi_ch_array_free(clsses); + return false; +} + +static bool +is_hex(char c) +{ + switch (c) { + case '0': + case '1': + case '2': + case '3': + case '4': + case '5': + case '6': + case '7': + case '8': + case '9': + case 'a': + case 'b': + case 'c': + case 'd': + case 'e': + case 'f': + return true; + default: + return false; + } +} + +static bool +is_hex_group(const char **str, size_t n, char c) +{ + for (size_t i = 0; i < n; i++) { + if (!is_hex(*(*str)++)) + return false; + } + + return *(*str)++ == c; +} + +static bool +is_uuid(const char *str, ...) +{ + if (!is_hex_group(&str, 8, '-')) + return false; + + if (!is_hex_group(&str, 4, '-')) + return false; + + if (!is_hex_group(&str, 4, '-')) + return false; + + if (!is_hex_group(&str, 4, '-')) + return false; + + return is_hex_group(&str, 12, '\0'); +} + +static int +preop_add(Slapi_PBlock *pb) +{ + Slapi_Entry *entry = NULL; + int is_repl_op = 0; + char *id; + + /* Bypass replication operations. */ + slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &is_repl_op); + if (is_repl_op) + return 0; + + /* Get the entry to be added. */ + slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &entry); + if (entry == NULL) + return 0; + + /* Ensure this is a token. */ + if (!is_token(entry)) + return 0; + + /* Get the ID. */ + id = slapi_entry_attr_get_charptr(entry, "ipatokenUniqueID"); + if (id == NULL) + return 0; + + /* Don't block operations that are in UUID format. */ + if (is_uuid(id)) { + slapi_ch_free_string(&id); + return 0; + } + + /* Non-UUIDs are allowed if the write ACI passes. */ + slapi_ch_free_string(&id); + if (slapi_access_allowed(pb, entry, "ipatokenUniqueID", + NULL, SLAPI_ACL_WRITE) == LDAP_SUCCESS) + return 0; + + return send_error(pb, LDAP_INSUFFICIENT_ACCESS, + "ipatokenUniqueID must be a UUID"); +} + +static int +preop_init(Slapi_PBlock *pb) +{ + return slapi_pblock_set(pb, SLAPI_PLUGIN_BE_TXN_PRE_ADD_FN, preop_add); +} + +static int +start_fn(Slapi_PBlock *pb) +{ + return 0; +} + +static int +close_fn(Slapi_PBlock *pb) +{ + return 0; +} + +int +ipa_otp_tokenid_init(Slapi_PBlock *pb) +{ + static const Slapi_PluginDesc preop_desc = { + "ipa-otp-tokenid", + "FreeIPA", + "FreeIPA/1.0", + "Only permit UUID token IDs for normal users" + }; + + void *plugin_id; + int ret = 0; + + ret |= slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &plugin_id); + ret |= slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION, SLAPI_PLUGIN_VERSION_01); + ret |= slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION, (void *) &preop_desc); + ret |= slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, start_fn); + ret |= slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, close_fn); + ret |= slapi_register_plugin("betxnpreoperation", 1, __func__, preop_init, + preop_desc.spd_id, NULL, plugin_id); + + return ret; +} diff --git a/daemons/ipa-slapi-plugins/ipa-otp-tokenid/otp-tokenid-conf.ldif b/daemons/ipa-slapi-plugins/ipa-otp-tokenid/otp-tokenid-conf.ldif new file mode 100644 index 0000000000000000000000000000000000000000..9843a497f3d836840eed09643b92369c2f204ecc --- /dev/null +++ b/daemons/ipa-slapi-plugins/ipa-otp-tokenid/otp-tokenid-conf.ldif @@ -0,0 +1,15 @@ +dn: cn=IPA OTP Token ID,cn=plugins,cn=config +changetype: add +objectclass: top +objectclass: nsSlapdPlugin +objectclass: extensibleObject +cn: IPA OTP Token ID +nsslapd-pluginpath: libipa_otp_tokenid +nsslapd-plugininitfunc: ipa_otp_tokenid_init +nsslapd-plugintype: preoperation +nsslapd-pluginenabled: on +nsslapd-pluginid: ipa-otp-tokenid +nsslapd-pluginversion: 1.0 +nsslapd-pluginvendor: Red Hat, Inc. +nsslapd-plugindescription: IPA OTP Token ID plugin +nsslapd-plugin-depends-on-type: database diff --git a/freeipa.spec.in b/freeipa.spec.in index 685b345fedb9d157c8deedc66f8712da32c5963b..d656cf71da713371b423cc4b1cdb20b41886baa3 100644 --- a/freeipa.spec.in +++ b/freeipa.spec.in @@ -349,6 +349,7 @@ rm %{buildroot}/%{plugin_dir}/libipa_sidgen_task.la rm %{buildroot}/%{plugin_dir}/libipa_extdom_extop.la rm %{buildroot}/%{plugin_dir}/libipa_range_check.la rm %{buildroot}/%{plugin_dir}/libipa_otp_lasttoken.la +rm %{buildroot}/%{plugin_dir}/libipa_otp_tokenid.la rm %{buildroot}/%{_libdir}/krb5/plugins/kdb/ipadb.la rm %{buildroot}/%{_libdir}/samba/pdb/ipasam.la @@ -698,6 +699,7 @@ fi %attr(755,root,root) %{plugin_dir}/libipa_dns.so %attr(755,root,root) %{plugin_dir}/libipa_range_check.so %attr(755,root,root) %{plugin_dir}/libipa_otp_lasttoken.so +%attr(755,root,root) %{plugin_dir}/libipa_otp_tokenid.so %dir %{_localstatedir}/lib/ipa %attr(700,root,root) %dir %{_localstatedir}/lib/ipa/backup %attr(700,root,root) %dir %{_localstatedir}/lib/ipa/sysrestore diff --git a/ipaserver/install/dsinstance.py b/ipaserver/install/dsinstance.py index 0518dd0e0f20255f4e42911af6f1f95fc25f554e..4463a95b06214701fb66d0a8754898a436c2ac66 100644 --- a/ipaserver/install/dsinstance.py +++ b/ipaserver/install/dsinstance.py @@ -277,6 +277,7 @@ class DsInstance(service.Service): self.step("enabling entryUSN plugin", self.__enable_entryusn) self.step("configuring lockout plugin", self.__config_lockout_module) self.step("configuring OTP last token plugin", self.__config_otp_lasttoken_module) + self.step("configuring OTP token ID plugin", self.__config_otp_tokenid_module) self.step("creating indices", self.__create_indices) self.step("enabling referential integrity plugin", self.__add_referint_module) if enable_ssl: @@ -591,6 +592,9 @@ class DsInstance(service.Service): def __config_otp_lasttoken_module(self): self._ldap_mod("otp-lasttoken-conf.ldif") + def __config_otp_tokenid_module(self): + self._ldap_mod("otp-tokenid-conf.ldif") + def __repoint_managed_entries(self): self._ldap_mod("repoint-managed-entries.ldif", self.sub_dict) -- 2.1.0
_______________________________________________ Freeipa-devel mailing list Freeipa-devel@redhat.com https://www.redhat.com/mailman/listinfo/freeipa-devel