ldap/ldif ldap/schema ldap/servers ltmain.sh Makefile.am Makefile.in
by Nathan Kinder
Makefile.am | 12
Makefile.in | 47
ldap/ldif/template-dse.ldif.in | 12
ldap/schema/10mep-plugin.ldif | 104 +
ldap/servers/plugins/mep/mep.c | 2257 ++++++++++++++++++++++++++++++++++++++
ldap/servers/plugins/mep/mep.h | 124 ++
ldap/servers/slapd/slapi-plugin.h | 2
7 files changed, 2553 insertions(+), 5 deletions(-)
New commits:
commit 1f56658556ff4987a0f870b279dbb4dccecfff8d
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Thu Apr 1 16:38:53 2010 -0700
Add managed entries plug-in
This adds a new managed entries plug-in. This plug-in allows
one to have the Directory Server automatically maintain a set
of entries that are based off of another type of entry (such
as user private group entries based off of user entries).
For more details, see the design document at:
http://directory.fedoraproject.org/wiki/Managed_Entry_Design
diff --git a/Makefile.am b/Makefile.am
index c3ec2f6..6cfbef8 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -176,7 +176,7 @@ endif
serverplugin_LTLIBRARIES = libacl-plugin.la libattr-unique-plugin.la \
libback-ldbm.la libchainingdb-plugin.la libcollation-plugin.la \
libcos-plugin.la libderef-plugin.la libdes-plugin.la libdistrib-plugin.la \
- libhttp-client-plugin.la liblinkedattrs-plugin.la \
+ libhttp-client-plugin.la liblinkedattrs-plugin.la libmanagedentries-plugin.la \
libmemberof-plugin.la libpassthru-plugin.la libpwdstorage-plugin.la \
libreferint-plugin.la libreplication-plugin.la libretrocl-plugin.la \
libroles-plugin.la libstatechange-plugin.la libsyntax-plugin.la \
@@ -251,6 +251,7 @@ schema_DATA = $(srcdir)/ldap/schema/00core.ldif \
$(srcdir)/ldap/schema/05rfc4523.ldif \
$(srcdir)/ldap/schema/05rfc4524.ldif \
$(srcdir)/ldap/schema/06inetorgperson.ldif \
+ $(srcdir)/ldap/schema/10mep-plugin.ldif \
$(srcdir)/ldap/schema/10rfc2307.ldif \
$(srcdir)/ldap/schema/20subscriber.ldif \
$(srcdir)/ldap/schema/25java-object.ldif \
@@ -874,6 +875,15 @@ liblinkedattrs_plugin_la_LIBADD = libslapd.la $(NSPR_LINK)
liblinkedattrs_plugin_la_LDFLAGS = -avoid-version
#------------------------
+# libmanagedentries-plugin
+#------------------------
+libmanagedentries_plugin_la_SOURCES = ldap/servers/plugins/mep/mep.c
+
+libmanagedentries_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
+libmanagedentries_plugin_la_LIBADD = libslapd.la $(NSPR_LINK)
+libmanagedentries_plugin_la_LDFLAGS = -avoid-version
+
+#------------------------
# libmemberof-plugin
#------------------------
libmemberof_plugin_la_SOURCES= ldap/servers/plugins/memberof/memberof.c \
diff --git a/Makefile.in b/Makefile.in
old mode 100644
new mode 100755
index bc4b1a6..f7c82fb
--- a/Makefile.in
+++ b/Makefile.in
@@ -279,6 +279,12 @@ am_liblinkedattrs_plugin_la_OBJECTS = ldap/servers/plugins/linkedattrs/liblinked
ldap/servers/plugins/linkedattrs/liblinkedattrs_plugin_la-linked_attrs.lo
liblinkedattrs_plugin_la_OBJECTS = \
$(am_liblinkedattrs_plugin_la_OBJECTS)
+libmanagedentries_plugin_la_DEPENDENCIES = libslapd.la \
+ $(am__DEPENDENCIES_1)
+am_libmanagedentries_plugin_la_OBJECTS = \
+ ldap/servers/plugins/mep/libmanagedentries_plugin_la-mep.lo
+libmanagedentries_plugin_la_OBJECTS = \
+ $(am_libmanagedentries_plugin_la_OBJECTS)
libmemberof_plugin_la_DEPENDENCIES = libslapd.la $(am__DEPENDENCIES_1) \
$(am__DEPENDENCIES_1)
am_libmemberof_plugin_la_OBJECTS = ldap/servers/plugins/memberof/libmemberof_plugin_la-memberof.lo \
@@ -855,6 +861,7 @@ SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \
$(libdistrib_plugin_la_SOURCES) $(libdna_plugin_la_SOURCES) \
$(libhttp_client_plugin_la_SOURCES) \
$(liblinkedattrs_plugin_la_SOURCES) \
+ $(libmanagedentries_plugin_la_SOURCES) \
$(libmemberof_plugin_la_SOURCES) $(libns_dshttpd_la_SOURCES) \
$(libpam_passthru_plugin_la_SOURCES) \
$(libpassthru_plugin_la_SOURCES) \
@@ -883,6 +890,7 @@ DIST_SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \
$(libdistrib_plugin_la_SOURCES) $(libdna_plugin_la_SOURCES) \
$(libhttp_client_plugin_la_SOURCES) \
$(liblinkedattrs_plugin_la_SOURCES) \
+ $(libmanagedentries_plugin_la_SOURCES) \
$(libmemberof_plugin_la_SOURCES) $(libns_dshttpd_la_SOURCES) \
$(libpam_passthru_plugin_la_SOURCES) \
$(libpassthru_plugin_la_SOURCES) \
@@ -1250,7 +1258,7 @@ server_LTLIBRARIES = libslapd.la libns-dshttpd.la
serverplugin_LTLIBRARIES = libacl-plugin.la libattr-unique-plugin.la \
libback-ldbm.la libchainingdb-plugin.la libcollation-plugin.la \
libcos-plugin.la libderef-plugin.la libdes-plugin.la libdistrib-plugin.la \
- libhttp-client-plugin.la liblinkedattrs-plugin.la \
+ libhttp-client-plugin.la liblinkedattrs-plugin.la libmanagedentries-plugin.la \
libmemberof-plugin.la libpassthru-plugin.la libpwdstorage-plugin.la \
libreferint-plugin.la libreplication-plugin.la libretrocl-plugin.la \
libroles-plugin.la libstatechange-plugin.la libsyntax-plugin.la \
@@ -1323,6 +1331,7 @@ schema_DATA = $(srcdir)/ldap/schema/00core.ldif \
$(srcdir)/ldap/schema/05rfc4523.ldif \
$(srcdir)/ldap/schema/05rfc4524.ldif \
$(srcdir)/ldap/schema/06inetorgperson.ldif \
+ $(srcdir)/ldap/schema/10mep-plugin.ldif \
$(srcdir)/ldap/schema/10rfc2307.ldif \
$(srcdir)/ldap/schema/20subscriber.ldif \
$(srcdir)/ldap/schema/25java-object.ldif \
@@ -1890,6 +1899,14 @@ liblinkedattrs_plugin_la_LIBADD = libslapd.la $(NSPR_LINK)
liblinkedattrs_plugin_la_LDFLAGS = -avoid-version
#------------------------
+# libmanagedentries-plugin
+#------------------------
+libmanagedentries_plugin_la_SOURCES = ldap/servers/plugins/mep/mep.c
+libmanagedentries_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS)
+libmanagedentries_plugin_la_LIBADD = libslapd.la $(NSPR_LINK)
+libmanagedentries_plugin_la_LDFLAGS = -avoid-version
+
+#------------------------
# libmemberof-plugin
#------------------------
libmemberof_plugin_la_SOURCES = ldap/servers/plugins/memberof/memberof.c \
@@ -2992,6 +3009,17 @@ ldap/servers/plugins/linkedattrs/liblinkedattrs_plugin_la-linked_attrs.lo: \
ldap/servers/plugins/linkedattrs/$(DEPDIR)/$(am__dirstamp)
liblinkedattrs-plugin.la: $(liblinkedattrs_plugin_la_OBJECTS) $(liblinkedattrs_plugin_la_DEPENDENCIES)
$(LINK) -rpath $(serverplugindir) $(liblinkedattrs_plugin_la_LDFLAGS) $(liblinkedattrs_plugin_la_OBJECTS) $(liblinkedattrs_plugin_la_LIBADD) $(LIBS)
+ldap/servers/plugins/mep/$(am__dirstamp):
+ @$(mkdir_p) ldap/servers/plugins/mep
+ @: > ldap/servers/plugins/mep/$(am__dirstamp)
+ldap/servers/plugins/mep/$(DEPDIR)/$(am__dirstamp):
+ @$(mkdir_p) ldap/servers/plugins/mep/$(DEPDIR)
+ @: > ldap/servers/plugins/mep/$(DEPDIR)/$(am__dirstamp)
+ldap/servers/plugins/mep/libmanagedentries_plugin_la-mep.lo: \
+ ldap/servers/plugins/mep/$(am__dirstamp) \
+ ldap/servers/plugins/mep/$(DEPDIR)/$(am__dirstamp)
+libmanagedentries-plugin.la: $(libmanagedentries_plugin_la_OBJECTS) $(libmanagedentries_plugin_la_DEPENDENCIES)
+ $(LINK) -rpath $(serverplugindir) $(libmanagedentries_plugin_la_LDFLAGS) $(libmanagedentries_plugin_la_OBJECTS) $(libmanagedentries_plugin_la_LIBADD) $(LIBS)
ldap/servers/plugins/memberof/$(am__dirstamp):
@$(mkdir_p) ldap/servers/plugins/memberof
@: > ldap/servers/plugins/memberof/$(am__dirstamp)
@@ -4420,6 +4448,8 @@ mostlyclean-compile:
-rm -f ldap/servers/plugins/memberof/libmemberof_plugin_la-memberof.lo
-rm -f ldap/servers/plugins/memberof/libmemberof_plugin_la-memberof_config.$(OBJEXT)
-rm -f ldap/servers/plugins/memberof/libmemberof_plugin_la-memberof_config.lo
+ -rm -f ldap/servers/plugins/mep/libmanagedentries_plugin_la-mep.$(OBJEXT)
+ -rm -f ldap/servers/plugins/mep/libmanagedentries_plugin_la-mep.lo
-rm -f ldap/servers/plugins/pam_passthru/libpam_passthru_plugin_la-pam_ptconfig.$(OBJEXT)
-rm -f ldap/servers/plugins/pam_passthru/libpam_passthru_plugin_la-pam_ptconfig.lo
-rm -f ldap/servers/plugins/pam_passthru/libpam_passthru_plugin_la-pam_ptdebug.$(OBJEXT)
@@ -5198,6 +5228,7 @@ distclean-compile:
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/linkedattrs/$(DEPDIR)/liblinkedattrs_plugin_la-linked_attrs.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/memberof/$(DEPDIR)/libmemberof_plugin_la-memberof.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/memberof/$(DEPDIR)/libmemberof_plugin_la-memberof_config.Plo(a)am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/mep/$(DEPDIR)/libmanagedentries_plugin_la-mep.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/pam_passthru/$(DEPDIR)/libpam_passthru_plugin_la-pam_ptconfig.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/pam_passthru/$(DEPDIR)/libpam_passthru_plugin_la-pam_ptdebug.Plo(a)am__quote@
@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/pam_passthru/$(DEPDIR)/libpam_passthru_plugin_la-pam_ptimpl.Plo(a)am__quote@
@@ -6551,6 +6582,13 @@ ldap/servers/plugins/linkedattrs/liblinkedattrs_plugin_la-linked_attrs.lo: ldap/
@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(liblinkedattrs_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/linkedattrs/liblinkedattrs_plugin_la-linked_attrs.lo `test -f 'ldap/servers/plugins/linkedattrs/linked_attrs.c' || echo '$(srcdir)/'`ldap/servers/plugins/linkedattrs/linked_attrs.c
+ldap/servers/plugins/mep/libmanagedentries_plugin_la-mep.lo: ldap/servers/plugins/mep/mep.c
+@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmanagedentries_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/mep/libmanagedentries_plugin_la-mep.lo -MD -MP -MF "ldap/servers/plugins/mep/$(DEPDIR)/libmanagedentries_plugin_la-mep.Tpo" -c -o ldap/servers/plugins/mep/libmanagedentries_plugin_la-mep.lo `test -f 'ldap/servers/plugins/mep/mep.c' || echo '$(srcdir)/'`ldap/servers/plugins/mep/mep.c; \
+@am__fastdepCC_TRUE@ then mv -f "ldap/servers/plugins/mep/$(DEPDIR)/libmanagedentries_plugin_la-mep.Tpo" "ldap/servers/plugins/mep/$(DEPDIR)/libmanagedentries_plugin_la-mep.Plo"; else rm -f "ldap/servers/plugins/mep/$(DEPDIR)/libmanagedentries_plugin_la-mep.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ldap/servers/plugins/mep/mep.c' object='ldap/servers/plugins/mep/libmanagedentries_plugin_la-mep.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmanagedentries_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/mep/libmanagedentries_plugin_la-mep.lo `test -f 'ldap/servers/plugins/mep/mep.c' || echo '$(srcdir)/'`ldap/servers/plugins/mep/mep.c
+
ldap/servers/plugins/memberof/libmemberof_plugin_la-memberof.lo: ldap/servers/plugins/memberof/memberof.c
@am__fastdepCC_TRUE@ if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libmemberof_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/memberof/libmemberof_plugin_la-memberof.lo -MD -MP -MF "ldap/servers/plugins/memberof/$(DEPDIR)/libmemberof_plugin_la-memberof.Tpo" -c -o ldap/servers/plugins/memberof/libmemberof_plugin_la-memberof.lo `test -f 'ldap/servers/plugins/memberof/memberof.c' || echo '$(srcdir)/'`ldap/servers/plugins/memberof/memberof.c; \
@am__fastdepCC_TRUE@ then mv -f "ldap/servers/plugins/memberof/$(DEPDIR)/libmemberof_plugin_la-memberof.Tpo" "ldap/servers/plugins/memberof/$(DEPDIR)/libmemberof_plugin_la-memberof.Plo"; else rm -f "ldap/servers/plugins/memberof/$(DEPDIR)/libmemberof_plugin_la-memberof.Tpo"; exit 1; fi
@@ -9280,6 +9318,7 @@ clean-libtool:
-rm -rf ldap/servers/plugins/http/.libs ldap/servers/plugins/http/_libs
-rm -rf ldap/servers/plugins/linkedattrs/.libs ldap/servers/plugins/linkedattrs/_libs
-rm -rf ldap/servers/plugins/memberof/.libs ldap/servers/plugins/memberof/_libs
+ -rm -rf ldap/servers/plugins/mep/.libs ldap/servers/plugins/mep/_libs
-rm -rf ldap/servers/plugins/pam_passthru/.libs ldap/servers/plugins/pam_passthru/_libs
-rm -rf ldap/servers/plugins/passthru/.libs ldap/servers/plugins/passthru/_libs
-rm -rf ldap/servers/plugins/presence/.libs ldap/servers/plugins/presence/_libs
@@ -9797,6 +9836,8 @@ distclean-generic:
-rm -f ldap/servers/plugins/linkedattrs/$(am__dirstamp)
-rm -f ldap/servers/plugins/memberof/$(DEPDIR)/$(am__dirstamp)
-rm -f ldap/servers/plugins/memberof/$(am__dirstamp)
+ -rm -f ldap/servers/plugins/mep/$(DEPDIR)/$(am__dirstamp)
+ -rm -f ldap/servers/plugins/mep/$(am__dirstamp)
-rm -f ldap/servers/plugins/pam_passthru/$(DEPDIR)/$(am__dirstamp)
-rm -f ldap/servers/plugins/pam_passthru/$(am__dirstamp)
-rm -f ldap/servers/plugins/passthru/$(DEPDIR)/$(am__dirstamp)
@@ -9867,7 +9908,7 @@ clean-am: clean-binPROGRAMS clean-generic clean-libtool clean-local \
distclean: distclean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
- -rm -rf ldap/libraries/libavl/$(DEPDIR) ldap/servers/plugins/acl/$(DEPDIR) ldap/servers/plugins/bitwise/$(DEPDIR) ldap/servers/plugins/chainingdb/$(DEPDIR) ldap/servers/plugins/collation/$(DEPDIR) ldap/servers/plugins/cos/$(DEPDIR) ldap/servers/plugins/deref/$(DEPDIR) ldap/servers/plugins/distrib/$(DEPDIR) ldap/servers/plugins/dna/$(DEPDIR) ldap/servers/plugins/http/$(DEPDIR) ldap/servers/plugins/linkedattrs/$(DEPDIR) ldap/servers/plugins/memberof/$(DEPDIR) ldap/servers/plugins/pam_passthru/$(DEPDIR) ldap/servers/plugins/passthru/$(DEPDIR) ldap/servers/plugins/presence/$(DEPDIR) ldap/servers/plugins/pwdstorage/$(DEPDIR) ldap/servers/plugins/referint/$(DEPDIR) ldap/servers/plugins/replication/$(DEPDIR) ldap/servers/plugins/retrocl/$(DEPDIR) ldap/servers/plugins/rever/$(DEPDIR) ldap/servers/plugins/roles/$(DEPDIR) ldap/servers/plugins/schema_reload/$(DEPDIR) ldap/servers/plugins/shared/$(DEPDIR) ldap/servers/plugins/statechange/$(DEPDIR) ldap/servers/plugins/syntaxes/$(DEPDIR
) ldap/servers/plugins/uiduniq/$(DEPDIR) ldap/servers/plugins/usn/$(DEPDIR) ldap/servers/plugins/views/$(DEPDIR) ldap/servers/slapd/$(DEPDIR) ldap/servers/slapd/back-ldbm/$(DEPDIR) ldap/servers/slapd/tools/$(DEPDIR) ldap/servers/slapd/tools/ldclt/$(DEPDIR) ldap/servers/slapd/tools/rsearch/$(DEPDIR) ldap/servers/snmp/$(DEPDIR) ldap/systools/$(DEPDIR) lib/base/$(DEPDIR) lib/ldaputil/$(DEPDIR) lib/libaccess/$(DEPDIR) lib/libadmin/$(DEPDIR) lib/libsi18n/$(DEPDIR)
+ -rm -rf ldap/libraries/libavl/$(DEPDIR) ldap/servers/plugins/acl/$(DEPDIR) ldap/servers/plugins/bitwise/$(DEPDIR) ldap/servers/plugins/chainingdb/$(DEPDIR) ldap/servers/plugins/collation/$(DEPDIR) ldap/servers/plugins/cos/$(DEPDIR) ldap/servers/plugins/deref/$(DEPDIR) ldap/servers/plugins/distrib/$(DEPDIR) ldap/servers/plugins/dna/$(DEPDIR) ldap/servers/plugins/http/$(DEPDIR) ldap/servers/plugins/linkedattrs/$(DEPDIR) ldap/servers/plugins/memberof/$(DEPDIR) ldap/servers/plugins/mep/$(DEPDIR) ldap/servers/plugins/pam_passthru/$(DEPDIR) ldap/servers/plugins/passthru/$(DEPDIR) ldap/servers/plugins/presence/$(DEPDIR) ldap/servers/plugins/pwdstorage/$(DEPDIR) ldap/servers/plugins/referint/$(DEPDIR) ldap/servers/plugins/replication/$(DEPDIR) ldap/servers/plugins/retrocl/$(DEPDIR) ldap/servers/plugins/rever/$(DEPDIR) ldap/servers/plugins/roles/$(DEPDIR) ldap/servers/plugins/schema_reload/$(DEPDIR) ldap/servers/plugins/shared/$(DEPDIR) ldap/servers/plugins/statechange/$(DEPDIR) lda
p/servers/plugins/syntaxes/$(DEPDIR) ldap/servers/plugins/uiduniq/$(DEPDIR) ldap/servers/plugins/usn/$(DEPDIR) ldap/servers/plugins/views/$(DEPDIR) ldap/servers/slapd/$(DEPDIR) ldap/servers/slapd/back-ldbm/$(DEPDIR) ldap/servers/slapd/tools/$(DEPDIR) ldap/servers/slapd/tools/ldclt/$(DEPDIR) ldap/servers/slapd/tools/rsearch/$(DEPDIR) ldap/servers/snmp/$(DEPDIR) ldap/systools/$(DEPDIR) lib/base/$(DEPDIR) lib/ldaputil/$(DEPDIR) lib/libaccess/$(DEPDIR) lib/libadmin/$(DEPDIR) lib/libsi18n/$(DEPDIR)
-rm -f Makefile
distclean-am: clean-am distclean-compile distclean-generic \
distclean-hdr distclean-libtool distclean-tags
@@ -9901,7 +9942,7 @@ installcheck-am:
maintainer-clean: maintainer-clean-am
-rm -f $(am__CONFIG_DISTCLEAN_FILES)
-rm -rf $(top_srcdir)/autom4te.cache
- -rm -rf ldap/libraries/libavl/$(DEPDIR) ldap/servers/plugins/acl/$(DEPDIR) ldap/servers/plugins/bitwise/$(DEPDIR) ldap/servers/plugins/chainingdb/$(DEPDIR) ldap/servers/plugins/collation/$(DEPDIR) ldap/servers/plugins/cos/$(DEPDIR) ldap/servers/plugins/deref/$(DEPDIR) ldap/servers/plugins/distrib/$(DEPDIR) ldap/servers/plugins/dna/$(DEPDIR) ldap/servers/plugins/http/$(DEPDIR) ldap/servers/plugins/linkedattrs/$(DEPDIR) ldap/servers/plugins/memberof/$(DEPDIR) ldap/servers/plugins/pam_passthru/$(DEPDIR) ldap/servers/plugins/passthru/$(DEPDIR) ldap/servers/plugins/presence/$(DEPDIR) ldap/servers/plugins/pwdstorage/$(DEPDIR) ldap/servers/plugins/referint/$(DEPDIR) ldap/servers/plugins/replication/$(DEPDIR) ldap/servers/plugins/retrocl/$(DEPDIR) ldap/servers/plugins/rever/$(DEPDIR) ldap/servers/plugins/roles/$(DEPDIR) ldap/servers/plugins/schema_reload/$(DEPDIR) ldap/servers/plugins/shared/$(DEPDIR) ldap/servers/plugins/statechange/$(DEPDIR) ldap/servers/plugins/syntaxes/$(DEPDIR
) ldap/servers/plugins/uiduniq/$(DEPDIR) ldap/servers/plugins/usn/$(DEPDIR) ldap/servers/plugins/views/$(DEPDIR) ldap/servers/slapd/$(DEPDIR) ldap/servers/slapd/back-ldbm/$(DEPDIR) ldap/servers/slapd/tools/$(DEPDIR) ldap/servers/slapd/tools/ldclt/$(DEPDIR) ldap/servers/slapd/tools/rsearch/$(DEPDIR) ldap/servers/snmp/$(DEPDIR) ldap/systools/$(DEPDIR) lib/base/$(DEPDIR) lib/ldaputil/$(DEPDIR) lib/libaccess/$(DEPDIR) lib/libadmin/$(DEPDIR) lib/libsi18n/$(DEPDIR)
+ -rm -rf ldap/libraries/libavl/$(DEPDIR) ldap/servers/plugins/acl/$(DEPDIR) ldap/servers/plugins/bitwise/$(DEPDIR) ldap/servers/plugins/chainingdb/$(DEPDIR) ldap/servers/plugins/collation/$(DEPDIR) ldap/servers/plugins/cos/$(DEPDIR) ldap/servers/plugins/deref/$(DEPDIR) ldap/servers/plugins/distrib/$(DEPDIR) ldap/servers/plugins/dna/$(DEPDIR) ldap/servers/plugins/http/$(DEPDIR) ldap/servers/plugins/linkedattrs/$(DEPDIR) ldap/servers/plugins/memberof/$(DEPDIR) ldap/servers/plugins/mep/$(DEPDIR) ldap/servers/plugins/pam_passthru/$(DEPDIR) ldap/servers/plugins/passthru/$(DEPDIR) ldap/servers/plugins/presence/$(DEPDIR) ldap/servers/plugins/pwdstorage/$(DEPDIR) ldap/servers/plugins/referint/$(DEPDIR) ldap/servers/plugins/replication/$(DEPDIR) ldap/servers/plugins/retrocl/$(DEPDIR) ldap/servers/plugins/rever/$(DEPDIR) ldap/servers/plugins/roles/$(DEPDIR) ldap/servers/plugins/schema_reload/$(DEPDIR) ldap/servers/plugins/shared/$(DEPDIR) ldap/servers/plugins/statechange/$(DEPDIR) lda
p/servers/plugins/syntaxes/$(DEPDIR) ldap/servers/plugins/uiduniq/$(DEPDIR) ldap/servers/plugins/usn/$(DEPDIR) ldap/servers/plugins/views/$(DEPDIR) ldap/servers/slapd/$(DEPDIR) ldap/servers/slapd/back-ldbm/$(DEPDIR) ldap/servers/slapd/tools/$(DEPDIR) ldap/servers/slapd/tools/ldclt/$(DEPDIR) ldap/servers/slapd/tools/rsearch/$(DEPDIR) ldap/servers/snmp/$(DEPDIR) ldap/systools/$(DEPDIR) lib/base/$(DEPDIR) lib/ldaputil/$(DEPDIR) lib/libaccess/$(DEPDIR) lib/libadmin/$(DEPDIR) lib/libsi18n/$(DEPDIR)
-rm -f Makefile
maintainer-clean-am: distclean-am maintainer-clean-generic
diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in
index 8aa1b0b..ca2ede8 100644
--- a/ldap/ldif/template-dse.ldif.in
+++ b/ldap/ldif/template-dse.ldif.in
@@ -690,6 +690,18 @@ nsslapd-plugintype: preoperation
nsslapd-pluginenabled: on
nsslapd-plugin-depends-on-type: database
+dn: cn=Managed Entries,cn=plugins,cn=config
+objectclass: top
+objectclass: nsSlapdPlugin
+objectclass: extensibleObject
+objectclass: nsContainer
+cn: Managed Entries
+nsslapd-pluginpath: libmanagedentries-plugin
+nsslapd-plugininitfunc: mep_init
+nsslapd-plugintype: preoperation
+nsslapd-pluginenabled: on
+nsslapd-plugin-depends-on-type: database
+
dn: cn=Pass Through Authentication,cn=plugins,cn=config
objectclass: top
objectclass: nsSlapdPlugin
diff --git a/ldap/schema/10mep-plugin.ldif b/ldap/schema/10mep-plugin.ldif
new file mode 100644
index 0000000..fc1f2bd
--- /dev/null
+++ b/ldap/schema/10mep-plugin.ldif
@@ -0,0 +1,104 @@
+#
+# 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.
+#
+# In addition, as a special exception, Red Hat, Inc. gives You the additional
+# right to link the code of this Program with code not covered under the GNU
+# General Public License ("Non-GPL Code") and to distribute linked combinations
+# including the two, subject to the limitations in this paragraph. Non-GPL Code
+# permitted under this exception must only link 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 GNU General Public License. Only Red Hat, Inc. may make changes or
+# additions to the list of Approved Interfaces. You must obey the GNU General
+# Public License in all respects for all of the Program code and other code used
+# in conjunction with the Program except the Non-GPL Code covered by this
+# exception. If you modify this file, you may extend this exception to your
+# version of the file, but you are not obligated to do so. If you do not wish to
+# provide this exception without modification, you must delete this exception
+# statement from your version and license this file solely under the GPL without
+# exception.
+#
+#
+# Copyright (C) 2010 Red Hat, Inc.
+# All rights reserved.
+# END COPYRIGHT BLOCK
+#
+#
+# Schema for Managed Entries Plugin
+#
+dn: cn=schema
+#
+################################################################################
+#
+attributeTypes: ( 2.16.840.1.113730.3.1.2086 NAME 'mepManagedBy'
+ DESC 'Managed Entries backpointer'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ X-ORIGIN '389 Directory Server' )
+#
+################################################################################
+#
+attributeTypes: ( 2.16.840.1.113730.3.1.2087 NAME 'mepManagedEntry'
+ DESC 'Managed Entries pointer'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.12
+ X-ORIGIN '389 Directory Server' )
+#
+################################################################################
+#
+attributeTypes: ( 2.16.840.1.113730.3.1.2088 NAME 'mepStaticAttr'
+ DESC 'Managed Entries static attribute'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
+ X-ORIGIN '389 Directory Server' )
+#
+################################################################################
+#
+attributeTypes: ( 2.16.840.1.113730.3.1.2089 NAME 'mepMappedAttr'
+ DESC 'Managed Entries mapped attribute'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.40
+ X-ORIGIN '389 Directory Server' )
+#
+################################################################################
+#
+attributeTypes: ( 2.16.840.1.113730.3.1.2090 NAME 'mepRDNAttr'
+ DESC 'Managed Entries RDN attribute'
+ SYNTAX 1.3.6.1.4.1.1466.115.121.1.15
+ X-ORIGIN '389 Directory Server' )
+#
+################################################################################
+#
+objectClasses: ( 2.16.840.1.113730.3.2.319 NAME 'mepManagedEntry'
+ DESC 'Managed Entries Managed Entry'
+ SUP top
+ AUXILIARY
+ MAY ( mepManagedBy )
+ X-ORIGIN '389 Directory Server' )
+#
+################################################################################
+#
+objectClasses: ( 2.16.840.1.113730.3.2.320 NAME 'mepOriginEntry'
+ DESC 'Managed Entries Origin Entry'
+ SUP top
+ AUXILIARY
+ MAY ( mepManagedEntry )
+ X-ORIGIN '389 Directory Server' )
+#
+################################################################################
+#
+objectClasses: ( 2.16.840.1.113730.3.2.321 NAME 'mepTemplateEntry'
+ DESC 'Managed Entries Template Entry'
+ SUP top
+ AUXILIARY
+ MAY ( cn $ mepStaticAttr $ mepMappedAttr $ mepRDNAttr)
+ X-ORIGIN '389 Directory Server' )
diff --git a/ldap/servers/plugins/mep/mep.c b/ldap/servers/plugins/mep/mep.c
new file mode 100644
index 0000000..e9d64fe
--- /dev/null
+++ b/ldap/servers/plugins/mep/mep.c
@@ -0,0 +1,2257 @@
+/** 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.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link 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 GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/*
+ * Managed Entries Plug-in
+ */
+#include "mep.h"
+
+
+/*
+ * Plug-in globals
+ */
+static PRCList *g_mep_config = NULL;
+static PRRWLock *g_mep_config_lock;
+
+static void *_PluginID = NULL;
+static char *_PluginDN = NULL;
+static int g_plugin_started = 0;
+
+static Slapi_PluginDesc pdesc = { MEP_FEATURE_DESC,
+ VENDOR,
+ DS_PACKAGE_VERSION,
+ MEP_PLUGIN_DESC };
+
+/*
+ * Plug-in management functions
+ */
+int mep_init(Slapi_PBlock * pb);
+static int mep_start(Slapi_PBlock * pb);
+static int mep_close(Slapi_PBlock * pb);
+static int mep_postop_init(Slapi_PBlock * pb);
+static int mep_internal_postop_init(Slapi_PBlock *pb);
+
+/*
+ * Operation callbacks (where the real work is done)
+ */
+static int mep_mod_post_op(Slapi_PBlock *pb);
+static int mep_add_post_op(Slapi_PBlock *pb);
+static int mep_del_post_op(Slapi_PBlock *pb);
+static int mep_modrdn_post_op(Slapi_PBlock *pb);
+static int mep_pre_op(Slapi_PBlock *pb, int modop);
+static int mep_mod_pre_op(Slapi_PBlock *pb);
+static int mep_add_pre_op(Slapi_PBlock *pb);
+static int mep_del_pre_op(Slapi_PBlock *pb);
+static int mep_modrdn_pre_op(Slapi_PBlock *pb);
+
+/*
+ * Config cache management functions
+ */
+static int mep_load_config();
+static void mep_delete_config();
+static int mep_parse_config_entry(Slapi_Entry * e, int apply);
+static void mep_insert_config_index(struct configEntry *entry);
+static void mep_free_config_entry(struct configEntry ** entry);
+
+/*
+ * helpers
+ */
+static char *mep_get_dn(Slapi_PBlock * pb);
+static int mep_dn_is_config(char *dn);
+static int mep_dn_is_template(char *dn);
+static void mep_find_config(Slapi_Entry *e, struct configEntry **config);
+static void mep_find_config_by_template_dn(const char *template_dn,
+ struct configEntry **config);
+static int mep_oktodo(Slapi_PBlock *pb);
+static int mep_isrepl(Slapi_PBlock *pb);
+static Slapi_Entry *mep_create_managed_entry(struct configEntry *config,
+ Slapi_Entry *origin);
+static void mep_add_managed_entry(struct configEntry *config,
+ Slapi_Entry *origin);
+static Slapi_Mods *mep_get_mapped_mods(struct configEntry *config,
+ Slapi_Entry *origin);
+static int mep_parse_mapped_attr(char *mapping, Slapi_Entry *origin,
+ char **type, char **value);
+static int mep_is_managed_entry(Slapi_Entry *e);
+static int mep_is_mapped_attr(Slapi_Entry *template, char *type);
+
+/*
+ * Config cache locking functions
+ */
+void
+mep_config_read_lock()
+{
+ PR_RWLock_Rlock(g_mep_config_lock);
+}
+
+void
+mep_config_write_lock()
+{
+ PR_RWLock_Wlock(g_mep_config_lock);
+}
+
+void
+mep_config_unlock()
+{
+ PR_RWLock_Unlock(g_mep_config_lock);
+}
+
+
+/*
+ * Plugin identity functions
+ */
+void
+mep_set_plugin_id(void *pluginID)
+{
+ _PluginID = pluginID;
+}
+
+void *
+mep_get_plugin_id()
+{
+ return _PluginID;
+}
+
+void
+mep_set_plugin_dn(char *pluginDN)
+{
+ _PluginDN = pluginDN;
+}
+
+char *
+mep_get_plugin_dn()
+{
+ return _PluginDN;
+}
+
+
+/*
+ * Plug-in initialization functions
+ */
+int
+mep_init(Slapi_PBlock *pb)
+{
+ int status = 0;
+ char *plugin_identity = NULL;
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_init\n");
+
+ /* Store the plugin identity for later use.
+ * Used for internal operations. */
+ slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &plugin_identity);
+ PR_ASSERT(plugin_identity);
+ mep_set_plugin_id(plugin_identity);
+
+ /* Register callbacks */
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
+ SLAPI_PLUGIN_VERSION_01) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN,
+ (void *) mep_start) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN,
+ (void *) mep_close) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *) &pdesc) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_MODIFY_FN,
+ (void *) mep_mod_pre_op) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_ADD_FN,
+ (void *) mep_add_pre_op) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_DELETE_FN,
+ (void *) mep_del_pre_op) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_MODRDN_FN,
+ (void *) mep_modrdn_pre_op) != 0 ||
+ slapi_register_plugin("internalpostoperation", /* op type */
+ 1, /* Enabled */
+ "mep_init", /* this function desc */
+ mep_internal_postop_init, /* init func */
+ MEP_INT_POSTOP_DESC, /* plugin desc */
+ NULL, /* ? */
+ plugin_identity /* access control */
+ ) ||
+ slapi_register_plugin("postoperation", /* op type */
+ 1, /* Enabled */
+ "mep_init", /* this function desc */
+ mep_postop_init, /* init func for post op */
+ MEP_POSTOP_DESC, /* plugin desc */
+ NULL, /* ? */
+ plugin_identity /* access control */
+ )
+ ) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_init: failed to register plugin\n");
+ status = -1;
+ }
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_init\n");
+ return status;
+}
+
+static int
+mep_internal_postop_init(Slapi_PBlock *pb)
+{
+ int status = 0;
+
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
+ SLAPI_PLUGIN_VERSION_01) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *) &pdesc) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_ADD_FN,
+ (void *) mep_add_post_op) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_DELETE_FN,
+ (void *) mep_del_post_op) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODIFY_FN,
+ (void *) mep_mod_post_op) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_INTERNAL_POST_MODRDN_FN,
+ (void *) mep_modrdn_post_op) != 0) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_internal_postop_init: failed to register plugin\n");
+ status = -1;
+ }
+
+ return status;
+}
+
+static int
+mep_postop_init(Slapi_PBlock *pb)
+{
+ int status = 0;
+
+ if (slapi_pblock_set(pb, SLAPI_PLUGIN_VERSION,
+ SLAPI_PLUGIN_VERSION_01) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_DESCRIPTION,
+ (void *) &pdesc) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_POST_ADD_FN,
+ (void *) mep_add_post_op) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_POST_DELETE_FN,
+ (void *) mep_del_post_op) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODIFY_FN,
+ (void *) mep_mod_post_op) != 0 ||
+ slapi_pblock_set(pb, SLAPI_PLUGIN_POST_MODRDN_FN,
+ (void *) mep_modrdn_post_op) != 0) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_postop_init: failed to register plugin\n");
+ status = -1;
+ }
+
+ return status;
+}
+
+
+/*
+ * mep_start()
+ *
+ * Creates config lock and loads config cache.
+ */
+static int
+mep_start(Slapi_PBlock * pb)
+{
+ char *plugindn = NULL;
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_start\n");
+
+ /* Check if we're already started */
+ if (g_plugin_started) {
+ goto done;
+ }
+
+ g_mep_config_lock = PR_NewRWLock(PR_RWLOCK_RANK_NONE, "mep_config");
+
+ if (!g_mep_config_lock) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_start: lock creation failed\n");
+
+ return -1;
+ }
+
+ /*
+ * Get the plug-in target dn from the system
+ * and store it for future use. */
+ slapi_pblock_get(pb, SLAPI_TARGET_DN, &plugindn);
+ if (NULL == plugindn || 0 == strlen(plugindn)) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_start: unable to retrieve plugin dn\n");
+ return -1;
+ }
+
+ mep_set_plugin_dn(plugindn);
+
+ /*
+ * Load the config cache
+ */
+ g_mep_config = (PRCList *)slapi_ch_calloc(1, sizeof(struct configEntry));
+ PR_INIT_CLIST(g_mep_config);
+
+ if (mep_load_config() != 0) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_start: unable to load plug-in configuration\n");
+ return -1;
+ }
+
+ g_plugin_started = 1;
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "managed entries plug-in: ready for service\n");
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_start\n");
+
+done:
+ return 0;
+}
+
+/*
+ * mep_close()
+ *
+ * Cleans up the config cache.
+ */
+static int
+mep_close(Slapi_PBlock * pb)
+{
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_close\n");
+
+ mep_delete_config();
+
+ slapi_ch_free((void **)&g_mep_config);
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_close\n");
+
+ return 0;
+}
+
+PRCList *
+mep_get_config()
+{
+ return g_mep_config;
+}
+
+/*
+ * config looks like this
+ * - cn=Managed Entries,cn=plugins,cn=config
+ * --- cn=user private groups,...
+ * --- cn=etc,...
+ */
+static int
+mep_load_config()
+{
+ int status = 0;
+ int result;
+ int i;
+ Slapi_PBlock *search_pb;
+ Slapi_Entry **entries = NULL;
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_load_config\n");
+
+ /* Clear out any old config. */
+ mep_config_write_lock();
+ mep_delete_config();
+
+ /* Find the config entries beneath our plugin entry. */
+ search_pb = slapi_pblock_new();
+ slapi_search_internal_set_pb(search_pb, mep_get_plugin_dn(),
+ LDAP_SCOPE_SUBTREE, "objectclass=*",
+ NULL, 0, NULL, NULL, mep_get_plugin_id(), 0);
+ slapi_search_internal_pb(search_pb);
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
+
+ if (LDAP_SUCCESS != result) {
+ status = -1;
+ goto cleanup;
+ }
+
+ slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES,
+ &entries);
+ if (NULL == entries || NULL == entries[0]) {
+ /* If there are no config entries, we're done. */
+ goto cleanup;
+ }
+
+ /* Loop through all of the entries we found and parse them. */
+ for (i = 0; (entries[i] != NULL); i++) {
+ /* We don't care about the status here because we may have
+ * some invalid config entries, but we just want to continue
+ * looking for valid ones. */
+ mep_parse_config_entry(entries[i], 1);
+ }
+
+ cleanup:
+ slapi_free_search_results_internal(search_pb);
+ slapi_pblock_destroy(search_pb);
+ mep_config_unlock();
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_load_config\n");
+
+ return status;
+}
+
+/*
+ * mep_parse_config_entry()
+ *
+ * Parses a single config entry. If apply is non-zero, then
+ * we will load and start using the new config. You can simply
+ * validate config without making any changes by setting apply
+ * to 0.
+ *
+ * Returns 0 if the entry is valid and -1 if it is invalid.
+ */
+static int
+mep_parse_config_entry(Slapi_Entry * e, int apply)
+{
+ char *value;
+ struct configEntry *entry = NULL;
+ struct configEntry *config_entry;
+ PRCList *list;
+ int entry_added = 0;
+ int ret = 0;
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_parse_config_entry\n");
+
+ /* If this is the main plug-in
+ * config entry, just bail. */
+ if (strcasecmp(mep_get_plugin_dn(), slapi_entry_get_ndn(e)) == 0) {
+ ret = -1;
+ goto bail;
+ }
+
+ entry = (struct configEntry *)slapi_ch_calloc(1, sizeof(struct configEntry));
+ if (NULL == entry) {
+ ret = -1;
+ goto bail;
+ }
+
+ value = slapi_entry_get_ndn(e);
+ if (value) {
+ entry->dn = slapi_ch_strdup(value);
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_config_entry: Error "
+ "reading dn from config entry\n");
+ ret = -1;
+ goto bail;
+ }
+
+ slapi_log_error(SLAPI_LOG_CONFIG, MEP_PLUGIN_SUBSYSTEM,
+ "----------> dn [%s]\n", entry->dn);
+
+ /* Load the origin scope */
+ value = slapi_entry_attr_get_charptr(e, MEP_SCOPE_TYPE);
+ if (value) {
+ entry->origin_scope = value;
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_config_entry: The %s config "
+ "setting is required for config entry \"%s\".\n",
+ MEP_SCOPE_TYPE, entry->dn);
+ ret = -1;
+ goto bail;
+ }
+
+ /* Load the origin filter */
+ value = slapi_entry_attr_get_charptr(e, MEP_FILTER_TYPE);
+ if (value) {
+ /* Convert to a Slapi_Filter to improve performance. */
+ if (NULL == (entry->origin_filter = slapi_str2filter(value))) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM ,
+ "mep_parse_config_entry: Invalid search filter in "
+ "%s config setting for config entry \"%s\" "
+ "(filter = \"%s\").\n", MEP_FILTER_TYPE, entry->dn, value);
+ ret = -1;
+ }
+
+ slapi_ch_free_string(&value);
+
+ if (ret != 0) {
+ goto bail;
+ }
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_config_entry: The %s config "
+ "setting is required for config entry \"%s\".\n",
+ MEP_FILTER_TYPE, entry->dn);
+ ret = -1;
+ goto bail;
+ }
+
+ /* Load the managed base */
+ value = slapi_entry_attr_get_charptr(e, MEP_MANAGED_BASE_TYPE);
+ if (value) {
+ entry->managed_base = value;
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_config_entry: The %s config "
+ "setting is required for config entry \"%s\".\n",
+ MEP_MANAGED_BASE_TYPE, entry->dn);
+ ret = -1;
+ goto bail;
+ }
+
+ /* Load the managed template */
+ value = slapi_entry_attr_get_charptr(e, MEP_MANAGED_TEMPLATE_TYPE);
+ if (value) {
+ Slapi_Entry *test_entry = NULL;
+ Slapi_DN *template_sdn = NULL;
+
+ entry->template_dn = value;
+
+ /* Fetch the managed entry template */
+ template_sdn = slapi_sdn_new_dn_byref(entry->template_dn);
+ slapi_search_internal_get_entry(template_sdn, 0,
+ &entry->template_entry, mep_get_plugin_id());
+ slapi_sdn_free(&template_sdn);
+
+ if (entry->template_entry == NULL) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_config_entry: The managed entry "
+ "template \"%s\" does not exist. Please "
+ "add it or correct the %s config setting for "
+ "config entry \"%s\"\n", entry->template_dn,
+ MEP_MANAGED_TEMPLATE_TYPE, entry->dn);
+ ret = -1;
+ goto bail;
+ }
+
+ /* Validate the template entry by creating a test managed
+ * entry and running a schema check on it */
+ test_entry = mep_create_managed_entry(entry, NULL);
+ if (test_entry == NULL) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_config_entry: Unable to create "
+ "a test managed entry from managed entry "
+ "template \"%s\". Please check the template "
+ "entry for errors.\n", entry->template_dn);
+ ret = -1;
+ goto bail;
+ }
+
+ if (slapi_entry_schema_check(NULL, test_entry) != 0) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_config_entry: Test managed "
+ "entry created from managed entry template "
+ "\"%s\" violates the schema. Please check "
+ "the template entry for schema errors.\n",
+ entry->template_dn);
+ slapi_entry_free(test_entry);
+ ret = -1;
+ goto bail;
+ }
+
+ /* Dispose of the test entry */
+ slapi_entry_free(test_entry);
+
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_config_entry: The %s config "
+ "setting is required for config entry \"%s\".\n",
+ MEP_MANAGED_TEMPLATE_TYPE, entry->dn);
+ ret = -1;
+ goto bail;
+ }
+
+ /* If we were only called to validate config, we can
+ * just bail out before applying the config changes */
+ if (apply == 0) {
+ goto bail;
+ }
+
+ /* Add the config object to the list. We order by scope. */
+ if (!PR_CLIST_IS_EMPTY(g_mep_config)) {
+ list = PR_LIST_HEAD(g_mep_config);
+ while (list != g_mep_config) {
+ config_entry = (struct configEntry *) list;
+
+ /* If the config entry we are adding has a scope that is
+ * a child of the scope of the current list item, we insert
+ * the entry before that list item. */
+ if (slapi_dn_issuffix(entry->origin_scope, config_entry->origin_scope)) {
+ PR_INSERT_BEFORE(&(entry->list), list);
+ slapi_log_error(SLAPI_LOG_CONFIG, MEP_PLUGIN_SUBSYSTEM,
+ "store [%s] before [%s] \n", entry->dn,
+ config_entry->dn);
+
+ entry_added = 1;
+ break;
+ }
+
+ list = PR_NEXT_LINK(list);
+
+ /* If we hit the end of the list, add to the tail. */
+ if (g_mep_config == list) {
+ PR_INSERT_BEFORE(&(entry->list), list);
+ slapi_log_error(SLAPI_LOG_CONFIG, MEP_PLUGIN_SUBSYSTEM,
+ "store [%s] at tail\n", entry->dn);
+
+ entry_added = 1;
+ break;
+ }
+ }
+ } else {
+ /* first entry */
+ PR_INSERT_LINK(&(entry->list), g_mep_config);
+ slapi_log_error(SLAPI_LOG_CONFIG, MEP_PLUGIN_SUBSYSTEM,
+ "store [%s] at head \n", entry->dn);
+
+ entry_added = 1;
+ }
+
+ bail:
+ if (0 == entry_added) {
+ /* Don't log error if we weren't asked to apply config */
+ if ((apply != 0) && (entry != NULL)) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_config_entry: Invalid config entry "
+ "[%s] skipped\n", entry->dn);
+ }
+ mep_free_config_entry(&entry);
+ } else {
+ ret = 0;
+ }
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_parse_config_entry\n");
+
+ return ret;
+}
+
+static void
+mep_free_config_entry(struct configEntry ** entry)
+{
+ struct configEntry *e = *entry;
+
+ if (e == NULL)
+ return;
+
+ if (e->dn) {
+ slapi_log_error(SLAPI_LOG_CONFIG, MEP_PLUGIN_SUBSYSTEM,
+ "freeing config entry [%s]\n", e->dn);
+ slapi_ch_free_string(&e->dn);
+ }
+
+ if (e->origin_scope) {
+ slapi_ch_free_string(&e->origin_scope);
+ }
+
+ if (e->origin_filter) {
+ slapi_filter_free(e->origin_filter, 1);
+ }
+
+ if (e->managed_base) {
+ slapi_ch_free_string(&e->managed_base);
+ }
+
+ if (e->template_dn) {
+ slapi_ch_free_string(&e->template_dn);
+ }
+
+ if (e->template_entry) {
+ slapi_entry_free(e->template_entry);
+ }
+
+ slapi_ch_free((void **) entry);
+}
+
+static void
+mep_delete_configEntry(PRCList *entry)
+{
+ PR_REMOVE_LINK(entry);
+ mep_free_config_entry((struct configEntry **) &entry);
+}
+
+static void
+mep_delete_config()
+{
+ PRCList *list;
+
+ /* Delete the config cache. */
+ while (!PR_CLIST_IS_EMPTY(g_mep_config)) {
+ list = PR_LIST_HEAD(g_mep_config);
+ mep_delete_configEntry(list);
+ }
+
+ return;
+}
+
+
+/*
+ * Helper functions
+ */
+static char *
+mep_get_dn(Slapi_PBlock * pb)
+{
+ char *dn = 0;
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_get_dn\n");
+
+ if (slapi_pblock_get(pb, SLAPI_TARGET_DN, &dn)) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_get_dn: failed to get dn of changed entry");
+ goto bail;
+ }
+
+ bail:
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_get_dn\n");
+
+ return dn;
+}
+
+/*
+ * mep_dn_is_config()
+ *
+ * Checks if dn is a managed entries config entry.
+ */
+static int
+mep_dn_is_config(char *dn)
+{
+ int ret = 0;
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_dn_is_config\n");
+
+ /* Return 1 if the passed in dn is a child of the main
+ * plugin config entry. */
+ if (slapi_dn_issuffix(dn, mep_get_plugin_dn()) &&
+ strcasecmp(dn, mep_get_plugin_dn())) {
+ ret = 1;
+ }
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_dn_is_config\n");
+
+ return ret;
+}
+
+/*
+ * mep_dn_is_template()
+ *
+ * Checks if dn is a managed entries template.
+ */
+static int
+mep_dn_is_template(char *dn)
+{
+ int ret = 0;
+ PRCList *list = NULL;
+ Slapi_DN *config_sdn = NULL;
+ Slapi_DN *sdn = slapi_sdn_new_dn_byref(dn);
+
+ if (!PR_CLIST_IS_EMPTY(g_mep_config)) {
+ list = PR_LIST_HEAD(g_mep_config);
+ while (list != g_mep_config) {
+ config_sdn = slapi_sdn_new_dn_byref(((struct configEntry *)list)->template_dn);
+
+ if (slapi_sdn_compare(config_sdn, sdn) == 0) {
+ ret = 1;
+ slapi_sdn_free(&config_sdn);
+ break;
+ } else {
+ list = PR_NEXT_LINK(list);
+ slapi_sdn_free(&config_sdn);
+ }
+ }
+ }
+
+ slapi_sdn_free(&sdn);
+
+ return ret;
+}
+
+/*
+ * mep_find_config()
+ *
+ * Finds the appropriate config entry for a given entry
+ * by checking if the entry meets the origin scope and
+ * filter requirements of any config entry. A read lock
+ * must be held on the config before calling this function.
+ * The configEntry that is returned is a pointer to the
+ * actual config entry in the config cache. It should not
+ * be modified in any way. The read lock should not be
+ * released until you are finished with the config entry
+ * that is returned.
+ *
+ * Returns NULL if no applicable config entry is found.
+ */
+static void
+mep_find_config(Slapi_Entry *e, struct configEntry **config)
+{
+ PRCList *list = NULL;
+ char *dn = NULL;
+
+ *config = NULL;
+
+ if (e && !PR_CLIST_IS_EMPTY(g_mep_config)) {
+ dn = slapi_entry_get_dn(e);
+
+ list = PR_LIST_HEAD(g_mep_config);
+ while (list != g_mep_config) {
+
+ /* See if the dn is within the scope of this config entry
+ * in addition to matching the origin filter. */
+ if (slapi_dn_issuffix(dn, ((struct configEntry *)list)->origin_scope) &&
+ (slapi_filter_test_simple(e, ((struct configEntry *)list)->origin_filter) == 0)) {
+ *config = (struct configEntry *)list;
+ break;
+ }
+
+ list = PR_NEXT_LINK(list);
+ }
+ }
+}
+
+/*
+ * mep_find_config_by_template_dn()
+ *
+ * Finds the config entry associated with a particular
+ * template dn. A read lock must be held on the config
+ * before calling this function. The configEntry that
+ * us returned is a pointer to the actual config entry
+ * in the config cache. It should not be modified in
+ * any way. The read lock should not be released until
+ * you are finished with the config entry that is returned.
+ *
+ * Returns NULL if no applicable config entry is found.
+ */
+static void
+mep_find_config_by_template_dn(const char *template_dn,
+ struct configEntry **config)
+{
+ PRCList *list = NULL;
+ Slapi_DN *config_sdn = NULL;
+ Slapi_DN *template_sdn = slapi_sdn_new_dn_byref(template_dn);
+
+ *config = NULL;
+
+ if (!PR_CLIST_IS_EMPTY(g_mep_config)) {
+ list = PR_LIST_HEAD(g_mep_config);
+ while (list != g_mep_config) {
+ config_sdn = slapi_sdn_new_dn_byref(((struct configEntry *)list)->template_dn);
+
+ if (slapi_sdn_compare(config_sdn, template_sdn) == 0) {
+ *config = (struct configEntry *)list;
+ slapi_sdn_free(&config_sdn);
+ break;
+ } else {
+ list = PR_NEXT_LINK(list);
+ slapi_sdn_free(&config_sdn);
+ }
+ }
+ }
+
+ slapi_sdn_free(&template_sdn);
+}
+
+/*
+ * mep_oktodo()
+ *
+ * Check if we want to process this operation. We need to be
+ * sure that the operation succeeded.
+ */
+static int
+mep_oktodo(Slapi_PBlock *pb)
+{
+ int ret = 1;
+ int oprc = 0;
+
+ slapi_log_error( SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_oktodo\n" );
+
+ if(slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &oprc) != 0) {
+ slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_oktodo: could not get parameters\n" );
+ ret = -1;
+ }
+
+ /* This plugin should only execute if the operation succeeded. */
+ if(oprc != 0) {
+ ret = 0;
+ }
+
+ slapi_log_error( SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_oktodo\n" );
+
+ return ret;
+}
+
+/*
+ * mep_isrepl()
+ *
+ * Returns 1 if the operation associated with pb
+ * is a replicated op. Returns 0 otherwise.
+ */
+static int
+mep_isrepl(Slapi_PBlock *pb)
+{
+ int is_repl = 0;
+
+ slapi_log_error( SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_isrepl\n" );
+
+ slapi_pblock_get(pb, SLAPI_IS_REPLICATED_OPERATION, &is_repl);
+
+ slapi_log_error( SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_isrepl\n" );
+
+ return is_repl;
+}
+
+/*
+ * mep_create_managed_entry()
+ *
+ * Creates a managed entry from a specified template and origin
+ * entry. If an origin entry is not passed in, the values of
+ * mapped attributes will not be filled in and the addition of
+ * a backlink to the origin is not added. This is useful for
+ * creating a test managed entry for template validation.
+ */
+static Slapi_Entry *
+mep_create_managed_entry(struct configEntry *config, Slapi_Entry *origin)
+{
+ Slapi_Entry *managed_entry = NULL;
+ Slapi_Entry *template = NULL;
+ char *rdn_type = NULL;
+ char **vals = NULL;
+ char *p = NULL;
+ char *type = NULL;
+ char *value = NULL;
+ int vlen = 0;
+ struct berval bval;
+ Slapi_Value *sval = NULL;
+ int found_rdn_map = 0;
+ int i = 0;
+ int err = 0;
+
+ /* If no template was supplied, there's nothing we can do. */
+ if ((config == NULL) || (config->template_entry == NULL)) {
+ return NULL;
+ } else {
+ template = config->template_entry;
+ }
+
+ /* Ensure that a RDN type was specified in the template. */
+ if ((rdn_type = slapi_entry_attr_get_charptr(template, MEP_RDN_ATTR_TYPE)) == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_create_managed_entry: The %s config attribute "
+ "was not found in template \"%s\". This attribute "
+ "is required.\n", MEP_RDN_ATTR_TYPE, config->template_dn);
+ err = 1;
+ goto done;
+ }
+
+ /* Create the entry to be returned. */
+ managed_entry = slapi_entry_alloc();
+ slapi_entry_init(managed_entry, NULL, NULL);
+
+ /* Add all of the static attributes from the template to the newly
+ * created managed entry. */
+ vals = slapi_entry_attr_get_charray(template, MEP_STATIC_ATTR_TYPE);
+ for (i = 0; vals && vals[i]; ++i) {
+ if (ldif_parse_line(vals[i], &type, &value, &vlen) != 0) {
+ slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_create_managed_entry: Value for %s config setting "
+ "is not in the correct format in template \"%s\". "
+ "(value: \"%s\")\n", MEP_STATIC_ATTR_TYPE,
+ config->template_dn, vals[i]);
+ err = 1;
+ goto done;
+ } else {
+ /* Create a berval and add the value to the entry. */
+ bval.bv_len = vlen;
+ bval.bv_val = value;
+ sval = slapi_value_new_berval(&bval);
+ slapi_entry_add_value(managed_entry, type, sval);
+ slapi_value_free(&sval);
+
+ /* Set type and value to NULL so they don't get
+ * free'd by mep_parse_mapped_attr(). */
+ type = NULL;
+ value = NULL;
+ }
+ }
+
+ /* Clear out vals so we can use them again */
+ slapi_ch_array_free(vals);
+
+ /* Add the mapped attributes to the newly created managed entry. */
+ vals = slapi_entry_attr_get_charray(template, MEP_MAPPED_ATTR_TYPE);
+ for (i = 0; vals && vals[i]; ++i) {
+ if (mep_parse_mapped_attr(vals[i], origin, &type, &value) == 0) {
+ /* Add the attribute to the managed entry. */
+ slapi_entry_add_string(managed_entry, type, value);
+
+ /* Check if this type is the RDN type. */
+ if (slapi_attr_type_cmp(type, rdn_type, SLAPI_TYPE_CMP_EXACT) == 0) {
+ found_rdn_map = 1;
+ }
+
+ slapi_ch_free_string(&type);
+ slapi_ch_free_string(&value);
+ } else {
+ slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_create_managed_entry: Error parsing mapped attribute "
+ "in template \"%s\".\n", config->template_dn);
+ err = 1;
+ goto done;
+ }
+ }
+
+ /* The RDN attribute must be a mapped attribute. If we didn't find it,
+ * we need to bail. */
+ if (!found_rdn_map) {
+ slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_create_managed_entry: The RDN type \"%s\" "
+ "was not found as a mapped attribute in template "
+ "\"%s\". It must be a mapped attribute.\n",
+ rdn_type, config->template_dn);
+ err = 1;
+ goto done;
+ } else {
+ /* Build the DN and set it in the entry. */
+ char *dn = NULL;
+ char *rdn_val = NULL;
+
+ /* If an origin entry was supplied, the RDN value will be
+ * the mapped value. If no origin entry was supplied, the
+ * value will be the mapping rule from the template. */
+ rdn_val = slapi_entry_attr_get_charptr(managed_entry, rdn_type);
+
+ /* Create the DN using the mapped RDN value
+ * and the base specified in the config. */
+ dn = slapi_ch_smprintf("%s=%s,%s", rdn_type, rdn_val, config->managed_base);
+
+ slapi_ch_free_string(&rdn_val);
+
+ if (dn != NULL) {
+ slapi_sdn_set_dn_passin(slapi_entry_get_sdn(managed_entry), dn);
+ } else {
+ slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_create_managed_entry: Error setting DN "
+ "in managed entry based off of template entry "
+ "\"%s\" (origin entry \"%s\").\n",
+ config->template_dn,
+ origin ? slapi_entry_get_dn(origin) : "NULL");
+ err = 1;
+ goto done;
+ }
+ }
+
+ /* If an origin entry was supplied, set a backpointer to the
+ * origin in the managed entry. */
+ if (origin) {
+ slapi_entry_add_string(managed_entry,
+ SLAPI_ATTR_OBJECTCLASS, MEP_MANAGED_OC);
+ slapi_entry_add_string(managed_entry, MEP_MANAGED_BY_TYPE,
+ slapi_entry_get_dn(origin));
+ }
+
+ done:
+ slapi_ch_array_free(vals);
+ slapi_ch_free_string(&rdn_type);
+
+ if (err != 0) {
+ slapi_entry_free(managed_entry);
+ managed_entry = NULL;
+ }
+
+ return managed_entry;
+}
+
+/*
+ * mep_add_managed_entry()
+ *
+ * Creates and adds a managed entry to the database. The
+ * origin entry will also be modified to add a link to the
+ * newly created managed entry.
+ */
+static void
+mep_add_managed_entry(struct configEntry *config,
+ Slapi_Entry *origin)
+{
+ Slapi_Entry *managed_entry = NULL;
+ char *managed_dn = NULL;
+ Slapi_PBlock *mod_pb = slapi_pblock_new();
+ int result = LDAP_SUCCESS;
+
+ /* Create the managed entry */
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_add_managed_entry: Creating a managed "
+ "entry from origin entry \"%s\" using "
+ "config \"%s\".\n", slapi_entry_get_dn(origin),
+ config->dn);
+ managed_entry = mep_create_managed_entry(config, origin);
+ if (managed_entry == NULL) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_add_managed_entry: Unable to create a managed "
+ "entry from origin entry \"%s\" using config "
+ "\"%s\".\n", slapi_entry_get_dn(origin), config->dn);
+ } else {
+ /* Copy the managed entry DN to use when
+ * creating the pointer attribute. */
+ managed_dn = slapi_ch_strdup(slapi_entry_get_dn(managed_entry));
+
+ /* Add managed entry to db. The entry will be consumed. */
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "Adding managed entry \"%s\" for origin "
+ "entry \"%s\"\n.", managed_dn, slapi_entry_get_dn(origin));
+ slapi_add_entry_internal_set_pb(mod_pb, managed_entry, NULL,
+ mep_get_plugin_id(), 0);
+ slapi_add_internal_pb(mod_pb);
+ slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
+
+ if (result != LDAP_SUCCESS) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_add_managed_entry: Unable to add managed "
+ "entry \"%s\" for origin entry \"%s\" (%s).\n",
+ managed_dn, slapi_entry_get_dn(origin),
+ ldap_err2string(result));
+ } else {
+ /* Add forward link to origin entry. */
+ LDAPMod oc_mod;
+ LDAPMod pointer_mod;
+ LDAPMod *mods[3];
+ char *oc_vals[2];
+ char *pointer_vals[2];
+
+ /* Clear out the pblock for reuse. */
+ slapi_pblock_init(mod_pb);
+
+ /* Add the origin entry objectclass. */
+ oc_vals[0] = MEP_ORIGIN_OC;
+ oc_vals[1] = 0;
+ oc_mod.mod_op = LDAP_MOD_ADD;
+ oc_mod.mod_type = SLAPI_ATTR_OBJECTCLASS;
+ oc_mod.mod_values = oc_vals;
+
+ /* Add a pointer to the managed entry. */
+ pointer_vals[0] = managed_dn;
+ pointer_vals[1] = 0;
+ pointer_mod.mod_op = LDAP_MOD_ADD;
+ pointer_mod.mod_type = MEP_MANAGED_ENTRY_TYPE;
+ pointer_mod.mod_values = pointer_vals;
+
+ mods[0] = &oc_mod;
+ mods[1] = &pointer_mod;
+ mods[2] = 0;
+
+ /* Perform the modify operation. */
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "Adding %s pointer to \"%s\" in entry \"%s\"\n.",
+ MEP_MANAGED_ENTRY_TYPE, managed_dn, slapi_entry_get_dn(origin));
+ slapi_modify_internal_set_pb(mod_pb, slapi_entry_get_dn(origin),
+ mods, 0, 0, mep_get_plugin_id(), 0);
+ slapi_modify_internal_pb(mod_pb);
+ slapi_pblock_get(mod_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
+
+ if (result != LDAP_SUCCESS) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_add_managed_entry: Unable to add pointer to "
+ "managed entry \"%s\" in origin entry \"%s\" "
+ "(%s).\n", managed_dn, slapi_entry_get_dn(origin),
+ ldap_err2string(result));
+ }
+ }
+ }
+
+ slapi_ch_free_string(&managed_dn);
+ slapi_pblock_destroy(mod_pb);
+}
+
+/*
+ * mep_get_mapped_mods()
+ *
+ * Creates the modifications needed to update the mapped values
+ * in a managed entry. It is up to the caller to free the
+ * returned mods when it is finished using them.
+ */
+static Slapi_Mods *mep_get_mapped_mods(struct configEntry *config,
+ Slapi_Entry *origin)
+{
+ Slapi_Mods *smods = NULL;
+ Slapi_Entry *template = NULL;
+ Slapi_Attr *attr = NULL;
+ char **vals = NULL;
+ char *type = NULL;
+ char *value = NULL;
+ int i = 0;
+
+ /* If no template was supplied, there's nothing we can do. */
+ if (origin == NULL || config == NULL || config->template_entry == NULL) {
+ return NULL;
+ } else {
+ template = config->template_entry;
+ }
+
+ /* See how many mods we will have and initialize the smods. */
+ if (slapi_entry_attr_find(config->template_entry, MEP_MAPPED_ATTR_TYPE, &attr) == 0) {
+ int numvals = 0;
+
+ slapi_attr_get_numvalues(attr, &numvals);
+ smods = slapi_mods_new();
+ slapi_mods_init(smods, numvals);
+ }
+
+ /* Go through the template and find the mapped attrs. */
+ vals = slapi_entry_attr_get_charray(template, MEP_MAPPED_ATTR_TYPE);
+ for (i = 0; vals && vals[i]; ++i) {
+ if (mep_parse_mapped_attr(vals[i], origin, &type, &value) == 0) {
+ /* Add a modify that replaces all values with the new value. */
+ slapi_mods_add_string(smods, LDAP_MOD_REPLACE, type, value);
+ slapi_ch_free_string(&type);
+ slapi_ch_free_string(&value);
+ } else {
+ slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_get_mapped_mods: Error parsing mapped attribute "
+ "in template \"%s\".\n", config->template_dn);
+ slapi_mods_free(&smods);
+ goto bail;
+ }
+ }
+
+ bail:
+ slapi_ch_array_free(vals);
+
+ return smods;
+}
+
+/*
+ * mep_parse_mapped_attr()
+ *
+ * Parses a mapped attribute setting from a template and
+ * fills in the type and value based off of the origin
+ * entry. If an origin entry is not supplied, the value
+ * is simply the mapping rule.
+ */
+static int
+mep_parse_mapped_attr(char *mapping, Slapi_Entry *origin,
+ char **type, char **value)
+{
+ int ret = 0;
+ char *p = NULL;
+ char *pre_str = NULL;
+ char *post_str = NULL;
+ char *end = NULL;
+ char *var_start = NULL;
+ char *map_type = NULL;
+
+ /* Clear out any existing type or value. */
+ slapi_ch_free_string(type);
+ slapi_ch_free_string(value);
+
+ /* split out the type from the value (use the first ':') */
+ if ((p = strchr(mapping, ':')) == NULL) {
+ slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_mapped_attr: Value for mapped attribute "
+ "is not in the correct format. (value: \"%s\").\n",
+ mapping);
+ ret = 1;
+ goto bail;
+ }
+
+ /* Ensure the type is not empty. */
+ if (p == mapping) {
+ slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_mapped_attr: Value for mapped attribute "
+ "is not in the correct format. The type is missing. "
+ "(value: \"%s\").\n",
+ mapping);
+ ret = 1;
+ goto bail;
+ }
+
+ /* Terminate the type so we can use it as a string. */
+ *p = '\0';
+
+ /* Duplicate the type to be returned. */
+ *type = slapi_ch_strdup(mapping);
+
+ /* Advance p to point to the beginning of the value. */
+ p++;
+ while (*p == ' ') {
+ p++;
+ }
+
+ pre_str = p;
+ end = p + strlen(p);
+
+ /* Find the variable that we need to substitute. */
+ for (; p <= end; p++) {
+ if (*p == '$') {
+ if (p == end) {
+ slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_mapped_attr: Invalid mapped "
+ "attribute value for type \"%s\".\n", mapping);
+ ret = 1;
+ goto bail;
+ }
+
+ if (*(p + 1) == '$') {
+ /* This is an escaped $, so just skip it. */
+ p++;
+ } else {
+ /* We found a variable. Terminate the pre
+ * string and process the variable. */
+ *p = '\0';
+ p++;
+
+ /* We should be pointing at the variable name now. */
+ var_start = p;
+
+ /* Move the pointer to the end of the variable name. */
+ while ((p < end) && !isspace(*p)) {
+ p++;
+ }
+
+ /* Check for a missing variable name. */
+ if (p == var_start) {
+ break;
+ }
+
+ /* Set the map type. */
+ map_type = strndup(var_start, p - var_start);
+
+ /* If we're at the end of the string, we
+ * don't have a post string. Just set
+ * it to an empty string. */
+ if (p == end) {
+ post_str = "";
+ } else {
+ post_str = p;
+ }
+
+ /* We only support a single variable, so we're done. */
+ break;
+ }
+ }
+ }
+
+ if (map_type) {
+ if (origin) {
+ char *map_val = slapi_entry_attr_get_charptr(origin, map_type);
+
+ if (map_val) {
+ /* Create the new mapped value. */
+ *value = slapi_ch_smprintf("%s%s%s", pre_str,
+ map_val, post_str);
+ slapi_ch_free_string(&map_val);
+ } else {
+ slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_mapped_attr: Mapped attribute \"%s\" "
+ "is not present in origin entry \"%s\". Please "
+ "correct template to only map attributes "
+ "required by the schema.\n", map_type,
+ slapi_entry_get_dn(origin));
+ ret = 1;
+ goto bail;
+ }
+ } else {
+ /* Just use the mapping since we have no origin entry. */
+ *value = slapi_ch_smprintf("%s$%s%s", pre_str, map_type,
+ post_str);
+ }
+ } else {
+ slapi_log_error( SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_parse_mapped_attr: No variable found in "
+ "mapped attribute value for type \"%s\".\n",
+ mapping);
+ ret = 1;
+ goto bail;
+ }
+
+ bail:
+ slapi_ch_free_string(&map_type);
+
+ if (ret != 0) {
+ slapi_ch_free_string(type);
+ slapi_ch_free_string(value);
+ }
+
+ return ret;
+}
+
+
+/*
+ * mep_is_managed_entry()
+ *
+ * Returns 1 if the entry is a managed entry, 0 otherwise.
+ * The check is performed by seeing if the managed entry
+ * objectclass is present.
+ */
+static int
+mep_is_managed_entry(Slapi_Entry *e)
+{
+ int ret = 0;
+ Slapi_Attr *attr = NULL;
+ struct berval bv;
+
+ bv.bv_val = MEP_MANAGED_OC;
+ bv.bv_len = strlen(bv.bv_val);
+
+ if (e && (slapi_entry_attr_find(e, SLAPI_ATTR_OBJECTCLASS, &attr) == 0)) {
+ if (slapi_attr_value_find(attr, &bv) == 0) {
+ ret = 1;
+ }
+ }
+
+ return ret;
+}
+
+/*
+ * mep_is_mapped_attr()
+ *
+ * Checks if type is defined as a mapped attribute in template.
+ */
+static int
+mep_is_mapped_attr(Slapi_Entry *template, char *type)
+{
+ int ret = 0;
+ int i = 0;
+ char **vals = NULL;
+ char *map_type = NULL;
+ char *value = NULL;
+
+ if (template && type) {
+ vals = slapi_entry_attr_get_charray(template, MEP_MAPPED_ATTR_TYPE);
+ for (i = 0; vals && vals[i]; ++i) {
+ if (mep_parse_mapped_attr(vals[i], NULL, &map_type, &value) == 0) {
+ if (slapi_attr_type_cmp(map_type, type, SLAPI_TYPE_CMP_EXACT) == 0) {
+ ret = 1;
+ }
+
+ slapi_ch_free_string(&map_type);
+ slapi_ch_free_string(&value);
+
+ /* If we found a match, we're done. */
+ if (ret == 1) {
+ break;
+ }
+ }
+ }
+
+ slapi_ch_array_free(vals);
+ }
+
+ return ret;
+}
+
+/*
+ * Operation callback functions
+ */
+
+/*
+ * mep_pre_op()
+ *
+ * Checks if an operation is modifying the managed
+ * entries config and validates the config changes.
+ */
+static int
+mep_pre_op(Slapi_PBlock * pb, int modop)
+{
+ char *dn = 0;
+ Slapi_Entry *e = 0;
+ Slapi_Mods *smods = 0;
+ LDAPMod **mods;
+ int free_entry = 0;
+ char *errstr = NULL;
+ struct configEntry *config = NULL;
+ void *caller_id = NULL;
+ int ret = 0;
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_pre_op\n");
+
+ /* Just bail if we aren't ready to service requests yet. */
+ if (!g_plugin_started)
+ goto bail;
+
+ /* See if we're calling ourselves. */
+ slapi_pblock_get (pb, SLAPI_PLUGIN_IDENTITY, &caller_id);
+
+ if (0 == (dn = mep_get_dn(pb)))
+ goto bail;
+
+ if (mep_dn_is_config(dn)) {
+ /* Validate config changes, but don't apply them.
+ * This allows us to reject invalid config changes
+ * here at the pre-op stage. Applying the config
+ * needs to be done at the post-op stage. */
+
+ if (LDAP_CHANGETYPE_ADD == modop) {
+ slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &e);
+ } else {
+ /* Fetch the entry being modified so we can
+ * create the resulting entry for validation. */
+ Slapi_DN *tmp_dn = slapi_sdn_new_dn_byref(dn);
+ if (tmp_dn) {
+ slapi_search_internal_get_entry(tmp_dn, 0, &e, mep_get_plugin_id());
+ slapi_sdn_free(&tmp_dn);
+ free_entry = 1;
+ }
+
+ /* If the entry doesn't exist, just bail and
+ * let the server handle it. */
+ if (e == NULL) {
+ goto bail;
+ }
+
+ /* Grab the mods. */
+ slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
+ smods = slapi_mods_new();
+ slapi_mods_init_byref(smods, mods);
+
+ /* Apply the mods to create the resulting entry. */
+ if (mods && (slapi_entry_apply_mods(e, mods) != LDAP_SUCCESS)) {
+ /* The mods don't apply cleanly, so we just let this op go
+ * to let the main server handle it. */
+ goto bailmod;
+ }
+ }
+
+ if (mep_parse_config_entry(e, 0) != 0) {
+ /* Refuse the operation if config parsing failed. */
+ ret = LDAP_UNWILLING_TO_PERFORM;
+ if (LDAP_CHANGETYPE_ADD == modop) {
+ errstr = slapi_ch_smprintf("Not a valid managed entries configuration entry.");
+ } else {
+ errstr = slapi_ch_smprintf("Changes result in an invalid "
+ "managed entries configuration.");
+ }
+ }
+ } else {
+ /* Check if an active template entry is being updated. If so, validate it. */
+ mep_config_read_lock();
+ mep_find_config_by_template_dn(dn, &config);
+ if (config) {
+ Slapi_Entry *test_entry = NULL;
+ struct configEntry *config_copy = NULL;
+ Slapi_DN *tmp_dn = NULL;
+
+ config_copy = (struct configEntry *)slapi_ch_calloc(1, sizeof(struct configEntry));
+
+ /* Make a temporary copy of the config to use for validation. */
+ config_copy->dn = slapi_ch_strdup(config->dn);
+ config_copy->managed_base = slapi_ch_strdup(config->managed_base);
+ config_copy->template_dn = slapi_ch_strdup(config->template_dn);
+
+ /* Reject attempts to delete or rename an active template.
+ * Validate changes to an active template. */
+ switch (modop) {
+ case LDAP_CHANGETYPE_DELETE:
+ errstr = slapi_ch_smprintf("Deleting an active managed "
+ "entries template is not allowed. "
+ "Delete the associated config "
+ "entry first.");
+ ret = LDAP_UNWILLING_TO_PERFORM;
+ break;
+ case LDAP_CHANGETYPE_MODDN:
+ errstr = slapi_ch_smprintf("Renaming an active managed "
+ "entries template is not allowed. "
+ "Create a new template and modify "
+ "the associated config entry instead.");
+ ret = LDAP_UNWILLING_TO_PERFORM;
+ break;
+ case LDAP_CHANGETYPE_MODIFY:
+ tmp_dn = slapi_sdn_new_dn_byref(dn);
+
+ /* Fetch the existing template entry. */
+ if (tmp_dn) {
+ slapi_search_internal_get_entry(tmp_dn, 0, &e, mep_get_plugin_id());
+ slapi_sdn_free(&tmp_dn);
+ free_entry = 1;
+ }
+
+ /* If the entry doesn't exist, we just skip
+ * validation and let the server handle it. */
+ if (e) {
+ /* Grab the mods. */
+ slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
+ smods = slapi_mods_new();
+ slapi_mods_init_byref(smods, mods);
+
+ /* Apply the mods to create the resulting entry. */
+ if (mods && (slapi_entry_apply_mods(e, mods) == LDAP_SUCCESS)) {
+ /* Set the resulting template in the config copy.
+ * The ownership of the resulting entry is handed
+ * over to the config copy. */
+ config_copy->template_entry = e;
+ e = NULL;
+
+ /* Validate the changed template. */
+ test_entry = mep_create_managed_entry(config_copy, NULL);
+ if (test_entry == NULL) {
+ errstr = slapi_ch_smprintf("Changes result in an invalid "
+ "managed entries template.");
+ ret = LDAP_UNWILLING_TO_PERFORM;
+ }
+
+ if (slapi_entry_schema_check(NULL, test_entry) != 0) {
+ errstr = slapi_ch_smprintf("Changes result in an invalid "
+ "managed entries template due "
+ "to a schema violation.");
+ ret = LDAP_UNWILLING_TO_PERFORM;
+ }
+ }
+ }
+
+ /* Dispose of the test entry */
+ slapi_entry_free(test_entry);
+
+ /* Free the config copy */
+ mep_free_config_entry(&config_copy);
+ break;
+ }
+ }
+ mep_config_unlock();
+
+ /* If replication, just bail. */
+ if (mep_isrepl(pb)) {
+ goto bailmod;
+ }
+
+ /* Check if a managed entry is being deleted or
+ * renamed and reject if it's not being done by
+ * this plugin. */
+ if (((modop == LDAP_CHANGETYPE_DELETE) || (modop == LDAP_CHANGETYPE_MODDN) ||
+ (modop == LDAP_CHANGETYPE_MODIFY)) && (caller_id != mep_get_plugin_id())) {
+ Slapi_DN *tmp_dn = slapi_sdn_new_dn_byref(dn);
+ Slapi_Entry *origin_e = NULL;
+ Slapi_Mod *smod = NULL;
+ Slapi_Mod *next_mod = NULL;
+ char *origin_dn = NULL;
+ Slapi_DN *origin_sdn = NULL;
+
+ /* Fetch the target entry. */
+ if (tmp_dn) {
+ /* Free any existing entry so we don't leak it. */
+ if (e && free_entry) {
+ slapi_entry_free(e);
+ }
+
+ slapi_search_internal_get_entry(tmp_dn, 0, &e, mep_get_plugin_id());
+ slapi_sdn_free(&tmp_dn);
+ free_entry = 1;
+ }
+
+ if (e && mep_is_managed_entry(e)) {
+ if (modop == LDAP_CHANGETYPE_MODIFY) {
+ /* Fetch the origin entry so we can locate the config template. */
+ origin_dn = slapi_entry_attr_get_charptr(e, MEP_MANAGED_BY_TYPE);
+ if (origin_dn) {
+ origin_sdn = slapi_sdn_new_dn_byref(origin_dn);
+ slapi_search_internal_get_entry(origin_sdn, 0,
+ &origin_e, mep_get_plugin_id());
+ slapi_sdn_free(&origin_sdn);
+ }
+
+ if (origin_e) {
+ /* Fetch the config. */
+ mep_config_read_lock();
+ mep_find_config(origin_e, &config);
+
+ if (config) {
+ /* Get the mods if we haven't already. */
+ if (smods == NULL) {
+ slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods);
+ smods = slapi_mods_new();
+ slapi_mods_init_byref(smods, mods);
+ }
+
+ next_mod = slapi_mod_new();
+ smod = slapi_mods_get_first_smod(smods, next_mod);
+ while(smod) {
+ char *type = (char *)slapi_mod_get_type(smod);
+
+ /* If this is a mapped attribute, reject the op. */
+ if (mep_is_mapped_attr(config->template_entry, type)) {
+ errstr = slapi_ch_smprintf("Modifying a mapped attribute "
+ " in a managed entry is not allowed. "
+ "The \"%s\" attribute is mapped for "
+ "this entry.", type);
+ ret = LDAP_UNWILLING_TO_PERFORM;
+ break;
+ }
+
+ slapi_mod_done(next_mod);
+ smod = slapi_mods_get_next_smod(smods, next_mod);
+ }
+
+ slapi_mod_free(&next_mod);
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_pre_op: Unable to fetch config for "
+ "origin entry \"%s\".\n", origin_dn);
+ }
+
+ slapi_entry_free(origin_e);
+ mep_config_unlock();
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_pre_op: Unable to fetch origin entry "
+ "\"%s\".\n", origin_dn);
+ }
+
+ slapi_ch_free_string(&origin_dn);
+ } else {
+ errstr = slapi_ch_smprintf("%s a managed entry is not allowed. "
+ "It needs to be manually unlinked first.",
+ modop == LDAP_CHANGETYPE_DELETE ? "Deleting"
+ : "Renaming");
+ ret = LDAP_UNWILLING_TO_PERFORM;
+ }
+ }
+ }
+ }
+
+ bailmod:
+ /* Clean up smods. */
+ if (LDAP_CHANGETYPE_MODIFY == modop) {
+ slapi_mods_free(&smods);
+ }
+
+ bail:
+ if (free_entry && e)
+ slapi_entry_free(e);
+
+ if (ret) {
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_pre_op: operation failure [%d]\n", ret);
+ slapi_send_ldap_result(pb, ret, NULL, errstr, 0, NULL);
+ slapi_ch_free((void **)&errstr);
+ ret = -1;
+ }
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_pre_op\n");
+
+ return ret;
+}
+
+static int
+mep_add_pre_op(Slapi_PBlock * pb)
+{
+ return mep_pre_op(pb, LDAP_CHANGETYPE_ADD);
+}
+
+static int
+mep_del_pre_op(Slapi_PBlock * pb)
+{
+ return mep_pre_op(pb, LDAP_CHANGETYPE_DELETE);
+}
+
+static int
+mep_mod_pre_op(Slapi_PBlock * pb)
+{
+ return mep_pre_op(pb, LDAP_CHANGETYPE_MODIFY);
+}
+
+static int
+mep_modrdn_pre_op(Slapi_PBlock * pb)
+{
+ return mep_pre_op(pb, LDAP_CHANGETYPE_MODDN);
+}
+
+static int
+mep_mod_post_op(Slapi_PBlock *pb)
+{
+ Slapi_Mods *smods = NULL;
+ Slapi_PBlock *mep_pb = NULL;
+ Slapi_Entry *e = NULL;
+ char *dn = NULL;
+ char *managed_dn = NULL;
+ struct configEntry *config = NULL;
+ int result = 0;
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_mod_post_op\n");
+
+ /* Just bail if we aren't ready to service requests yet. */
+ if (!g_plugin_started)
+ return 0;
+
+ if (mep_oktodo(pb) && (dn = mep_get_dn(pb))) {
+ /* First check if the config or a template is being modified. */
+ if (mep_dn_is_config(dn) || mep_dn_is_template(dn)) {
+ mep_load_config();
+ }
+
+ /* If replication, just bail. */
+ if (mep_isrepl(pb)) {
+ goto bail;
+ }
+
+ /* Fetch the modified entry. */
+ slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e);
+ if (e == NULL) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_mod_post_op: Unable to fetch postop entry.\n");
+ goto bail;
+ }
+
+ /* Check if we're an origin entry. Update the
+ * mapped attrs of it's managed entry if so. */
+ managed_dn = slapi_entry_attr_get_charptr(e, MEP_MANAGED_ENTRY_TYPE);
+ if (managed_dn) {
+ mep_config_read_lock();
+ mep_find_config(e, &config);
+ if (config) {
+ smods = mep_get_mapped_mods(config, e);
+ if (smods) {
+ /* Clear out the pblock for reuse. */
+ mep_pb = slapi_pblock_new();
+
+ /* Perform the modify operation. */
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_mod_post_op: Updating mapped attributes "
+ "in entry \"%s\"\n.", managed_dn);
+ slapi_modify_internal_set_pb(mep_pb, managed_dn,
+ slapi_mods_get_ldapmods_byref(smods), 0, 0,
+ mep_get_plugin_id(), 0);
+ slapi_modify_internal_pb(mep_pb);
+ slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
+
+ if (result != LDAP_SUCCESS) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_mod_post_op: Unable to update mapped "
+ "attributes from origin entry \"%s\" in managed "
+ "entry \"%s\" (%s).\n", dn, managed_dn,
+ ldap_err2string(result));
+ }
+
+ slapi_mods_free(&smods);
+ slapi_pblock_destroy(mep_pb);
+ }
+ } else {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_mod_post_op: Unable to find config for origin "
+ "entry \"%s\".\n", dn);
+ }
+
+ slapi_ch_free_string(&managed_dn);
+
+ mep_config_unlock();
+ }
+
+ }
+
+ bail:
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_mod_post_op\n");
+
+ return 0;
+}
+
+static int
+mep_add_post_op(Slapi_PBlock *pb)
+{
+ Slapi_Entry *e = NULL;
+ char *dn = NULL;
+ struct configEntry *config = NULL;
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_add_post_op\n");
+
+ /* Just bail if we aren't ready to service requests yet. */
+ if (!g_plugin_started || !mep_oktodo(pb))
+ return 0;
+
+ /* Reload config if a config entry was added. */
+ if ((dn = mep_get_dn(pb))) {
+ if (mep_dn_is_config(dn)) {
+ mep_load_config();
+ }
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_add_post_op: Error "
+ "retrieving dn\n");
+ }
+
+ /* If replication, just bail. */
+ if (mep_isrepl(pb)) {
+ return 0;
+ }
+
+ /* Get the newly added entry. */
+ slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &e);
+
+ if (e) {
+ /* Check if a config entry applies
+ * to the entry being added. */
+ mep_config_read_lock();
+ mep_find_config(e, &config);
+ if (config) {
+ mep_add_managed_entry(config, e);
+ }
+
+ mep_config_unlock();
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_add_post_op: Error "
+ "retrieving post-op entry %s\n", dn);
+ }
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_add_post_op\n");
+
+ return 0;
+}
+
+static int
+mep_del_post_op(Slapi_PBlock *pb)
+{
+ char *dn = NULL;
+ Slapi_Entry *e = NULL;
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_del_post_op\n");
+
+ /* Just bail if we aren't ready to service requests yet. */
+ if (!g_plugin_started || !mep_oktodo(pb)) {
+ return 0;
+ }
+
+ /* Reload config if a config entry was deleted. */
+ if ((dn = mep_get_dn(pb))) {
+ if (mep_dn_is_config(dn))
+ mep_load_config();
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_del_post_op: Error "
+ "retrieving dn\n");
+ }
+
+ /* If replication, just bail. */
+ if (mep_isrepl(pb)) {
+ return 0;
+ }
+
+ /* Get deleted entry, then go through types to find config. */
+ slapi_pblock_get( pb, SLAPI_ENTRY_PRE_OP, &e );
+
+ if (e) {
+ char *managed_dn = NULL;
+
+ /* See if we're an origin entry . */
+ managed_dn = slapi_entry_attr_get_charptr(e, MEP_MANAGED_ENTRY_TYPE);
+ if (managed_dn) {
+ Slapi_PBlock *mep_pb = slapi_pblock_new();
+
+ /* Delete the managed entry. */
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_del_post_op: Deleting managed entry "
+ "\"%s\" due to deletion of origin entry "
+ "\"%s\".\n ", managed_dn, dn);
+ slapi_delete_internal_set_pb(mep_pb, managed_dn, NULL,
+ NULL, mep_get_plugin_id(), 0);
+ slapi_delete_internal_pb(mep_pb);
+
+ slapi_ch_free_string(&managed_dn);
+ slapi_pblock_destroy(mep_pb);
+ }
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_del_post_op: Error "
+ "retrieving pre-op entry %s\n", dn);
+ }
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_del_post_op\n");
+
+ return 0;
+}
+
+static int
+mep_modrdn_post_op(Slapi_PBlock *pb)
+{
+ char *old_dn = NULL;
+ char *new_dn = NULL;
+ Slapi_Entry *post_e = NULL;
+ char *managed_dn = NULL;
+ struct configEntry *config = NULL;
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "--> mep_modrdn_post_op\n");
+
+ /* Just bail if we aren't ready to service requests yet. */
+ if (!g_plugin_started || !mep_oktodo(pb))
+ return 0;;
+
+ /* Reload config if an existing config entry was renamed,
+ * or if the new dn brings an entry into the scope of the
+ * config entries. */
+ slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &post_e);
+ if (post_e) {
+ new_dn = slapi_entry_get_ndn(post_e);
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Error "
+ "retrieving post-op entry\n");
+ }
+
+ if ((old_dn = mep_get_dn(pb))) {
+ if (mep_dn_is_config(old_dn) || mep_dn_is_config(new_dn))
+ mep_load_config();
+ } else {
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Error "
+ "retrieving dn\n");
+ }
+
+ /* If replication, just bail. */
+ if (mep_isrepl(pb)) {
+ return 0;
+ }
+
+ /* See if we're an origin entry . */
+ managed_dn = slapi_entry_attr_get_charptr(post_e, MEP_MANAGED_ENTRY_TYPE);
+ if (managed_dn) {
+ LDAPMod mod;
+ LDAPMod *mods[3];
+ char *vals[2];
+ int result = LDAP_SUCCESS;
+ Slapi_PBlock *mep_pb = slapi_pblock_new();
+ Slapi_Entry *new_managed_entry = NULL;
+ Slapi_DN *managed_sdn = NULL;
+ Slapi_Mods *smods = NULL;
+
+ mep_config_read_lock();
+ mep_find_config(post_e, &config);
+ if (!config) {
+ LDAPMod mod2;
+ char *vals2[2];
+
+ /* Delete the associated managed entry. */
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Removing managed entry \"%s\" "
+ "since origin entry \"%s\" was moved out of scope.\n",
+ managed_dn, old_dn);
+ slapi_delete_internal_set_pb (mep_pb, managed_dn, NULL, NULL,
+ mep_get_plugin_id(), 0);
+ slapi_delete_internal_pb(mep_pb);
+
+ /* Clear out the pblock for reuse. */
+ slapi_pblock_init(mep_pb);
+
+ /* Remove the pointer from the origin entry. */
+ vals[0] = 0;
+ mod.mod_op = LDAP_MOD_DELETE;
+ mod.mod_type = MEP_MANAGED_ENTRY_TYPE;
+ mod.mod_values = vals;
+
+ /* Remove the origin objectclass. */
+ vals2[0] = MEP_ORIGIN_OC;
+ vals2[1] = 0;
+ mod2.mod_op = LDAP_MOD_DELETE;
+ mod2.mod_type = SLAPI_ATTR_OBJECTCLASS;
+ mod2.mod_values = vals2;
+
+ mods[0] = &mod;
+ mods[1] = &mod2;
+ mods[2] = 0;
+
+ /* Perform the modify operation. */
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Removing %s pointer and %s "
+ "objectclass from entry \"%s\".\n",
+ MEP_MANAGED_ENTRY_TYPE, MEP_ORIGIN_OC, new_dn);
+ slapi_modify_internal_set_pb(mep_pb, new_dn, mods, 0, 0,
+ mep_get_plugin_id(), 0);
+ slapi_modify_internal_pb(mep_pb);
+ slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
+
+ if (result != LDAP_SUCCESS) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Unable to remove %s "
+ "pointer and %s objectclass from entry "
+ "\"%s\".\n", MEP_MANAGED_ENTRY_TYPE,
+ MEP_ORIGIN_OC, new_dn);
+ }
+ } else {
+ /* Update backlink to new origin DN in managed entry. */
+ vals[0] = new_dn;
+ vals[1] = 0;
+ mod.mod_op = LDAP_MOD_REPLACE;
+ mod.mod_type = MEP_MANAGED_BY_TYPE;
+ mod.mod_values = vals;
+
+ mods[0] = &mod;
+ mods[1] = 0;
+
+ /* Perform the modify operation. */
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Updating %s pointer to \"%s\" "
+ "in entry \"%s\".\n", MEP_MANAGED_BY_TYPE, new_dn, managed_dn);
+ slapi_modify_internal_set_pb(mep_pb, managed_dn, mods, 0, 0,
+ mep_get_plugin_id(), 0);
+ slapi_modify_internal_pb(mep_pb);
+ slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
+
+ if (result != LDAP_SUCCESS) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Unable to update pointer to "
+ "origin entry \"%s\" in managed entry \"%s\" "
+ "(%s).\n", new_dn, managed_dn, ldap_err2string(result));
+ } else {
+ /* Create a new managed entry to determine what changes
+ * we need to make to the existing managed entry. */
+ new_managed_entry = mep_create_managed_entry(config, post_e);
+
+ /* See if we need to rename the managed entry. */
+ managed_sdn = slapi_sdn_new_dn_byref(managed_dn);
+ if (slapi_sdn_compare(slapi_entry_get_sdn(new_managed_entry), managed_sdn) != 0) {
+ Slapi_RDN *srdn = slapi_rdn_new();
+
+ /* Clear out the pblock for reuse. */
+ slapi_pblock_init(mep_pb);
+
+ /* Create new RDN */
+ slapi_rdn_set_dn(srdn, slapi_entry_get_dn(new_managed_entry));
+
+ /* Rename the managed entry. */
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Renaming managed entry "
+ "\"%s\" to \"%s\" due to rename of origin "
+ "entry \"%s\".\n ", managed_dn,
+ slapi_entry_get_dn(new_managed_entry), old_dn);
+ slapi_rename_internal_set_pb(mep_pb, managed_dn,
+ slapi_rdn_get_rdn(srdn),
+ NULL, 1, NULL, NULL, mep_get_plugin_id(), 0);
+ slapi_modrdn_internal_pb(mep_pb);
+ slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
+
+ if (result != LDAP_SUCCESS) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Unable to rename managed "
+ "entry \"%s\" to \"%s\" (%s).\n", managed_dn,
+ slapi_entry_get_dn(new_managed_entry),
+ ldap_err2string(result));
+ } else {
+ /* Clear out the pblock for reuse. */
+ slapi_pblock_init(mep_pb);
+
+ /* Update the link to the managed entry in the origin
+ * entry. We can just reuse the mod structure. */
+ vals[0] = slapi_entry_get_dn(new_managed_entry);
+ mod.mod_op = LDAP_MOD_REPLACE;
+ mod.mod_type = MEP_MANAGED_ENTRY_TYPE;
+ mod.mod_values = vals;
+
+ /* Perform the modify operation. */
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Updating %s pointer to "
+ "\"%s\" in entry \"%s\"\n.", MEP_MANAGED_ENTRY_TYPE,
+ vals[0], new_dn);
+ slapi_modify_internal_set_pb(mep_pb, new_dn, mods, 0, 0,
+ mep_get_plugin_id(), 0);
+ slapi_modify_internal_pb(mep_pb);
+ slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
+
+ if (result != LDAP_SUCCESS) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Unable to rename managed "
+ "entry \"%s\" to \"%s\" (%s).\n", managed_dn,
+ slapi_entry_get_dn(new_managed_entry),
+ ldap_err2string(result));
+ slapi_rdn_free(&srdn);
+ goto bail;
+ }
+ }
+
+ slapi_rdn_free(&srdn);
+ }
+
+ /* Update all of the mapped attributes
+ * to be sure they are up to date. */
+ smods = mep_get_mapped_mods(config, post_e);
+ if (smods) {
+ /* Clear out the pblock for reuse. */
+ slapi_pblock_init(mep_pb);
+
+ /* Perform the modify operation. */
+ slapi_log_error(SLAPI_LOG_PLUGIN, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Updating mapped attributes "
+ "in entry \"%s\"\n.", managed_dn);
+ slapi_modify_internal_set_pb(mep_pb, slapi_entry_get_dn(new_managed_entry),
+ slapi_mods_get_ldapmods_byref(smods), 0, 0,
+ mep_get_plugin_id(), 0);
+ slapi_modify_internal_pb(mep_pb);
+ slapi_pblock_get(mep_pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
+
+ if (result != LDAP_SUCCESS) {
+ slapi_log_error(SLAPI_LOG_FATAL, MEP_PLUGIN_SUBSYSTEM,
+ "mep_modrdn_post_op: Unable to update mapped "
+ "attributes from origin entry \"%s\" in managed "
+ "entry \"%s\" (%s).\n", new_dn,
+ slapi_entry_get_dn(new_managed_entry),
+ ldap_err2string(result));
+ }
+
+ slapi_mods_free(&smods);
+ }
+
+ bail:
+ slapi_sdn_free(&managed_sdn);
+ slapi_entry_free(new_managed_entry);
+ }
+ }
+
+ slapi_pblock_destroy(mep_pb);
+
+ slapi_ch_free_string(&managed_dn);
+
+ mep_config_unlock();
+ } else {
+ /* Was this entry moved into scope of a config entry?
+ * If so, treat like an add and create the new managed
+ * entry and links. */
+ mep_config_read_lock();
+ mep_find_config(post_e, &config);
+ if (config) {
+ mep_add_managed_entry(config, post_e);
+ }
+
+ mep_config_unlock();
+ }
+
+ slapi_log_error(SLAPI_LOG_TRACE, MEP_PLUGIN_SUBSYSTEM,
+ "<-- mep_modrdn_post_op\n");
+
+ return 0;
+}
+
diff --git a/ldap/servers/plugins/mep/mep.h b/ldap/servers/plugins/mep/mep.h
new file mode 100644
index 0000000..9cbd204
--- /dev/null
+++ b/ldap/servers/plugins/mep/mep.h
@@ -0,0 +1,124 @@
+/** 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.
+ *
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
+ * right to link the code of this Program with code not covered under the GNU
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
+ * permitted under this exception must only link 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 GNU General Public License. Only Red Hat, Inc. may make changes or
+ * additions to the list of Approved Interfaces. You must obey the GNU General
+ * Public License in all respects for all of the Program code and other code used
+ * in conjunction with the Program except the Non-GPL Code covered by this
+ * exception. If you modify this file, you may extend this exception to your
+ * version of the file, but you are not obligated to do so. If you do not wish to
+ * provide this exception without modification, you must delete this exception
+ * statement from your version and license this file solely under the GPL without
+ * exception.
+ *
+ *
+ * Copyright (C) 2010 Red Hat, Inc.
+ * All rights reserved.
+ * END COPYRIGHT BLOCK **/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+/*
+ * Managed entries plug-in header file
+ */
+#include <stdio.h>
+#include <ctype.h>
+#include <string.h>
+#include <errno.h>
+#include "portable.h"
+#include "nspr.h"
+#include "slapi-plugin.h"
+#include "prclist.h"
+#include "ldif.h"
+
+/*
+ * Plug-in defines
+ */
+#define MEP_PLUGIN_SUBSYSTEM "managed-entries-plugin"
+#define MEP_FEATURE_DESC "Managed Entries"
+#define MEP_PLUGIN_DESC "Managed Entries plugin"
+#define MEP_INT_POSTOP_DESC "Managed Entries internal postop plugin"
+#define MEP_POSTOP_DESC "Managed Entries postop plugin"
+
+/*
+ * Config type defines
+ */
+#define MEP_SCOPE_TYPE "originScope"
+#define MEP_FILTER_TYPE "originFilter"
+#define MEP_MANAGED_BASE_TYPE "managedBase"
+#define MEP_MANAGED_TEMPLATE_TYPE "managedTemplate"
+
+/*
+ * Link type defines
+ */
+#define MEP_MANAGED_ENTRY_TYPE "mepManagedEntry"
+#define MEP_MANAGED_BY_TYPE "mepManagedBy"
+
+/*
+ * Template type defines
+ */
+#define MEP_STATIC_ATTR_TYPE "mepStaticAttr"
+#define MEP_MAPPED_ATTR_TYPE "mepMappedAttr"
+#define MEP_RDN_ATTR_TYPE "mepRDNAttr"
+
+/*
+ * Objectclass defines
+ */
+#define MEP_MANAGED_OC "mepManagedEntry"
+#define MEP_TEMPLATE_OC "mepTemplateEntry"
+#define MEP_ORIGIN_OC "mepOriginEntry"
+
+/*
+ * Linked list of config entries.
+ */
+struct configEntry {
+ PRCList list;
+ char *dn;
+ char *origin_scope;
+ Slapi_Filter *origin_filter;
+ char *managed_base;
+ char *template_dn;
+ Slapi_Entry *template_entry;
+};
+
+/*
+ * Config fetch function
+ */
+PRCList *mep_get_config();
+
+/*
+ * Config cache locking functions
+ */
+void mep_config_read_lock();
+void mep_config_write_lock();
+void mep_config_unlock();
+
+/*
+ * Plugin identity functions
+ */
+void mep_set_plugin_id(void *pluginID);
+void *mep_get_plugin_id();
+void mep_set_plugin_dn(char *pluginDN);
+char *mep_get_plugin_dn();
+
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
index 47fc7b8..9229ea7 100644
--- a/ldap/servers/slapd/slapi-plugin.h
+++ b/ldap/servers/slapd/slapi-plugin.h
@@ -3384,7 +3384,7 @@ int slapi_attr_value_cmp( const Slapi_Attr *attr, const struct berval *v1, const
* \param v Pointer to the \c berval structure containing the value for
* which you want to search.
* \return \c 0 if the attribute contains the specified value.
- * \return \c 01 if the attribute does not contain the specified value.
+ * \return \c -1 if the attribute does not contain the specified value.
* \see slapi_attr_add_value()
* \see slapi_attr_first_value()
* \see slapi_attr_next_value()
diff --git a/ltmain.sh b/ltmain.sh
old mode 100644
new mode 100755
13 years, 11 months
ldap/servers
by Richard Allen Megginson
ldap/servers/plugins/replication/repl5_replica.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
New commits:
commit 4b520bfed95c10ecf9239f7a42f3fb38b673d203
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Fri Apr 2 17:38:57 2010 -0600
Bug 561575 - setup-ds-admin fails to supply nsds5ReplicaName when configuring via ConfigFile
https://bugzilla.redhat.com/show_bug.cgi?id=561575
Resolves: bug 561575
Bug Description: setup-ds-admin fails to supply nsds5ReplicaName when configuring via ConfigFile
Reviewed by: nhosoi (Thanks!)
Branch: HEAD
Fix Description: The main problem was that the mod val was a berval, so we
needed |LDAP_MOD_BVALUES for the mod_op. The other problem is that the
mod and values were being used out of scope. While this seems to work, it's
better to make sure all of the values are in scope.
Platforms tested: RHEL5 x86_64
Flag Day: no
Doc impact: no
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index a563835..f669900 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -2104,6 +2104,9 @@ _replica_update_state (time_t when, void *arg)
LDAPMod *mods[3];
Slapi_PBlock *pb = NULL;
char *dn = NULL;
+ struct berval *vals[2];
+ struct berval val;
+ LDAPMod mod;
if (NULL == replica_name)
return;
@@ -2173,13 +2176,9 @@ _replica_update_state (time_t when, void *arg)
/* write replica name if it has not been written before */
if (r->new_name)
{
- struct berval *vals[2];
- struct berval val;
- LDAPMod mod;
-
mods[1] = &mod;
- mod.mod_op = LDAP_MOD_REPLACE;
+ mod.mod_op = LDAP_MOD_REPLACE|LDAP_MOD_BVALUES;
mod.mod_type = (char*)attr_replicaName;
mod.mod_bvalues = vals;
vals [0] = &val;
13 years, 11 months
Branch 'Directory_Server_8_2_Branch' - ldap/servers
by Richard Allen Megginson
ldap/servers/plugins/replication/repl5_replica.c | 9 ++++-----
1 file changed, 4 insertions(+), 5 deletions(-)
New commits:
commit df5b545c13720de2b9996d8dc0cb1babc936bea7
Author: Rich Megginson <rmeggins(a)redhat.com>
Date: Fri Apr 2 17:38:57 2010 -0600
Bug 561575 - setup-ds-admin fails to supply nsds5ReplicaName when configuring via ConfigFile
https://bugzilla.redhat.com/show_bug.cgi?id=561575
Resolves: bug 561575
Bug Description: setup-ds-admin fails to supply nsds5ReplicaName when configuring via ConfigFile
Reviewed by: nhosoi (Thanks!)
Branch: Directory_Server_8_2_Branch
Fix Description: The main problem was that the mod val was a berval, so we
needed |LDAP_MOD_BVALUES for the mod_op. The other problem is that the
mod and values were being used out of scope. While this seems to work, it's
better to make sure all of the values are in scope.
Platforms tested: RHEL5 x86_64
Flag Day: no
Doc impact: no
(cherry picked from commit 4b520bfed95c10ecf9239f7a42f3fb38b673d203)
diff --git a/ldap/servers/plugins/replication/repl5_replica.c b/ldap/servers/plugins/replication/repl5_replica.c
index a563835..f669900 100644
--- a/ldap/servers/plugins/replication/repl5_replica.c
+++ b/ldap/servers/plugins/replication/repl5_replica.c
@@ -2104,6 +2104,9 @@ _replica_update_state (time_t when, void *arg)
LDAPMod *mods[3];
Slapi_PBlock *pb = NULL;
char *dn = NULL;
+ struct berval *vals[2];
+ struct berval val;
+ LDAPMod mod;
if (NULL == replica_name)
return;
@@ -2173,13 +2176,9 @@ _replica_update_state (time_t when, void *arg)
/* write replica name if it has not been written before */
if (r->new_name)
{
- struct berval *vals[2];
- struct berval val;
- LDAPMod mod;
-
mods[1] = &mod;
- mod.mod_op = LDAP_MOD_REPLACE;
+ mod.mod_op = LDAP_MOD_REPLACE|LDAP_MOD_BVALUES;
mod.mod_type = (char*)attr_replicaName;
mod.mod_bvalues = vals;
vals [0] = &val;
13 years, 11 months
src/com
by Richard Allen Megginson
src/com/netscape/admin/dirserv/panel/LDAPUrlDialog.java | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
New commits:
commit 66871c50937eede01d26052ea6e355fbdfb5ab57
Author: Endi S. Dewata <edewata(a)redhat.com>
Date: Sun Mar 28 12:10:04 2010 -0500
Bug 496863 - 'Construct' button creates incorrect referral urls
Resolves: bug 496863
Bug Description: 'Construct' button creates incorrect referral urls
Reviewed by: rmeggins (and pushed by)
Fix Description: The com.netscape.admin.dirserv.panel.LDAPUrlDialog. notifyUpdate() has been modified to encode the base DN of the LDAP URL.
Platforms tested: F12
diff --git a/src/com/netscape/admin/dirserv/panel/LDAPUrlDialog.java b/src/com/netscape/admin/dirserv/panel/LDAPUrlDialog.java
index c62dc42..85a1184 100644
--- a/src/com/netscape/admin/dirserv/panel/LDAPUrlDialog.java
+++ b/src/com/netscape/admin/dirserv/panel/LDAPUrlDialog.java
@@ -225,7 +225,7 @@ implements DocumentListener, SuiConstants {
String tdn = _refTargetDNText.getText().trim();
String sUrl = "ldap://" + host + ":" + port;
if (tdn.length() > 0) {
- sUrl += "/" + tdn;
+ sUrl += "/" + LDAPUrl.encode(tdn);
}
try {
_url = new LDAPUrl( sUrl );
13 years, 11 months
console/src/com/netscape/management/client/ug LdapQueryBuilderDialog.java, 1.1.1.1, 1.2
by Richard Allen Megginson
Author: rmeggins
Update of /cvs/dirsec/console/src/com/netscape/management/client/ug
In directory cvs01.phx2.fedoraproject.org:/tmp/cvs-serv12046/src/com/netscape/management/client/ug
Modified Files:
LdapQueryBuilderDialog.java
Log Message:
Bug 496863 - 'Construct' button creates incorrect referral urls
https://bugzilla.redhat.com/show_bug.cgi?id=496863
Resolves: bug 496863
Bug Description: 'Construct' button creates incorrect referral urls
Fixed by: edewata
Reviewed by: rmeggins (and checked in by)
Branch: HEAD
Fix Description: Use LDAPUrl.encode() to encode DN and filter values
used in LDAP URLs
Platforms tested: Fedora 12
Flag Day: no
Doc impact: no
Index: LdapQueryBuilderDialog.java
===================================================================
RCS file: /cvs/dirsec/console/src/com/netscape/management/client/ug/LdapQueryBuilderDialog.java,v
retrieving revision 1.1.1.1
retrieving revision 1.2
diff -u -r1.1.1.1 -r1.2
--- LdapQueryBuilderDialog.java 18 Jul 2005 00:34:22 -0000 1.1.1.1
+++ LdapQueryBuilderDialog.java 2 Apr 2010 17:26:52 -0000 1.2
@@ -272,7 +272,7 @@
*/
private void createQueryString() {
_queryString = "ldap:///";
- _queryString += _baseDN.getText();
+ _queryString += LDAPUrl.encode(_baseDN.getText());
switch (_searchScope.getSelectedIndex()) {
case 0: // Base DN only
@@ -287,30 +287,31 @@
break;
}
+ String filter;
switch (_userOrGroup.getSelectedIndex()) {
case 0: // users only
- _queryString += "(&(objectclass=person)";
+ filter = "(&(objectclass=person)";
break;
case 1: // groups only
- _queryString += "(&(objectclass=groupofuniquenames)";
+ filter = "(&(objectclass=groupofuniquenames)";
break;
case 2: // both users and groups
default:
- _queryString += "(&(|(objectclass=person)(objectclass=groupofuniquenames))";
+ filter = "(&(|(objectclass=person)(objectclass=groupofuniquenames))";
break;
}
String value;
for (int i = 0; i < _criteriaCount; i++) {
if (_criteria[i]._condition.getSelectedIndex() == 3) {
- _queryString += "(!(";
+ filter += "(!(";
} else if (_criteria[i]._condition.getSelectedIndex() == 1) {
- _queryString += "(!(";
+ filter += "(!(";
} else {
- _queryString += "(";
+ filter += "(";
}
- _queryString +=
+ filter +=
(String)(_criteria[i]._attribute.getSelectedItem());
value = _criteria[i]._value.getText();
@@ -321,65 +322,67 @@
switch (_criteria[i]._condition.getSelectedIndex()) {
case 0: // contains
if (value.charAt(0) == '*')
- _queryString += "=";
+ filter += "=";
else
- _queryString += "=*";
- _queryString += value;
+ filter += "=*";
+ filter += value;
if (value.charAt(value.length() - 1) == '*')
- _queryString += ")";
+ filter += ")";
else
- _queryString += "*)";
+ filter += "*)";
break;
case 1: // does not contain (see above)
if (value.charAt(0) == '*')
- _queryString += "=";
+ filter += "=";
else
- _queryString += "=*";
- _queryString += value;
+ filter += "=*";
+ filter += value;
if (value.charAt(value.length() - 1) == '*')
- _queryString += "))";
+ filter += "))";
else
- _queryString += "*))";
+ filter += "*))";
break;
case 2: // is
- _queryString += "=";
- _queryString += value;
- _queryString += ")";
+ filter += "=";
+ filter += value;
+ filter += ")";
break;
case 3: // is not (see above)
- _queryString += "=";
- _queryString += value;
- _queryString += "))";
+ filter += "=";
+ filter += value;
+ filter += "))";
break;
case 4: // begins with
- _queryString += "=";
- _queryString += value;
+ filter += "=";
+ filter += value;
if (value.charAt(value.length() - 1) == '*')
- _queryString += ")";
+ filter += ")";
else
- _queryString += "*)";
+ filter += "*)";
break;
case 5: // ends with
if (value.charAt(0) == '*')
- _queryString += "=";
+ filter += "=";
else
- _queryString += "=*";
- _queryString += value;
- _queryString += ")";
+ filter += "=*";
+ filter += value;
+ filter += ")";
break;
case 6: // sounds like
- _queryString += "~=";
- _queryString += value;
- _queryString += ")";
+ filter += "~=";
+ filter += value;
+ filter += ")";
break;
default: // just in case treat like is
- _queryString += "=";
- _queryString += value;
- _queryString += ")";
+ filter += "=";
+ filter += value;
+ filter += ")";
break;
}
}
- _queryString += ")";
+ filter += ")";
+
+ _queryString += LDAPUrl.encode(filter);
}
13 years, 11 months
Branch 'Directory_Server_8_2_Branch' - lib/libdsa
by Nathan Kinder
lib/libdsa/dsalib_location.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
New commits:
commit 3e2913b166f7b7535e87a15a72b87674e3015aa5
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Wed Mar 31 16:11:16 2010 -0700
Change parsing of start-slapd for instance name
The format of start-slapd changed recently, causing the
parsing of the instance name from that script in the CGIs
to break. This corrects the parsing.
diff --git a/lib/libdsa/dsalib_location.c b/lib/libdsa/dsalib_location.c
index 8cccd0f..7b4bfff 100644
--- a/lib/libdsa/dsalib_location.c
+++ b/lib/libdsa/dsalib_location.c
@@ -110,13 +110,10 @@ ds_get_run_dir()
fp = fopen(start_script, "r");
if (fp) {
while(fgets(line, BIG_LINE, fp)) {
- /* Find the line that calls start-dirsrv */
- if ((start = strstr(line, "start-dirsrv"))) {
+ /* Find the line with the instance name */
+ if ((start = strstr(line, "INSTANCE"))) {
/* skip any spaces after start-dirsrv */
- start += strlen("start-dirsrv");
- while (isspace(*start)) {
- start++;
- }
+ start += strlen("INSTANCE=");
/* find the end of the instance name */
p = start;
@@ -128,6 +125,8 @@ ds_get_run_dir()
if (strlen(start) > 0) {
inst_name = PR_smprintf("%s", start);
}
+
+ break;
}
}
fclose(fp);
13 years, 11 months
Branch 'Directory_Server_8_2_Branch' - ldap/admin
by Nathan Kinder
ldap/admin/src/scripts/DSCreate.pm.in | 57 ++++++++++++++-----------
ldap/admin/src/scripts/DSUpdate.pm.in | 9 +++
ldap/admin/src/scripts/template-start-slapd.in | 3 -
3 files changed, 42 insertions(+), 27 deletions(-)
New commits:
commit 322cb3eec8b26690a16f2c05fbe08a9fce6ff2a4
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Thu Apr 1 12:11:34 2010 -0700
Allow instance name to be parsed from start-slapd
The admin server CGIs need to be able to easily parse the
instance name from the start-slapd script. Recent format
changes have caused the existing parsing to break, so this
patch makes the parsing of the instance name easier.
To deal with the change in start-slapd format for an upgraded
instance, I have changed the setup code to regenerate all of
the instance scripts during an upgrade instead of simply adding
missing scripts. This is needed for any bug fix that modifies
a script template to work for an upgraded instance. I also
added code to write the instance sysconfig script during upgrade
if it doesn't exist already. We don't want to overwrite this
file if it already exists since it's designed for local changes
to be made to it.
diff --git a/ldap/admin/src/scripts/DSCreate.pm.in b/ldap/admin/src/scripts/DSCreate.pm.in
index 571d859..e04f1cd 100644
--- a/ldap/admin/src/scripts/DSCreate.pm.in
+++ b/ldap/admin/src/scripts/DSCreate.pm.in
@@ -64,8 +64,8 @@ use Mozilla::LDAP::LDIF;
use Exporter;
@ISA = qw(Exporter);
-@EXPORT = qw(createDSInstance removeDSInstance setDefaults createInstanceScripts installSchema);
-@EXPORT_OK = qw(createDSInstance removeDSInstance setDefaults createInstanceScripts installSchema);
+@EXPORT = qw(createDSInstance removeDSInstance setDefaults createInstanceScripts makeOtherConfigFiles installSchema);
+@EXPORT_OK = qw(createDSInstance removeDSInstance setDefaults createInstanceScripts makeOtherConfigFiles installSchema);
use strict;
@@ -424,6 +424,7 @@ sub createConfigFile {
sub makeOtherConfigFiles {
my $inf = shift;
+ my $skip = shift;
my @errs;
my %maptable = (
"DS-ROOT" => $inf->{General}->{prefix},
@@ -449,13 +450,18 @@ sub makeOtherConfigFiles {
$src = "$inf->{General}->{prefix}@configdir(a)/slapd-collations.conf";
$dest = "$inf->{slapd}->{config_dir}/slapd-collations.conf";
+
$! = 0; # clear errno
- copy($src, $dest);
- if ($!) {
- return ('error_copying_file', $src, $dest, $!);
- }
- if (@errs = changeOwnerMode($inf, 4, $dest)) {
- return @errs;
+
+ #in skip mode, skip files that already exist
+ unless ($skip and -f $dest) {
+ copy($src, $dest);
+ if ($!) {
+ return ('error_copying_file', $src, $dest, $!);
+ }
+ if (@errs = changeOwnerMode($inf, 4, $dest)) {
+ return @errs;
+ }
}
# install instance specific initconfig script
@@ -463,22 +469,25 @@ sub makeOtherConfigFiles {
$dest = "$inf->{General}->{prefix}@initconfigdir@/@package_name@-$inf->{slapd}->{ServerIdentifier}";
$! = 0; # clear errno
- if (!open(SRC, "< $src")) {
- return ("error_opening_scripttmpl", $src, $!);
- }
- if (!open(DEST, "> $dest")) {
- return ("error_opening_scripttmpl", $dest, $!);
- }
- my $contents; # slurp entire file into memory
- read SRC, $contents, int(-s $src);
- close(SRC);
- while (my ($key, $val) = each %maptable) {
- $contents =~ s/\{\{$key\}\}/$val/g;
- }
- print DEST $contents;
- close(DEST);
- if (@errs = changeOwnerMode($inf, 4, $dest)) {
- return @errs;
+ # in skip mode, skip files that already exist
+ unless ($skip and -f $dest) {
+ if (!open(SRC, "< $src")) {
+ return ("error_opening_scripttmpl", $src, $!);
+ }
+ if (!open(DEST, "> $dest")) {
+ return ("error_opening_scripttmpl", $dest, $!);
+ }
+ my $contents; # slurp entire file into memory
+ read SRC, $contents, int(-s $src);
+ close(SRC);
+ while (my ($key, $val) = each %maptable) {
+ $contents =~ s/\{\{$key\}\}/$val/g;
+ }
+ print DEST $contents;
+ close(DEST);
+ if (@errs = changeOwnerMode($inf, 4, $dest)) {
+ return @errs;
+ }
}
return ();
diff --git a/ldap/admin/src/scripts/DSUpdate.pm.in b/ldap/admin/src/scripts/DSUpdate.pm.in
index 3792afe..3241a58 100644
--- a/ldap/admin/src/scripts/DSUpdate.pm.in
+++ b/ldap/admin/src/scripts/DSUpdate.pm.in
@@ -47,7 +47,7 @@ package DSUpdate;
use DSUtil;
use Inf;
use FileConn;
-use DSCreate qw(setDefaults createInstanceScripts);
+use DSCreate qw(setDefaults createInstanceScripts makeOtherConfigFiles);
use File::Basename qw(basename dirname);
@@ -315,7 +315,12 @@ sub updateDSInstance {
}
# upgrade instance scripts
- if (@errs = createInstanceScripts($inf, 1)) {
+ if (@errs = createInstanceScripts($inf, 0)) {
+ return @errs;
+ }
+
+ # add new or missing config files
+ if (@errs = makeOtherConfigFiles($inf, 1)) {
return @errs;
}
diff --git a/ldap/admin/src/scripts/template-start-slapd.in b/ldap/admin/src/scripts/template-start-slapd.in
index 7608d37..6718d84 100755
--- a/ldap/admin/src/scripts/template-start-slapd.in
+++ b/ldap/admin/src/scripts/template-start-slapd.in
@@ -5,6 +5,7 @@
# 0: Server started successfully
# 1: Server could not be started
# 2: Server already running
+INSTANCE={{SERV-ID}}
-@sbindir@/start-dirsrv {{SERV-ID}} "$@"
+@sbindir@/start-dirsrv $INSTANCE "$@"
exit $?
13 years, 11 months
lib/libdsa
by Nathan Kinder
lib/libdsa/dsalib_location.c | 11 +++++------
1 file changed, 5 insertions(+), 6 deletions(-)
New commits:
commit 258be85ceff527859d2834a282ca3d83b230e0b1
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Wed Mar 31 16:11:16 2010 -0700
Change parsing of start-slapd for instance name
The format of start-slapd changed recently, causing the
parsing of the instance name from that script in the CGIs
to break. This corrects the parsing.
diff --git a/lib/libdsa/dsalib_location.c b/lib/libdsa/dsalib_location.c
index 8cccd0f..7b4bfff 100644
--- a/lib/libdsa/dsalib_location.c
+++ b/lib/libdsa/dsalib_location.c
@@ -110,13 +110,10 @@ ds_get_run_dir()
fp = fopen(start_script, "r");
if (fp) {
while(fgets(line, BIG_LINE, fp)) {
- /* Find the line that calls start-dirsrv */
- if ((start = strstr(line, "start-dirsrv"))) {
+ /* Find the line with the instance name */
+ if ((start = strstr(line, "INSTANCE"))) {
/* skip any spaces after start-dirsrv */
- start += strlen("start-dirsrv");
- while (isspace(*start)) {
- start++;
- }
+ start += strlen("INSTANCE=");
/* find the end of the instance name */
p = start;
@@ -128,6 +125,8 @@ ds_get_run_dir()
if (strlen(start) > 0) {
inst_name = PR_smprintf("%s", start);
}
+
+ break;
}
}
fclose(fp);
13 years, 11 months
ldap/admin
by Nathan Kinder
ldap/admin/src/scripts/DSCreate.pm.in | 57 ++++++++++++++-----------
ldap/admin/src/scripts/DSUpdate.pm.in | 9 +++
ldap/admin/src/scripts/template-start-slapd.in | 3 -
3 files changed, 42 insertions(+), 27 deletions(-)
New commits:
commit f232bda45d7bc6216b091f38fa7ab4549ede6fde
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Thu Apr 1 11:12:02 2010 -0700
Allow instance name to be parsed from start-slapd
The admin server CGIs need to be able to easily parse the
instance name from the start-slapd script. Recent format
changes have caused the existing parsing to break, so this
patch makes the parsing of the instance name easier.
To deal with the change in start-slapd format for an upgraded
instance, I have changed the setup code to regenerate all of
the instance scripts during an upgrade instead of simply adding
missing scripts. This is needed for any bug fix that modifies
a script template to work for an upgraded instance. I also
added code to write the instance sysconfig script during upgrade
if it doesn't exist already. We don't want to overwrite this
file if it already exists since it's designed for local changes
to be made to it.
diff --git a/ldap/admin/src/scripts/DSCreate.pm.in b/ldap/admin/src/scripts/DSCreate.pm.in
index 06b2d1f..09b7cd1 100644
--- a/ldap/admin/src/scripts/DSCreate.pm.in
+++ b/ldap/admin/src/scripts/DSCreate.pm.in
@@ -64,8 +64,8 @@ use Mozilla::LDAP::LDIF;
use Exporter;
@ISA = qw(Exporter);
-@EXPORT = qw(createDSInstance removeDSInstance setDefaults createInstanceScripts installSchema);
-@EXPORT_OK = qw(createDSInstance removeDSInstance setDefaults createInstanceScripts installSchema);
+@EXPORT = qw(createDSInstance removeDSInstance setDefaults createInstanceScripts makeOtherConfigFiles installSchema);
+@EXPORT_OK = qw(createDSInstance removeDSInstance setDefaults createInstanceScripts makeOtherConfigFiles installSchema);
use strict;
@@ -436,6 +436,7 @@ sub createConfigFile {
sub makeOtherConfigFiles {
my $inf = shift;
+ my $skip = shift;
my @errs;
my %maptable = (
"DS-ROOT" => $inf->{General}->{prefix},
@@ -461,13 +462,18 @@ sub makeOtherConfigFiles {
$src = "$inf->{General}->{prefix}@configdir(a)/slapd-collations.conf";
$dest = "$inf->{slapd}->{config_dir}/slapd-collations.conf";
+
$! = 0; # clear errno
- copy($src, $dest);
- if ($!) {
- return ('error_copying_file', $src, $dest, $!);
- }
- if (@errs = changeOwnerMode($inf, 4, $dest)) {
- return @errs;
+
+ #in skip mode, skip files that already exist
+ unless ($skip and -f $dest) {
+ copy($src, $dest);
+ if ($!) {
+ return ('error_copying_file', $src, $dest, $!);
+ }
+ if (@errs = changeOwnerMode($inf, 4, $dest)) {
+ return @errs;
+ }
}
# determine initconfig_dir
@@ -487,22 +493,25 @@ sub makeOtherConfigFiles {
$! = 0; # clear errno
- if (!open(SRC, "< $src")) {
- return ("error_opening_scripttmpl", $src, $!);
- }
- if (!open(DEST, "> $dest")) {
- return ("error_opening_scripttmpl", $dest, $!);
- }
- my $contents; # slurp entire file into memory
- read SRC, $contents, int(-s $src);
- close(SRC);
- while (my ($key, $val) = each %maptable) {
- $contents =~ s/\{\{$key\}\}/$val/g;
- }
- print DEST $contents;
- close(DEST);
- if (@errs = changeOwnerMode($inf, 4, $dest)) {
- return @errs;
+ # in skip mode, skip files that already exist
+ unless ($skip and -f $dest) {
+ if (!open(SRC, "< $src")) {
+ return ("error_opening_scripttmpl", $src, $!);
+ }
+ if (!open(DEST, "> $dest")) {
+ return ("error_opening_scripttmpl", $dest, $!);
+ }
+ my $contents; # slurp entire file into memory
+ read SRC, $contents, int(-s $src);
+ close(SRC);
+ while (my ($key, $val) = each %maptable) {
+ $contents =~ s/\{\{$key\}\}/$val/g;
+ }
+ print DEST $contents;
+ close(DEST);
+ if (@errs = changeOwnerMode($inf, 4, $dest)) {
+ return @errs;
+ }
}
return ();
diff --git a/ldap/admin/src/scripts/DSUpdate.pm.in b/ldap/admin/src/scripts/DSUpdate.pm.in
index 3792afe..3241a58 100644
--- a/ldap/admin/src/scripts/DSUpdate.pm.in
+++ b/ldap/admin/src/scripts/DSUpdate.pm.in
@@ -47,7 +47,7 @@ package DSUpdate;
use DSUtil;
use Inf;
use FileConn;
-use DSCreate qw(setDefaults createInstanceScripts);
+use DSCreate qw(setDefaults createInstanceScripts makeOtherConfigFiles);
use File::Basename qw(basename dirname);
@@ -315,7 +315,12 @@ sub updateDSInstance {
}
# upgrade instance scripts
- if (@errs = createInstanceScripts($inf, 1)) {
+ if (@errs = createInstanceScripts($inf, 0)) {
+ return @errs;
+ }
+
+ # add new or missing config files
+ if (@errs = makeOtherConfigFiles($inf, 1)) {
return @errs;
}
diff --git a/ldap/admin/src/scripts/template-start-slapd.in b/ldap/admin/src/scripts/template-start-slapd.in
index 444a37f..0c9ac63 100755
--- a/ldap/admin/src/scripts/template-start-slapd.in
+++ b/ldap/admin/src/scripts/template-start-slapd.in
@@ -5,6 +5,7 @@
# 0: Server started successfully
# 1: Server could not be started
# 2: Server already running
+INSTANCE={{SERV-ID}}
-@sbindir@/start-dirsrv -d {{INITCONFIG-DIR}} {{SERV-ID}} "$@"
+@sbindir@/start-dirsrv -d {{INITCONFIG-DIR}} $INSTANCE "$@"
exit $?
13 years, 11 months
selinux/dirsrv-admin.te
by Nathan Kinder
selinux/dirsrv-admin.te | 1 +
1 file changed, 1 insertion(+)
New commits:
commit 9f1ab162a04c4f0c2f9d17a3417f6bb7ebbbcb46
Author: Nathan Kinder <nkinder(a)redhat.com>
Date: Thu Apr 1 11:41:44 2010 -0700
Bug 570912 - Avoid selinux context conflict with httpd
This patch makes the confined context for the admin server CGIs
use a new macro provided by the dirsrv policy. This macro allows
pid directories created by the CGIs to be labelled with the proper
dirsrv context. This was previously provided by a different macro
that was applied to httpd as well as the CGIs, but it caused a
conflict with the httpd policy. With this change the rule only
applies to the CGIs.
diff --git a/selinux/dirsrv-admin.te b/selinux/dirsrv-admin.te
index e6ecb4b..2bcb359 100644
--- a/selinux/dirsrv-admin.te
+++ b/selinux/dirsrv-admin.te
@@ -123,6 +123,7 @@ dirsrv_signal(httpd_dirsrvadmin_script_t)
dirsrv_signull(httpd_dirsrvadmin_script_t)
dirsrv_manage_log(httpd_dirsrvadmin_script_t)
dirsrv_manage_var_lib(httpd_dirsrvadmin_script_t)
+dirsrv_pid_filetrans(httpd_dirsrvadmin_script_t)
dirsrv_manage_var_run(httpd_dirsrvadmin_script_t)
dirsrv_manage_config(httpd_dirsrvadmin_script_t)
dirsrv_exec_lib(httpd_dirsrvadmin_script_t)
13 years, 11 months