summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorPetr Spacek <pspacek@redhat.com>2013-03-08 18:54:58 +0100
committerMartin Kosek <mkosek@redhat.com>2013-03-22 14:31:22 +0100
commit952a7ac9f55e09eeaa7a24400957aac684a616fb (patch)
tree3641375ac8daf2b7fd06cee459e031a1d8d911e0
parent797baef1a433d14694fcb234c24828c1ad4019dc (diff)
downloadfreeipa-952a7ac9f55e09eeaa7a24400957aac684a616fb.tar.gz
freeipa-952a7ac9f55e09eeaa7a24400957aac684a616fb.tar.xz
freeipa-952a7ac9f55e09eeaa7a24400957aac684a616fb.zip
Add 389 DS plugin for special idnsSOASerial attribute handling
Default value "1" is added to replicated idnsZone objects if idnsSOASerial attribute is missing. https://fedorahosted.org/freeipa/ticket/3347 Signed-off-by: Petr Spacek <pspacek@redhat.com>
-rw-r--r--daemons/configure.ac1
-rw-r--r--daemons/ipa-slapi-plugins/Makefile.am1
-rw-r--r--daemons/ipa-slapi-plugins/ipa-dns/Makefile.am40
-rw-r--r--daemons/ipa-slapi-plugins/ipa-dns/ipa_dns.c211
-rw-r--r--freeipa.spec.in2
5 files changed, 255 insertions, 0 deletions
diff --git a/daemons/configure.ac b/daemons/configure.ac
index ae57d64ee..d3b6b19d1 100644
--- a/daemons/configure.ac
+++ b/daemons/configure.ac
@@ -334,6 +334,7 @@ AC_CONFIG_FILES([
ipa-sam/Makefile
ipa-slapi-plugins/Makefile
ipa-slapi-plugins/ipa-cldap/Makefile
+ ipa-slapi-plugins/ipa-dns/Makefile
ipa-slapi-plugins/ipa-enrollment/Makefile
ipa-slapi-plugins/ipa-lockout/Makefile
ipa-slapi-plugins/ipa-pwd-extop/Makefile
diff --git a/daemons/ipa-slapi-plugins/Makefile.am b/daemons/ipa-slapi-plugins/Makefile.am
index c79e68db1..08c7558c8 100644
--- a/daemons/ipa-slapi-plugins/Makefile.am
+++ b/daemons/ipa-slapi-plugins/Makefile.am
@@ -2,6 +2,7 @@ NULL =
SUBDIRS = \
ipa-cldap \
+ ipa-dns \
ipa-enrollment \
ipa-lockout \
ipa-modrdn \
diff --git a/daemons/ipa-slapi-plugins/ipa-dns/Makefile.am b/daemons/ipa-slapi-plugins/ipa-dns/Makefile.am
new file mode 100644
index 000000000..319c6676e
--- /dev/null
+++ b/daemons/ipa-slapi-plugins/ipa-dns/Makefile.am
@@ -0,0 +1,40 @@
+NULL =
+
+PLUGIN_COMMON_DIR=../common
+
+INCLUDES = \
+ -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) \
+ $(NULL)
+
+plugindir = $(libdir)/dirsrv/plugins
+plugin_LTLIBRARIES = \
+ libipa_dns.la \
+ $(NULL)
+
+libipa_dns_la_SOURCES = \
+ ipa_dns.c \
+ $(NULL)
+
+libipa_dns_la_LDFLAGS = -avoid-version
+
+libipa_dns_la_LIBADD = \
+ $(LDAP_LIBS) \
+ $(NULL)
+
+EXTRA_DIST = \
+ $(NULL)
+
+MAINTAINERCLEANFILES = \
+ *~ \
+ Makefile.in
diff --git a/daemons/ipa-slapi-plugins/ipa-dns/ipa_dns.c b/daemons/ipa-slapi-plugins/ipa-dns/ipa_dns.c
new file mode 100644
index 000000000..0769a54aa
--- /dev/null
+++ b/daemons/ipa-slapi-plugins/ipa-dns/ipa_dns.c
@@ -0,0 +1,211 @@
+/** 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; version 2 of the License.
+ *
+ * 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, write to the Free Software Foundation, Inc., 59 Temple
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
+ *
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
+ * Copyright (C) 2013 Red Hat, Inc.
+ *
+ * Authors:
+ * original authors of 389 example ldap/servers/slapd/test-plugins/testpreop.c
+ * Petr Spacek <pspacek@redhat.com>
+ *
+ * All rights reserved.
+ *
+ * END COPYRIGHT BLOCK **/
+
+/*
+ * This is 389 DS plug-in with supporting functions for IPA-integrated DNS.
+ *
+ * To test this plug-in, stop the server, edit the dse.ldif file
+ * (in the <server_root>/slapd-<server_id>/config directory)
+ * and add the following lines before restarting the server:
+ *
+ * dn: cn=IPA DNS,cn=plugins,cn=config
+ * objectClass: top
+ * objectClass: nsslapdPlugin
+ * objectClass: extensibleObject
+ * cn: IPA DNS
+ * nsslapd-pluginDescription: IPA DNS support plugin
+ * nsslapd-pluginEnabled: on
+ * nsslapd-pluginId: ipa_dns
+ * nsslapd-pluginInitfunc: ipadns_init
+ * nsslapd-pluginPath: libipa_dns.so
+ * nsslapd-pluginType: preoperation
+ * nsslapd-pluginVendor: Red Hat, Inc.
+ * nsslapd-pluginVersion: 1.0
+ * nsslapd-plugin-depends-on-type: database
+ */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include "slapi-plugin.h"
+#include "util.h"
+
+#define IPA_PLUGIN_NAME "ipa_dns"
+#define IPADNS_CLASS_ZONE "idnsZone"
+#define IPADNS_ATTR_SERIAL "idnsSOASerial"
+#define IPADNS_DEFAULT_SERIAL "1"
+
+#define EFALSE 0
+#define ETRUE 1
+
+Slapi_PluginDesc ipadns_desc = { IPA_PLUGIN_NAME, "Red Hat, Inc.", "1.0",
+ "IPA DNS support plugin" };
+
+/* Global variable with "constant" = IPADNS_ZONE_SERIAL. */
+Slapi_Value *value_zone = NULL;
+
+/**
+ * Determine if given entry represents IPA DNS zone.
+ *
+ * \return \c 0 when objectClass idnsZone is not present in the entry.
+ * \return \c 1 when objectClass idnsZone is present in the entry.
+ * \return \c -1 when some error occurred.
+ */
+int
+ipadns_entry_iszone( Slapi_Entry *entry ) {
+ Slapi_Attr *obj_class = NULL;
+ Slapi_Value *value = NULL;
+ char *dn = NULL;
+ int hint = 0;
+
+ dn = slapi_entry_get_dn( entry );
+
+ if ( slapi_entry_attr_find( entry, SLAPI_ATTR_OBJECTCLASS, &obj_class )
+ != 0) {
+ LOG( "Object without objectClass encountered: entry '%s'\n",
+ dn );
+ return EFAIL;
+ }
+
+ if ( slapi_attr_first_value( obj_class, &value ) != 0 ) {
+ LOG( "Cannot iterate over objectClass values in entry '%s'\n",
+ dn );
+ return EOK;
+ }
+
+ do {
+ if ( slapi_value_compare( obj_class, value, value_zone ) == 0 )
+ return ETRUE; /* Entry is a DNS zone */
+
+ hint = slapi_attr_next_value( obj_class, hint, &value );
+ } while ( hint != -1 );
+
+ return EFALSE; /* Entry is not a DNS zone */
+}
+
+/**
+ * The server calls this plug-in function before executing LDAP ADD operation.
+ *
+ * ipadns_add function adds default value to idnsSOAserial attribute
+ * in idnsZone objects if the the attribute is not present.
+ *
+ * Default value is added only to objects coming from other servers
+ * via replication.
+ */
+int
+ipadns_add( Slapi_PBlock *pb )
+{
+ Slapi_Entry *e = NULL;
+ Slapi_Attr *a = NULL;
+ char *dn = NULL;
+ int cnt;
+ int ret;
+ int is_repl_op;
+
+ if ( slapi_pblock_get( pb, SLAPI_IS_REPLICATED_OPERATION,
+ &is_repl_op ) != 0 ) {
+ LOG_FATAL( "slapi_pblock_get SLAPI_IS_REPLICATED_OPERATION "
+ "failed!?\n" );
+ return EFAIL;
+ }
+
+ /* Mangle only ADDs coming from replication. */
+ if ( !is_repl_op )
+ return EOK;
+
+ /* Get the entry that is about to be added. */
+ if ( slapi_pblock_get( pb, SLAPI_ADD_ENTRY, &e ) != 0 ) {
+ LOG( "Could not get entry\n" );
+ return EFAIL;
+ }
+ dn = slapi_entry_get_dn( e );
+
+ /* Do nothing if entry doesn't represent IPA DNS zone. */
+ ret = ipadns_entry_iszone( e );
+ if ( ret == EFALSE )
+ return EOK;
+ else if ( ret == EFAIL ) {
+ LOG( "Could not check objectClasses in entry '%s'\n", dn );
+ return EFAIL; /* TODO: Should I return OK to not block DS? */
+ }
+
+ /* Do nothing if the entry already has idnsSOASerial attribute set
+ * and a value is present. */
+ if ( slapi_entry_attr_find( e, IPADNS_ATTR_SERIAL, &a ) == 0 ) {
+ if ( slapi_attr_get_numvalues( a, &cnt ) != 0 ) {
+ LOG( "Could not get value count for attribute '%s' "
+ "in entry '%s'\n", IPADNS_ATTR_SERIAL, dn );
+ return EFAIL;
+ } else if ( cnt != 0 ) {
+ return EOK;
+ }
+ }
+
+ if ( slapi_entry_add_string( e, IPADNS_ATTR_SERIAL,
+ IPADNS_DEFAULT_SERIAL ) != 0 ) {
+ LOG( "Could not add default SOA serial to entry '%s'\n", dn );
+ return EFAIL;
+ }
+
+ return EOK; /* allow the operation to continue */
+}
+
+static int
+ipadns_close( Slapi_PBlock *pb )
+{
+ ( void ) pb;
+ if ( value_zone )
+ slapi_value_free( &value_zone );
+
+ return EOK;
+}
+
+/* Initialization function. */
+#ifdef _WIN32
+__declspec(dllexport)
+#endif
+int
+ipadns_init( Slapi_PBlock *pb )
+{
+ /* Register the two pre-operation plug-in functions,
+ and specify the server plug-in version. */
+ if ( slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
+ SLAPI_PLUGIN_VERSION_03 ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *)&ipadns_desc ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_CLOSE_FN,
+ (void *) ipadns_close ) != 0 ||
+ slapi_pblock_set( pb, SLAPI_PLUGIN_PRE_ADD_FN,
+ (void *) ipadns_add ) != 0 ) {
+ LOG_FATAL( "Failed to set version and function\n" );
+ return EFAIL;
+ }
+
+ value_zone = slapi_value_new_string( IPADNS_CLASS_ZONE );
+
+ return EOK;
+}
diff --git a/freeipa.spec.in b/freeipa.spec.in
index 1a390648c..f864cb2ad 100644
--- a/freeipa.spec.in
+++ b/freeipa.spec.in
@@ -341,6 +341,7 @@ rm %{buildroot}/%{plugin_dir}/libipa_uuid.la
rm %{buildroot}/%{plugin_dir}/libipa_modrdn.la
rm %{buildroot}/%{plugin_dir}/libipa_lockout.la
rm %{buildroot}/%{plugin_dir}/libipa_cldap.la
+rm %{buildroot}/%{plugin_dir}/libipa_dns.la
rm %{buildroot}/%{plugin_dir}/libipa_sidgen.la
rm %{buildroot}/%{plugin_dir}/libipa_sidgen_task.la
rm %{buildroot}/%{plugin_dir}/libipa_extdom_extop.la
@@ -667,6 +668,7 @@ fi
%attr(755,root,root) %{plugin_dir}/libipa_modrdn.so
%attr(755,root,root) %{plugin_dir}/libipa_lockout.so
%attr(755,root,root) %{plugin_dir}/libipa_cldap.so
+%attr(755,root,root) %{plugin_dir}/libipa_dns.so
%attr(755,root,root) %{plugin_dir}/libipa_range_check.so
%dir %{_localstatedir}/lib/ipa
%attr(700,root,root) %dir %{_localstatedir}/lib/ipa/sysrestore