diff options
author | Noriko Hosoi <nhosoi@redhat.com> | 2009-07-21 12:59:38 -0700 |
---|---|---|
committer | Rich Megginson <rmeggins@redhat.com> | 2009-08-12 12:46:18 -0600 |
commit | 7feaa84f3580ee3080c0876661b80a361601b12b (patch) | |
tree | dd8b5821162aec047945eaee28676689216ae61d | |
parent | 752a9b2700d2a9acfabe9e8d4813b42de117203b (diff) | |
download | ds-7feaa84f3580ee3080c0876661b80a361601b12b.tar.gz ds-7feaa84f3580ee3080c0876661b80a361601b12b.tar.xz ds-7feaa84f3580ee3080c0876661b80a361601b12b.zip |
Entry USN
First cut for implementing Entry USN.
See http://directory.fedoraproject.org/wiki/Entry_USN for the design details.
This change includes a bug fix for "db2ldif -r"; event queue system was not
shutdown before the plugins are closed, which could have crashed the command
line utility.
25 files changed, 1748 insertions, 81 deletions
diff --git a/Makefile.am b/Makefile.am index 65977d9d..29d9d28d 100644 --- a/Makefile.am +++ b/Makefile.am @@ -157,9 +157,10 @@ serverplugin_LTLIBRARIES = libacl-plugin.la libattr-unique-plugin.la \ libhttp-client-plugin.la liblinkedattrs-plugin.la \ libmemberof-plugin.la libpassthru-plugin.la libpwdstorage-plugin.la \ libreferint-plugin.la libreplication-plugin.la libretrocl-plugin.la \ - libroles-plugin.la libschemareload-plugin.la libstatechange-plugin.la \ - libsyntax-plugin.la libviews-plugin.la $(LIBPAM_PASSTHRU_PLUGIN) \ - $(LIBDNA_PLUGIN) $(LIBBITWISE_PLUGIN) $(LIBPRESENCE_PLUGIN) + libroles-plugin.la libstatechange-plugin.la libsyntax-plugin.la \ + libviews-plugin.la libschemareload-plugin.la libusn-plugin.la \ + $(LIBPAM_PASSTHRU_PLUGIN) $(LIBDNA_PLUGIN) \ + $(LIBBITWISE_PLUGIN) $(LIBPRESENCE_PLUGIN) nodist_property_DATA = ns-slapd.properties @@ -312,6 +313,7 @@ task_SCRIPTS = ldap/admin/src/scripts/template-bak2db \ ldap/admin/src/scripts/template-ns-newpwpolicy.pl \ ldap/admin/src/scripts/template-schema-reload.pl \ ldap/admin/src/scripts/template-syntax-validate.pl \ + ldap/admin/src/scripts/template-usn-tombstone-cleanup.pl \ ldap/admin/src/scripts/template-verify-db.pl \ ldap/admin/src/scripts/template-dbverify @@ -615,6 +617,7 @@ libback_ldbm_la_SOURCES = ldap/servers/slapd/back-ldbm/ancestorid.c \ ldap/servers/slapd/back-ldbm/ldbm_modrdn.c \ ldap/servers/slapd/back-ldbm/ldbm_search.c \ ldap/servers/slapd/back-ldbm/ldbm_unbind.c \ + ldap/servers/slapd/back-ldbm/ldbm_usn.c \ ldap/servers/slapd/back-ldbm/ldif2ldbm.c \ ldap/servers/slapd/back-ldbm/dbverify.c \ ldap/servers/slapd/back-ldbm/matchrule.c \ @@ -966,6 +969,15 @@ libsyntax_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) libsyntax_plugin_la_LDFLAGS = -avoid-version #------------------------ +# libusn-plugin +#------------------------ +libusn_plugin_la_SOURCES = ldap/servers/plugins/usn/usn.c \ + ldap/servers/plugins/usn/usn_cleanup.c + +libusn_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) +libusn_plugin_la_LDFLAGS = -avoid-version + +#------------------------ # libviews-plugin #------------------------ libviews_plugin_la_SOURCES = ldap/servers/plugins/views/views.c diff --git a/Makefile.in b/Makefile.in index 00c5fae4..2b9f3486 100644 --- a/Makefile.in +++ b/Makefile.in @@ -173,6 +173,7 @@ am_libback_ldbm_la_OBJECTS = \ ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_modrdn.lo \ ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_search.lo \ ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_unbind.lo \ + ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_usn.lo \ ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldif2ldbm.lo \ ldap/servers/slapd/back-ldbm/libback_ldbm_la-dbverify.lo \ ldap/servers/slapd/back-ldbm/libback_ldbm_la-matchrule.lo \ @@ -688,6 +689,14 @@ libsyntax_plugin_la_OBJECTS = $(am_libsyntax_plugin_la_OBJECTS) libsyntax_plugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ $(libsyntax_plugin_la_LDFLAGS) $(LDFLAGS) -o $@ +libusn_plugin_la_LIBADD = +am_libusn_plugin_la_OBJECTS = \ + ldap/servers/plugins/usn/libusn_plugin_la-usn.lo \ + ldap/servers/plugins/usn/libusn_plugin_la-usn_cleanup.lo +libusn_plugin_la_OBJECTS = $(am_libusn_plugin_la_OBJECTS) +libusn_plugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(libusn_plugin_la_LDFLAGS) $(LDFLAGS) -o $@ libviews_plugin_la_LIBADD = am_libviews_plugin_la_OBJECTS = \ ldap/servers/plugins/views/libviews_plugin_la-views.lo @@ -899,10 +908,11 @@ SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \ $(libretrocl_plugin_la_SOURCES) $(libroles_plugin_la_SOURCES) \ $(libschemareload_plugin_la_SOURCES) $(libslapd_la_SOURCES) \ $(libstatechange_plugin_la_SOURCES) \ - $(libsyntax_plugin_la_SOURCES) $(libviews_plugin_la_SOURCES) \ - $(dbscan_bin_SOURCES) $(dsktune_bin_SOURCES) \ - $(infadd_bin_SOURCES) $(ldap_agent_bin_SOURCES) \ - $(ldclt_bin_SOURCES) $(ldif_bin_SOURCES) $(makstrdb_SOURCES) \ + $(libsyntax_plugin_la_SOURCES) $(libusn_plugin_la_SOURCES) \ + $(libviews_plugin_la_SOURCES) $(dbscan_bin_SOURCES) \ + $(dsktune_bin_SOURCES) $(infadd_bin_SOURCES) \ + $(ldap_agent_bin_SOURCES) $(ldclt_bin_SOURCES) \ + $(ldif_bin_SOURCES) $(makstrdb_SOURCES) \ $(migratecred_bin_SOURCES) $(mmldif_bin_SOURCES) \ $(ns_slapd_SOURCES) $(pwdhash_bin_SOURCES) \ $(rsearch_bin_SOURCES) @@ -927,13 +937,14 @@ DIST_SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \ $(libschemareload_plugin_la_SOURCES) \ $(am__libslapd_la_SOURCES_DIST) \ $(libstatechange_plugin_la_SOURCES) \ - $(libsyntax_plugin_la_SOURCES) $(libviews_plugin_la_SOURCES) \ - $(dbscan_bin_SOURCES) $(dsktune_bin_SOURCES) \ - $(infadd_bin_SOURCES) $(ldap_agent_bin_SOURCES) \ - $(am__ldclt_bin_SOURCES_DIST) $(ldif_bin_SOURCES) \ - $(makstrdb_SOURCES) $(migratecred_bin_SOURCES) \ - $(mmldif_bin_SOURCES) $(am__ns_slapd_SOURCES_DIST) \ - $(pwdhash_bin_SOURCES) $(rsearch_bin_SOURCES) + $(libsyntax_plugin_la_SOURCES) $(libusn_plugin_la_SOURCES) \ + $(libviews_plugin_la_SOURCES) $(dbscan_bin_SOURCES) \ + $(dsktune_bin_SOURCES) $(infadd_bin_SOURCES) \ + $(ldap_agent_bin_SOURCES) $(am__ldclt_bin_SOURCES_DIST) \ + $(ldif_bin_SOURCES) $(makstrdb_SOURCES) \ + $(migratecred_bin_SOURCES) $(mmldif_bin_SOURCES) \ + $(am__ns_slapd_SOURCES_DIST) $(pwdhash_bin_SOURCES) \ + $(rsearch_bin_SOURCES) man1dir = $(mandir)/man1 man8dir = $(mandir)/man8 NROFF = nroff @@ -1251,9 +1262,10 @@ serverplugin_LTLIBRARIES = libacl-plugin.la libattr-unique-plugin.la \ libhttp-client-plugin.la liblinkedattrs-plugin.la \ libmemberof-plugin.la libpassthru-plugin.la libpwdstorage-plugin.la \ libreferint-plugin.la libreplication-plugin.la libretrocl-plugin.la \ - libroles-plugin.la libschemareload-plugin.la libstatechange-plugin.la \ - libsyntax-plugin.la libviews-plugin.la $(LIBPAM_PASSTHRU_PLUGIN) \ - $(LIBDNA_PLUGIN) $(LIBBITWISE_PLUGIN) $(LIBPRESENCE_PLUGIN) + libroles-plugin.la libstatechange-plugin.la libsyntax-plugin.la \ + libviews-plugin.la libschemareload-plugin.la libusn-plugin.la \ + $(LIBPAM_PASSTHRU_PLUGIN) $(LIBDNA_PLUGIN) \ + $(LIBBITWISE_PLUGIN) $(LIBPRESENCE_PLUGIN) nodist_property_DATA = ns-slapd.properties noinst_LIBRARIES = libavl.a libldaputil.a @@ -1405,6 +1417,7 @@ task_SCRIPTS = ldap/admin/src/scripts/template-bak2db \ ldap/admin/src/scripts/template-ns-newpwpolicy.pl \ ldap/admin/src/scripts/template-schema-reload.pl \ ldap/admin/src/scripts/template-syntax-validate.pl \ + ldap/admin/src/scripts/template-usn-tombstone-cleanup.pl \ ldap/admin/src/scripts/template-verify-db.pl \ ldap/admin/src/scripts/template-dbverify @@ -1654,6 +1667,7 @@ libback_ldbm_la_SOURCES = ldap/servers/slapd/back-ldbm/ancestorid.c \ ldap/servers/slapd/back-ldbm/ldbm_modrdn.c \ ldap/servers/slapd/back-ldbm/ldbm_search.c \ ldap/servers/slapd/back-ldbm/ldbm_unbind.c \ + ldap/servers/slapd/back-ldbm/ldbm_usn.c \ ldap/servers/slapd/back-ldbm/ldif2ldbm.c \ ldap/servers/slapd/back-ldbm/dbverify.c \ ldap/servers/slapd/back-ldbm/matchrule.c \ @@ -1998,6 +2012,15 @@ libsyntax_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) libsyntax_plugin_la_LDFLAGS = -avoid-version #------------------------ +# libusn-plugin +#------------------------ +libusn_plugin_la_SOURCES = ldap/servers/plugins/usn/usn.c \ + ldap/servers/plugins/usn/usn_cleanup.c + +libusn_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) +libusn_plugin_la_LDFLAGS = -avoid-version + +#------------------------ # libviews-plugin #------------------------ libviews_plugin_la_SOURCES = ldap/servers/plugins/views/views.c @@ -2623,6 +2646,9 @@ ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_search.lo: \ ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_unbind.lo: \ ldap/servers/slapd/back-ldbm/$(am__dirstamp) \ ldap/servers/slapd/back-ldbm/$(DEPDIR)/$(am__dirstamp) +ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_usn.lo: \ + ldap/servers/slapd/back-ldbm/$(am__dirstamp) \ + ldap/servers/slapd/back-ldbm/$(DEPDIR)/$(am__dirstamp) ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldif2ldbm.lo: \ ldap/servers/slapd/back-ldbm/$(am__dirstamp) \ ldap/servers/slapd/back-ldbm/$(DEPDIR)/$(am__dirstamp) @@ -3744,6 +3770,20 @@ ldap/servers/plugins/syntaxes/libsyntax_plugin_la-value.lo: \ ldap/servers/plugins/syntaxes/$(DEPDIR)/$(am__dirstamp) libsyntax-plugin.la: $(libsyntax_plugin_la_OBJECTS) $(libsyntax_plugin_la_DEPENDENCIES) $(libsyntax_plugin_la_LINK) -rpath $(serverplugindir) $(libsyntax_plugin_la_OBJECTS) $(libsyntax_plugin_la_LIBADD) $(LIBS) +ldap/servers/plugins/usn/$(am__dirstamp): + @$(MKDIR_P) ldap/servers/plugins/usn + @: > ldap/servers/plugins/usn/$(am__dirstamp) +ldap/servers/plugins/usn/$(DEPDIR)/$(am__dirstamp): + @$(MKDIR_P) ldap/servers/plugins/usn/$(DEPDIR) + @: > ldap/servers/plugins/usn/$(DEPDIR)/$(am__dirstamp) +ldap/servers/plugins/usn/libusn_plugin_la-usn.lo: \ + ldap/servers/plugins/usn/$(am__dirstamp) \ + ldap/servers/plugins/usn/$(DEPDIR)/$(am__dirstamp) +ldap/servers/plugins/usn/libusn_plugin_la-usn_cleanup.lo: \ + ldap/servers/plugins/usn/$(am__dirstamp) \ + ldap/servers/plugins/usn/$(DEPDIR)/$(am__dirstamp) +libusn-plugin.la: $(libusn_plugin_la_OBJECTS) $(libusn_plugin_la_DEPENDENCIES) + $(libusn_plugin_la_LINK) -rpath $(serverplugindir) $(libusn_plugin_la_OBJECTS) $(libusn_plugin_la_LIBADD) $(LIBS) ldap/servers/plugins/views/$(am__dirstamp): @$(MKDIR_P) ldap/servers/plugins/views @: > ldap/servers/plugins/views/$(am__dirstamp) @@ -4481,6 +4521,10 @@ mostlyclean-compile: -rm -f ldap/servers/plugins/uiduniq/libattr_unique_plugin_la-7bit.lo -rm -f ldap/servers/plugins/uiduniq/libattr_unique_plugin_la-uid.$(OBJEXT) -rm -f ldap/servers/plugins/uiduniq/libattr_unique_plugin_la-uid.lo + -rm -f ldap/servers/plugins/usn/libusn_plugin_la-usn.$(OBJEXT) + -rm -f ldap/servers/plugins/usn/libusn_plugin_la-usn.lo + -rm -f ldap/servers/plugins/usn/libusn_plugin_la-usn_cleanup.$(OBJEXT) + -rm -f ldap/servers/plugins/usn/libusn_plugin_la-usn_cleanup.lo -rm -f ldap/servers/plugins/views/libviews_plugin_la-views.$(OBJEXT) -rm -f ldap/servers/plugins/views/libviews_plugin_la-views.lo -rm -f ldap/servers/slapd/back-ldbm/libback_ldbm_la-ancestorid.$(OBJEXT) @@ -4569,6 +4613,8 @@ mostlyclean-compile: -rm -f ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_search.lo -rm -f ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_unbind.$(OBJEXT) -rm -f ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_unbind.lo + -rm -f ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_usn.$(OBJEXT) + -rm -f ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_usn.lo -rm -f ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldif2ldbm.$(OBJEXT) -rm -f ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldif2ldbm.lo -rm -f ldap/servers/slapd/back-ldbm/libback_ldbm_la-matchrule.$(OBJEXT) @@ -5141,6 +5187,8 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/syntaxes/$(DEPDIR)/libsyntax_plugin_la-value.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/uiduniq/$(DEPDIR)/libattr_unique_plugin_la-7bit.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/uiduniq/$(DEPDIR)/libattr_unique_plugin_la-uid.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/usn/$(DEPDIR)/libusn_plugin_la-usn.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/usn/$(DEPDIR)/libusn_plugin_la-usn_cleanup.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/views/$(DEPDIR)/libviews_plugin_la-views.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/ldap_agent_bin-agtmmap.Po@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/$(DEPDIR)/libslapd_la-add.Plo@am__quote@ @@ -5313,6 +5361,7 @@ distclean-compile: @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-ldbm_modrdn.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-ldbm_search.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-ldbm_unbind.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-ldbm_usn.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-ldif2ldbm.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-matchrule.Plo@am__quote@ @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-misc.Plo@am__quote@ @@ -5991,6 +6040,13 @@ ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_unbind.lo: ldap/servers/slapd/ @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libback_ldbm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_unbind.lo `test -f 'ldap/servers/slapd/back-ldbm/ldbm_unbind.c' || echo '$(srcdir)/'`ldap/servers/slapd/back-ldbm/ldbm_unbind.c +ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_usn.lo: ldap/servers/slapd/back-ldbm/ldbm_usn.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libback_ldbm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_usn.lo -MD -MP -MF ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-ldbm_usn.Tpo -c -o ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_usn.lo `test -f 'ldap/servers/slapd/back-ldbm/ldbm_usn.c' || echo '$(srcdir)/'`ldap/servers/slapd/back-ldbm/ldbm_usn.c +@am__fastdepCC_TRUE@ mv -f ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-ldbm_usn.Tpo ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-ldbm_usn.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ldap/servers/slapd/back-ldbm/ldbm_usn.c' object='ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_usn.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libback_ldbm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldbm_usn.lo `test -f 'ldap/servers/slapd/back-ldbm/ldbm_usn.c' || echo '$(srcdir)/'`ldap/servers/slapd/back-ldbm/ldbm_usn.c + ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldif2ldbm.lo: ldap/servers/slapd/back-ldbm/ldif2ldbm.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libback_ldbm_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldif2ldbm.lo -MD -MP -MF ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-ldif2ldbm.Tpo -c -o ldap/servers/slapd/back-ldbm/libback_ldbm_la-ldif2ldbm.lo `test -f 'ldap/servers/slapd/back-ldbm/ldif2ldbm.c' || echo '$(srcdir)/'`ldap/servers/slapd/back-ldbm/ldif2ldbm.c @am__fastdepCC_TRUE@ mv -f ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-ldif2ldbm.Tpo ldap/servers/slapd/back-ldbm/$(DEPDIR)/libback_ldbm_la-ldif2ldbm.Plo @@ -7909,6 +7965,20 @@ ldap/servers/plugins/syntaxes/libsyntax_plugin_la-value.lo: ldap/servers/plugins @AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libsyntax_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/syntaxes/libsyntax_plugin_la-value.lo `test -f 'ldap/servers/plugins/syntaxes/value.c' || echo '$(srcdir)/'`ldap/servers/plugins/syntaxes/value.c +ldap/servers/plugins/usn/libusn_plugin_la-usn.lo: ldap/servers/plugins/usn/usn.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libusn_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/usn/libusn_plugin_la-usn.lo -MD -MP -MF ldap/servers/plugins/usn/$(DEPDIR)/libusn_plugin_la-usn.Tpo -c -o ldap/servers/plugins/usn/libusn_plugin_la-usn.lo `test -f 'ldap/servers/plugins/usn/usn.c' || echo '$(srcdir)/'`ldap/servers/plugins/usn/usn.c +@am__fastdepCC_TRUE@ mv -f ldap/servers/plugins/usn/$(DEPDIR)/libusn_plugin_la-usn.Tpo ldap/servers/plugins/usn/$(DEPDIR)/libusn_plugin_la-usn.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ldap/servers/plugins/usn/usn.c' object='ldap/servers/plugins/usn/libusn_plugin_la-usn.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libusn_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/usn/libusn_plugin_la-usn.lo `test -f 'ldap/servers/plugins/usn/usn.c' || echo '$(srcdir)/'`ldap/servers/plugins/usn/usn.c + +ldap/servers/plugins/usn/libusn_plugin_la-usn_cleanup.lo: ldap/servers/plugins/usn/usn_cleanup.c +@am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libusn_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/usn/libusn_plugin_la-usn_cleanup.lo -MD -MP -MF ldap/servers/plugins/usn/$(DEPDIR)/libusn_plugin_la-usn_cleanup.Tpo -c -o ldap/servers/plugins/usn/libusn_plugin_la-usn_cleanup.lo `test -f 'ldap/servers/plugins/usn/usn_cleanup.c' || echo '$(srcdir)/'`ldap/servers/plugins/usn/usn_cleanup.c +@am__fastdepCC_TRUE@ mv -f ldap/servers/plugins/usn/$(DEPDIR)/libusn_plugin_la-usn_cleanup.Tpo ldap/servers/plugins/usn/$(DEPDIR)/libusn_plugin_la-usn_cleanup.Plo +@AMDEP_TRUE@@am__fastdepCC_FALSE@ source='ldap/servers/plugins/usn/usn_cleanup.c' object='ldap/servers/plugins/usn/libusn_plugin_la-usn_cleanup.lo' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCC_FALSE@ DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCC_FALSE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libusn_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/usn/libusn_plugin_la-usn_cleanup.lo `test -f 'ldap/servers/plugins/usn/usn_cleanup.c' || echo '$(srcdir)/'`ldap/servers/plugins/usn/usn_cleanup.c + ldap/servers/plugins/views/libviews_plugin_la-views.lo: ldap/servers/plugins/views/views.c @am__fastdepCC_TRUE@ $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libviews_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/views/libviews_plugin_la-views.lo -MD -MP -MF ldap/servers/plugins/views/$(DEPDIR)/libviews_plugin_la-views.Tpo -c -o ldap/servers/plugins/views/libviews_plugin_la-views.lo `test -f 'ldap/servers/plugins/views/views.c' || echo '$(srcdir)/'`ldap/servers/plugins/views/views.c @am__fastdepCC_TRUE@ mv -f ldap/servers/plugins/views/$(DEPDIR)/libviews_plugin_la-views.Tpo ldap/servers/plugins/views/$(DEPDIR)/libviews_plugin_la-views.Plo @@ -9125,6 +9195,7 @@ clean-libtool: -rm -rf ldap/servers/plugins/statechange/.libs ldap/servers/plugins/statechange/_libs -rm -rf ldap/servers/plugins/syntaxes/.libs ldap/servers/plugins/syntaxes/_libs -rm -rf ldap/servers/plugins/uiduniq/.libs ldap/servers/plugins/uiduniq/_libs + -rm -rf ldap/servers/plugins/usn/.libs ldap/servers/plugins/usn/_libs -rm -rf ldap/servers/plugins/views/.libs ldap/servers/plugins/views/_libs -rm -rf ldap/servers/slapd/.libs ldap/servers/slapd/_libs -rm -rf ldap/servers/slapd/back-ldbm/.libs ldap/servers/slapd/back-ldbm/_libs @@ -9639,6 +9710,8 @@ distclean-generic: -rm -f ldap/servers/plugins/syntaxes/$(am__dirstamp) -rm -f ldap/servers/plugins/uiduniq/$(DEPDIR)/$(am__dirstamp) -rm -f ldap/servers/plugins/uiduniq/$(am__dirstamp) + -rm -f ldap/servers/plugins/usn/$(DEPDIR)/$(am__dirstamp) + -rm -f ldap/servers/plugins/usn/$(am__dirstamp) -rm -f ldap/servers/plugins/views/$(DEPDIR)/$(am__dirstamp) -rm -f ldap/servers/plugins/views/$(am__dirstamp) -rm -f ldap/servers/slapd/$(DEPDIR)/$(am__dirstamp) @@ -9679,7 +9752,7 @@ clean-am: clean-binPROGRAMS clean-generic clean-libtool \ 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/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/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/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 -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-hdr distclean-libtool distclean-tags @@ -9721,7 +9794,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/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/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/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 -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic diff --git a/ldap/admin/src/scripts/template-usn-tombstone-cleanup.pl.in b/ldap/admin/src/scripts/template-usn-tombstone-cleanup.pl.in new file mode 100644 index 00000000..bd8c2575 --- /dev/null +++ b/ldap/admin/src/scripts/template-usn-tombstone-cleanup.pl.in @@ -0,0 +1,180 @@ +#{{PERL-EXEC}} +# +# 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) 2009 Red Hat, Inc. +# All rights reserved. +# END COPYRIGHT BLOCK +# + +sub usage { + print(STDERR "Usage: $0 [-v] -D rootdn { -w password | -w - | -j filename } -s suffix | -n backend [ -m maxusn_to_delete ]\n"); + print(STDERR " Opts: -D rootdn - Directory Manager\n"); + print(STDERR " : -w password - Directory Manager's password\n"); + print(STDERR " : -w - - Prompt for Directory Manager's password\n"); + print(STDERR " : -j filename - Read Directory Manager's password from file\n"); + print(STDERR " : -s suffix - Suffix where USN tombstone entries are cleaned up\n"); + print(STDERR " : -n backend - Backend instance in which USN tombstone entries \n"); + print(STDERR " are cleaned up (alternative to suffix)\n"); + print(STDERR " : -m maxusn_to_delete - USN tombstone entries are deleted up to \n"); + print(STDERR " the entry with maxusn_to_delete\n"); + print(STDERR " : -v - verbose\n"); +} + +$rootdn = ""; +$passwd = ""; +$passwdfile = ""; +$args = ""; +$suffix_arg = ""; +$backend_arg = ""; +$maxusn_arg = ""; +$verbose = 0; + +$prefix = "{{DS-ROOT}}"; + +$ENV{'PATH'} = "$prefix@ldapsdk_bindir@:$prefix/usr/bin:@ldapsdk_bindir@:/usr/bin"; +$ENV{'LD_LIBRARY_PATH'} = "$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib"; +$ENV{'SHLIB_PATH'} = "$prefix@nss_libdir@:$prefix/usr/lib:@nss_libdir@:/usr/lib"; + +$i = 0; +while ($i <= $#ARGV) +{ + if ("$ARGV[$i]" eq "-s") + { + # suffix + $i++; $suffix_arg = $ARGV[$i]; + } + elsif ("$ARGV[$i]" eq "-n") + { + # backend + $i++; $backend_arg = $ARGV[$i]; + } + elsif ("$ARGV[$i]" eq "-m") + { + # max usn + $i++; $maxusn_arg = $ARGV[$i]; + } + elsif ("$ARGV[$i]" eq "-D") + { + # Directory Manager + $i++; $rootdn = $ARGV[$i]; + } + elsif ("$ARGV[$i]" eq "-w") + { + # Directory Manager's password + $i++; $passwd = $ARGV[$i]; + } + elsif ("$ARGV[$i]" eq "-j") + { + # Read Directory Manager's password from a file + $i++; $passwdfile = $ARGV[$i]; + } + elsif ("$ARGV[$i]" eq "-v") + { + # verbose + $verbose = 1; + } + else + { + &usage; exit(1); + } + $i++; +} + +if ($passwdfile ne ""){ +# Open file and get the password + unless (open (RPASS, $passwdfile)) { + die "Error, cannot open password file $passwdfile\n"; + } + $passwd = <RPASS>; + chomp($passwd); + close(RPASS); +} elsif ($passwd eq "-"){ +# Read the password from terminal + print "Bind Password: "; + # Disable console echo + system("stty -echo"); + # read the answer + $passwd = <STDIN>; + # Enable console echo + system("stty echo"); + print "\n"; + chop($passwd); # trim trailing newline +} + +if ( $rootdn eq "" || $passwd eq "" ) +{ + &usage; + exit(1); +} + +$vstr = ""; +if ($verbose != 0) +{ + $vstr = "-v"; +} + +# Use a timestamp as part of the task entry name +($s, $m, $h, $dy, $mn, $yr, $wdy, $ydy, $r) = localtime(time); +$mn++; $yr += 1900; +$taskname = "usn_cleanup_${yr}_${mn}_${dy}_${h}_${m}_${s}"; + +# Build the task entry to add +$dn = "dn: cn=$taskname, cn=USN tombstone cleanup task, cn=tasks, cn=config\n"; +$misc = "changetype: add\nobjectclass: top\nobjectclass: extensibleObject\n"; +$cn = "cn: $taskname\n"; + +if ( $suffix_arg eq "" && $backend_arg eq "" ) +{ + &usage; + exit(1); +} +elsif ( $suffix_arg ne "" ) +{ + $args = "suffix: $suffix_arg\n"; +} +else +{ + $args = "backend: $backend_arg\n"; +} + +if ( $maxusn_arg ne "" ) +{ + $args = $args . "maxusn_to_delete: $maxusn_arg\n"; +} + +$entry = "${dn}${misc}${cn}${basedn}${args}"; +open(FOO, "| ldapmodify $vstr -h {{SERVER-NAME}} -p {{SERVER-PORT}} -D \"$rootdn\" -w \"$passwd\" -a" ); +print(FOO "$entry"); +close(FOO); diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in index d0e29278..c2ac588f 100644 --- a/ldap/ldif/template-dse.ldif.in +++ b/ldap/ldif/template-dse.ldif.in @@ -677,6 +677,17 @@ nsslapd-plugintype: preoperation nsslapd-pluginenabled: off nsslapd-plugin-depends-on-type: database +dn: cn=USN,cn=plugins,cn=config +objectclass: top +objectclass: nsSlapdPlugin +objectclass: extensibleObject +cn: USN +nsslapd-pluginpath: libusn-plugin +nsslapd-plugininitfunc: usn_init +nsslapd-plugintype: object +nsslapd-pluginenabled: off +nsslapd-plugin-depends-on-type: database + dn: cn=ldbm database,cn=plugins,cn=config objectclass: top objectclass: nsSlapdPlugin @@ -724,6 +735,14 @@ cn: entrydn nssystemindex: true nsindextype: eq +dn: cn=entryusn,cn=default indexes, cn=config,cn=ldbm database,cn=plugins,cn=config +objectclass: top +objectclass: nsIndex +cn: entryusn +nssystemindex: true +nsindextype: eq +nsmatchingrule: integerOrderingMatch + dn: cn=givenName,cn=default indexes, cn=config,cn=ldbm database,cn=plugins,cn=config objectclass: top objectclass: nsIndex diff --git a/ldap/servers/plugins/usn/usn.c b/ldap/servers/plugins/usn/usn.c new file mode 100644 index 00000000..2bb389a2 --- /dev/null +++ b/ldap/servers/plugins/usn/usn.c @@ -0,0 +1,570 @@ +/** 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) 2009 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "usn.h" + +static Slapi_PluginDesc pdesc = { + "USN", PLUGIN_MAGIC_VENDOR_STR, PRODUCTTEXT, + "USN (Update Sequence Number) plugin" }; + +static CSNGen *_usn_csngen = NULL; + +static void *_usn_identity = NULL; + +static int usn_preop_init(Slapi_PBlock *pb); +static int usn_bepreop_init(Slapi_PBlock *pb); +static int usn_bepostop_init(Slapi_PBlock *pb); +static int usn_rootdse_init(); + +static int usn_preop_delete(Slapi_PBlock *pb); +static int usn_bepreop_add(Slapi_PBlock *pb); +static int usn_bepreop_delete(Slapi_PBlock *pb); +static int usn_bepreop_modify(Slapi_PBlock *pb); +static int usn_bepostop(Slapi_PBlock *pb); +static int usn_start(Slapi_PBlock *pb); +static int usn_close(Slapi_PBlock *pb); +static int usn_get_attr(Slapi_PBlock *pb, const char* type, void *value); + +static int usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, + Slapi_Entry* entryAfter, int *returncode, char *returntext, void *arg); + +/* + * Register USN plugin + * Note: USN counter initialization is done in the backend (ldbm_usn_init). + */ +int +usn_init(Slapi_PBlock *pb) +{ + int rc = 0; + void *identity = NULL; + int enabled = 0; + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "--> usn_init\n"); + + slapi_pblock_get(pb, SLAPI_PLUGIN_ENABLED, &enabled); + + if (!enabled) { + /* not enabled */ + goto bail; + } + + slapi_pblock_get(pb, SLAPI_PLUGIN_IDENTITY, &identity); + + /* slapi_register_plugin always returns SUCCESS (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_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "usn_init: failed to register version & description\n"); + rc = -1; + goto bail; + } + if (slapi_pblock_set(pb, SLAPI_PLUGIN_START_FN, + (void *)usn_start) != 0 ) { + slapi_pblock_set(pb, SLAPI_PLUGIN_CLOSE_FN, + (void *)usn_close) != 0 || + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "usn_init: failed to register close callback & task\n"); + rc = -1; + goto bail; + } + + rc = slapi_register_plugin("preoperation", 1 /* Enabled */, + "usn_preop_init", usn_preop_init, + "USN preoperation plugin", NULL, identity); + rc = slapi_register_plugin("bepreoperation", 1 /* Enabled */, + "usn_bepreop_init", usn_bepreop_init, + "USN bepreoperation plugin", NULL, identity); + rc = slapi_register_plugin("bepostoperation", 1 /* Enabled */, + "usn_bepostop_init", usn_bepostop_init, + "USN bepostoperation plugin", NULL, identity); + usn_set_identity(identity); +bail: + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "<-- usn_init\n"); + return rc; +} + +static int +usn_preop_init(Slapi_PBlock *pb) +{ + int rc = 0; + + /* set up csn generator for tombstone */ + _usn_csngen = csngen_new(USN_CSNGEN_ID, NULL); + if (NULL == _usn_csngen) { + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "usn_preop_init: csngen_new failed\n"); + rc = -1; + } + + if (slapi_pblock_set(pb, SLAPI_PLUGIN_PRE_DELETE_FN, + (void *)usn_preop_delete) != 0) { + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "usn_preop_init: failed to register preop plugin\n"); + rc = -1; + } + + return rc; +} + +static int +usn_bepreop_init(Slapi_PBlock *pb) +{ + int rc = 0; + + if (slapi_pblock_set(pb, SLAPI_PLUGIN_BE_PRE_ADD_FN, + (void *)usn_bepreop_add) != 0 || + slapi_pblock_set(pb, SLAPI_PLUGIN_BE_PRE_DELETE_FN, + (void *)usn_bepreop_delete) != 0 || + slapi_pblock_set(pb, SLAPI_PLUGIN_BE_PRE_MODIFY_FN, + (void *)usn_bepreop_modify) != 0 || + slapi_pblock_set(pb, SLAPI_PLUGIN_BE_PRE_MODRDN_FN, + (void *)usn_bepreop_modify) != 0) { + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "usn_bepreop_init: failed to register bepreop plugin\n"); + rc = -1; + } + + return rc; +} + +static int +usn_bepostop_init(Slapi_PBlock *pb) +{ + int rc = 0; + + if (slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_ADD_FN, + (void *)usn_bepostop) != 0 || + slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_DELETE_FN, + (void *)usn_bepostop) != 0 || + slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_MODIFY_FN, + (void *)usn_bepostop) != 0 || + slapi_pblock_set(pb, SLAPI_PLUGIN_BE_POST_MODRDN_FN, + (void *)usn_bepostop) != 0) { + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "usn_bepostop_init: failed to register bepostop plugin\n"); + rc = -1; + } + + return rc; +} + +static int +usn_rootdse_init() +{ + int rc = -1; + + if (slapi_config_register_callback(SLAPI_OPERATION_SEARCH, DSE_FLAG_PREOP, + "", LDAP_SCOPE_BASE, "(objectclass=*)", + usn_rootdse_search, NULL)) { + rc = 0; + } + + return rc; +} + +/* + * usn_start: usn_rootdse_init -- set rootdse callback to aggregate in rootDSE + * usn_cleanup_start -- initialize USN tombstone cleanup task + */ +static int +usn_start(Slapi_PBlock *pb) +{ + int rc = 0; + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "--> usn_start\n"); + + rc = usn_rootdse_init(); + rc |= usn_cleanup_start(pb); + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "<-- usn_start\n"); + + return rc; +} + +/* + * usn_close: release the csn generator used to convert an entry to tombstone + */ +static int +usn_close(Slapi_PBlock *pb) +{ + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "--> usn_close\n"); + + csngen_free(&_usn_csngen); + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, "<-- usn_close\n"); +} + +/* + * usn_preop_delete -- set params to turn the entry to tombstone + */ +static int +usn_preop_delete(Slapi_PBlock *pb) +{ + int rc = 0; + CSN *csn = NULL; + CSN *orig_csn = NULL; + Slapi_Operation *op = NULL; + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "--> usn_preop_delete\n"); + + slapi_pblock_get(pb, SLAPI_OPERATION, &op); + orig_csn = operation_get_csn(op); + + if (NULL == orig_csn) { + /* + * No other plugins hasn't set csn yet, so let's set USN's csn. + * If other plugin overrides csn and replica_attr_handler, that's fine. + */ + rc = csngen_new_csn(_usn_csngen, &csn, PR_FALSE /* notify */); + if (CSN_SUCCESS != rc) { + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "usn_preop_delete: csngen_new failed (%d)\n", rc); + goto bail; + } + operation_set_csn(op, csn); + slapi_operation_set_replica_attr_handler(op, (void *)usn_get_attr); + } +bail: + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "<-- usn_preop_delete\n"); + + return rc; +} + +#define KEEP_PREV_USN 1 + +static void +_usn_add_next_usn(Slapi_Entry *e, Slapi_Backend *be, int flags) +{ + struct berval usn_berval = {0}; + Slapi_Attr* attr = NULL; + + if (NULL == be->be_usn_counter) { + /* USN plugin is not enabled */ + return; + } + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "--> _usn_add_next_usn\n"); + + /* add next USN to the entry; "be" contains the usn counter */ + usn_berval.bv_val = slapi_ch_smprintf("%" NSPRIu64, + slapi_counter_get_value(be->be_usn_counter)); + usn_berval.bv_len = strlen(usn_berval.bv_val); + slapi_entry_attr_find(e, SLAPI_ATTR_ENTRYUSN, &attr); + if (NULL == attr) { /* ENTRYUSN does not exist; add it */ + Slapi_Value *usn_value = slapi_value_new_berval(&usn_berval); + slapi_entry_add_value(e, SLAPI_ATTR_ENTRYUSN, usn_value); + slapi_value_free(&usn_value); + } else { /* ENTRYUSN exists; replace it */ + struct berval *new_bvals[2]; + struct berval **prev_values = NULL; + if (KEEP_PREV_USN == flags) { + if (0 == slapi_attr_get_bervals_copy(attr, &prev_values)) { + slapi_entry_add_values(e, + SLAPI_ATTR_ENTRYUSN_PREV, prev_values); + ber_bvecfree(prev_values); + } + } + new_bvals[0] = &usn_berval; + new_bvals[1] = NULL; + slapi_entry_attr_replace(e, SLAPI_ATTR_ENTRYUSN, new_bvals); + } + slapi_ch_free_string(&usn_berval.bv_val); + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "<-- _usn_add_next_usn\n"); + + return; +} + +static int +_usn_mod_next_usn(LDAPMod ***mods, Slapi_Backend *be) +{ + Slapi_Mods smods = {0}; + struct berval *bvals[2]; + struct berval usn_berval = {0}; + char counter_buf[USN_COUNTER_BUF_LEN]; + + if (NULL == be->be_usn_counter) { + /* USN plugin is not enabled */ + return LDAP_UNWILLING_TO_PERFORM; + } + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "--> _usn_mod_next_usn\n"); + + /* add next USN to the mods; "be" contains the usn counter */ + usn_berval.bv_val = counter_buf; + PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, + slapi_counter_get_value(be->be_usn_counter)); + usn_berval.bv_len = strlen(usn_berval.bv_val); + bvals[0] = &usn_berval; + bvals[1] = NULL; + + slapi_mods_init_byref(&smods, *mods); + /* bvals is duplicated by ber_bvdup in slapi_mods_add_modbvps */ + slapi_mods_add_modbvps(&smods, LDAP_MOD_REPLACE | LDAP_MOD_BVALUES, + SLAPI_ATTR_ENTRYUSN, bvals); + + *mods = slapi_mods_get_ldapmods_byref(&smods); + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "<-- _usn_mod_next_usn\n"); + return LDAP_SUCCESS; +} + +/* + * usn_bepreop_add - add next USN to the entry to be added + */ +static int +usn_bepreop_add(Slapi_PBlock *pb) +{ + Slapi_Entry *e = NULL; + Slapi_Backend *be = NULL; + int rc = LDAP_SUCCESS; + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "--> usn_bepreop_add\n"); + + /* add next USN to the entry; "be" contains the usn counter */ + slapi_pblock_get(pb, SLAPI_ADD_ENTRY, &e); + if (NULL == e) { + rc = LDAP_NO_SUCH_OBJECT; + goto bail; + } + slapi_pblock_get(pb, SLAPI_BACKEND, &be); + if (NULL == be) { + rc = LDAP_PARAM_ERROR; + goto bail; + } + _usn_add_next_usn(e, be, 0); +bail: + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "<-- usn_bepreop_add\n"); + return rc; +} + +/* + * usn_bepreop_delete -- add/replace next USN to the entry + * bepreop_delete is not called if the entry is tombstone + */ +static int +usn_bepreop_delete(Slapi_PBlock *pb) +{ + Slapi_Entry *e = NULL; + Slapi_Backend *be = NULL; + int rc = LDAP_SUCCESS; + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "--> usn_bepreop_delete\n"); + + /* add next USN to the entry; "be" contains the usn counter */ + slapi_pblock_get(pb, SLAPI_DELETE_BEPREOP_ENTRY, &e); + if (NULL == e) { + rc = LDAP_NO_SUCH_OBJECT; + goto bail; + } + slapi_pblock_get(pb, SLAPI_BACKEND, &be); + if (NULL == be) { + rc = LDAP_PARAM_ERROR; + goto bail; + } + if (e->e_flags & SLAPI_ENTRY_FLAG_TOMBSTONE) { + Slapi_Operation *op = NULL; + slapi_pblock_get(pb, SLAPI_OPERATION, &op); + slapi_operation_set_flag(op, OP_FLAG_TOMBSTONE_ENTRY); + } else { + _usn_add_next_usn(e, be, KEEP_PREV_USN); + } +bail: + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "<-- usn_bepreop_delete\n"); + return rc; +} + +/* + * usn_bepreop_modify - add/replace next USN to the mods; + * shared by modify and modrdn + */ +static int +usn_bepreop_modify (Slapi_PBlock *pb) +{ + LDAPMod **mods = NULL; + Slapi_Backend *be = NULL; + int rc = LDAP_SUCCESS; + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "--> usn_bepreop_modify\n"); + + /* add/replace next USN to the mods; "be" contains the usn counter */ + slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &mods); + slapi_pblock_get(pb, SLAPI_BACKEND, &be); + if (NULL == be) { + rc = LDAP_PARAM_ERROR; + goto bail; + } + if (LDAP_SUCCESS == _usn_mod_next_usn(&mods, be)) { + slapi_pblock_set(pb, SLAPI_MODIFY_MODS, mods); + } +bail: + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "<-- usn_bepreop_modify\n"); + return rc; +} + +/* count up the counter */ +static int +usn_bepostop (Slapi_PBlock *pb) +{ + int rc = -1; + Slapi_Backend *be = NULL; + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "--> usn_bepostop\n"); + + /* if op is not successful, don't increment the counter */ + slapi_pblock_get(pb, SLAPI_RESULT_CODE, &rc); + if (LDAP_SUCCESS != rc) { + goto bail; + } + + slapi_pblock_get(pb, SLAPI_BACKEND, &be); + if (NULL == be) { + rc = LDAP_PARAM_ERROR; + goto bail; + } + + if (be->be_usn_counter) { + slapi_counter_increment(be->be_usn_counter); + } +bail: + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "<-- usn_bepostop\n"); + return rc; +} + +/* mimic replication to turn on create_tombstone_entry */ +static int +usn_get_attr(Slapi_PBlock *pb, const char* type, void *value) +{ + if (0 == strcasecmp(type, "nsds5ReplicaTombstonePurgeInterval")) { + *(int *)value = 1; + } else { + *(int *)value = 0; + } +} + +void +usn_set_identity(void *identity) +{ + _usn_identity = identity; +} + +void * +usn_get_identity() +{ + return _usn_identity; +} + +/* + * usn_rootdse_search -- callback for the search on root DSN + * add lastusn value per backend + * + * example: + * ldapsearch -b "" -s base "(objectclass=*)" lastusn + * dn: + * lastusn;userroot: 72 + * lastusn;testbackend: 15 + */ +static int +usn_rootdse_search(Slapi_PBlock *pb, Slapi_Entry* e, Slapi_Entry* entryAfter, + int *returncode, char *returntext, void *arg) +{ + char *cookie = NULL; + Slapi_Backend *be; + struct berval *vals[2]; + struct berval usn_berval; + vals[0] = &usn_berval; + vals[1] = NULL; + char counter_buf[USN_COUNTER_BUF_LEN]; + int attr_len = 64; /* length of lastusn;<backend_name> */ + char *attr = (char *)slapi_ch_malloc(attr_len); + char *attr_subp = NULL; + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "--> usn_rootdse_search\n"); + + usn_berval.bv_val = counter_buf; + PR_snprintf(attr, USN_LAST_USN_ATTR_CORE_LEN+1, "%s;", USN_LAST_USN); + attr_subp = attr + USN_LAST_USN_ATTR_CORE_LEN; + for (be = slapi_get_first_backend(&cookie); be; + be = slapi_get_next_backend(cookie)) { + if (NULL == be->be_usn_counter) { /* no counter == not a db backend */ + continue; + } + /* get a next USN counter from be_usn_counter; then minus 1 from it */ + PR_snprintf(usn_berval.bv_val, USN_COUNTER_BUF_LEN, "%" NSPRIu64, + slapi_counter_get_value(be->be_usn_counter)-1); + usn_berval.bv_len = strlen(usn_berval.bv_val); + + if (USN_LAST_USN_ATTR_CORE_LEN + strlen(be->be_name) + 1 > attr_len) { + attr_len *= 2; + attr = (char *)slapi_ch_realloc(attr, attr_len); + attr_subp = attr + USN_LAST_USN_ATTR_CORE_LEN; + } + PR_snprintf(attr_subp, attr_len - USN_LAST_USN_ATTR_CORE_LEN, + "%s", be->be_name); + slapi_entry_attr_replace(e, attr, vals); + } + + slapi_ch_free_string(&cookie); + slapi_ch_free_string(&attr); + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "<-- usn_rootdse_search\n"); + return SLAPI_DSE_CALLBACK_OK; +} diff --git a/ldap/servers/plugins/usn/usn.h b/ldap/servers/plugins/usn/usn.h new file mode 100644 index 00000000..cf0cd184 --- /dev/null +++ b/ldap/servers/plugins/usn/usn.h @@ -0,0 +1,57 @@ +/** 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) 2009 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK **/ + +#include <string.h> +#include "slap.h" +#include "slapi-plugin.h" + +#define USN_PLUGIN_SUBSYSTEM "usn-plugin" + +#define USN_CSNGEN_ID 65535 + +#define USN_LAST_USN "lastusn" +#define USN_LAST_USN_ATTR_CORE_LEN 8 /* lastusn; */ + +#define USN_COUNTER_BUF_LEN 32 /* enough size for 64 bit inteters */ + +/* usn.c */ +void usn_set_identity(void *identity); +void *usn_get_identity(); + +/* usn_cleanup.c */ +int usn_cleanup_start(Slapi_PBlock *pb); + diff --git a/ldap/servers/plugins/usn/usn_cleanup.c b/ldap/servers/plugins/usn/usn_cleanup.c new file mode 100644 index 00000000..bf13073a --- /dev/null +++ b/ldap/servers/plugins/usn/usn_cleanup.c @@ -0,0 +1,326 @@ +/** 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) 2009 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "usn.h" + +struct usn_cleanup_data { + char *suffix; + char *maxusn_to_delete; +}; + + +static int usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, + Slapi_Entry *eAfter, int *returncode, char *returntext, void *arg); + +int +usn_cleanup_start(Slapi_PBlock *pb) +{ + int rc = slapi_task_register_handler("USN tombstone cleanup task", + usn_cleanup_add); + return rc; +} + +/* + * Task thread + */ +static void +usn_cleanup_thread(void *arg) +{ + Slapi_Task *task = (Slapi_Task *)arg; + int rv = 0; + int total_work = 2; + /* fetch our argument from the task */ + struct usn_cleanup_data *cleanup_data = + (struct usn_cleanup_data*)slapi_task_get_data(task); + Slapi_PBlock *search_pb = NULL; + Slapi_Entry **entries = NULL, **ep = NULL; + Slapi_PBlock *delete_pb = NULL; + char *filter = "objectclass=nsTombstone"; + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "--> usn_cleanup_thread\n"); + + if (NULL == usn_get_identity()) { /* plugin is not initialized */ + slapi_task_log_notice(task, "USN plugin is not initialized\n"); + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "USN tombstone cleanup: USN plugin is not initialized\n"); + rv = -1; + goto bail; + } + + /* update task state to show it's running */ + slapi_task_begin(task, total_work); + if (cleanup_data->maxusn_to_delete) { + /* (&(objectclass=nsTombstone)(entryusn<=maxusn_to_delete)) */ + int filter_len = + strlen(filter) + strlen(cleanup_data->maxusn_to_delete) + 32; + filter = (char *)slapi_ch_malloc(filter_len); + PR_snprintf(filter, filter_len, + "(&(objectclass=nsTombstone)(entryusn<=%s))", + cleanup_data->maxusn_to_delete); + } + + search_pb = slapi_pblock_new(); + slapi_search_internal_set_pb(search_pb, cleanup_data->suffix, + LDAP_SCOPE_SUBTREE, filter, + NULL, 0, NULL, NULL, usn_get_identity(), 0); + slapi_search_internal_pb(search_pb); + slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rv); + if (LDAP_NO_SUCH_OBJECT == rv) { + slapi_task_log_notice(task, + "USN tombstone cleanup: no such suffix %s.\n", + cleanup_data->suffix); + slapi_task_log_status(task, + "USN tombstone cleanup: no such suffix %s.\n", + cleanup_data->suffix); + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "USN tombstone cleanup: no such suffix %s.\n", + cleanup_data->suffix); + goto bail; + } else if (LDAP_SUCCESS != rv) { + slapi_task_log_notice(task, + "USN tombstone cleanup: searching tombstone entries " + "in %s failed; (%d).\n", cleanup_data->suffix, rv); + slapi_task_log_status(task, + "USN tombstone cleanup: searching tombstone entries in " + "%s failed; (%d).\n", cleanup_data->suffix, rv); + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "USN tombstone cleanup: searching tombstone entries in " + "%s failed; (%d).\n", cleanup_data->suffix, rv); + goto bail; + } + + slapi_task_log_notice(task, + "USN tombstone cleanup task starts (suffix: %s) ...\n", + cleanup_data->suffix); + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "USN tombstone cleanup task starts (suffix: %s) ...\n", + cleanup_data->suffix); + + slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); + + delete_pb = slapi_pblock_new(); + for (ep = entries; ep && *ep; ep++) { + int delrv = 0; + const Slapi_DN *sdn = slapi_entry_get_sdn_const(*ep); + + slapi_delete_internal_set_pb(delete_pb, slapi_sdn_get_dn(sdn), + NULL, NULL, usn_get_identity(), 0); + slapi_delete_internal_pb(delete_pb); + slapi_pblock_get(delete_pb, SLAPI_PLUGIN_INTOP_RESULT, &delrv); + if (LDAP_SUCCESS != delrv) { + slapi_task_log_notice(task, + "USN tombstone cleanup: deleting %s failed; (%d).\n", + slapi_sdn_get_dn(sdn), delrv); + slapi_task_log_status(task, + "USN tombstone cleanup: deleting %s failed; (%d).\n", + slapi_sdn_get_dn(sdn), delrv); + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "USN tombstone cleanup: deleting %s failed; (%d).\n", + slapi_sdn_get_dn(sdn), delrv); + rv = delrv; + } + + slapi_pblock_init(delete_pb); + slapi_task_inc_progress(task); + } + slapi_task_log_notice(task, "USN tombstone cleanup task finished."); + slapi_task_log_status(task, "USN tombstone cleanup task finished."); + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "USN tombstone cleanup task finished.\n"); +bail: + slapi_free_search_results_internal(search_pb); + slapi_pblock_destroy(search_pb); + slapi_pblock_destroy(delete_pb); + if (cleanup_data->maxusn_to_delete) { + slapi_ch_free_string(&filter); + } + slapi_ch_free_string(&cleanup_data->maxusn_to_delete); + slapi_ch_free_string(&cleanup_data->suffix); + slapi_ch_free((void **)&cleanup_data); + + /* this will queue the destruction of the task */ + slapi_task_finish(task, rv); + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "<-- usn_cleanup_thread\n"); +} + +#define MAPPING_TREE_BASE_DN "cn=mapping tree,cn=config" + +static int +_usn_cleanup_is_mmr_enabled(const char *suffix) +{ + Slapi_PBlock *search_pb = NULL; + Slapi_Entry **entries = NULL; + char *base_dn = NULL; + int rc = 0; /* disabled, by default */ + + base_dn = slapi_ch_smprintf("cn=replica,cn=\"%s\",%s", + suffix, MAPPING_TREE_BASE_DN); + search_pb = slapi_pblock_new(); + slapi_search_internal_set_pb(search_pb, base_dn, LDAP_SCOPE_ONELEVEL, + "objectclass=nsDS5ReplicationAgreement", + NULL, 0, NULL, NULL, usn_get_identity(), 0); + slapi_search_internal_pb(search_pb); + slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); + if (LDAP_SUCCESS != rc) { /* agreement is not available */ + goto bail; + } + slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); + if (entries && *entries) { + rc = 1; /* At least one agreement on the suffix is found */ + } +bail: + slapi_free_search_results_internal(search_pb); + slapi_pblock_destroy(search_pb); + slapi_ch_free_string(&base_dn); + + return rc; +} + +static int +usn_cleanup_add(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter, + int *returncode, char *returntext, void *arg) +{ + PRThread *thread = NULL; + char *cn = NULL; + char *suffix = NULL; + char *backend = NULL; + char *maxusn = NULL; + struct usn_cleanup_data *cleanup_data = NULL; + int rv = SLAPI_DSE_CALLBACK_OK; + Slapi_Task *task = NULL; + Slapi_Backend *be = NULL; + const Slapi_DN *be_suffix = NULL; + + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "--> usn_cleanup_add\n"); + + *returncode = LDAP_SUCCESS; + cn = slapi_entry_attr_get_charptr(e, "cn"); + if (NULL == cn) { + *returncode = LDAP_OBJECT_CLASS_VIOLATION; + rv = SLAPI_DSE_CALLBACK_ERROR; + goto bail; + } + + /* get args */ + suffix = slapi_entry_attr_get_charptr(e, "suffix"); + backend = slapi_entry_attr_get_charptr(e, "backend"); + maxusn = slapi_entry_attr_get_charptr(e, "maxusn_to_delete"); + + if (NULL == suffix && NULL == backend) { + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "USN tombstone cleanup: Both suffix and backend are missing.\n"); + *returncode = LDAP_PARAM_ERROR; + rv = SLAPI_DSE_CALLBACK_ERROR; + goto bail; + } + + /* suffix is not given, but backend is; get the suffix */ + if (NULL == suffix && NULL != backend) { + be = slapi_be_select_by_instance_name(backend); + be_suffix = slapi_be_getsuffix(be, 0); + if (be_suffix) { + suffix = slapi_ch_strdup(slapi_sdn_get_ndn(be_suffix)); + } else { + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "USN tombstone cleanup: Backend %s is invalid.\n", backend); + *returncode = LDAP_PARAM_ERROR; + rv = SLAPI_DSE_CALLBACK_ERROR; + goto bail; + } + } + + /* The suffix is the target of replication, + * we don't want to clean up tombstones used by MMR */ + if (_usn_cleanup_is_mmr_enabled(suffix)) { + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "USN tombstone cleanup: Suffix %s is replicated. Unwilling to " + "perform cleaning up tombstones.\n", suffix); + *returncode = LDAP_UNWILLING_TO_PERFORM; + rv = SLAPI_DSE_CALLBACK_ERROR; + goto bail; + } + + cleanup_data = + (struct usn_cleanup_data *)slapi_ch_malloc(sizeof(struct usn_cleanup_data)); + cleanup_data->suffix = slapi_ch_strdup(suffix); + cleanup_data->maxusn_to_delete = slapi_ch_strdup(maxusn); + + /* allocate new task now */ + task = slapi_new_task(slapi_entry_get_ndn(e)); + if (task == NULL) { + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "USN tombstone cleanup: unable to allocate new task.\n"); + *returncode = LDAP_OPERATIONS_ERROR; + rv = SLAPI_DSE_CALLBACK_ERROR; + goto bail; + } + + /* Stash our argument in the task for use by the task thread */ + slapi_task_set_data(task, cleanup_data); + + /* start the USN tombstone cleanup task as a separate thread */ + thread = PR_CreateThread(PR_USER_THREAD, usn_cleanup_thread, + (void *)task, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, + PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); + if (thread == NULL) { + slapi_log_error(SLAPI_LOG_FATAL, USN_PLUGIN_SUBSYSTEM, + "USN tombstone cleanup: unable to create task thread.\n"); + *returncode = LDAP_OPERATIONS_ERROR; + rv = SLAPI_DSE_CALLBACK_ERROR; + slapi_task_finish(task, *returncode); + } else { + /* thread successful */ + rv = SLAPI_DSE_CALLBACK_OK; + } +bail: + slapi_ch_free_string(&cn); + slapi_ch_free_string(&suffix); + slapi_ch_free_string(&backend); + slapi_ch_free_string(&maxusn); + slapi_log_error(SLAPI_LOG_TRACE, USN_PLUGIN_SUBSYSTEM, + "<-- usn_cleanup_add\n"); + return rv; +} + diff --git a/ldap/servers/slapd/back-ldbm/back-ldbm.h b/ldap/servers/slapd/back-ldbm/back-ldbm.h index 1b6dda54..3036bf7c 100644 --- a/ldap/servers/slapd/back-ldbm/back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/back-ldbm.h @@ -739,6 +739,7 @@ typedef struct _back_search_result_set #define LDBM_DNCOMP_OID "2.16.840.1.113730.3.1.603" #define LDBM_PARENTID_OID "2.16.840.1.113730.3.1.604" #define LDBM_ENTRYID_OID "2.16.840.1.113730.3.1.605" +#define LDBM_ENTRYUSN_OID "2.16.840.1.113730.3.1.606" /* Name of psuedo attribute used to track default indexes */ #define LDBM_PSEUDO_ATTR_DEFAULT ".default" diff --git a/ldap/servers/slapd/back-ldbm/import.c b/ldap/servers/slapd/back-ldbm/import.c index 57c208a8..48e19c81 100644 --- a/ldap/servers/slapd/back-ldbm/import.c +++ b/ldap/servers/slapd/back-ldbm/import.c @@ -1052,6 +1052,9 @@ static int import_all_done(ImportJob *job, int ret) if (ret != 0) return ret; + /* Reset USN slapi_counter with the last key of the entryUSN index */ + ldbm_set_last_usn(inst->inst_be); + /* bring backend online again */ slapi_mtn_be_enable(inst->inst_be); } diff --git a/ldap/servers/slapd/back-ldbm/init.c b/ldap/servers/slapd/back-ldbm/init.c index c32f9825..be9c114d 100644 --- a/ldap/servers/slapd/back-ldbm/init.c +++ b/ldap/servers/slapd/back-ldbm/init.c @@ -84,6 +84,10 @@ ldbm_back_add_schema( Slapi_PBlock *pb ) LDBM_ENTRYID_OID, DIRSTRING_SYNTAX_OID, CASEIGNOREMATCH_NAME, SLAPI_ATTR_FLAG_SINGLE ); + rc |= add_ldbm_internal_attr_syntax( "entryusn", + LDBM_ENTRYUSN_OID, INTEGER_SYNTAX_OID, INTFIRSTCOMPMATCH_NAME, + SLAPI_ATTR_FLAG_SINGLE|SLAPI_ATTR_FLAG_NOUSERMOD ); + return rc; } diff --git a/ldap/servers/slapd/back-ldbm/ldbm_add.c b/ldap/servers/slapd/back-ldbm/ldbm_add.c index b9f573a7..fa53e05f 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_add.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_add.c @@ -159,6 +159,7 @@ ldbm_back_add( Slapi_PBlock *pb ) operation->o_status = SLAPI_OP_STATUS_WILL_COMPLETE; } if ( slapi_op_abandoned( pb ) ) { + ldap_result_code = -1; /* needs to distinguish from "success" */ goto error_return; } @@ -847,6 +848,8 @@ common_return: { cache_return( &inst->inst_cache, &addingentry ); } + /* bepost op needs to know this result */ + slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code); /* JCMREPL - The bepostop is called even if the operation fails. */ plugin_call_plugins (pb, SLAPI_PLUGIN_BE_POST_ADD_FN); diff --git a/ldap/servers/slapd/back-ldbm/ldbm_delete.c b/ldap/servers/slapd/back-ldbm/ldbm_delete.c index fe02b207..74d8de8e 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_delete.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_delete.c @@ -82,6 +82,9 @@ ldbm_back_delete( Slapi_PBlock *pb ) int tombstone_in_cache = 0; entry_address *addr; int addordel_flags = 0; /* passed to index_addordel */ + char *entryusn_str = NULL; + char *prev_entryusn_str = NULL; + Slapi_Entry *orig_entry = NULL; slapi_pblock_get( pb, SLAPI_BACKEND, &be); slapi_pblock_get( pb, SLAPI_PLUGIN_PRIVATE, &li ); @@ -133,6 +136,23 @@ ldbm_back_delete( Slapi_PBlock *pb ) goto error_return; } + /* find and lock the entry we are about to modify */ + if ( (e = find_entry2modify( pb, be, addr, NULL )) == NULL ) + { + ldap_result_code= -1; + goto error_return; /* error result sent by find_entry2modify() */ + } + + if ( slapi_entry_has_children( e->ep_entry ) ) + { + ldap_result_code= LDAP_NOT_ALLOWED_ON_NONLEAF; + goto error_return; + } + + /* set entry in case be-preop plugins need to work on it (e.g., USN) */ + slapi_pblock_get( pb, SLAPI_DELETE_BEPREOP_ENTRY, &orig_entry ); + slapi_pblock_set( pb, SLAPI_DELETE_BEPREOP_ENTRY, e->ep_entry ); + /* Don't call pre-op for Tombstone entries */ if (!delete_tombstone_entry) { @@ -141,7 +161,8 @@ ldbm_back_delete( Slapi_PBlock *pb ) * backend pre-op plugin. To ensure a consistent snapshot of this state * we wrap the reading of the entry with the dblock. */ - ldap_result_code= get_copy_of_entry(pb, addr, &txn, SLAPI_DELETE_EXISTING_ENTRY, !is_replicated_operation); + ldap_result_code= get_copy_of_entry(pb, addr, &txn, + SLAPI_DELETE_EXISTING_ENTRY, !is_replicated_operation); slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code); if(plugin_call_plugins(pb, SLAPI_PLUGIN_BE_PRE_DELETE_FN)==-1) { @@ -152,21 +173,12 @@ ldbm_back_delete( Slapi_PBlock *pb ) slapi_pblock_get(pb, SLAPI_RESULT_CODE, &ldap_result_code); goto error_return; } - } - - - /* find and lock the entry we are about to modify */ - if ( (e = find_entry2modify( pb, be, addr, NULL )) == NULL ) - { - ldap_result_code= -1; - goto error_return; /* error result sent by find_entry2modify() */ + /* the flag could be set in a preop plugin (e.g., USN) */ + delete_tombstone_entry = operation_is_flag_set(operation, + OP_FLAG_TOMBSTONE_ENTRY); } - if ( slapi_entry_has_children( e->ep_entry ) ) - { - ldap_result_code= LDAP_NOT_ALLOWED_ON_NONLEAF; - goto error_return; - } + slapi_pblock_set( pb, SLAPI_DELETE_BEPREOP_ENTRY, orig_entry ); /* * Sanity check to avoid to delete a non-tombstone or to tombstone again @@ -196,8 +208,12 @@ ldbm_back_delete( Slapi_PBlock *pb ) opcsn = operation_get_csn (operation); if (!delete_tombstone_entry) { - if (opcsn == NULL && !is_fixup_operation && operation->o_csngen_handler) + /* If both USN and replication is enabled, csn set by replication + * should be honored. */ + if ((opcsn == NULL || ldbm_usn_enabled(be)) && + !is_fixup_operation && operation->o_csngen_handler) { + csn_free(&opcsn); /* free opcsn set by USN plugin, if any */ /* * Current op is a user request. Opcsn will be assigned * by entry_assign_operation_csn() if the dn is in an @@ -338,6 +354,20 @@ ldbm_back_delete( Slapi_PBlock *pb ) slapi_entry_add_value(tombstone->ep_entry, SLAPI_ATTR_OBJECTCLASS, tomb_value); slapi_value_free(&tomb_value); + /* retrieve previous entry usn value, if any */ + prev_entryusn_str = slapi_entry_attr_get_charptr(tombstone->ep_entry, + SLAPI_ATTR_ENTRYUSN_PREV); + if (prev_entryusn_str) { + /* discard the previous value from the tombstone entry */ + retval = slapi_entry_delete_string(tombstone->ep_entry, + SLAPI_ATTR_ENTRYUSN_PREV, prev_entryusn_str); + if (0 != retval) { + LDAPDebug( LDAP_DEBUG_TRACE, + "delete (deleting %s) failed, err=%d\n", + SLAPI_ATTR_ENTRYUSN, retval, 0) ; + } + } + /* XXXggood above used to be: slapi_entry_add_string(tombstone->ep_entry, SLAPI_ATTR_OBJECTCLASS, SLAPI_ATTR_VALUE_TOMBSTONE); */ /* JCMREPL - Add a description of what's going on? */ } @@ -432,45 +462,110 @@ ldbm_back_delete( Slapi_PBlock *pb ) * above, but we want it to remain in the nsUniqueID and nscpEntryDN indexes * and for objectclass=tombstone. */ - retval = index_addordel_string(be,SLAPI_ATTR_OBJECTCLASS,SLAPI_ATTR_VALUE_TOMBSTONE,tombstone->ep_id,BE_INDEX_ADD,&txn); + retval = index_addordel_string(be, SLAPI_ATTR_OBJECTCLASS, + SLAPI_ATTR_VALUE_TOMBSTONE, + tombstone->ep_id,BE_INDEX_ADD, &txn); if (DB_LOCK_DEADLOCK == retval) { - LDAPDebug( LDAP_DEBUG_ARGS, "delete 4 DB_LOCK_DEADLOCK\n", 0, 0, 0 ); + LDAPDebug( LDAP_DEBUG_ARGS, + "delete (adding %s) DB_LOCK_DEADLOCK\n", + SLAPI_ATTR_VALUE_TOMBSTONE, 0, 0 ); /* Retry txn */ continue; } if (0 != retval) { - LDAPDebug( LDAP_DEBUG_TRACE, "delete 1 BAD, err=%d %s\n", - retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 ); + LDAPDebug( LDAP_DEBUG_TRACE, + "delete (adding %s) failed, err=%d %s\n", + SLAPI_ATTR_VALUE_TOMBSTONE, retval, + (msg = dblayer_strerror( retval )) ? msg : "" ); if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1; - ldap_result_code= LDAP_OPERATIONS_ERROR; + ldap_result_code= LDAP_OPERATIONS_ERROR; goto error_return; } - retval = index_addordel_string(be,SLAPI_ATTR_UNIQUEID,slapi_entry_get_uniqueid(tombstone->ep_entry),tombstone->ep_id,BE_INDEX_ADD,&txn); + retval = index_addordel_string(be, SLAPI_ATTR_UNIQUEID, + slapi_entry_get_uniqueid(tombstone->ep_entry), + tombstone->ep_id,BE_INDEX_ADD,&txn); if (DB_LOCK_DEADLOCK == retval) { - LDAPDebug( LDAP_DEBUG_ARGS, "delete 5 DB_LOCK_DEADLOCK\n", 0, 0, 0 ); + LDAPDebug( LDAP_DEBUG_ARGS, + "delete (adding %s) DB_LOCK_DEADLOCK\n", + SLAPI_ATTR_UNIQUEID, 0, 0 ); /* Retry txn */ continue; } if (0 != retval) { - LDAPDebug( LDAP_DEBUG_TRACE, "delete 2 BAD, err=%d %s\n", - retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 ); + LDAPDebug( LDAP_DEBUG_TRACE, + "delete (adding %s) failed, err=%d %s\n", + SLAPI_ATTR_UNIQUEID, retval, + (msg = dblayer_strerror( retval )) ? msg : "" ); if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1; - ldap_result_code= LDAP_OPERATIONS_ERROR; + ldap_result_code= LDAP_OPERATIONS_ERROR; goto error_return; } - retval = index_addordel_string(be,SLAPI_ATTR_NSCP_ENTRYDN, slapi_sdn_get_ndn(nscpEntrySDN),tombstone->ep_id,BE_INDEX_ADD,&txn); + retval = index_addordel_string(be, SLAPI_ATTR_NSCP_ENTRYDN, + slapi_sdn_get_ndn(nscpEntrySDN), + tombstone->ep_id, BE_INDEX_ADD, &txn); if (DB_LOCK_DEADLOCK == retval) { - LDAPDebug( LDAP_DEBUG_ARGS, "delete 6 DB_LOCK_DEADLOCK\n", 0, 0, 0 ); + LDAPDebug( LDAP_DEBUG_ARGS, + "delete (adding %s) DB_LOCK_DEADLOCK\n", + SLAPI_ATTR_NSCP_ENTRYDN, 0, 0 ); /* Retry txn */ continue; } if (0 != retval) { - LDAPDebug( LDAP_DEBUG_TRACE, "delete 3 BAD, err=%d %s\n", - retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 ); + LDAPDebug( LDAP_DEBUG_TRACE, + "delete (adding %s) failed, err=%d %s\n", + SLAPI_ATTR_NSCP_ENTRYDN, retval, + (msg = dblayer_strerror( retval )) ? msg : "" ); if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1; - ldap_result_code= LDAP_OPERATIONS_ERROR; + ldap_result_code= LDAP_OPERATIONS_ERROR; goto error_return; } + /* add a new usn to the entryusn index */ + entryusn_str = slapi_entry_attr_get_charptr(tombstone->ep_entry, + SLAPI_ATTR_ENTRYUSN); + if (entryusn_str) { + retval = index_addordel_string(be, SLAPI_ATTR_ENTRYUSN, + entryusn_str, tombstone->ep_id, BE_INDEX_ADD, &txn); + slapi_ch_free_string(&entryusn_str); + if (DB_LOCK_DEADLOCK == retval) { + LDAPDebug( LDAP_DEBUG_ARGS, + "delete (adding %s) DB_LOCK_DEADLOCK\n", + SLAPI_ATTR_ENTRYUSN, 0, 0 ); + /* Retry txn */ + continue; + } + if (0 != retval) { + LDAPDebug( LDAP_DEBUG_TRACE, + "delete (adding %s) failed, err=%d %s\n", + SLAPI_ATTR_ENTRYUSN, retval, + (msg = dblayer_strerror( retval )) ? msg : "" ); + if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1; + ldap_result_code= LDAP_OPERATIONS_ERROR; + goto error_return; + } + } + /* delete a previous value (if it exists) from the entryusn index */ + if (prev_entryusn_str) { + retval = index_addordel_string(be, SLAPI_ATTR_ENTRYUSN, + prev_entryusn_str, tombstone->ep_id, + BE_INDEX_DEL|BE_INDEX_EQUALITY, &txn); + slapi_ch_free_string(&prev_entryusn_str); + if (DB_LOCK_DEADLOCK == retval) { + LDAPDebug( LDAP_DEBUG_ARGS, + "delete (deleting %s) DB_LOCK_DEADLOCK\n", + SLAPI_ATTR_ENTRYUSN, 0, 0 ); + /* Retry txn */ + continue; + } + if (0 != retval) { + LDAPDebug( LDAP_DEBUG_TRACE, + "delete (deleting %s) failed, err=%d %s\n", + SLAPI_ATTR_ENTRYUSN, retval, + (msg = dblayer_strerror( retval )) ? msg : "" ); + if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1; + ldap_result_code= LDAP_OPERATIONS_ERROR; + goto error_return; + } + } } /* create_tombstone_entry */ else if (delete_tombstone_entry) { @@ -480,45 +575,88 @@ ldbm_back_delete( Slapi_PBlock *pb ) */ char *nscpedn = NULL; - retval = index_addordel_string(be,SLAPI_ATTR_OBJECTCLASS,SLAPI_ATTR_VALUE_TOMBSTONE,e->ep_id,BE_INDEX_DEL,&txn); + retval = index_addordel_string(be, SLAPI_ATTR_OBJECTCLASS, + SLAPI_ATTR_VALUE_TOMBSTONE, e->ep_id, + BE_INDEX_DEL, &txn); if (DB_LOCK_DEADLOCK == retval) { - LDAPDebug( LDAP_DEBUG_ARGS, "delete 4 DB_LOCK_DEADLOCK\n", 0, 0, 0 ); + LDAPDebug( LDAP_DEBUG_ARGS, + "delete (deleting %s) DB_LOCK_DEADLOCK\n", + SLAPI_ATTR_VALUE_TOMBSTONE, 0, 0 ); /* Retry txn */ continue; } if (0 != retval) { - LDAPDebug( LDAP_DEBUG_TRACE, "delete 1 BAD, err=%d %s\n", - retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 ); + LDAPDebug( LDAP_DEBUG_TRACE, + "delete (deleting %s) failed, err=%d %s\n", + SLAPI_ATTR_VALUE_TOMBSTONE, retval, + (msg = dblayer_strerror( retval )) ? msg : "" ); if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1; - ldap_result_code= LDAP_OPERATIONS_ERROR; + ldap_result_code= LDAP_OPERATIONS_ERROR; goto error_return; } - retval = index_addordel_string(be,SLAPI_ATTR_UNIQUEID,slapi_entry_get_uniqueid(e->ep_entry),e->ep_id,BE_INDEX_DEL,&txn); + retval = index_addordel_string(be, SLAPI_ATTR_UNIQUEID, + slapi_entry_get_uniqueid(e->ep_entry), + e->ep_id, BE_INDEX_DEL, &txn); if (DB_LOCK_DEADLOCK == retval) { - LDAPDebug( LDAP_DEBUG_ARGS, "delete 5 DB_LOCK_DEADLOCK\n", 0, 0, 0 ); + LDAPDebug( LDAP_DEBUG_ARGS, + "delete (deleting %s) DB_LOCK_DEADLOCK\n", + SLAPI_ATTR_UNIQUEID, 0, 0 ); /* Retry txn */ continue; } if (0 != retval) { - LDAPDebug( LDAP_DEBUG_TRACE, "delete 2 BAD, err=%d %s\n", - retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 ); + LDAPDebug( LDAP_DEBUG_TRACE, + "delete (deleting %s) failed, err=%d %s\n", + SLAPI_ATTR_UNIQUEID, retval, + (msg = dblayer_strerror( retval )) ? msg : "" ); if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1; - ldap_result_code= LDAP_OPERATIONS_ERROR; + ldap_result_code= LDAP_OPERATIONS_ERROR; goto error_return; } - nscpedn = slapi_entry_attr_get_charptr(e->ep_entry, SLAPI_ATTR_NSCP_ENTRYDN); + nscpedn = slapi_entry_attr_get_charptr(e->ep_entry, + SLAPI_ATTR_NSCP_ENTRYDN); if (nscpedn) { - retval = index_addordel_string(be,SLAPI_ATTR_NSCP_ENTRYDN, nscpedn, e->ep_id,BE_INDEX_DEL,&txn); + retval = index_addordel_string(be, SLAPI_ATTR_NSCP_ENTRYDN, + nscpedn, e->ep_id, BE_INDEX_DEL, &txn); slapi_ch_free((void **)&nscpedn); if (DB_LOCK_DEADLOCK == retval) { - LDAPDebug( LDAP_DEBUG_ARGS, "delete 6 DB_LOCK_DEADLOCK\n", 0, 0, 0 ); + LDAPDebug( LDAP_DEBUG_ARGS, + "delete (deleting %s) DB_LOCK_DEADLOCK\n", + SLAPI_ATTR_NSCP_ENTRYDN, 0, 0 ); + /* Retry txn */ + continue; + } + if (0 != retval) { + LDAPDebug( LDAP_DEBUG_TRACE, + "delete (deleting %s) failed, err=%d %s\n", + SLAPI_ATTR_NSCP_ENTRYDN, retval, + (msg = dblayer_strerror( retval )) ? msg : "" ); + if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1; + ldap_result_code= LDAP_OPERATIONS_ERROR; + goto error_return; + } + } + /* delete usn from the entryusn index */ + entryusn_str = slapi_entry_attr_get_charptr(e->ep_entry, + SLAPI_ATTR_ENTRYUSN); + if (entryusn_str) { + retval = index_addordel_string(be, SLAPI_ATTR_ENTRYUSN, + entryusn_str, e->ep_id, + BE_INDEX_DEL|BE_INDEX_EQUALITY, &txn); + slapi_ch_free_string(&entryusn_str); + if (DB_LOCK_DEADLOCK == retval) { + LDAPDebug( LDAP_DEBUG_ARGS, + "delete (deleting %s) DB_LOCK_DEADLOCK\n", + SLAPI_ATTR_ENTRYUSN, 0, 0 ); /* Retry txn */ continue; } if (0 != retval) { - LDAPDebug( LDAP_DEBUG_TRACE, "delete 3 BAD, err=%d %s\n", - retval, (msg = dblayer_strerror( retval )) ? msg : "", 0 ); + LDAPDebug( LDAP_DEBUG_TRACE, + "delete (deleting %s) failed, err=%d %s\n", + SLAPI_ATTR_ENTRYUSN, retval, + (msg = dblayer_strerror( retval )) ? msg : "" ); if (LDBM_OS_ERR_IS_DISKFULL(retval)) disk_full = 1; ldap_result_code= LDAP_OPERATIONS_ERROR; goto error_return; diff --git a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c index e8fc3d73..b4e44732 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_instance_config.c @@ -752,6 +752,12 @@ static int ldbm_instance_generate(struct ldbminfo *li, char *instance_name, ldbm_instance_config_load_dse_info(new_be->be_instance_info); rc = ldbm_instance_create_default_indexes(new_be); + /* if USN plugin is enabled, set slapi_counter */ + if (plugin_enabled("USN", li->li_identity)) { + /* slapi_counter_new sets the initial value to 0 */ + new_be->be_usn_counter = slapi_counter_new(); + } + if (ret_be != NULL) { *ret_be = new_be; } diff --git a/ldap/servers/slapd/back-ldbm/ldbm_modify.c b/ldap/servers/slapd/back-ldbm/ldbm_modify.c index e85443d7..6ae95448 100644 --- a/ldap/servers/slapd/back-ldbm/ldbm_modify.c +++ b/ldap/servers/slapd/back-ldbm/ldbm_modify.c @@ -303,6 +303,7 @@ ldbm_back_modify( Slapi_PBlock *pb ) } if ( !change_entry || ldap_result_code != 0 ) { /* change_entry == 0 is not an error, but we need to free lock etc */ + slapi_pblock_set(pb, SLAPI_RESULT_CODE, &ldap_result_code); goto error_return; } } diff --git a/ldap/servers/slapd/back-ldbm/ldbm_usn.c b/ldap/servers/slapd/back-ldbm/ldbm_usn.c new file mode 100644 index 00000000..e8dd7237 --- /dev/null +++ b/ldap/servers/slapd/back-ldbm/ldbm_usn.c @@ -0,0 +1,196 @@ +/** 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) 2009 Red Hat, Inc. + * All rights reserved. + * END COPYRIGHT BLOCK **/ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include "back-ldbm.h" + +static int usn_get_last_usn(Slapi_Backend *be, PRUint64 *last_usn); + +/* + * USN counter part in the backend + * - If usn is enabled, + * - For each backend, + * - Get the last USN index key + * - Initialize the slapi counter with the next USN (last USN + 1) + * + * dn: cn=entryusn,cn=default indexes,cn=config,cn=ldbm database,cn=plugins,cn= + * config + * objectClass: top + * objectClass: nsIndex + * cn: entryusn + * nsSystemIndex: true + * nsIndexType: eq + */ + +void +ldbm_usn_init(struct ldbminfo *li) +{ + Slapi_DN *sdn = NULL; + void *node = NULL; + const char *base = NULL; + int rc = 0; + Slapi_Backend *be = NULL; + PRUint64 last_usn = 0; + + /* if USN is not enabled, return immediately */ + if (!plugin_enabled("USN", li->li_identity)) { + goto bail; + } + + /* Search each namingContext in turn */ + for ( sdn = slapi_get_first_suffix( &node, 0 ); sdn != NULL; + sdn = slapi_get_next_suffix( &node, 0 )) { + base = slapi_sdn_get_dn( sdn ); + be = slapi_mapping_tree_find_backend_for_sdn(sdn); + slapi_log_error(SLAPI_LOG_TRACE, "ldbm_usn_init", + "backend: %s\n", be->be_name); + rc = usn_get_last_usn(be, &last_usn); + if (0 == rc) { /* only when the last usn is available */ + be->be_usn_counter = slapi_counter_new(); + slapi_counter_set_value(be->be_usn_counter, last_usn); + slapi_counter_increment(be->be_usn_counter); /* stores next usn */ + } + } +bail: + return; +} + +/* + * usn_ge_last_usn: get the last USN from the entryusn equality index + */ +static int +usn_get_last_usn(Slapi_Backend *be, PRUint64 *last_usn) +{ + struct attrinfo *ai = NULL; + struct ldbminfo *li = (struct ldbminfo *)be->be_database->plg_private; + int rc = -1; + DB *db = NULL; + DBC *dbc = NULL; + DBT key; /* For the last usn */ + DBT value; + + if (NULL == last_usn) { + return rc; + } + + memset(&key, 0, sizeof(key)); + memset(&value, 0, sizeof(key)); + + *last_usn = -1; /* to start from 0 */ + + /* Open the entryusn index */ + ainfo_get(be, "entryusn", &ai); + + /* Open the entryusn index file */ + rc = dblayer_get_index_file(be, ai, &db, DBOPEN_CREATE); + if (0 != rc) { + /* entryusn.db# is missing; it would be the first time. */ + slapi_log_error(SLAPI_LOG_FATAL, "usn_get_last_usn", + "failed to open the entryusn index: %d", rc); + goto bail; + } + + /* Get a cursor */ + rc = db->cursor(db, NULL, &dbc, 0); + if (0 != rc) { + slapi_log_error(SLAPI_LOG_FATAL, "usn_get_last_usn", + "failed to create a cursor: %d", rc); + goto bail; + } + + key.flags = DB_DBT_MALLOC; + value.flags = DB_DBT_MALLOC; + rc = dbc->c_get(dbc, &key, &value, DB_LAST); + if ((0 == rc) && key.data) { + char *p = (char *)key.data; + while ((0 == rc) && ('=' != *p)) { /* get the last elem of equality */ + slapi_ch_free(&(key.data)); + slapi_ch_free(&(value.data)); + rc = dbc->c_get(dbc, &key, &value, DB_PREV); + p = (char *)key.data; + } + if (0 == rc) { + *last_usn = strtoll(++p, (char **)NULL, 0); /* key.data: =num */ + } + } else if (DB_NOTFOUND == rc) { + /* if empty, it's okay. This is just a beginning. */ + rc = 0; + } + slapi_ch_free(&(key.data)); + slapi_ch_free(&(value.data)); + +bail: + if (dbc) { + dbc->c_close(dbc); + } + if (db) { + dblayer_release_index_file(be, ai, db); + } + return rc; +} + +/* + * Whether USN is enabled or not is checked with be_usn_counter. + */ +int +ldbm_usn_enabled(Slapi_Backend *be) +{ + return (NULL != be->be_usn_counter); +} + +/* + * set last usn to the USN slapi_counter in backend + */ +int +ldbm_set_last_usn(Slapi_Backend *be) +{ + PRUint64 last_usn = 0; + int rc = usn_get_last_usn(be, &last_usn); + + if (0 == rc) { /* only when the last usn is available */ + /* destroy old counter, if any */ + slapi_counter_destroy(&(be->be_usn_counter)); + be->be_usn_counter = slapi_counter_new(); + slapi_counter_set_value(be->be_usn_counter, last_usn); + slapi_counter_increment(be->be_usn_counter); /* stores next usn */ + } + + return rc; +} diff --git a/ldap/servers/slapd/back-ldbm/misc.c b/ldap/servers/slapd/back-ldbm/misc.c index b4c7942f..8fcb81f8 100644 --- a/ldap/servers/slapd/back-ldbm/misc.c +++ b/ldap/servers/slapd/back-ldbm/misc.c @@ -94,17 +94,19 @@ int return_on_disk_full(struct ldbminfo *li) /* System Indexes */ static const char *systemIndexes[] = { - "entrydn", - "parentid", - "objectclass", "aci", + "entrydn", "numsubordinates", + "parentid", + SLAPI_ATTR_OBJECTCLASS, SLAPI_ATTR_UNIQUEID, SLAPI_ATTR_NSCP_ENTRYDN, ATTR_NSDS5_REPLCONFLICT, + SLAPI_ATTR_ENTRYUSN, NULL }; + int ldbm_attribute_always_indexed(const char *attrtype) { diff --git a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h index 30d607ee..3fc58328 100644 --- a/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h +++ b/ldap/servers/slapd/back-ldbm/proto-back-ldbm.h @@ -632,3 +632,12 @@ int attrcrypt_encrypt_entry_inplace(backend *be, const struct backentry *inout); int attrcrypt_encrypt_entry(backend *be, const struct backentry *in, struct backentry **out); int attrcrypt_encrypt_index_key(backend *be, struct attrinfo *ai, const struct berval *in, struct berval **out); int attrcrypt_init(ldbm_instance *li); + +/* + * ldbm_usn.c + */ +void ldbm_usn_init(struct ldbminfo *li); +int ldbm_usn_enabled(backend *be); +int ldbm_set_last_usn(Slapi_Backend *be); + + diff --git a/ldap/servers/slapd/back-ldbm/start.c b/ldap/servers/slapd/back-ldbm/start.c index 9b517eb1..6d833571 100644 --- a/ldap/servers/slapd/back-ldbm/start.c +++ b/ldap/servers/slapd/back-ldbm/start.c @@ -222,6 +222,9 @@ ldbm_back_start( Slapi_PBlock *pb ) initialized = 1; } + /* initialize the USN counter */ + ldbm_usn_init(li); + LDAPDebug( LDAP_DEBUG_TRACE, "ldbm backend done starting\n", 0, 0, 0 ); return( 0 ); diff --git a/ldap/servers/slapd/backend.c b/ldap/servers/slapd/backend.c index c4c399f9..740de29d 100644 --- a/ldap/servers/slapd/backend.c +++ b/ldap/servers/slapd/backend.c @@ -64,7 +64,7 @@ be_init( Slapi_Backend *be, const char *type, const char *name, int isprivate, i /* maximum group nesting level before giving up */ be->be_maxnestlevel = SLAPD_DEFAULT_GROUPNESTLEVEL; be->be_noacl= 0; - be->be_flags=0; + be->be_flags=0; if (( fecfg = getFrontendConfig()) != NULL ) { if ( fecfg->backendconfig != NULL && fecfg->backendconfig[ 0 ] != NULL ) diff --git a/ldap/servers/slapd/main.c b/ldap/servers/slapd/main.c index 7e595111..ed51825e 100644 --- a/ldap/servers/slapd/main.c +++ b/ldap/servers/slapd/main.c @@ -2372,6 +2372,8 @@ slapd_exemode_db2ldif(int argc, char** argv) } slapi_ch_free( (void**)&myname ); if (db2ldif_dump_replica) { + eq_stop(); /* event queue should be shutdown before closing + all plugins (especailly, replication plugin) */ plugin_closeall( 1 /* Close Backends */, 1 /* Close Globals */); } return( return_value ); diff --git a/ldap/servers/slapd/pblock.c b/ldap/servers/slapd/pblock.c index 98984ada..e5751a92 100644 --- a/ldap/servers/slapd/pblock.c +++ b/ldap/servers/slapd/pblock.c @@ -1592,6 +1592,10 @@ slapi_pblock_get( Slapi_PBlock *pblock, int arg, void *value ) (*(IFP *)value) = pblock->pb_plugin->plg_entrystorefunc; break; + case SLAPI_PLUGIN_ENABLED: + *((int *)value) = pblock->pb_plugin_enabled; + break; + /* DSE add parameters */ case SLAPI_DSE_DONT_WRITE_WHEN_ADDING: (*(int *)value) = pblock->pb_dse_dont_add_write; @@ -2857,6 +2861,10 @@ slapi_pblock_set( Slapi_PBlock *pblock, int arg, void *value ) pblock->pb_plugin->plg_entrystorefunc = (IFP) value; break; + case SLAPI_PLUGIN_ENABLED: + pblock->pb_plugin_enabled = *((int *)value); + break; + /* DSE add parameters */ case SLAPI_DSE_DONT_WRITE_WHEN_ADDING: pblock->pb_dse_dont_add_write = *((int *)value); diff --git a/ldap/servers/slapd/plugin.c b/ldap/servers/slapd/plugin.c index 5ae63564..17730d59 100644 --- a/ldap/servers/slapd/plugin.c +++ b/ldap/servers/slapd/plugin.c @@ -2166,6 +2166,20 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid *group, configdir = config_get_configdir(); slapi_pblock_set(&pb, SLAPI_CONFIG_DIRECTORY, configdir); + /* see if the plugin is enabled or not */ + if ((value = slapi_entry_attr_get_charptr(plugin_entry, + ATTR_PLUGIN_ENABLED)) && + !strcasecmp(value, "off")) + { + enabled = 0; + } + else + { + enabled = 1; + } + + slapi_pblock_set(&pb, SLAPI_PLUGIN_ENABLED, &enabled); + if ((*initfunc)(&pb) != 0) { LDAPDebug(LDAP_DEBUG_ANY, "Init function \"%s\" for \"%s\" plugin" @@ -2193,18 +2207,6 @@ plugin_setup(Slapi_Entry *plugin_entry, struct slapi_componentid *group, } } - /* see if the plugin is enabled or not */ - if ((value = slapi_entry_attr_get_charptr(plugin_entry, - ATTR_PLUGIN_ENABLED)) && - !strcasecmp(value, "off")) - { - enabled = 0; - } - else - { - enabled = 1; - } - if (value) slapi_ch_free((void**)&value); @@ -2859,3 +2861,45 @@ void plugin_print_versions(void) } } + +/* + * check the spedified plugin entry and its nssladp-pluginEnabled value + * Return Value: 1 if the plugin is on. + * : 0 otherwise. + */ +int +plugin_enabled(const char *plugin_name, void *identity) +{ + Slapi_PBlock *search_pb = NULL; + Slapi_Entry **entries = NULL, **ep = NULL; + char *on_off = NULL; + char *filter = NULL; + int rc = 0; /* disabled, by default */ + + filter = slapi_ch_smprintf("cn=%s", plugin_name); + search_pb = slapi_pblock_new(); + slapi_search_internal_set_pb(search_pb, PLUGIN_BASE_DN, LDAP_SCOPE_ONELEVEL, + filter, NULL, 0, NULL, NULL, identity, 0); + slapi_search_internal_pb(search_pb); + slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_RESULT, &rc); + if (LDAP_SUCCESS != rc) { /* plugin is not available */ + goto bail; + } + + slapi_pblock_get(search_pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); + for (ep = entries; ep && *ep; ep++) { + on_off = slapi_entry_attr_get_charptr(*ep, "nsslapd-pluginEnabled"); + if (on_off && (0 == strcasecmp(on_off, "on"))) { + rc = 1; /* plugin is on */ + goto bail; + } + } + +bail: + slapi_ch_free_string(&on_off); + slapi_free_search_results_internal(search_pb); + slapi_pblock_destroy(search_pb); + slapi_ch_free_string(&filter); + + return rc; +} diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h index b4eb0c03..6eecd013 100644 --- a/ldap/servers/slapd/slap.h +++ b/ldap/servers/slapd/slap.h @@ -1115,6 +1115,7 @@ typedef struct backend { PRRWLock *be_lock; PRRWLock *vlvSearchList_lock; void *vlvSearchList; + Slapi_Counter *be_usn_counter; /* USN counter; one counter per backend */ } backend; enum @@ -1488,6 +1489,8 @@ typedef struct slapi_pblock { int *pb_substrlens; /* user specified minimum substr search key lengths: * nsSubStrBegin, nsSubStrMiddle, nsSubStrEnd */ + int pb_plugin_enabled; /* nsslapd-pluginEnabled: on|off */ + /* used in plugin init; pb_plugin is not ready, then */ } slapi_pblock; /* index if substrlens */ diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h index e04fad9b..d5efe4d5 100644 --- a/ldap/servers/slapd/slapi-plugin.h +++ b/ldap/servers/slapd/slapi-plugin.h @@ -296,7 +296,9 @@ NSPR_API(PRUint32) PR_fprintf(struct PRFileDesc* fd, const char *fmt, ...) #define SLAPI_ATTR_OBJECTCLASS "objectclass" #define SLAPI_ATTR_VALUE_TOMBSTONE "nsTombstone" #define SLAPI_ATTR_VALUE_PARENT_UNIQUEID "nsParentUniqueID" -#define SLAPI_ATTR_NSCP_ENTRYDN "nscpEntryDN" +#define SLAPI_ATTR_NSCP_ENTRYDN "nscpEntryDN" +#define SLAPI_ATTR_ENTRYUSN "entryusn" +#define SLAPI_ATTR_ENTRYUSN_PREV "preventryusn" /* opaque structures */ @@ -3272,6 +3274,7 @@ typedef struct slapi_plugindesc { /* entry fetch and entry store values */ #define SLAPI_PLUGIN_ENTRY_FETCH_FUNC 813 #define SLAPI_PLUGIN_ENTRY_STORE_FUNC 814 +#define SLAPI_PLUGIN_ENABLED 815 /* * Defined values of SLAPI_PLUGIN_SYNTAX_FLAGS: @@ -3332,6 +3335,7 @@ typedef struct slapi_plugindesc { #define SLAPI_DELETE_TARGET SLAPI_TARGET_DN #define SLAPI_DELETE_EXISTING_ENTRY SLAPI_ADD_EXISTING_DN_ENTRY #define SLAPI_DELETE_GLUE_PARENT_ENTRY SLAPI_ADD_PARENT_ENTRY +#define SLAPI_DELETE_BEPREOP_ENTRY SLAPI_ENTRY_PRE_OP /* modify arguments */ #define SLAPI_MODIFY_TARGET SLAPI_TARGET_DN diff --git a/ldap/servers/slapd/slapi-private.h b/ldap/servers/slapd/slapi-private.h index 85c45896..21b8dc4f 100644 --- a/ldap/servers/slapd/slapi-private.h +++ b/ldap/servers/slapd/slapi-private.h @@ -1200,6 +1200,9 @@ void DS_Sleep(PRIntervalTime ticks); #define PRLDAP_SET_PORT(myaddr,myport) \ ((myaddr)->raw.family == PR_AF_INET6 ? ((myaddr)->ipv6.port = PR_htons(myport)) : ((myaddr)->inet.port = PR_htons(myport))) +/* plugin.c */ +int plugin_enabled(const char *plugin_name, void *identity); + #ifdef __cplusplus } #endif |