andykimpe / rpms / 389-ds-base

Forked from rpms/389-ds-base 5 months ago
Clone
dc8c34
From 3c6d253521c6a64353136e74d72e5977d25fab1b Mon Sep 17 00:00:00 2001
dc8c34
From: Mark Reynolds <mreynolds@redhat.com>
dc8c34
Date: Tue, 6 Sep 2016 16:05:49 -0400
dc8c34
Subject: [PATCH 392/394] Ticket 47462 - Add AES plugin to replace DES plugin
dc8c34
dc8c34
Description:  This patch is the cumulative patch of this tickets:
dc8c34
dc8c34
Ticket 48862 - At startup DES to AES password conversion causes timeout in start script
dc8c34
Ticket 48243 - replica upgrade failed in starting dirsrv service due to upgrade scripts did not run
dc8c34
Ticket 47888 - DES to AES password conversion fails if a backend is empty
dc8c34
Ticket 47462 - Stop using DES in the reversible password encryption plug-in
dc8c34
dc8c34
              This patch is just for the backport to 1.2.11
dc8c34
dc8c34
https://fedorahosted.org/389/attachment/ticket/47462
dc8c34
dc8c34
Reviewed by: nhosoi(Thanks!)
dc8c34
dc8c34
(cherry picked from commit ea241668ec7be475092a0da2a5d579e31ade1058)
dc8c34
(cherry picked from commit f98228de6324ff6946e912b30ad18e03ec404a67)
dc8c34
---
dc8c34
 Makefile.am                                  |  12 +-
dc8c34
 Makefile.in                                  | 108 ++---
dc8c34
 ldap/admin/src/scripts/50AES-pbe-plugin.ldif |  16 +
dc8c34
 ldap/admin/src/scripts/52updateAESplugin.pl  |  84 ++++
dc8c34
 ldap/admin/src/scripts/DSCreate.pm.in        |   5 +-
dc8c34
 ldap/admin/src/scripts/DSMigration.pm.in     |   2 +-
dc8c34
 ldap/admin/src/scripts/DSUpdate.pm.in        |   2 +-
dc8c34
 ldap/ldif/50replication-plugins.ldif         |   2 +-
dc8c34
 ldap/ldif/template-dse.ldif.in               |  16 +-
dc8c34
 ldap/servers/plugins/rever/des.c             | 551 ------------------------
dc8c34
 ldap/servers/plugins/rever/pbe.c             | 621 +++++++++++++++++++++++++++
dc8c34
 ldap/servers/plugins/rever/rever.c           | 116 +++--
dc8c34
 ldap/servers/plugins/rever/rever.h           |  11 +-
dc8c34
 ldap/servers/slapd/daemon.c                  | 155 ++++++-
dc8c34
 ldap/servers/slapd/proto-slap.h              |   1 +
dc8c34
 ldap/servers/slapd/pw.c                      |  86 ++--
dc8c34
 ldap/servers/slapd/pw.h                      |  24 +-
dc8c34
 ldap/servers/slapd/security_wrappers.c       |   6 +
dc8c34
 ldap/servers/slapd/slap.h                    |  95 ++--
dc8c34
 ldap/servers/slapd/slapi-plugin.h            |   2 +
dc8c34
 ldap/servers/slapd/ssl.c                     |   4 +-
dc8c34
 ldap/servers/slapd/task.c                    | 338 +++++++++++++++
dc8c34
 22 files changed, 1520 insertions(+), 737 deletions(-)
dc8c34
 create mode 100644 ldap/admin/src/scripts/50AES-pbe-plugin.ldif
dc8c34
 create mode 100644 ldap/admin/src/scripts/52updateAESplugin.pl
dc8c34
 delete mode 100644 ldap/servers/plugins/rever/des.c
dc8c34
 create mode 100644 ldap/servers/plugins/rever/pbe.c
dc8c34
dc8c34
diff --git a/Makefile.am b/Makefile.am
dc8c34
index 9ad2c3a..bc40ea7 100644
dc8c34
--- a/Makefile.am
dc8c34
+++ b/Makefile.am
dc8c34
@@ -205,7 +205,7 @@ endif
dc8c34
 serverplugin_LTLIBRARIES = libacl-plugin.la libattr-unique-plugin.la \
dc8c34
 	libautomember-plugin.la libback-ldbm.la libchainingdb-plugin.la \
dc8c34
 	libcollation-plugin.la libcos-plugin.la libderef-plugin.la \
dc8c34
-	libdes-plugin.la libdistrib-plugin.la libhttp-client-plugin.la \
dc8c34
+	libpbe-plugin.la libdistrib-plugin.la libhttp-client-plugin.la \
dc8c34
 	liblinkedattrs-plugin.la libmanagedentries-plugin.la \
dc8c34
 	libmemberof-plugin.la libpassthru-plugin.la libpwdstorage-plugin.la \
dc8c34
 	libreferint-plugin.la libreplication-plugin.la libretrocl-plugin.la \
dc8c34
@@ -936,14 +936,14 @@ libderef_plugin_la_LIBADD = libslapd.la $(LDAPSDK_LINK) $(NSPR_LINK)
dc8c34
 libderef_plugin_la_LDFLAGS = -avoid-version
dc8c34
 
dc8c34
 #------------------------
dc8c34
-# libdes-plugin
dc8c34
+# libpbe-plugin
dc8c34
 #-----------------------
dc8c34
-libdes_plugin_la_SOURCES = ldap/servers/plugins/rever/des.c \
dc8c34
+libpbe_plugin_la_SOURCES = ldap/servers/plugins/rever/pbe.c \
dc8c34
 	ldap/servers/plugins/rever/rever.c
dc8c34
 
dc8c34
-libdes_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) @svrcore_inc@
dc8c34
-libdes_plugin_la_LIBADD = libslapd.la $(NSS_LINK)
dc8c34
-libdes_plugin_la_LDFLAGS = -avoid-version
dc8c34
+libpbe_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) @svrcore_inc@
dc8c34
+libpbe_plugin_la_LIBADD = libslapd.la $(NSS_LINK)
dc8c34
+libpbe_plugin_la_LDFLAGS = -avoid-version
dc8c34
 
dc8c34
 #------------------------
dc8c34
 # libdistrib-plugin
dc8c34
diff --git a/Makefile.in b/Makefile.in
dc8c34
index 930d22b..7fded4f 100644
dc8c34
--- a/Makefile.in
dc8c34
+++ b/Makefile.in
dc8c34
@@ -317,14 +317,6 @@ libderef_plugin_la_OBJECTS = $(am_libderef_plugin_la_OBJECTS)
dc8c34
 libderef_plugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
dc8c34
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
dc8c34
 	$(libderef_plugin_la_LDFLAGS) $(LDFLAGS) -o $@
dc8c34
-libdes_plugin_la_DEPENDENCIES = libslapd.la $(am__DEPENDENCIES_1)
dc8c34
-am_libdes_plugin_la_OBJECTS =  \
dc8c34
-	ldap/servers/plugins/rever/libdes_plugin_la-des.lo \
dc8c34
-	ldap/servers/plugins/rever/libdes_plugin_la-rever.lo
dc8c34
-libdes_plugin_la_OBJECTS = $(am_libdes_plugin_la_OBJECTS)
dc8c34
-libdes_plugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
dc8c34
-	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
dc8c34
-	$(libdes_plugin_la_LDFLAGS) $(LDFLAGS) -o $@
dc8c34
 libdistrib_plugin_la_DEPENDENCIES = libslapd.la
dc8c34
 am_libdistrib_plugin_la_OBJECTS =  \
dc8c34
 	ldap/servers/plugins/distrib/libdistrib_plugin_la-distrib.lo
dc8c34
@@ -462,6 +454,14 @@ libpassthru_plugin_la_OBJECTS = $(am_libpassthru_plugin_la_OBJECTS)
dc8c34
 libpassthru_plugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
dc8c34
 	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
dc8c34
 	$(libpassthru_plugin_la_LDFLAGS) $(LDFLAGS) -o $@
dc8c34
+libpbe_plugin_la_DEPENDENCIES = libslapd.la $(am__DEPENDENCIES_1)
dc8c34
+am_libpbe_plugin_la_OBJECTS =  \
dc8c34
+	ldap/servers/plugins/rever/libpbe_plugin_la-pbe.lo \
dc8c34
+	ldap/servers/plugins/rever/libpbe_plugin_la-rever.lo
dc8c34
+libpbe_plugin_la_OBJECTS = $(am_libpbe_plugin_la_OBJECTS)
dc8c34
+libpbe_plugin_la_LINK = $(LIBTOOL) --tag=CC $(AM_LIBTOOLFLAGS) \
dc8c34
+	$(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \
dc8c34
+	$(libpbe_plugin_la_LDFLAGS) $(LDFLAGS) -o $@
dc8c34
 libposix_winsync_plugin_la_DEPENDENCIES = libslapd.la \
dc8c34
 	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
dc8c34
 am_libposix_winsync_plugin_la_OBJECTS = ldap/servers/plugins/posix-winsync/libposix_winsync_plugin_la-posix-winsync.lo \
dc8c34
@@ -1011,14 +1011,14 @@ SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \
dc8c34
 	$(libbitwise_plugin_la_SOURCES) \
dc8c34
 	$(libchainingdb_plugin_la_SOURCES) \
dc8c34
 	$(libcollation_plugin_la_SOURCES) $(libcos_plugin_la_SOURCES) \
dc8c34
-	$(libderef_plugin_la_SOURCES) $(libdes_plugin_la_SOURCES) \
dc8c34
-	$(libdistrib_plugin_la_SOURCES) $(libdna_plugin_la_SOURCES) \
dc8c34
+	$(libderef_plugin_la_SOURCES) $(libdistrib_plugin_la_SOURCES) \
dc8c34
+	$(libdna_plugin_la_SOURCES) \
dc8c34
 	$(libhttp_client_plugin_la_SOURCES) \
dc8c34
 	$(liblinkedattrs_plugin_la_SOURCES) \
dc8c34
 	$(libmanagedentries_plugin_la_SOURCES) \
dc8c34
 	$(libmemberof_plugin_la_SOURCES) $(libns_dshttpd_la_SOURCES) \
dc8c34
 	$(libpam_passthru_plugin_la_SOURCES) \
dc8c34
-	$(libpassthru_plugin_la_SOURCES) \
dc8c34
+	$(libpassthru_plugin_la_SOURCES) $(libpbe_plugin_la_SOURCES) \
dc8c34
 	$(libposix_winsync_plugin_la_SOURCES) \
dc8c34
 	$(libpresence_plugin_la_SOURCES) \
dc8c34
 	$(libpwdstorage_plugin_la_SOURCES) \
dc8c34
@@ -1045,14 +1045,14 @@ DIST_SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \
dc8c34
 	$(libbitwise_plugin_la_SOURCES) \
dc8c34
 	$(libchainingdb_plugin_la_SOURCES) \
dc8c34
 	$(libcollation_plugin_la_SOURCES) $(libcos_plugin_la_SOURCES) \
dc8c34
-	$(libderef_plugin_la_SOURCES) $(libdes_plugin_la_SOURCES) \
dc8c34
-	$(libdistrib_plugin_la_SOURCES) $(libdna_plugin_la_SOURCES) \
dc8c34
+	$(libderef_plugin_la_SOURCES) $(libdistrib_plugin_la_SOURCES) \
dc8c34
+	$(libdna_plugin_la_SOURCES) \
dc8c34
 	$(libhttp_client_plugin_la_SOURCES) \
dc8c34
 	$(liblinkedattrs_plugin_la_SOURCES) \
dc8c34
 	$(libmanagedentries_plugin_la_SOURCES) \
dc8c34
 	$(libmemberof_plugin_la_SOURCES) $(libns_dshttpd_la_SOURCES) \
dc8c34
 	$(libpam_passthru_plugin_la_SOURCES) \
dc8c34
-	$(libpassthru_plugin_la_SOURCES) \
dc8c34
+	$(libpassthru_plugin_la_SOURCES) $(libpbe_plugin_la_SOURCES) \
dc8c34
 	$(libposix_winsync_plugin_la_SOURCES) \
dc8c34
 	$(libpresence_plugin_la_SOURCES) \
dc8c34
 	$(libpwdstorage_plugin_la_SOURCES) \
dc8c34
@@ -1435,7 +1435,7 @@ server_LTLIBRARIES = libslapd.la libns-dshttpd.la
dc8c34
 serverplugin_LTLIBRARIES = libacl-plugin.la libattr-unique-plugin.la \
dc8c34
 	libautomember-plugin.la libback-ldbm.la libchainingdb-plugin.la \
dc8c34
 	libcollation-plugin.la libcos-plugin.la libderef-plugin.la \
dc8c34
-	libdes-plugin.la libdistrib-plugin.la libhttp-client-plugin.la \
dc8c34
+	libpbe-plugin.la libdistrib-plugin.la libhttp-client-plugin.la \
dc8c34
 	liblinkedattrs-plugin.la libmanagedentries-plugin.la \
dc8c34
 	libmemberof-plugin.la libpassthru-plugin.la libpwdstorage-plugin.la \
dc8c34
 	libreferint-plugin.la libreplication-plugin.la libretrocl-plugin.la \
dc8c34
@@ -2101,14 +2101,14 @@ libderef_plugin_la_LIBADD = libslapd.la $(LDAPSDK_LINK) $(NSPR_LINK)
dc8c34
 libderef_plugin_la_LDFLAGS = -avoid-version
dc8c34
 
dc8c34
 #------------------------
dc8c34
-# libdes-plugin
dc8c34
+# libpbe-plugin
dc8c34
 #-----------------------
dc8c34
-libdes_plugin_la_SOURCES = ldap/servers/plugins/rever/des.c \
dc8c34
+libpbe_plugin_la_SOURCES = ldap/servers/plugins/rever/pbe.c \
dc8c34
 	ldap/servers/plugins/rever/rever.c
dc8c34
 
dc8c34
-libdes_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) @svrcore_inc@
dc8c34
-libdes_plugin_la_LIBADD = libslapd.la $(NSS_LINK)
dc8c34
-libdes_plugin_la_LDFLAGS = -avoid-version
dc8c34
+libpbe_plugin_la_CPPFLAGS = $(PLUGIN_CPPFLAGS) @svrcore_inc@
dc8c34
+libpbe_plugin_la_LIBADD = libslapd.la $(NSS_LINK)
dc8c34
+libpbe_plugin_la_LDFLAGS = -avoid-version
dc8c34
 
dc8c34
 #------------------------
dc8c34
 # libdistrib-plugin
dc8c34
@@ -3271,20 +3271,6 @@ ldap/servers/plugins/deref/libderef_plugin_la-deref.lo:  \
dc8c34
 	ldap/servers/plugins/deref/$(DEPDIR)/$(am__dirstamp)
dc8c34
 libderef-plugin.la: $(libderef_plugin_la_OBJECTS) $(libderef_plugin_la_DEPENDENCIES) 
dc8c34
 	$(libderef_plugin_la_LINK) -rpath $(serverplugindir) $(libderef_plugin_la_OBJECTS) $(libderef_plugin_la_LIBADD) $(LIBS)
dc8c34
-ldap/servers/plugins/rever/$(am__dirstamp):
dc8c34
-	@$(MKDIR_P) ldap/servers/plugins/rever
dc8c34
-	@: > ldap/servers/plugins/rever/$(am__dirstamp)
dc8c34
-ldap/servers/plugins/rever/$(DEPDIR)/$(am__dirstamp):
dc8c34
-	@$(MKDIR_P) ldap/servers/plugins/rever/$(DEPDIR)
dc8c34
-	@: > ldap/servers/plugins/rever/$(DEPDIR)/$(am__dirstamp)
dc8c34
-ldap/servers/plugins/rever/libdes_plugin_la-des.lo:  \
dc8c34
-	ldap/servers/plugins/rever/$(am__dirstamp) \
dc8c34
-	ldap/servers/plugins/rever/$(DEPDIR)/$(am__dirstamp)
dc8c34
-ldap/servers/plugins/rever/libdes_plugin_la-rever.lo:  \
dc8c34
-	ldap/servers/plugins/rever/$(am__dirstamp) \
dc8c34
-	ldap/servers/plugins/rever/$(DEPDIR)/$(am__dirstamp)
dc8c34
-libdes-plugin.la: $(libdes_plugin_la_OBJECTS) $(libdes_plugin_la_DEPENDENCIES) 
dc8c34
-	$(libdes_plugin_la_LINK) -rpath $(serverplugindir) $(libdes_plugin_la_OBJECTS) $(libdes_plugin_la_LIBADD) $(LIBS)
dc8c34
 ldap/servers/plugins/distrib/$(am__dirstamp):
dc8c34
 	@$(MKDIR_P) ldap/servers/plugins/distrib
dc8c34
 	@: > ldap/servers/plugins/distrib/$(am__dirstamp)
dc8c34
@@ -3565,6 +3551,20 @@ ldap/servers/plugins/passthru/libpassthru_plugin_la-ptutil.lo:  \
dc8c34
 	ldap/servers/plugins/passthru/$(DEPDIR)/$(am__dirstamp)
dc8c34
 libpassthru-plugin.la: $(libpassthru_plugin_la_OBJECTS) $(libpassthru_plugin_la_DEPENDENCIES) 
dc8c34
 	$(libpassthru_plugin_la_LINK) -rpath $(serverplugindir) $(libpassthru_plugin_la_OBJECTS) $(libpassthru_plugin_la_LIBADD) $(LIBS)
dc8c34
+ldap/servers/plugins/rever/$(am__dirstamp):
dc8c34
+	@$(MKDIR_P) ldap/servers/plugins/rever
dc8c34
+	@: > ldap/servers/plugins/rever/$(am__dirstamp)
dc8c34
+ldap/servers/plugins/rever/$(DEPDIR)/$(am__dirstamp):
dc8c34
+	@$(MKDIR_P) ldap/servers/plugins/rever/$(DEPDIR)
dc8c34
+	@: > ldap/servers/plugins/rever/$(DEPDIR)/$(am__dirstamp)
dc8c34
+ldap/servers/plugins/rever/libpbe_plugin_la-pbe.lo:  \
dc8c34
+	ldap/servers/plugins/rever/$(am__dirstamp) \
dc8c34
+	ldap/servers/plugins/rever/$(DEPDIR)/$(am__dirstamp)
dc8c34
+ldap/servers/plugins/rever/libpbe_plugin_la-rever.lo:  \
dc8c34
+	ldap/servers/plugins/rever/$(am__dirstamp) \
dc8c34
+	ldap/servers/plugins/rever/$(DEPDIR)/$(am__dirstamp)
dc8c34
+libpbe-plugin.la: $(libpbe_plugin_la_OBJECTS) $(libpbe_plugin_la_DEPENDENCIES) 
dc8c34
+	$(libpbe_plugin_la_LINK) -rpath $(serverplugindir) $(libpbe_plugin_la_OBJECTS) $(libpbe_plugin_la_LIBADD) $(LIBS)
dc8c34
 ldap/servers/plugins/posix-winsync/$(am__dirstamp):
dc8c34
 	@$(MKDIR_P) ldap/servers/plugins/posix-winsync
dc8c34
 	@: > ldap/servers/plugins/posix-winsync/$(am__dirstamp)
dc8c34
@@ -5105,10 +5105,10 @@ mostlyclean-compile:
dc8c34
 	-rm -f ldap/servers/plugins/retrocl/libretrocl_plugin_la-retrocl_rootdse.lo
dc8c34
 	-rm -f ldap/servers/plugins/retrocl/libretrocl_plugin_la-retrocl_trim.$(OBJEXT)
dc8c34
 	-rm -f ldap/servers/plugins/retrocl/libretrocl_plugin_la-retrocl_trim.lo
dc8c34
-	-rm -f ldap/servers/plugins/rever/libdes_plugin_la-des.$(OBJEXT)
dc8c34
-	-rm -f ldap/servers/plugins/rever/libdes_plugin_la-des.lo
dc8c34
-	-rm -f ldap/servers/plugins/rever/libdes_plugin_la-rever.$(OBJEXT)
dc8c34
-	-rm -f ldap/servers/plugins/rever/libdes_plugin_la-rever.lo
dc8c34
+	-rm -f ldap/servers/plugins/rever/libpbe_plugin_la-pbe.$(OBJEXT)
dc8c34
+	-rm -f ldap/servers/plugins/rever/libpbe_plugin_la-pbe.lo
dc8c34
+	-rm -f ldap/servers/plugins/rever/libpbe_plugin_la-rever.$(OBJEXT)
dc8c34
+	-rm -f ldap/servers/plugins/rever/libpbe_plugin_la-rever.lo
dc8c34
 	-rm -f ldap/servers/plugins/roles/libroles_plugin_la-roles_cache.$(OBJEXT)
dc8c34
 	-rm -f ldap/servers/plugins/roles/libroles_plugin_la-roles_cache.lo
dc8c34
 	-rm -f ldap/servers/plugins/roles/libroles_plugin_la-roles_plugin.$(OBJEXT)
dc8c34
@@ -5812,8 +5812,8 @@ distclean-compile:
dc8c34
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/retrocl/$(DEPDIR)/libretrocl_plugin_la-retrocl_po.Plo@am__quote@
dc8c34
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/retrocl/$(DEPDIR)/libretrocl_plugin_la-retrocl_rootdse.Plo@am__quote@
dc8c34
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/retrocl/$(DEPDIR)/libretrocl_plugin_la-retrocl_trim.Plo@am__quote@
dc8c34
-@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/rever/$(DEPDIR)/libdes_plugin_la-des.Plo@am__quote@
dc8c34
-@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/rever/$(DEPDIR)/libdes_plugin_la-rever.Plo@am__quote@
dc8c34
+@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/rever/$(DEPDIR)/libpbe_plugin_la-pbe.Plo@am__quote@
dc8c34
+@AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/rever/$(DEPDIR)/libpbe_plugin_la-rever.Plo@am__quote@
dc8c34
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/roles/$(DEPDIR)/libroles_plugin_la-roles_cache.Plo@am__quote@
dc8c34
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/roles/$(DEPDIR)/libroles_plugin_la-roles_plugin.Plo@am__quote@
dc8c34
 @AMDEP_TRUE@@am__include@ @am__quote@ldap/servers/plugins/rootdn_access/$(DEPDIR)/librootdn_access_plugin_la-rootdn_access.Plo@am__quote@
dc8c34
@@ -7077,20 +7077,6 @@ ldap/servers/plugins/deref/libderef_plugin_la-deref.lo: ldap/servers/plugins/der
dc8c34
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
dc8c34
 @am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libderef_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/deref/libderef_plugin_la-deref.lo `test -f 'ldap/servers/plugins/deref/deref.c' || echo '$(srcdir)/'`ldap/servers/plugins/deref/deref.c
dc8c34
 
dc8c34
-ldap/servers/plugins/rever/libdes_plugin_la-des.lo: ldap/servers/plugins/rever/des.c
dc8c34
-@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdes_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/rever/libdes_plugin_la-des.lo -MD -MP -MF ldap/servers/plugins/rever/$(DEPDIR)/libdes_plugin_la-des.Tpo -c -o ldap/servers/plugins/rever/libdes_plugin_la-des.lo `test -f 'ldap/servers/plugins/rever/des.c' || echo '$(srcdir)/'`ldap/servers/plugins/rever/des.c
dc8c34
-@am__fastdepCC_TRUE@	$(am__mv) ldap/servers/plugins/rever/$(DEPDIR)/libdes_plugin_la-des.Tpo ldap/servers/plugins/rever/$(DEPDIR)/libdes_plugin_la-des.Plo
dc8c34
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ldap/servers/plugins/rever/des.c' object='ldap/servers/plugins/rever/libdes_plugin_la-des.lo' libtool=yes @AMDEPBACKSLASH@
dc8c34
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
dc8c34
-@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdes_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/rever/libdes_plugin_la-des.lo `test -f 'ldap/servers/plugins/rever/des.c' || echo '$(srcdir)/'`ldap/servers/plugins/rever/des.c
dc8c34
-
dc8c34
-ldap/servers/plugins/rever/libdes_plugin_la-rever.lo: ldap/servers/plugins/rever/rever.c
dc8c34
-@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdes_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/rever/libdes_plugin_la-rever.lo -MD -MP -MF ldap/servers/plugins/rever/$(DEPDIR)/libdes_plugin_la-rever.Tpo -c -o ldap/servers/plugins/rever/libdes_plugin_la-rever.lo `test -f 'ldap/servers/plugins/rever/rever.c' || echo '$(srcdir)/'`ldap/servers/plugins/rever/rever.c
dc8c34
-@am__fastdepCC_TRUE@	$(am__mv) ldap/servers/plugins/rever/$(DEPDIR)/libdes_plugin_la-rever.Tpo ldap/servers/plugins/rever/$(DEPDIR)/libdes_plugin_la-rever.Plo
dc8c34
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ldap/servers/plugins/rever/rever.c' object='ldap/servers/plugins/rever/libdes_plugin_la-rever.lo' libtool=yes @AMDEPBACKSLASH@
dc8c34
-@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
dc8c34
-@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdes_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/rever/libdes_plugin_la-rever.lo `test -f 'ldap/servers/plugins/rever/rever.c' || echo '$(srcdir)/'`ldap/servers/plugins/rever/rever.c
dc8c34
-
dc8c34
 ldap/servers/plugins/distrib/libdistrib_plugin_la-distrib.lo: ldap/servers/plugins/distrib/distrib.c
dc8c34
 @am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libdistrib_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/distrib/libdistrib_plugin_la-distrib.lo -MD -MP -MF ldap/servers/plugins/distrib/$(DEPDIR)/libdistrib_plugin_la-distrib.Tpo -c -o ldap/servers/plugins/distrib/libdistrib_plugin_la-distrib.lo `test -f 'ldap/servers/plugins/distrib/distrib.c' || echo '$(srcdir)/'`ldap/servers/plugins/distrib/distrib.c
dc8c34
 @am__fastdepCC_TRUE@	$(am__mv) ldap/servers/plugins/distrib/$(DEPDIR)/libdistrib_plugin_la-distrib.Tpo ldap/servers/plugins/distrib/$(DEPDIR)/libdistrib_plugin_la-distrib.Plo
dc8c34
@@ -7329,6 +7315,20 @@ ldap/servers/plugins/passthru/libpassthru_plugin_la-ptutil.lo: ldap/servers/plug
dc8c34
 @AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
dc8c34
 @am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpassthru_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/passthru/libpassthru_plugin_la-ptutil.lo `test -f 'ldap/servers/plugins/passthru/ptutil.c' || echo '$(srcdir)/'`ldap/servers/plugins/passthru/ptutil.c
dc8c34
 
dc8c34
+ldap/servers/plugins/rever/libpbe_plugin_la-pbe.lo: ldap/servers/plugins/rever/pbe.c
dc8c34
+@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpbe_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/rever/libpbe_plugin_la-pbe.lo -MD -MP -MF ldap/servers/plugins/rever/$(DEPDIR)/libpbe_plugin_la-pbe.Tpo -c -o ldap/servers/plugins/rever/libpbe_plugin_la-pbe.lo `test -f 'ldap/servers/plugins/rever/pbe.c' || echo '$(srcdir)/'`ldap/servers/plugins/rever/pbe.c
dc8c34
+@am__fastdepCC_TRUE@	$(am__mv) ldap/servers/plugins/rever/$(DEPDIR)/libpbe_plugin_la-pbe.Tpo ldap/servers/plugins/rever/$(DEPDIR)/libpbe_plugin_la-pbe.Plo
dc8c34
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ldap/servers/plugins/rever/pbe.c' object='ldap/servers/plugins/rever/libpbe_plugin_la-pbe.lo' libtool=yes @AMDEPBACKSLASH@
dc8c34
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
dc8c34
+@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpbe_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/rever/libpbe_plugin_la-pbe.lo `test -f 'ldap/servers/plugins/rever/pbe.c' || echo '$(srcdir)/'`ldap/servers/plugins/rever/pbe.c
dc8c34
+
dc8c34
+ldap/servers/plugins/rever/libpbe_plugin_la-rever.lo: ldap/servers/plugins/rever/rever.c
dc8c34
+@am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpbe_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/rever/libpbe_plugin_la-rever.lo -MD -MP -MF ldap/servers/plugins/rever/$(DEPDIR)/libpbe_plugin_la-rever.Tpo -c -o ldap/servers/plugins/rever/libpbe_plugin_la-rever.lo `test -f 'ldap/servers/plugins/rever/rever.c' || echo '$(srcdir)/'`ldap/servers/plugins/rever/rever.c
dc8c34
+@am__fastdepCC_TRUE@	$(am__mv) ldap/servers/plugins/rever/$(DEPDIR)/libpbe_plugin_la-rever.Tpo ldap/servers/plugins/rever/$(DEPDIR)/libpbe_plugin_la-rever.Plo
dc8c34
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	source='ldap/servers/plugins/rever/rever.c' object='ldap/servers/plugins/rever/libpbe_plugin_la-rever.lo' libtool=yes @AMDEPBACKSLASH@
dc8c34
+@AMDEP_TRUE@@am__fastdepCC_FALSE@	DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
dc8c34
+@am__fastdepCC_FALSE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libpbe_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -c -o ldap/servers/plugins/rever/libpbe_plugin_la-rever.lo `test -f 'ldap/servers/plugins/rever/rever.c' || echo '$(srcdir)/'`ldap/servers/plugins/rever/rever.c
dc8c34
+
dc8c34
 ldap/servers/plugins/posix-winsync/libposix_winsync_plugin_la-posix-winsync.lo: ldap/servers/plugins/posix-winsync/posix-winsync.c
dc8c34
 @am__fastdepCC_TRUE@	$(LIBTOOL)  --tag=CC $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(libposix_winsync_plugin_la_CPPFLAGS) $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -MT ldap/servers/plugins/posix-winsync/libposix_winsync_plugin_la-posix-winsync.lo -MD -MP -MF ldap/servers/plugins/posix-winsync/$(DEPDIR)/libposix_winsync_plugin_la-posix-winsync.Tpo -c -o ldap/servers/plugins/posix-winsync/libposix_winsync_plugin_la-posix-winsync.lo `test -f 'ldap/servers/plugins/posix-winsync/posix-winsync.c' || echo '$(srcdir)/'`ldap/servers/plugins/posix-winsync/posix-winsync.c
dc8c34
 @am__fastdepCC_TRUE@	$(am__mv) ldap/servers/plugins/posix-winsync/$(DEPDIR)/libposix_winsync_plugin_la-posix-winsync.Tpo ldap/servers/plugins/posix-winsync/$(DEPDIR)/libposix_winsync_plugin_la-posix-winsync.Plo
dc8c34
diff --git a/ldap/admin/src/scripts/50AES-pbe-plugin.ldif b/ldap/admin/src/scripts/50AES-pbe-plugin.ldif
dc8c34
new file mode 100644
dc8c34
index 0000000..564ceae
dc8c34
--- /dev/null
dc8c34
+++ b/ldap/admin/src/scripts/50AES-pbe-plugin.ldif
dc8c34
@@ -0,0 +1,16 @@
dc8c34
+dn: cn=AES,cn=Password Storage Schemes,cn=plugins,cn=config
dc8c34
+objectclass: top
dc8c34
+objectclass: nsSlapdPlugin
dc8c34
+objectclass: extensibleObject
dc8c34
+cn: AES
dc8c34
+nsslapd-pluginpath: libpbe-plugin
dc8c34
+nsslapd-plugininitfunc: aes_init
dc8c34
+nsslapd-plugintype: reverpwdstoragescheme
dc8c34
+nsslapd-pluginenabled: on
dc8c34
+nsslapd-pluginarg0: nsmultiplexorcredentials
dc8c34
+nsslapd-pluginarg1: nsds5ReplicaCredentials
dc8c34
+nsslapd-pluginprecedence: 1
dc8c34
+nsslapd-pluginid: ID
dc8c34
+nsslapd-pluginDescription: DESC
dc8c34
+nsslapd-pluginVersion: PACKAGE_VERSION
dc8c34
+nsslapd-pluginVendor: VENDOR
dc8c34
diff --git a/ldap/admin/src/scripts/52updateAESplugin.pl b/ldap/admin/src/scripts/52updateAESplugin.pl
dc8c34
new file mode 100644
dc8c34
index 0000000..6a8a885
dc8c34
--- /dev/null
dc8c34
+++ b/ldap/admin/src/scripts/52updateAESplugin.pl
dc8c34
@@ -0,0 +1,84 @@
dc8c34
+use Mozilla::LDAP::Conn;
dc8c34
+use Mozilla::LDAP::Entry;
dc8c34
+use Mozilla::LDAP::Utils qw(normalizeDN);
dc8c34
+use Mozilla::LDAP::API qw(:constant ldap_url_parse ldap_explode_dn);
dc8c34
+use File::Basename;
dc8c34
+use File::Copy;
dc8c34
+use DSUtil qw(debug serverIsRunning);
dc8c34
+
dc8c34
+#
dc8c34
+# Check if there is a DES plugin and make sure the AES plugin contains the same attributes
dc8c34
+#
dc8c34
+sub runinst {
dc8c34
+    my ($inf, $inst, $dseldif, $conn) = @_;
dc8c34
+    my @attrs;
dc8c34
+    my @attrs_to_add;
dc8c34
+    my $aes_count = 0;
dc8c34
+    my $des_count = 0;
dc8c34
+    my $i = 0;
dc8c34
+
dc8c34
+    my $aes_dn = "cn=AES,cn=Password Storage Schemes,cn=plugins,cn=config";
dc8c34
+    my $aes_entry = $conn->search($aes_dn, "base", "(cn=*)");
dc8c34
+    if (!$aes_entry) {
dc8c34
+        # No AES plugin - nothing to do
dc8c34
+        return ();
dc8c34
+    }
dc8c34
+
dc8c34
+    # We need to grab the AES plugin args...
dc8c34
+    while(1){
dc8c34
+        my $argattr = "nsslapd-pluginarg" . $i;
dc8c34
+        my $val = $aes_entry->getValues($argattr);
dc8c34
+        if($val ne ""){
dc8c34
+            $attrs[$aes_count] = $val;
dc8c34
+            $aes_count++;
dc8c34
+        } else {
dc8c34
+            last;
dc8c34
+        }
dc8c34
+        $i++;
dc8c34
+    }
dc8c34
+
dc8c34
+    # Grab the DES plugin
dc8c34
+    my $des_dn = "cn=DES,cn=Password Storage Schemes,cn=plugins,cn=config";
dc8c34
+    my $des_entry = $conn->search($des_dn, "base", "(cn=*)");
dc8c34
+    if (!$des_entry) {
dc8c34
+        # No DES plugin - nothing to do
dc8c34
+        return ();
dc8c34
+    }
dc8c34
+
dc8c34
+    # We need to check the DES plugin args against the AES args.
dc8c34
+    $i = 0;
dc8c34
+    while(1){
dc8c34
+        my $argattr = "nsslapd-pluginarg" . $i;
dc8c34
+        my $val = $des_entry->getValues($argattr);
dc8c34
+        if($val eq ""){
dc8c34
+            last;
dc8c34
+        }
dc8c34
+        if(!($val ~~ @attrs) ){
dc8c34
+            $attrs_to_add[$des_count] = $val;
dc8c34
+            $des_count++;
dc8c34
+        }
dc8c34
+        $i++;
dc8c34
+    }
dc8c34
+
dc8c34
+    # Add the missing attributes to the AES plugin
dc8c34
+    if($#attrs_to_add >= 0){
dc8c34
+        foreach $val (@attrs_to_add){
dc8c34
+            $aes_entry->addValue("nsslapd-pluginarg" . $aes_count, $val);
dc8c34
+	    $aes_count++;
dc8c34
+        }
dc8c34
+        $conn->update($aes_entry);
dc8c34
+    }
dc8c34
+
dc8c34
+    # Change replication plugin dependency from DES to AES
dc8c34
+    my $mmr_entry = $conn->search("cn=Multimaster Replication Plugin,cn=plugins,cn=config", "base", "(cn=*)");
dc8c34
+    $mmr_entry->removeValue("nsslapd-plugin-depends-on-named", "DES");
dc8c34
+    $mmr_entry->addValue("nsslapd-plugin-depends-on-named", "AES");
dc8c34
+    $conn->update($mmr_entry);
dc8c34
+
dc8c34
+    # Change the des plugin to use the new libpbe-plugin library
dc8c34
+    $des_entry->{"nsslapd-pluginPath"} = [ "libpbe-plugin" ];
dc8c34
+    $conn->update($des_entry);
dc8c34
+
dc8c34
+    return ();
dc8c34
+}
dc8c34
+
dc8c34
diff --git a/ldap/admin/src/scripts/DSCreate.pm.in b/ldap/admin/src/scripts/DSCreate.pm.in
dc8c34
index dbfcedf..8897563 100644
dc8c34
--- a/ldap/admin/src/scripts/DSCreate.pm.in
dc8c34
+++ b/ldap/admin/src/scripts/DSCreate.pm.in
dc8c34
@@ -1088,6 +1088,7 @@ sub updateTmpfilesDotD {
dc8c34
 }
dc8c34
 
dc8c34
 sub updateSystemD {
dc8c34
+    my $noservicelink = shift;
dc8c34
     my $inf = shift;
dc8c34
     my $unitdir = "@systemdsystemunitdir@";
dc8c34
     my $confbasedir = "@systemdsystemconfdir@";
dc8c34
@@ -1119,7 +1120,7 @@ sub updateSystemD {
dc8c34
             next;
dc8c34
         } else {
dc8c34
             my $servicelink = "$confdir/$pkgname\@$inst.service";
dc8c34
-            if (! -l $servicelink) {
dc8c34
+            if (! -l $servicelink && ! $noservicelink) {
dc8c34
                 if (!symlink($servicefile, $servicelink)) {
dc8c34
                     debug(1, "error updating link $servicelink to $servicefile - $!\n");
dc8c34
                     push @errs, [ 'error_linking_file', $servicefile, $servicelink, $! ];
dc8c34
@@ -1206,7 +1207,7 @@ sub createDSInstance {
dc8c34
         return @errs;
dc8c34
     }
dc8c34
 
dc8c34
-    if (@errs = updateSystemD($inf)) {
dc8c34
+    if (@errs = updateSystemD(0, $inf)) {
dc8c34
         return @errs;
dc8c34
     }
dc8c34
 
dc8c34
diff --git a/ldap/admin/src/scripts/DSMigration.pm.in b/ldap/admin/src/scripts/DSMigration.pm.in
dc8c34
index 3a73f98..e1069f7 100644
dc8c34
--- a/ldap/admin/src/scripts/DSMigration.pm.in
dc8c34
+++ b/ldap/admin/src/scripts/DSMigration.pm.in
dc8c34
@@ -1161,7 +1161,7 @@ sub migrateDS {
dc8c34
         }
dc8c34
 
dc8c34
 	# do the systemd stuff
dc8c34
-        @errs = DSCreate::updateSystemD($inf);
dc8c34
+        @errs = DSCreate::updateSystemD(0, $inf);
dc8c34
         if (@errs) {
dc8c34
             $mig->msg(@errs);
dc8c34
             goto cleanup;
dc8c34
diff --git a/ldap/admin/src/scripts/DSUpdate.pm.in b/ldap/admin/src/scripts/DSUpdate.pm.in
dc8c34
index ecdfeb7..f1bc802 100644
dc8c34
--- a/ldap/admin/src/scripts/DSUpdate.pm.in
dc8c34
+++ b/ldap/admin/src/scripts/DSUpdate.pm.in
dc8c34
@@ -416,7 +416,7 @@ sub updateDSInstance {
dc8c34
 
dc8c34
     push @errs, updateTmpfilesDotD($inf);
dc8c34
 
dc8c34
-    push @errs, updateSystemD($inf);
dc8c34
+    push @errs, updateSystemD(1, $inf);
dc8c34
 
dc8c34
     return @errs;
dc8c34
 }
dc8c34
diff --git a/ldap/ldif/50replication-plugins.ldif b/ldap/ldif/50replication-plugins.ldif
dc8c34
index af0c46b..c259ac6 100644
dc8c34
--- a/ldap/ldif/50replication-plugins.ldif
dc8c34
+++ b/ldap/ldif/50replication-plugins.ldif
dc8c34
@@ -21,6 +21,6 @@ nsslapd-plugininitfunc: replication_multimaster_plugin_init
dc8c34
 nsslapd-plugintype: object
dc8c34
 nsslapd-pluginenabled: on
dc8c34
 nsslapd-plugin-depends-on-named: ldbm database
dc8c34
-nsslapd-plugin-depends-on-named: DES
dc8c34
+nsslapd-plugin-depends-on-named: AES
dc8c34
 nsslapd-plugin-depends-on-named: Class of Service
dc8c34
 
dc8c34
diff --git a/ldap/ldif/template-dse.ldif.in b/ldap/ldif/template-dse.ldif.in
dc8c34
index c626726..4e45145 100644
dc8c34
--- a/ldap/ldif/template-dse.ldif.in
dc8c34
+++ b/ldap/ldif/template-dse.ldif.in
dc8c34
@@ -196,12 +196,26 @@ nsslapd-plugininitfunc: ns_mta_md5_pwd_storage_scheme_init
dc8c34
 nsslapd-plugintype: pwdstoragescheme
dc8c34
 nsslapd-pluginenabled: on
dc8c34
 
dc8c34
+dn: cn=AES,cn=Password Storage Schemes,cn=plugins,cn=config
dc8c34
+objectclass: top
dc8c34
+objectclass: nsSlapdPlugin
dc8c34
+objectclass: extensibleObject
dc8c34
+cn: AES
dc8c34
+nsslapd-pluginpath: libpbe-plugin
dc8c34
+nsslapd-plugininitfunc: aes_init
dc8c34
+nsslapd-plugintype: reverpwdstoragescheme
dc8c34
+nsslapd-pluginenabled: on
dc8c34
+nsslapd-pluginarg0: nsmultiplexorcredentials
dc8c34
+nsslapd-pluginarg1: nsds5ReplicaCredentials
dc8c34
+nsslapd-pluginid: aes-storage-scheme
dc8c34
+nsslapd-pluginprecedence: 1
dc8c34
+
dc8c34
 dn: cn=DES,cn=Password Storage Schemes,cn=plugins,cn=config
dc8c34
 objectclass: top
dc8c34
 objectclass: nsSlapdPlugin
dc8c34
 objectclass: extensibleObject
dc8c34
 cn: DES
dc8c34
-nsslapd-pluginpath: libdes-plugin
dc8c34
+nsslapd-pluginpath: libpbe-plugin
dc8c34
 nsslapd-plugininitfunc: des_init
dc8c34
 nsslapd-plugintype: reverpwdstoragescheme
dc8c34
 nsslapd-pluginenabled: on
dc8c34
diff --git a/ldap/servers/plugins/rever/des.c b/ldap/servers/plugins/rever/des.c
dc8c34
deleted file mode 100644
dc8c34
index 73830f0..0000000
dc8c34
--- a/ldap/servers/plugins/rever/des.c
dc8c34
+++ /dev/null
dc8c34
@@ -1,551 +0,0 @@
dc8c34
-/** BEGIN COPYRIGHT BLOCK
dc8c34
- * This Program is free software; you can redistribute it and/or modify it under
dc8c34
- * the terms of the GNU General Public License as published by the Free Software
dc8c34
- * Foundation; version 2 of the License.
dc8c34
- * 
dc8c34
- * This Program is distributed in the hope that it will be useful, but WITHOUT
dc8c34
- * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dc8c34
- * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dc8c34
- * 
dc8c34
- * You should have received a copy of the GNU General Public License along with
dc8c34
- * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
dc8c34
- * Place, Suite 330, Boston, MA 02111-1307 USA.
dc8c34
- * 
dc8c34
- * In addition, as a special exception, Red Hat, Inc. gives You the additional
dc8c34
- * right to link the code of this Program with code not covered under the GNU
dc8c34
- * General Public License ("Non-GPL Code") and to distribute linked combinations
dc8c34
- * including the two, subject to the limitations in this paragraph. Non-GPL Code
dc8c34
- * permitted under this exception must only link to the code of this Program
dc8c34
- * through those well defined interfaces identified in the file named EXCEPTION
dc8c34
- * found in the source code files (the "Approved Interfaces"). The files of
dc8c34
- * Non-GPL Code may instantiate templates or use macros or inline functions from
dc8c34
- * the Approved Interfaces without causing the resulting work to be covered by
dc8c34
- * the GNU General Public License. Only Red Hat, Inc. may make changes or
dc8c34
- * additions to the list of Approved Interfaces. You must obey the GNU General
dc8c34
- * Public License in all respects for all of the Program code and other code used
dc8c34
- * in conjunction with the Program except the Non-GPL Code covered by this
dc8c34
- * exception. If you modify this file, you may extend this exception to your
dc8c34
- * version of the file, but you are not obligated to do so. If you do not wish to
dc8c34
- * provide this exception without modification, you must delete this exception
dc8c34
- * statement from your version and license this file solely under the GPL without
dc8c34
- * exception. 
dc8c34
- * 
dc8c34
- * 
dc8c34
- * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
dc8c34
- * Copyright (C) 2005 Red Hat, Inc.
dc8c34
- * All rights reserved.
dc8c34
- * END COPYRIGHT BLOCK **/
dc8c34
-
dc8c34
-#ifdef HAVE_CONFIG_H
dc8c34
-#  include <config.h>
dc8c34
-#endif
dc8c34
-
dc8c34
-/* from /usr/project/iplanet/ws/ds5.ke/ns/svrcore/pkcs7/tstarchive.c */
dc8c34
-
dc8c34
-#include <string.h>
dc8c34
-#include <stdio.h>
dc8c34
-
dc8c34
-#include <ldap.h>
dc8c34
-#include <nspr.h> 
dc8c34
-#include <nss.h> 
dc8c34
-#include <secmod.h>
dc8c34
-/*
dc8c34
-#include <secasn1.h>
dc8c34
-#include <secpkcs7.h>
dc8c34
-*/
dc8c34
-#include <key.h>
dc8c34
-#include <certdb.h>
dc8c34
-#include <cert.h>
dc8c34
-#include <svrcore.h>
dc8c34
-#include <secmodt.h>
dc8c34
-#include <prtypes.h>
dc8c34
-#include <seccomon.h>
dc8c34
-#include <pk11func.h>
dc8c34
-
dc8c34
-#define NEED_TOK_DES /* see slap.h - defines tokDes and ptokDes */
dc8c34
-#include "rever.h"
dc8c34
-#include <slap.h>
dc8c34
-#include "slapi-plugin.h"
dc8c34
-#include <uuid.h>
dc8c34
-
dc8c34
-
dc8c34
-struct pk11MechItem
dc8c34
-{
dc8c34
-  CK_MECHANISM_TYPE type;
dc8c34
-  const char *mechName;
dc8c34
-};
dc8c34
-static const struct pk11MechItem mymech = { CKM_DES_CBC, "DES CBC encryption" };
dc8c34
-
dc8c34
-
dc8c34
-static Slapi_Mutex *mylock = NULL;
dc8c34
-
dc8c34
-struct pk11ContextStore
dc8c34
-{
dc8c34
-  PK11SlotInfo *slot;
dc8c34
-  const struct pk11MechItem *mech;
dc8c34
- 
dc8c34
-  PK11SymKey *key;
dc8c34
-  SECItem *params;
dc8c34
- 
dc8c34
-  int length;
dc8c34
-  unsigned char *crypt;
dc8c34
-};
dc8c34
-
dc8c34
-static int encode_path(char *inPlain, char **outCipher, char *path);
dc8c34
-static int decode_path(char *inCipher, char **outPlain, char *path);
dc8c34
-static SVRCOREError genKey(struct pk11ContextStore **out, const char *token, char *path);
dc8c34
-static SVRCOREError cryptPassword(struct pk11ContextStore *store, char * clear, unsigned char **out);
dc8c34
-static SVRCOREError decryptPassword(struct pk11ContextStore *store, unsigned char *cipher, char **out, int len);
dc8c34
-static void freeDes(struct pk11ContextStore *out);
dc8c34
-
dc8c34
-void
dc8c34
-init_des_plugin()
dc8c34
-{
dc8c34
-	mylock = slapi_new_mutex();
dc8c34
-}
dc8c34
-
dc8c34
-int
dc8c34
-encode(char *inPlain, char **outCipher)
dc8c34
-{
dc8c34
-	return encode_path(inPlain, outCipher, NULL);
dc8c34
-}
dc8c34
-
dc8c34
-static int
dc8c34
-encode_path(char *inPlain, char **outCipher, char *path)
dc8c34
-{
dc8c34
-	struct pk11ContextStore *context = NULL;
dc8c34
-	int err;
dc8c34
-
dc8c34
-	unsigned char *cipher = NULL;
dc8c34
-	char *tmp = NULL;
dc8c34
-	char *base = NULL;
dc8c34
-
dc8c34
-
dc8c34
-	*outCipher = NULL;
dc8c34
-	err = 1;
dc8c34
-
dc8c34
-	if ( genKey(&context, tokDes, path) == SVRCORE_Success )
dc8c34
-	{
dc8c34
-		/* Try an encryption */
dc8c34
-		if ( cryptPassword(context, inPlain, &cipher) == SVRCORE_Success )
dc8c34
-		{
dc8c34
-			base = BTOA_DataToAscii(cipher, context->length);
dc8c34
-			if ( base != NULL )
dc8c34
-			{	
dc8c34
-				tmp = slapi_ch_malloc( 3 + strlen(REVER_SCHEME_NAME) + strlen(base));
dc8c34
-				if ( tmp != NULL )
dc8c34
-				{
dc8c34
-					sprintf( tmp, "%c%s%c%s", PWD_HASH_PREFIX_START, REVER_SCHEME_NAME, PWD_HASH_PREFIX_END, base);
dc8c34
-					*outCipher = tmp;
dc8c34
-					tmp = NULL;
dc8c34
-					err = 0;
dc8c34
-				}
dc8c34
-				PORT_Free(base);
dc8c34
-			}
dc8c34
-		}
dc8c34
-	}
dc8c34
-	
dc8c34
-	freeDes(context);
dc8c34
-	slapi_ch_free((void **) &context);
dc8c34
-	return(err);
dc8c34
-}
dc8c34
-
dc8c34
-int
dc8c34
-decode(char *inCipher, char **outPlain)
dc8c34
-{
dc8c34
-	return decode_path(inCipher, outPlain, NULL);
dc8c34
-}
dc8c34
-
dc8c34
-
dc8c34
-static int
dc8c34
-decode_path(char *inCipher, char **outPlain, char *path)
dc8c34
-{
dc8c34
-	struct pk11ContextStore *context = NULL;
dc8c34
-	char *plain= NULL;
dc8c34
-	int err;
dc8c34
-
dc8c34
-	unsigned char *base = NULL;
dc8c34
-	int len = 0;
dc8c34
-
dc8c34
-
dc8c34
-	*outPlain = NULL;
dc8c34
-	err = 1;
dc8c34
-
dc8c34
-	if ( genKey(&context, tokDes, path) == SVRCORE_Success )
dc8c34
-	{
dc8c34
-		/* it seems that there is memory leak in that function: bug 400170 */
dc8c34
-
dc8c34
-		base = ATOB_AsciiToData(inCipher, (unsigned int*)&len;;
dc8c34
-		if ( base != NULL )
dc8c34
-		{
dc8c34
-			if ( decryptPassword(context, base, &plain, len) == SVRCORE_Success )
dc8c34
-			{
dc8c34
-				*outPlain = plain;
dc8c34
-				err = 0;
dc8c34
-			}
dc8c34
-		}
dc8c34
-	}
dc8c34
-
dc8c34
-	PORT_Free(base);
dc8c34
-	freeDes(context);
dc8c34
-	slapi_ch_free((void **) &context);
dc8c34
-	return(err);
dc8c34
-}
dc8c34
-
dc8c34
-static void freeDes(struct pk11ContextStore *out)
dc8c34
-{
dc8c34
-	if (out)
dc8c34
-	{
dc8c34
-		if (out->slot) 
dc8c34
-			slapd_pk11_freeSlot(out->slot);
dc8c34
-		if (out->key) 
dc8c34
-			slapd_pk11_freeSymKey(out->key);
dc8c34
-		if (out->params) 
dc8c34
-			SECITEM_FreeItem(out->params,PR_TRUE);
dc8c34
-		if (out->crypt)
dc8c34
-			free(out->crypt);
dc8c34
-	}
dc8c34
-}
dc8c34
-
dc8c34
-static SVRCOREError genKey(struct pk11ContextStore **out, const char *token, char *path)
dc8c34
-{
dc8c34
-	SVRCOREError err = SVRCORE_Success;
dc8c34
-	struct pk11ContextStore *store = NULL;
dc8c34
-	SECItem *pwitem = NULL;
dc8c34
-	SECItem *result = NULL;
dc8c34
-	SECAlgorithmID *algid = NULL;
dc8c34
-	SECOidTag algoid;
dc8c34
-	SECItem *salt = NULL;
dc8c34
-	CK_MECHANISM pbeMech;
dc8c34
-	CK_MECHANISM cryptoMech;
dc8c34
-
dc8c34
-	char *configdir = NULL;
dc8c34
-	char *iv = NULL;
dc8c34
-
dc8c34
-	store = (struct pk11ContextStore*)slapi_ch_malloc(sizeof(*store));
dc8c34
-	if (store == NULL) 
dc8c34
-	{
dc8c34
-		err = SVRCORE_NoMemory_Error;
dc8c34
-		goto done;
dc8c34
-	}
dc8c34
-	*out = store;
dc8c34
-
dc8c34
-	/* Low-level init */
dc8c34
-	store->slot = NULL;
dc8c34
-	store->key = NULL;
dc8c34
-	store->params = NULL;
dc8c34
-	store->crypt = NULL;
dc8c34
-
dc8c34
-	/* Use the tokenName to find a PKCS11 slot */
dc8c34
-	store->slot = slapd_pk11_findSlotByName((char *)token);
dc8c34
-	if (store->slot == NULL) 
dc8c34
-	{
dc8c34
-		err = SVRCORE_NoSuchToken_Error;
dc8c34
-		goto done;
dc8c34
-	}
dc8c34
-
dc8c34
-	/* Generate a key and parameters to do the encryption */
dc8c34
-	store->mech = &mymech;
dc8c34
-
dc8c34
-	/* Generate a unique id, used as salt for the key generation */
dc8c34
-	if ( path == NULL )
dc8c34
-	{
dc8c34
-		configdir = config_get_configdir();
dc8c34
-		if ( configdir == NULL )
dc8c34
-		{
dc8c34
-		  err = SVRCORE_System_Error;
dc8c34
-		  goto done;
dc8c34
-		}
dc8c34
-	}
dc8c34
-	else
dc8c34
-	{
dc8c34
-		configdir = slapi_ch_strdup(path);
dc8c34
-	}
dc8c34
-	if ( slapi_uniqueIDGenerateFromNameString (&iv, NULL, configdir, strlen(configdir)) != UID_SUCCESS )
dc8c34
-	{
dc8c34
-	  slapi_ch_free((void**)&configdir);
dc8c34
-	  err = SVRCORE_System_Error;
dc8c34
-	  goto done;
dc8c34
-	}
dc8c34
-	slapi_ch_free((void**)&configdir);
dc8c34
-
dc8c34
-	pwitem = (SECItem *) PORT_Alloc(sizeof(SECItem));
dc8c34
-	if (pwitem == NULL)
dc8c34
-	{
dc8c34
-		err = SVRCORE_NoMemory_Error;
dc8c34
-		goto done;
dc8c34
-	}
dc8c34
-	pwitem->type = siBuffer;
dc8c34
-	pwitem->data = (unsigned char *)PORT_Alloc(strlen(iv)+1);
dc8c34
-	if (pwitem->data == NULL)
dc8c34
-	{
dc8c34
-		err = SVRCORE_NoMemory_Error;
dc8c34
-		goto done;
dc8c34
-	}
dc8c34
-	strcpy((char*)pwitem->data, iv);		
dc8c34
-	pwitem->len = strlen(iv) + 1;
dc8c34
-
dc8c34
-	algoid = SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC;
dc8c34
-
dc8c34
-	salt = (SECItem *) PORT_Alloc(sizeof(SECItem));
dc8c34
-	if (salt == NULL)
dc8c34
-	{
dc8c34
-		err = SVRCORE_NoMemory_Error;
dc8c34
-		goto done;
dc8c34
-	}
dc8c34
-	salt->type = siBuffer;
dc8c34
-	salt->data = (unsigned char *)PORT_Alloc(strlen(iv)+1);
dc8c34
-	if ( salt->data == NULL )
dc8c34
-	{
dc8c34
-		err = SVRCORE_NoMemory_Error;
dc8c34
-		goto done;
dc8c34
-	}
dc8c34
-	strcpy((char*)salt->data, iv);		
dc8c34
-	salt->len = strlen(iv) + 1;
dc8c34
-
dc8c34
-	algid = slapd_pk11_createPBEAlgorithmID(algoid, 2, salt);
dc8c34
-
dc8c34
-	slapi_lock_mutex(mylock);
dc8c34
-	store->key = slapd_pk11_pbeKeyGen(store->slot, algid, pwitem, 0, 0);
dc8c34
-	if (store->key == 0)
dc8c34
-	{
dc8c34
-      slapi_unlock_mutex(mylock);
dc8c34
-	  err = SVRCORE_System_Error;
dc8c34
-	  goto done;
dc8c34
-	}
dc8c34
-
dc8c34
-	slapi_unlock_mutex(mylock);
dc8c34
-    pbeMech.mechanism = slapd_pk11_algtagToMechanism(algoid);
dc8c34
-    result = slapd_pk11_paramFromAlgid(algid);
dc8c34
-    secoid_destroyAlgorithmID(algid, PR_TRUE);
dc8c34
-    pbeMech.pParameter = result->data;
dc8c34
-    pbeMech.ulParameterLen = result->len;
dc8c34
-    if(slapd_pk11_mapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, pwitem,
dc8c34
-                        PR_FALSE) != CKR_OK) 
dc8c34
-	{
dc8c34
-		SECITEM_FreeItem(result, PR_TRUE); 
dc8c34
-        err = SVRCORE_System_Error;
dc8c34
-        goto done;
dc8c34
-    }
dc8c34
-	SECITEM_FreeItem(result, PR_TRUE);
dc8c34
-	SECITEM_FreeItem(pwitem, PR_TRUE);
dc8c34
-	SECITEM_FreeItem(salt, PR_TRUE);
dc8c34
-	store->params = (SECItem *) PORT_Alloc(sizeof(SECItem));
dc8c34
-    if (store->params == NULL) 
dc8c34
-	{
dc8c34
-	  err = SVRCORE_System_Error;
dc8c34
-	  goto done;
dc8c34
-	}
dc8c34
-    store->params->type = store->mech->type;
dc8c34
-    store->params->data = (unsigned char *)PORT_Alloc(cryptoMech.ulParameterLen);
dc8c34
-    if (store->params->data == NULL) 
dc8c34
-	{
dc8c34
-	  err = SVRCORE_System_Error;
dc8c34
-	  goto done;
dc8c34
-	}
dc8c34
-    memcpy(store->params->data, (unsigned char *)cryptoMech.pParameter, cryptoMech.ulParameterLen);
dc8c34
-    store->params->len = cryptoMech.ulParameterLen;
dc8c34
-	PORT_Free(cryptoMech.pParameter);
dc8c34
-
dc8c34
-done:
dc8c34
-	slapi_ch_free((void**)&iv;;
dc8c34
-	return (err);
dc8c34
-}
dc8c34
-
dc8c34
-static SVRCOREError decryptPassword(struct pk11ContextStore *store, unsigned char *cipher, char **out, int len)
dc8c34
-{
dc8c34
-	SVRCOREError err = SVRCORE_Success;
dc8c34
-	unsigned char *plain = NULL;
dc8c34
-	unsigned char *cipher_with_padding = NULL;
dc8c34
-	SECStatus rv;
dc8c34
-	PK11Context *ctx = 0;
dc8c34
-	int outLen = 0;
dc8c34
-	int blocksize = 0;
dc8c34
-
dc8c34
-	blocksize = slapd_pk11_getBlockSize(store->mech->type, 0);
dc8c34
-	store->length = len;
dc8c34
-
dc8c34
-	/* store->length is the max. length of the returned clear text - 
dc8c34
-	   must be >= length of crypted bytes - also must be a multiple
dc8c34
-	   of blocksize */
dc8c34
-	if (blocksize != 0)
dc8c34
-	{
dc8c34
-		store->length += blocksize - (store->length % blocksize);
dc8c34
-	}
dc8c34
-
dc8c34
-	/* plain will hold the returned clear text */
dc8c34
-	plain = (unsigned char *)slapi_ch_calloc(sizeof(unsigned char),
dc8c34
-											 store->length+1);
dc8c34
-	if (!plain) 
dc8c34
-	{
dc8c34
-		err = SVRCORE_NoMemory_Error;
dc8c34
-		goto done;
dc8c34
-	}
dc8c34
-
dc8c34
-	/* create a buffer holding the original cipher bytes, padded with
dc8c34
-	   zeros to a multiple of blocksize - do not need +1 since buffer is not
dc8c34
-	   a string */
dc8c34
-	cipher_with_padding = (unsigned char *)slapi_ch_calloc(sizeof(unsigned char),
dc8c34
-														   store->length);
dc8c34
-	if (!cipher_with_padding)
dc8c34
-	{
dc8c34
-		err = SVRCORE_NoMemory_Error;
dc8c34
-		goto done;
dc8c34
-	}
dc8c34
-	memcpy(cipher_with_padding, cipher, len);
dc8c34
-
dc8c34
-	ctx = slapd_pk11_createContextBySymKey(store->mech->type, CKA_DECRYPT,
dc8c34
-	  store->key, store->params);
dc8c34
-	if (!ctx) 
dc8c34
-	{
dc8c34
-		err = SVRCORE_System_Error;
dc8c34
-		goto done;
dc8c34
-	}
dc8c34
-
dc8c34
-	/* warning - there is a purify UMR in the NSS des code - you may see it when the
dc8c34
-	   password is not a multiple of 8 bytes long */
dc8c34
-	rv = slapd_pk11_cipherOp(ctx, plain, &outLen, store->length,
dc8c34
-			cipher_with_padding, store->length);
dc8c34
-	if (rv)
dc8c34
-	{
dc8c34
-		err = SVRCORE_System_Error;
dc8c34
-	}
dc8c34
-
dc8c34
-	rv = slapd_pk11_finalize(ctx);
dc8c34
-	/* we must do the finalize, but we only want to set the err return
dc8c34
-	   code if it is not already set */
dc8c34
-	if (rv && (SVRCORE_Success == err))
dc8c34
-		err = SVRCORE_System_Error;
dc8c34
-
dc8c34
-done:
dc8c34
-	if (err == SVRCORE_Success)
dc8c34
-	{
dc8c34
-		*out = (char *)plain;
dc8c34
-	}
dc8c34
-	else
dc8c34
-	{
dc8c34
-		slapi_ch_free((void **)&plain);
dc8c34
-	}
dc8c34
-
dc8c34
-	slapi_ch_free((void **)&cipher_with_padding);
dc8c34
-	/* We should free the PK11Context... Something like : */
dc8c34
-	if (ctx) slapd_pk11_destroyContext(ctx, PR_TRUE);
dc8c34
-
dc8c34
-	return err;
dc8c34
-}
dc8c34
-
dc8c34
-static SVRCOREError cryptPassword(struct pk11ContextStore *store, char * clear, unsigned char **out)
dc8c34
-{
dc8c34
-	SVRCOREError err = SVRCORE_Success;
dc8c34
-	SECStatus rv;
dc8c34
-	PK11Context *ctx = 0;
dc8c34
-	int outLen = 0;
dc8c34
-	int blocksize = 0;
dc8c34
-	unsigned char *clear_with_padding = NULL; /* clear with padding up to blocksize */
dc8c34
-
dc8c34
-	blocksize = slapd_pk11_getBlockSize(store->mech->type, 0);
dc8c34
-	store->length = strlen(clear);
dc8c34
-
dc8c34
-	/* the size of the clear text buffer passed to the des encryption functions
dc8c34
-	   must be a multiple of blocksize (usually 8 bytes) - we allocate a buffer
dc8c34
-	   of this size, copy the clear text password into it, and pad the rest with
dc8c34
-	   zeros */
dc8c34
-	if (blocksize != 0)
dc8c34
-	{
dc8c34
-		store->length += blocksize - (store->length % blocksize);
dc8c34
-	}
dc8c34
-
dc8c34
-	/* store->crypt will hold the crypted password - it must be >= clear length */
dc8c34
-	/* store->crypt is freed in NSS; let's not use slapi_ch_calloc */
dc8c34
-	store->crypt = (unsigned char *)calloc(sizeof(unsigned char),
dc8c34
-													store->length+1);
dc8c34
-	if (!store->crypt) 
dc8c34
-	{
dc8c34
-		err = SVRCORE_NoMemory_Error;
dc8c34
-		goto done;
dc8c34
-	}
dc8c34
-
dc8c34
-	/* create a buffer big enough to hold the clear text password and padding */
dc8c34
-	clear_with_padding = (unsigned char *)slapi_ch_calloc(sizeof(unsigned char),
dc8c34
-														  store->length+1);
dc8c34
-	if (!clear_with_padding)
dc8c34
-	{
dc8c34
-		err = SVRCORE_NoMemory_Error;
dc8c34
-		goto done;
dc8c34
-	}
dc8c34
-	/* copy the clear text password into the buffer - the calloc insures the
dc8c34
-	   remainder is zero padded */
dc8c34
-	strcpy((char *)clear_with_padding, clear);
dc8c34
-
dc8c34
-	ctx = slapd_pk11_createContextBySymKey(store->mech->type, CKA_ENCRYPT,
dc8c34
-	  store->key, store->params);
dc8c34
-	if (!ctx) 
dc8c34
-	{
dc8c34
-		err = SVRCORE_System_Error;
dc8c34
-		goto done;
dc8c34
-	}
dc8c34
-
dc8c34
-	rv = slapd_pk11_cipherOp(ctx, store->crypt, &outLen, store->length,
dc8c34
-			clear_with_padding, store->length);
dc8c34
-	if (rv)
dc8c34
-	{
dc8c34
-		err = SVRCORE_System_Error;
dc8c34
-	}
dc8c34
-
dc8c34
-	rv = slapd_pk11_finalize(ctx);
dc8c34
-	/* we must do the finalize, but we only want to set the err return
dc8c34
-	   code if it is not already set */
dc8c34
-	if (rv && (SVRCORE_Success == err))
dc8c34
-		err = SVRCORE_System_Error;
dc8c34
-
dc8c34
-done:
dc8c34
-	if (err == SVRCORE_Success)
dc8c34
-		*out = store->crypt;
dc8c34
-
dc8c34
-	slapi_ch_free((void **)&clear_with_padding);
dc8c34
-	/* We should free the PK11Context... Something like : */
dc8c34
-	if (ctx) slapd_pk11_destroyContext(ctx, PR_TRUE);
dc8c34
-
dc8c34
-	return err;
dc8c34
-}
dc8c34
-
dc8c34
-/*
dc8c34
-  The UUID name based generator was broken on x86 platforms.  We use
dc8c34
-  this to generate the password encryption key.  During migration,
dc8c34
-  we have to fix this so we can use the fixed generator.  The env.
dc8c34
-  var USE_BROKEN_UUID tells the uuid generator to use the old
dc8c34
-  broken method to create the UUID.  That will allow us to decrypt
dc8c34
-  the password to the correct clear text, then we can turn off
dc8c34
-  the broken method and use the fixed method to encrypt the
dc8c34
-  password.
dc8c34
-*/
dc8c34
-char *
dc8c34
-migrateCredentials(char *oldpath, char *newpath, char *oldcred)
dc8c34
-{
dc8c34
-	static char *useBrokenUUID = "USE_BROKEN_UUID=1";
dc8c34
-	static char *disableBrokenUUID = "USE_BROKEN_UUID=0";
dc8c34
-	char *plain = NULL;
dc8c34
-	char *cipher = NULL;
dc8c34
-
dc8c34
-	init_des_plugin();
dc8c34
-
dc8c34
-	slapd_pk11_configurePKCS11(NULL, NULL, tokDes, ptokDes, NULL, NULL, NULL, NULL, 0, 0 );	
dc8c34
-	NSS_NoDB_Init(NULL);
dc8c34
-
dc8c34
-	if (getenv("MIGRATE_BROKEN_PWD")) {
dc8c34
-		putenv(useBrokenUUID);
dc8c34
-	}
dc8c34
-
dc8c34
-	if ( decode_path(oldcred, &plain, oldpath) == 0 )
dc8c34
-	{
dc8c34
-		if (getenv("MIGRATE_BROKEN_PWD")) {
dc8c34
-			putenv(disableBrokenUUID);
dc8c34
-		}
dc8c34
-		if ( encode_path(plain, &cipher, newpath) != 0 )
dc8c34
-			return(NULL);
dc8c34
-		else
dc8c34
-			return(cipher);
dc8c34
-	}
dc8c34
-	else
dc8c34
-		return(NULL);
dc8c34
-}
dc8c34
diff --git a/ldap/servers/plugins/rever/pbe.c b/ldap/servers/plugins/rever/pbe.c
dc8c34
new file mode 100644
dc8c34
index 0000000..abb8d1b
dc8c34
--- /dev/null
dc8c34
+++ b/ldap/servers/plugins/rever/pbe.c
dc8c34
@@ -0,0 +1,621 @@
dc8c34
+/** BEGIN COPYRIGHT BLOCK
dc8c34
+ * This Program is free software; you can redistribute it and/or modify it under
dc8c34
+ * the terms of the GNU General Public License as published by the Free Software
dc8c34
+ * Foundation; version 2 of the License.
dc8c34
+ * 
dc8c34
+ * This Program is distributed in the hope that it will be useful, but WITHOUT
dc8c34
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS
dc8c34
+ * FOR A PARTICULAR PURPOSE. See the GNU General Public License for more details.
dc8c34
+ * 
dc8c34
+ * You should have received a copy of the GNU General Public License along with
dc8c34
+ * this Program; if not, write to the Free Software Foundation, Inc., 59 Temple
dc8c34
+ * Place, Suite 330, Boston, MA 02111-1307 USA.
dc8c34
+ * 
dc8c34
+ * In addition, as a special exception, Red Hat, Inc. gives You the additional
dc8c34
+ * right to link the code of this Program with code not covered under the GNU
dc8c34
+ * General Public License ("Non-GPL Code") and to distribute linked combinations
dc8c34
+ * including the two, subject to the limitations in this paragraph. Non-GPL Code
dc8c34
+ * permitted under this exception must only link to the code of this Program
dc8c34
+ * through those well defined interfaces identified in the file named EXCEPTION
dc8c34
+ * found in the source code files (the "Approved Interfaces"). The files of
dc8c34
+ * Non-GPL Code may instantiate templates or use macros or inline functions from
dc8c34
+ * the Approved Interfaces without causing the resulting work to be covered by
dc8c34
+ * the GNU General Public License. Only Red Hat, Inc. may make changes or
dc8c34
+ * additions to the list of Approved Interfaces. You must obey the GNU General
dc8c34
+ * Public License in all respects for all of the Program code and other code used
dc8c34
+ * in conjunction with the Program except the Non-GPL Code covered by this
dc8c34
+ * exception. If you modify this file, you may extend this exception to your
dc8c34
+ * version of the file, but you are not obligated to do so. If you do not wish to
dc8c34
+ * provide this exception without modification, you must delete this exception
dc8c34
+ * statement from your version and license this file solely under the GPL without
dc8c34
+ * exception. 
dc8c34
+ * 
dc8c34
+ * 
dc8c34
+ * Copyright (C) 2001 Sun Microsystems, Inc. Used by permission.
dc8c34
+ * Copyright (C) 2015 Red Hat, Inc.
dc8c34
+ * All rights reserved.
dc8c34
+ * END COPYRIGHT BLOCK **/
dc8c34
+
dc8c34
+#ifdef HAVE_CONFIG_H
dc8c34
+#  include <config.h>
dc8c34
+#endif
dc8c34
+
dc8c34
+#include <string.h>
dc8c34
+#include <stdio.h>
dc8c34
+
dc8c34
+#include <ldap.h>
dc8c34
+#include <nspr.h> 
dc8c34
+#include <nss.h> 
dc8c34
+#include <secmod.h>
dc8c34
+/*
dc8c34
+#include <secasn1.h>
dc8c34
+#include <secpkcs7.h>
dc8c34
+*/
dc8c34
+#include <key.h>
dc8c34
+#include <certdb.h>
dc8c34
+#include <cert.h>
dc8c34
+#include <svrcore.h>
dc8c34
+#include <secmodt.h>
dc8c34
+#include <prtypes.h>
dc8c34
+#include <seccomon.h>
dc8c34
+#include <pk11func.h>
dc8c34
+
dc8c34
+#define NEED_TOK_PBE /* see slap.h - defines tokPBE and ptokPBE */
dc8c34
+#include "rever.h"
dc8c34
+#include <slap.h>
dc8c34
+#include "slapi-plugin.h"
dc8c34
+#include <uuid.h>
dc8c34
+#include <plbase64.h>
dc8c34
+
dc8c34
+struct pk11MechItem
dc8c34
+{
dc8c34
+    CK_MECHANISM_TYPE type;
dc8c34
+    const char *mechName;
dc8c34
+};
dc8c34
+
dc8c34
+static const struct pk11MechItem DESmech = { CKM_DES_CBC, "DES CBC encryption" };
dc8c34
+static const struct pk11MechItem AESmech = { CKM_AES_CBC, "AES CBC encryption" };
dc8c34
+static Slapi_Mutex *pbe_lock = NULL;
dc8c34
+
dc8c34
+struct pk11ContextStore
dc8c34
+{
dc8c34
+    PK11SlotInfo *slot;
dc8c34
+    const struct pk11MechItem *mech;
dc8c34
+    PK11SymKey *key;
dc8c34
+    SECItem *params;
dc8c34
+    int length;
dc8c34
+    unsigned char *crypt;
dc8c34
+    char *algid_base64;
dc8c34
+};
dc8c34
+
dc8c34
+/*
dc8c34
+ *  der_algid converting functions:
dc8c34
+ *
dc8c34
+ *  SECStatus ATOB_ConvertAsciiToItem(SECItem *binary_item, const char *ascii);
dc8c34
+ *  char *    BTOA_ConvertItemToAscii(SECItem *binary_item);
dc8c34
+ *
dc8c34
+ */
dc8c34
+
dc8c34
+static int encode_path(char *inPlain, char **outCipher, char *path, int mech);
dc8c34
+static int decode_path(char *inCipher, char **outPlain, char *path, int mech, char *algid);
dc8c34
+static SVRCOREError genKey(struct pk11ContextStore **out, const char *token, char *path, int mech, PRArenaPool *arena, char *algid);
dc8c34
+static SVRCOREError cryptPassword(struct pk11ContextStore *store, char * clear, unsigned char **out);
dc8c34
+static SVRCOREError decryptPassword(struct pk11ContextStore *store, unsigned char *cipher, char **out, int len);
dc8c34
+static void freePBE(struct pk11ContextStore *store);
dc8c34
+
dc8c34
+void
dc8c34
+init_pbe_plugin()
dc8c34
+{
dc8c34
+    if(!pbe_lock){
dc8c34
+        pbe_lock = slapi_new_mutex();
dc8c34
+    }
dc8c34
+}
dc8c34
+
dc8c34
+int
dc8c34
+encode(char *inPlain, char **outCipher, int mech)
dc8c34
+{
dc8c34
+    return encode_path(inPlain, outCipher, NULL, mech);
dc8c34
+}
dc8c34
+
dc8c34
+static int
dc8c34
+encode_path(char *inPlain, char **outCipher, char *path, int mech)
dc8c34
+{
dc8c34
+    struct pk11ContextStore *context = NULL;
dc8c34
+    PRArenaPool *arena = NULL;
dc8c34
+    unsigned char *cipher = NULL;
dc8c34
+    char *tmp = NULL;
dc8c34
+    char *base = NULL;
dc8c34
+    int len = 0;
dc8c34
+    int err;
dc8c34
+
dc8c34
+    *outCipher = NULL;
dc8c34
+    err = 1;
dc8c34
+
dc8c34
+    if ( genKey(&context, tokPBE, path, mech, arena, NULL) == SVRCORE_Success ){
dc8c34
+        /* Try an encryption */
dc8c34
+        if ( cryptPassword(context, inPlain, &cipher) == SVRCORE_Success ){
dc8c34
+            base = BTOA_DataToAscii(cipher, context->length);
dc8c34
+            if ( base != NULL ){
dc8c34
+                const char *scheme;
dc8c34
+                if (mech == AES_MECH){
dc8c34
+                    scheme = AES_REVER_SCHEME_NAME;
dc8c34
+                    len = 3 + strlen(scheme)+ strlen(context->algid_base64)  + strlen(base) + 1;
dc8c34
+                    if( (tmp = slapi_ch_malloc( len )) ){
dc8c34
+                    	/*
dc8c34
+                    	 * {AES-<BASE64_ALG_ID>}<ENCODED PASSWORD>
dc8c34
+                    	 */
dc8c34
+                        sprintf( tmp, "%c%s-%s%c%s", PWD_HASH_PREFIX_START, scheme,
dc8c34
+                                 context->algid_base64,PWD_HASH_PREFIX_END, base);
dc8c34
+                    }
dc8c34
+                } else {
dc8c34
+                    /* Old school DES */
dc8c34
+                    scheme = DES_REVER_SCHEME_NAME;
dc8c34
+                    if((tmp = slapi_ch_malloc( 3 + strlen(scheme) + strlen(base)))){
dc8c34
+                        sprintf( tmp, "%c%s%c%s", PWD_HASH_PREFIX_START, scheme,
dc8c34
+                                 PWD_HASH_PREFIX_END, base);
dc8c34
+                    }
dc8c34
+                }
dc8c34
+                if ( tmp != NULL ){
dc8c34
+                    *outCipher = tmp;
dc8c34
+                    tmp = NULL;
dc8c34
+                    err = 0;
dc8c34
+                }
dc8c34
+                PORT_Free(base);
dc8c34
+            }
dc8c34
+        }
dc8c34
+    }
dc8c34
+    freePBE(context);
dc8c34
+
dc8c34
+    return(err);
dc8c34
+}
dc8c34
+
dc8c34
+int
dc8c34
+decode(char *inCipher, char **outPlain, int mech, char *algid)
dc8c34
+{
dc8c34
+    return decode_path(inCipher, outPlain, NULL, mech, algid);
dc8c34
+}
dc8c34
+
dc8c34
+
dc8c34
+static int
dc8c34
+decode_path(char *inCipher, char **outPlain, char *path, int mech, char *algid)
dc8c34
+{
dc8c34
+    struct pk11ContextStore *context = NULL;
dc8c34
+    PRArenaPool *arena = NULL;
dc8c34
+    unsigned char *base = NULL;
dc8c34
+    char *plain = NULL;
dc8c34
+    int err;
dc8c34
+    int len = 0;
dc8c34
+
dc8c34
+    *outPlain = NULL;
dc8c34
+    err = 1;
dc8c34
+
dc8c34
+    if ( genKey(&context, tokPBE, path, mech, arena, algid) == SVRCORE_Success ){
dc8c34
+        /* it seems that there is memory leak in that function: bug 400170 */
dc8c34
+        base = ATOB_AsciiToData(inCipher, (unsigned int*)&len;;
dc8c34
+        if ( base != NULL ){
dc8c34
+            if ( decryptPassword(context, base, &plain, len) == SVRCORE_Success ){
dc8c34
+                *outPlain = plain;
dc8c34
+                err = 0;
dc8c34
+            }
dc8c34
+        }
dc8c34
+    }
dc8c34
+
dc8c34
+    slapi_ch_free_string(&algid);
dc8c34
+    PORT_Free(base);
dc8c34
+    PORT_FreeArena(arena, PR_TRUE);
dc8c34
+    freePBE(context);
dc8c34
+
dc8c34
+    return(err);
dc8c34
+}
dc8c34
+
dc8c34
+static void
dc8c34
+freePBE(struct pk11ContextStore *store)
dc8c34
+{
dc8c34
+    if (store){
dc8c34
+        if (store->slot)
dc8c34
+            slapd_pk11_freeSlot(store->slot);
dc8c34
+        if (store->key)
dc8c34
+            slapd_pk11_freeSymKey(store->key);
dc8c34
+        if (store->params)
dc8c34
+            SECITEM_FreeItem(store->params, PR_TRUE);
dc8c34
+        slapi_ch_free((void **)&store->crypt);
dc8c34
+        slapi_ch_free_string(&store->algid_base64);
dc8c34
+        slapi_ch_free((void **)&store);
dc8c34
+    }
dc8c34
+}
dc8c34
+
dc8c34
+static SVRCOREError
dc8c34
+genKey(struct pk11ContextStore **out, const char *token, char *path, int mech, PRArenaPool *arena, char *alg)
dc8c34
+{
dc8c34
+    SVRCOREError err = SVRCORE_Success;
dc8c34
+    struct pk11ContextStore *store = NULL;
dc8c34
+    SECItem *pwitem = NULL;
dc8c34
+    SECItem *result = NULL;
dc8c34
+    SECItem *salt = NULL;
dc8c34
+    SECItem der_algid;
dc8c34
+    SECAlgorithmID *algid = NULL;
dc8c34
+    SECOidTag algoid;
dc8c34
+    CK_MECHANISM pbeMech;
dc8c34
+    CK_MECHANISM cryptoMech;
dc8c34
+    SECAlgorithmID my_algid;
dc8c34
+    char *configdir = NULL;
dc8c34
+    char *der_ascii = NULL;
dc8c34
+    char *iv = NULL;
dc8c34
+    int free_it = 0;
dc8c34
+
dc8c34
+    arena = PORT_NewArena(DER_DEFAULT_CHUNKSIZE);
dc8c34
+
dc8c34
+    store = (struct pk11ContextStore*)slapi_ch_calloc(1, sizeof(*store));
dc8c34
+    if (store == NULL){
dc8c34
+        err = SVRCORE_NoMemory_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+    *out = store;
dc8c34
+
dc8c34
+    /* Use the tokenName to find a PKCS11 slot */
dc8c34
+    store->slot = slapd_pk11_findSlotByName((char *)token);
dc8c34
+    if (store->slot == NULL){
dc8c34
+        err = SVRCORE_NoSuchToken_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+
dc8c34
+    /* Generate a key and parameters to do the encryption */
dc8c34
+    if(mech == AES_MECH){
dc8c34
+        store->mech = &AESmech;
dc8c34
+        algoid = SEC_OID_AES_256_CBC;
dc8c34
+    } else {
dc8c34
+        store->mech = &DESmech;
dc8c34
+        algoid = SEC_OID_PKCS5_PBE_WITH_MD2_AND_DES_CBC;
dc8c34
+    }
dc8c34
+
dc8c34
+    /* Generate a unique id, used as salt for the key generation */
dc8c34
+    if ( path == NULL ){
dc8c34
+        configdir = config_get_configdir();
dc8c34
+        if ( configdir == NULL ){
dc8c34
+            err = SVRCORE_System_Error;
dc8c34
+            goto done;
dc8c34
+        }
dc8c34
+    } else {
dc8c34
+        configdir = slapi_ch_strdup(path);
dc8c34
+    }
dc8c34
+    if ( slapi_uniqueIDGenerateFromNameString (&iv, NULL, configdir, strlen(configdir)) != UID_SUCCESS ){
dc8c34
+        err = SVRCORE_System_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+
dc8c34
+    pwitem = (SECItem *) PORT_Alloc(sizeof(SECItem));
dc8c34
+    if (pwitem == NULL){
dc8c34
+        err = SVRCORE_NoMemory_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+    pwitem->type = siBuffer;
dc8c34
+    pwitem->data = (unsigned char *)PORT_Alloc(strlen(iv)+1);
dc8c34
+    if (pwitem->data == NULL){
dc8c34
+        err = SVRCORE_NoMemory_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+    strcpy((char*)pwitem->data, iv);
dc8c34
+    pwitem->len = strlen(iv) + 1;
dc8c34
+
dc8c34
+    salt = (SECItem *) PORT_Alloc(sizeof(SECItem));
dc8c34
+    if (salt == NULL){
dc8c34
+        err = SVRCORE_NoMemory_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+    salt->type = siBuffer;
dc8c34
+    salt->data = (unsigned char *)PORT_Alloc(strlen(iv)+1);
dc8c34
+    if ( salt->data == NULL ){
dc8c34
+        err = SVRCORE_NoMemory_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+    strcpy((char*)salt->data, iv);        
dc8c34
+    salt->len = strlen(iv) + 1;
dc8c34
+
dc8c34
+    PORT_Memset(&der_algid, 0, sizeof(der_algid));
dc8c34
+    if(!alg){
dc8c34
+    	/*
dc8c34
+    	 * This is DES, or we are encoding AES - the process is the same.
dc8c34
+    	 */
dc8c34
+    	algid = slapd_pk11_createPBEAlgorithmID(algoid, 2, salt);
dc8c34
+    	free_it = 1; /* we need to free this algid */
dc8c34
+
dc8c34
+    	/*
dc8c34
+    	 * The following is only need for AES - we need to store
dc8c34
+    	 * algid for future decodings(unlike with DES).  So convert
dc8c34
+    	 * algid to its DER encoding.  Then convert the DER to ascii,
dc8c34
+    	 * and finally convert the DER ascii to base64 so we can store
dc8c34
+    	 * it in the cipher prefix.
dc8c34
+    	 */
dc8c34
+    	SEC_ASN1EncodeItem(arena, &der_algid, algid, SEC_ASN1_GET(SECOID_AlgorithmIDTemplate));
dc8c34
+    	der_ascii = BTOA_ConvertItemToAscii(&der_algid);
dc8c34
+    	store->algid_base64 = PL_Base64Encode(der_ascii,strlen(der_ascii), NULL);
dc8c34
+    	slapi_ch_free_string(&der_ascii);
dc8c34
+    } else {
dc8c34
+    	/*
dc8c34
+    	 * We are decoding AES - use the supplied algid
dc8c34
+    	 */
dc8c34
+    	PORT_Memset(&my_algid, 0, sizeof(my_algid));
dc8c34
+
dc8c34
+    	/* Decode the base64 der encoding */
dc8c34
+    	der_ascii =  PL_Base64Decode(alg, strlen(alg), NULL);
dc8c34
+
dc8c34
+    	/* convert the der ascii to the SEC item */
dc8c34
+    	ATOB_ConvertAsciiToItem(&der_algid, der_ascii);
dc8c34
+    	SEC_ASN1DecodeItem(arena, &my_algid, SEC_ASN1_GET(SECOID_AlgorithmIDTemplate), &der_algid);
dc8c34
+    	SECITEM_FreeItem(&der_algid, PR_FALSE);
dc8c34
+    	algid = &my_algid;
dc8c34
+    	slapi_ch_free_string(&der_ascii);
dc8c34
+    }
dc8c34
+
dc8c34
+    slapi_lock_mutex(pbe_lock);
dc8c34
+    store->key = slapd_pk11_pbeKeyGen(store->slot, algid, pwitem, 0, 0);
dc8c34
+    if (store->key == 0){
dc8c34
+        slapi_unlock_mutex(pbe_lock);
dc8c34
+        err = SVRCORE_System_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+
dc8c34
+    slapi_unlock_mutex(pbe_lock);
dc8c34
+
dc8c34
+    if(mech == AES_MECH)
dc8c34
+    {
dc8c34
+        cryptoMech.mechanism = PK11_GetPBECryptoMechanism(algid, &store->params, pwitem);
dc8c34
+        if (cryptoMech.mechanism == CKM_INVALID_MECHANISM) {
dc8c34
+            err = SVRCORE_System_Error;
dc8c34
+            goto done;
dc8c34
+        }
dc8c34
+    }
dc8c34
+    else
dc8c34
+    {
dc8c34
+        /* DES */
dc8c34
+        pbeMech.mechanism = slapd_pk11_algtagToMechanism(algoid);
dc8c34
+        result = slapd_pk11_paramFromAlgid(algid);
dc8c34
+        if(result){
dc8c34
+            pbeMech.pParameter = result->data;
dc8c34
+            pbeMech.ulParameterLen = result->len;
dc8c34
+        }
dc8c34
+        if(slapd_pk11_mapPBEMechanismToCryptoMechanism(&pbeMech, &cryptoMech, pwitem,
dc8c34
+                            PR_FALSE) != CKR_OK){
dc8c34
+            err = SVRCORE_System_Error;
dc8c34
+            goto done;
dc8c34
+        }
dc8c34
+
dc8c34
+        store->params = (SECItem *) PORT_Alloc(sizeof(SECItem));
dc8c34
+        if (store->params == NULL){
dc8c34
+            err = SVRCORE_System_Error;
dc8c34
+            goto done;
dc8c34
+        }
dc8c34
+        store->params->type = store->mech->type;
dc8c34
+        store->params->data = (unsigned char *)PORT_Alloc(cryptoMech.ulParameterLen);
dc8c34
+        if (store->params->data == NULL){
dc8c34
+            err = SVRCORE_System_Error;
dc8c34
+            goto done;
dc8c34
+        }
dc8c34
+        memcpy(store->params->data, (unsigned char *)cryptoMech.pParameter, cryptoMech.ulParameterLen);
dc8c34
+        store->params->len = cryptoMech.ulParameterLen;
dc8c34
+        PORT_Free(cryptoMech.pParameter);
dc8c34
+    }
dc8c34
+
dc8c34
+done:
dc8c34
+    SECITEM_FreeItem(result, PR_TRUE);
dc8c34
+    SECITEM_FreeItem(pwitem, PR_TRUE);
dc8c34
+    SECITEM_FreeItem(salt, PR_TRUE);
dc8c34
+    if(free_it){
dc8c34
+    	secoid_destroyAlgorithmID(algid, PR_TRUE);
dc8c34
+    }
dc8c34
+    slapi_ch_free_string(&configdir);
dc8c34
+    slapi_ch_free_string(&iv;;
dc8c34
+    if (arena) {
dc8c34
+        PORT_FreeArena(arena, PR_TRUE);
dc8c34
+    }
dc8c34
+    return (err);
dc8c34
+}
dc8c34
+
dc8c34
+static SVRCOREError
dc8c34
+decryptPassword(struct pk11ContextStore *store, unsigned char *cipher, char **out, int len)
dc8c34
+{
dc8c34
+    SVRCOREError err = SVRCORE_Success;
dc8c34
+    unsigned char *plain = NULL;
dc8c34
+    unsigned char *cipher_with_padding = NULL;
dc8c34
+    SECStatus rv;
dc8c34
+    PK11Context *ctx = NULL;
dc8c34
+    int outLen = 0;
dc8c34
+    int blocksize = 0;
dc8c34
+
dc8c34
+    blocksize = slapd_pk11_getBlockSize(store->mech->type, 0);
dc8c34
+    store->length = len;
dc8c34
+
dc8c34
+    /*
dc8c34
+     * store->length is the max. length of the returned clear text -
dc8c34
+     * must be >= length of crypted bytes - also must be a multiple
dc8c34
+     * of blocksize
dc8c34
+     */
dc8c34
+    if (blocksize != 0){
dc8c34
+        store->length += blocksize - (store->length % blocksize);
dc8c34
+    }
dc8c34
+
dc8c34
+    /* plain will hold the returned clear text */
dc8c34
+    plain = (unsigned char *)slapi_ch_calloc(sizeof(unsigned char),
dc8c34
+                                             store->length+1);
dc8c34
+    if (!plain){
dc8c34
+        err = SVRCORE_NoMemory_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+
dc8c34
+    /*
dc8c34
+     * create a buffer holding the original cipher bytes, padded with
dc8c34
+     * zeros to a multiple of blocksize - do not need +1 since buffer is not
dc8c34
+     * a string
dc8c34
+     */
dc8c34
+    cipher_with_padding = (unsigned char *)slapi_ch_calloc(sizeof(unsigned char),
dc8c34
+                                                           store->length);
dc8c34
+    if (!cipher_with_padding){
dc8c34
+        err = SVRCORE_NoMemory_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+    memcpy(cipher_with_padding, cipher, len);
dc8c34
+
dc8c34
+    ctx = slapd_pk11_createContextBySymKey(store->mech->type, CKA_DECRYPT,
dc8c34
+      store->key, store->params);
dc8c34
+    if (!ctx) {
dc8c34
+        err = SVRCORE_System_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+
dc8c34
+    /*
dc8c34
+     * Warning - there is a purify UMR in the NSS des code - you may see it when the
dc8c34
+     * password is not a multiple of 8 bytes long
dc8c34
+     */
dc8c34
+    rv = slapd_pk11_cipherOp(ctx, plain, &outLen, store->length,
dc8c34
+            cipher_with_padding, store->length);
dc8c34
+    if (rv){
dc8c34
+        err = SVRCORE_System_Error;
dc8c34
+    }
dc8c34
+
dc8c34
+    rv = slapd_pk11_finalize(ctx);
dc8c34
+    /*
dc8c34
+     * We must do the finalize, but we only want to set the err return
dc8c34
+     * code if it is not already set
dc8c34
+     */
dc8c34
+    if (rv && (SVRCORE_Success == err))
dc8c34
+        err = SVRCORE_System_Error;
dc8c34
+
dc8c34
+done:
dc8c34
+    if (err == SVRCORE_Success){
dc8c34
+        *out = (char *)plain;
dc8c34
+    } else {
dc8c34
+        slapi_ch_free((void **)&plain);
dc8c34
+    }
dc8c34
+
dc8c34
+    slapi_ch_free((void **)&cipher_with_padding);
dc8c34
+    /* We should free the PK11Context... Something like : */
dc8c34
+    if (ctx){
dc8c34
+        slapd_pk11_destroyContext(ctx, PR_TRUE);
dc8c34
+    }
dc8c34
+
dc8c34
+    return err;
dc8c34
+}
dc8c34
+
dc8c34
+static SVRCOREError
dc8c34
+cryptPassword(struct pk11ContextStore *store, char * clear, unsigned char **out)
dc8c34
+{
dc8c34
+    SVRCOREError err = SVRCORE_Success;
dc8c34
+    SECStatus rv;
dc8c34
+    PK11Context *ctx = NULL;
dc8c34
+    unsigned char *clear_with_padding = NULL; /* clear with padding up to blocksize */
dc8c34
+    int blocksize = 0;
dc8c34
+    int outLen = 0;
dc8c34
+
dc8c34
+    blocksize = slapd_pk11_getBlockSize(store->mech->type, 0);
dc8c34
+    store->length = strlen(clear);
dc8c34
+
dc8c34
+    /*
dc8c34
+     * The size of the clear text buffer passed to the encryption functions
dc8c34
+     * must be a multiple of blocksize (usually 8 bytes) - we allocate a buffer
dc8c34
+     * of this size, copy the clear text password into it, and pad the rest with
dc8c34
+     * zeros.
dc8c34
+     */
dc8c34
+    if (blocksize != 0){
dc8c34
+        store->length += blocksize - (store->length % blocksize);
dc8c34
+    }
dc8c34
+
dc8c34
+    /*
dc8c34
+     * store->crypt will hold the crypted password - it must be >= clear length
dc8c34
+     * store->crypt is freed in NSS; let's not use slapi_ch_calloc
dc8c34
+     */
dc8c34
+    store->crypt = (unsigned char *)calloc(sizeof(unsigned char),
dc8c34
+                                                    store->length+1);
dc8c34
+    if (!store->crypt) {
dc8c34
+        err = SVRCORE_NoMemory_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+
dc8c34
+    /* Create a buffer big enough to hold the clear text password and padding */
dc8c34
+    clear_with_padding = (unsigned char *)slapi_ch_calloc(sizeof(unsigned char),
dc8c34
+                                                          store->length+1);
dc8c34
+    if (!clear_with_padding){
dc8c34
+        err = SVRCORE_NoMemory_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+    /*
dc8c34
+     * Copy the clear text password into the buffer - the calloc insures the
dc8c34
+     * remainder is zero padded .
dc8c34
+     */
dc8c34
+    strcpy((char *)clear_with_padding, clear);
dc8c34
+
dc8c34
+    ctx = slapd_pk11_createContextBySymKey(store->mech->type, CKA_ENCRYPT,
dc8c34
+      store->key, store->params);
dc8c34
+    if (!ctx) {
dc8c34
+        err = SVRCORE_System_Error;
dc8c34
+        goto done;
dc8c34
+    }
dc8c34
+
dc8c34
+    rv = slapd_pk11_cipherOp(ctx, store->crypt, &outLen, store->length,
dc8c34
+            clear_with_padding, store->length);
dc8c34
+    if (rv) {
dc8c34
+        err = SVRCORE_System_Error;
dc8c34
+    }
dc8c34
+
dc8c34
+    rv = slapd_pk11_finalize(ctx);
dc8c34
+    /*
dc8c34
+     * We must do the finalize, but we only want to set the err return
dc8c34
+     * code if it is not already set
dc8c34
+     */
dc8c34
+    if (rv && (SVRCORE_Success == err)){
dc8c34
+        err = SVRCORE_System_Error;
dc8c34
+    }
dc8c34
+
dc8c34
+done:
dc8c34
+    if (err == SVRCORE_Success){
dc8c34
+        *out = store->crypt;
dc8c34
+    }
dc8c34
+
dc8c34
+    slapi_ch_free((void **)&clear_with_padding);
dc8c34
+    /* We should free the PK11Context... Something like : */
dc8c34
+    if (ctx){
dc8c34
+        slapd_pk11_destroyContext(ctx, PR_TRUE);
dc8c34
+    }
dc8c34
+
dc8c34
+    return err;
dc8c34
+}
dc8c34
+
dc8c34
+/*
dc8c34
+ * The UUID name based generator was broken on x86 platforms.  We use
dc8c34
+ * this to generate the password encryption key.  During migration,
dc8c34
+ * we have to fix this so we can use the fixed generator.  The env.
dc8c34
+ * var USE_BROKEN_UUID tells the uuid generator to use the old
dc8c34
+ * broken method to create the UUID.  That will allow us to decrypt
dc8c34
+ * the password to the correct clear text, then we can turn off
dc8c34
+ * the broken method and use the fixed method to encrypt the
dc8c34
+ * password.
dc8c34
+ */
dc8c34
+char *
dc8c34
+migrateCredentials(char *oldpath, char *newpath, char *oldcred)
dc8c34
+{
dc8c34
+    static char *useBrokenUUID = "USE_BROKEN_UUID=1";
dc8c34
+    static char *disableBrokenUUID = "USE_BROKEN_UUID=0";
dc8c34
+    char *plain = NULL;
dc8c34
+    char *cipher = NULL;
dc8c34
+
dc8c34
+    init_pbe_plugin();
dc8c34
+
dc8c34
+    slapd_pk11_configurePKCS11(NULL, NULL, tokPBE, ptokPBE, NULL, NULL, NULL, NULL, 0, 0 );
dc8c34
+    NSS_NoDB_Init(NULL);
dc8c34
+
dc8c34
+    if (getenv("MIGRATE_BROKEN_PWD")) {
dc8c34
+        putenv(useBrokenUUID);
dc8c34
+    }
dc8c34
+
dc8c34
+    if ( decode_path(oldcred, &plain, oldpath, DES_MECH, NULL) == 0 ){
dc8c34
+        if (getenv("MIGRATE_BROKEN_PWD")) {
dc8c34
+            putenv(disableBrokenUUID);
dc8c34
+        }
dc8c34
+        if ( encode_path(plain, &cipher, newpath, AES_MECH) != 0 ){
dc8c34
+            return(NULL);
dc8c34
+        } else {
dc8c34
+            return(cipher);
dc8c34
+        }
dc8c34
+    } else {
dc8c34
+        return(NULL);
dc8c34
+    }
dc8c34
+}
dc8c34
diff --git a/ldap/servers/plugins/rever/rever.c b/ldap/servers/plugins/rever/rever.c
dc8c34
index 9d7e82d..51d602f 100644
dc8c34
--- a/ldap/servers/plugins/rever/rever.c
dc8c34
+++ b/ldap/servers/plugins/rever/rever.c
dc8c34
@@ -43,25 +43,92 @@
dc8c34
 #include <stdio.h>
dc8c34
 #include <string.h>
dc8c34
 #include <sys/types.h>
dc8c34
-
dc8c34
 #include "rever.h"
dc8c34
 
dc8c34
-static Slapi_PluginDesc pdesc = { "des-storage-scheme", VENDOR, DS_PACKAGE_VERSION, "DES storage scheme plugin" };
dc8c34
+static Slapi_PluginDesc pdesc_aes = { "aes-storage-scheme", VENDOR, DS_PACKAGE_VERSION, "AES storage scheme plugin" };
dc8c34
+static Slapi_PluginDesc pdesc_des = { "des-storage-scheme", VENDOR, DS_PACKAGE_VERSION, "DES storage scheme plugin" };
dc8c34
+
dc8c34
 
dc8c34
 static char *plugin_name = "ReverStoragePlugin";
dc8c34
 
dc8c34
+#define AES_MECH 1
dc8c34
+#define DES_MECH 2
dc8c34
+
dc8c34
+int
dc8c34
+aes_cmp( char *userpwd, char *dbpwd )
dc8c34
+{
dc8c34
+	char *cipher = NULL;
dc8c34
+	int rc = 0;
dc8c34
+
dc8c34
+	if ( encode(userpwd, &cipher, AES_MECH) != 0 ){
dc8c34
+		rc = 1;
dc8c34
+	} else {
dc8c34
+		rc = strcmp(cipher, dbpwd);
dc8c34
+	}
dc8c34
+	slapi_ch_free_string(&cipher);
dc8c34
+
dc8c34
+	return rc;
dc8c34
+}
dc8c34
+
dc8c34
+char *
dc8c34
+aes_enc( char *pwd )
dc8c34
+{
dc8c34
+	char *cipher = NULL;
dc8c34
+
dc8c34
+	if ( encode(pwd, &cipher, AES_MECH) != 0 ){
dc8c34
+		return(NULL);
dc8c34
+	} else {
dc8c34
+		return( cipher );
dc8c34
+	}
dc8c34
+}
dc8c34
+
dc8c34
+char *
dc8c34
+aes_dec( char *pwd, char *alg )
dc8c34
+{
dc8c34
+	char *plain = NULL;
dc8c34
+
dc8c34
+	if ( decode(pwd, &plain, AES_MECH, alg) != 0 ){
dc8c34
+		return(NULL);
dc8c34
+	} else {
dc8c34
+		return( plain );
dc8c34
+	}
dc8c34
+}
dc8c34
+
dc8c34
+int
dc8c34
+aes_init( Slapi_PBlock *pb)
dc8c34
+{
dc8c34
+       char *name = slapi_ch_strdup(AES_REVER_SCHEME_NAME);
dc8c34
+       int rc;
dc8c34
+
dc8c34
+       slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "=> aes_init\n" );
dc8c34
+
dc8c34
+       rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, (void *) SLAPI_PLUGIN_VERSION_01 );
dc8c34
+       rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&pdesc_aes );
dc8c34
+       rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN, (void *) aes_enc);
dc8c34
+       rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN, (void *) aes_cmp );
dc8c34
+       rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_DEC_FN, (void *) aes_dec );
dc8c34
+       rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_NAME, name );
dc8c34
+
dc8c34
+       init_pbe_plugin();
dc8c34
+
dc8c34
+       slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "<= aes_init %d\n", rc );
dc8c34
+
dc8c34
+       return( rc );
dc8c34
+}
dc8c34
+
dc8c34
 int
dc8c34
 des_cmp( char *userpwd, char *dbpwd )
dc8c34
 {
dc8c34
 	char *cipher = NULL;
dc8c34
 	int rc = 0;
dc8c34
 
dc8c34
-	if ( encode(userpwd, &cipher) != 0 )
dc8c34
+	if ( encode(userpwd, &cipher, DES_MECH) != 0 ){
dc8c34
 		rc = 1;
dc8c34
-	else
dc8c34
+	} else {
dc8c34
 		rc = strcmp(cipher, dbpwd);
dc8c34
+	}
dc8c34
+	slapi_ch_free_string(&cipher);
dc8c34
 
dc8c34
-	slapi_ch_free((void**)&cipher);
dc8c34
 	return rc;
dc8c34
 }
dc8c34
 
dc8c34
@@ -70,10 +137,11 @@ des_enc( char *pwd )
dc8c34
 {
dc8c34
 	char *cipher = NULL;
dc8c34
 	
dc8c34
-	if ( encode(pwd, &cipher) != 0 )
dc8c34
+	if ( encode(pwd, &cipher, DES_MECH ) != 0 ){
dc8c34
 		return(NULL);
dc8c34
-	else
dc8c34
+	} else {
dc8c34
 		return( cipher );
dc8c34
+	}
dc8c34
 }
dc8c34
 
dc8c34
 char *
dc8c34
@@ -81,37 +149,31 @@ des_dec( char *pwd )
dc8c34
 {
dc8c34
 	char *plain = NULL;
dc8c34
 	
dc8c34
-	if ( decode(pwd, &plain) != 0 )
dc8c34
+	if ( decode(pwd, &plain, DES_MECH, NULL) != 0 ){
dc8c34
 		return(NULL);
dc8c34
-	else
dc8c34
+	} else {
dc8c34
 		return( plain );
dc8c34
+	}
dc8c34
 }
dc8c34
 
dc8c34
 int
dc8c34
 des_init( Slapi_PBlock *pb )
dc8c34
 {
dc8c34
+	char *name = slapi_ch_strdup(DES_REVER_SCHEME_NAME);
dc8c34
 	int	rc;
dc8c34
-	char *name;
dc8c34
 
dc8c34
 	slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "=> des_init\n" );
dc8c34
 
dc8c34
-	rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION,
dc8c34
-	    (void *) SLAPI_PLUGIN_VERSION_01 );
dc8c34
-	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION,
dc8c34
-	    (void *)&pdesc );
dc8c34
-	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN,
dc8c34
-	    (void *) des_enc);
dc8c34
-	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN,
dc8c34
-	    (void *) des_cmp );
dc8c34
-	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_DEC_FN,
dc8c34
-	    (void *) des_dec );
dc8c34
-	name = slapi_ch_strdup(REVER_SCHEME_NAME);
dc8c34
-	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_NAME,
dc8c34
-	    name );
dc8c34
-
dc8c34
-	init_des_plugin();
dc8c34
-
dc8c34
-	slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "<= des_init %d\n\n", rc );
dc8c34
+	rc = slapi_pblock_set( pb, SLAPI_PLUGIN_VERSION, (void *) SLAPI_PLUGIN_VERSION_01 );
dc8c34
+	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_DESCRIPTION, (void *)&pdesc_des );
dc8c34
+	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_ENC_FN, (void *) des_enc);
dc8c34
+	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_CMP_FN, (void *) des_cmp );
dc8c34
+	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_DEC_FN, (void *) des_dec );
dc8c34
+	rc |= slapi_pblock_set( pb, SLAPI_PLUGIN_PWD_STORAGE_SCHEME_NAME, name );
dc8c34
+
dc8c34
+	init_pbe_plugin();
dc8c34
+
dc8c34
+	slapi_log_error( SLAPI_LOG_PLUGIN, plugin_name, "<= des_init %d\n", rc );
dc8c34
 
dc8c34
 	return( rc );
dc8c34
 }
dc8c34
diff --git a/ldap/servers/plugins/rever/rever.h b/ldap/servers/plugins/rever/rever.h
dc8c34
index 8ea6279..9edddd8 100644
dc8c34
--- a/ldap/servers/plugins/rever/rever.h
dc8c34
+++ b/ldap/servers/plugins/rever/rever.h
dc8c34
@@ -49,7 +49,10 @@
dc8c34
 #include "slap.h"
dc8c34
 #include "ldaplog.h"
dc8c34
 
dc8c34
-#define REVER_SCHEME_NAME	"DES"
dc8c34
+#define AES_MECH 1
dc8c34
+#define DES_MECH 2
dc8c34
+#define AES_REVER_SCHEME_NAME	"AES"
dc8c34
+#define DES_REVER_SCHEME_NAME	"DES"
dc8c34
 #define PWD_HASH_PREFIX_START   '{'
dc8c34
 #define PWD_HASH_PREFIX_END '}'
dc8c34
 
dc8c34
@@ -58,10 +61,10 @@ int rever_cmp( char *userpwd, char *dbpwd );
dc8c34
 char *rever_enc( char *pwd );
dc8c34
 char *rever_dec( char *pwd );
dc8c34
 int rever_init( Slapi_PBlock *pb );
dc8c34
-void init_des_plugin();
dc8c34
+void init_pbe_plugin();
dc8c34
 
dc8c34
-int encode(char *inPlain, char ** outCipher);
dc8c34
-int decode(char *inCipher, char **outPlain);
dc8c34
+int encode(char *inPlain, char **outCipher, int mech);
dc8c34
+int decode(char *inCipher, char **outPlain, int mech, char *algid);
dc8c34
 
dc8c34
 char *migrateCredentials(char *oldpath, char *newpath, char *oldcred);
dc8c34
 typedef char *(*migrate_fn_type)(char *, char *, char *);
dc8c34
diff --git a/ldap/servers/slapd/daemon.c b/ldap/servers/slapd/daemon.c
dc8c34
index b34358d..56d150e 100644
dc8c34
--- a/ldap/servers/slapd/daemon.c
dc8c34
+++ b/ldap/servers/slapd/daemon.c
dc8c34
@@ -933,6 +933,155 @@ handle_listeners(Connection_Table *ct, listener_info *listener_idxs, int n_liste
dc8c34
 	return;
dc8c34
 }
dc8c34
 
dc8c34
+/*
dc8c34
+ * Convert any pre-existing DES passwords to AES.
dc8c34
+ *
dc8c34
+ * Grab the "password" attributes and search all the backends for
dc8c34
+ * these attributes and convert them to AES if they are DES encoded.
dc8c34
+ */
dc8c34
+static void
dc8c34
+convert_pbe_des_to_aes()
dc8c34
+{
dc8c34
+    Slapi_PBlock *pb = NULL;
dc8c34
+    Slapi_Entry **entries = NULL;
dc8c34
+    struct slapdplugin *plugin = NULL;
dc8c34
+    char **attrs = NULL;
dc8c34
+    char *val = NULL;
dc8c34
+    int converted_des_passwd = 0;
dc8c34
+    int result = -1;
dc8c34
+    int have_aes = 0;
dc8c34
+    int have_des = 0;
dc8c34
+    int i = 0, ii = 0;
dc8c34
+
dc8c34
+    /*
dc8c34
+     * Check that AES plugin is enabled, and grab all the unique
dc8c34
+     * password attributes.
dc8c34
+     */
dc8c34
+    for ( plugin = get_plugin_list(PLUGIN_LIST_REVER_PWD_STORAGE_SCHEME);
dc8c34
+          plugin != NULL;
dc8c34
+          plugin = plugin->plg_next )
dc8c34
+    {
dc8c34
+        char *arg = NULL;
dc8c34
+
dc8c34
+        if(strcasecmp(plugin->plg_name, "AES") == 0){
dc8c34
+            /* We have the AES plugin, and its enabled */
dc8c34
+            have_aes = 1;
dc8c34
+        }
dc8c34
+        if(strcasecmp(plugin->plg_name, "DES") == 0){
dc8c34
+            /* We have the DES plugin, and its enabled */
dc8c34
+            have_des = 1;
dc8c34
+        }
dc8c34
+        /* Gather all the unique password attributes from all the PBE plugins */
dc8c34
+        for ( i = 0, arg = plugin->plg_argv[i];
dc8c34
+              i < plugin->plg_argc;
dc8c34
+              arg = plugin->plg_argv[++i] )
dc8c34
+        {
dc8c34
+            if(charray_inlist(attrs, arg)){
dc8c34
+                continue;
dc8c34
+            }
dc8c34
+            charray_add(&attrs, slapi_ch_strdup(arg));
dc8c34
+        }
dc8c34
+    }
dc8c34
+
dc8c34
+    if(have_aes && have_des){
dc8c34
+        /*
dc8c34
+         * Find any entries in cn=config that contain DES passwords and convert
dc8c34
+         * them to AES
dc8c34
+         */
dc8c34
+        slapi_log_error(SLAPI_LOG_HOUSE,  "convert_pbe_des_to_aes",
dc8c34
+                "Converting DES passwords to AES...\n");
dc8c34
+
dc8c34
+        for (i = 0; attrs && attrs[i]; i++){
dc8c34
+            char *filter = PR_smprintf("%s=*", attrs[i]);
dc8c34
+
dc8c34
+            pb = slapi_pblock_new();
dc8c34
+            slapi_search_internal_set_pb(pb, "cn=config",
dc8c34
+                LDAP_SCOPE_SUBTREE, filter, NULL, 0, NULL, NULL,
dc8c34
+                (void *)plugin_get_default_component_id(),
dc8c34
+                SLAPI_OP_FLAG_IGNORE_UNINDEXED);
dc8c34
+            slapi_search_internal_pb(pb);
dc8c34
+            slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
dc8c34
+            for (ii = 0; entries && entries[ii]; ii++){
dc8c34
+                if((val = slapi_entry_attr_get_charptr(entries[ii], attrs[i]))){
dc8c34
+                    if(strlen(val) >= 5 && strncmp(val,"{DES}", 5) == 0){
dc8c34
+                        /*
dc8c34
+                         * We have a DES encoded password, convert it to AES
dc8c34
+                         */
dc8c34
+                        Slapi_PBlock *mod_pb = NULL;
dc8c34
+                        Slapi_Value *sval = NULL;
dc8c34
+                        LDAPMod mod_replace;
dc8c34
+                        LDAPMod *mods[2];
dc8c34
+                        char *replace_val[2];
dc8c34
+                        char *passwd = NULL;
dc8c34
+                        int rc = 0;
dc8c34
+
dc8c34
+                        /* decode the DES password */
dc8c34
+                        if(pw_rever_decode(val, &passwd, attrs[i]) == -1){
dc8c34
+                            slapi_log_error(SLAPI_LOG_FATAL ,"convert_pbe_des_to_aes",
dc8c34
+                                    "Failed to decode existing DES password for (%s)\n",
dc8c34
+                                    slapi_entry_get_dn(entries[ii]));
dc8c34
+                            rc = -1;
dc8c34
+                        }
dc8c34
+
dc8c34
+                        /* encode the password */
dc8c34
+                        if (rc == 0){
dc8c34
+                            sval = slapi_value_new_string(passwd);
dc8c34
+                            if(pw_rever_encode(&sval, attrs[i]) == -1){
dc8c34
+                                slapi_log_error(SLAPI_LOG_FATAL, "convert_pbe_des_to_aes",
dc8c34
+                                        "failed to encode AES password for (%s)\n",
dc8c34
+                                        slapi_entry_get_dn(entries[ii]));
dc8c34
+                                rc = -1;
dc8c34
+                            }
dc8c34
+                        }
dc8c34
+
dc8c34
+                        if (rc == 0){
dc8c34
+                            /* replace the attribute in the entry */
dc8c34
+                            replace_val[0] = (char *)slapi_value_get_string(sval);
dc8c34
+                            replace_val[1] = NULL;
dc8c34
+                            mod_replace.mod_op = LDAP_MOD_REPLACE;
dc8c34
+                            mod_replace.mod_type = attrs[i];
dc8c34
+                            mod_replace.mod_values = replace_val;
dc8c34
+                            mods[0] = &mod_replace;
dc8c34
+                            mods[1] = 0;
dc8c34
+
dc8c34
+                            mod_pb = slapi_pblock_new();
dc8c34
+                            slapi_modify_internal_set_pb(mod_pb, slapi_entry_get_dn(entries[ii]),
dc8c34
+                                    mods, 0, 0, (void *)plugin_get_default_component_id(), 0);
dc8c34
+                            slapi_modify_internal_pb(mod_pb);
dc8c34
+
dc8c34
+                            slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
dc8c34
+                            if (LDAP_SUCCESS != result) {
dc8c34
+                                slapi_log_error(SLAPI_LOG_FATAL, "convert_pbe_des_to_aes"
dc8c34
+                                        "Failed to convert password for (%s) error (%d)\n",
dc8c34
+                                        slapi_entry_get_dn(entries[ii]), result);
dc8c34
+                            } else {
dc8c34
+                                slapi_log_error(SLAPI_LOG_HOUSE, "convert_pbe_des_to_aes",
dc8c34
+                                        "Successfully converted password for (%s)\n",
dc8c34
+                                         slapi_entry_get_dn(entries[ii]));
dc8c34
+                                converted_des_passwd = 1;
dc8c34
+                            }
dc8c34
+                        }
dc8c34
+                        slapi_ch_free_string(&passwd);
dc8c34
+                        slapi_value_free(&sval);
dc8c34
+                        slapi_pblock_destroy(mod_pb);
dc8c34
+                    }
dc8c34
+                    slapi_ch_free_string(&val;;
dc8c34
+                }
dc8c34
+            }
dc8c34
+            slapi_free_search_results_internal(pb);
dc8c34
+            slapi_pblock_destroy(pb);
dc8c34
+            pb = NULL;
dc8c34
+            slapi_ch_free_string(&filter);
dc8c34
+        }
dc8c34
+
dc8c34
+        if (!converted_des_passwd){
dc8c34
+            slapi_log_error(SLAPI_LOG_HOUSE, "convert_pbe_des_to_aes",
dc8c34
+                "No DES passwords found to convert.\n");
dc8c34
+        }
dc8c34
+    }
dc8c34
+    charray_free(attrs);
dc8c34
+}
dc8c34
+
dc8c34
 void slapd_daemon( daemon_ports_t *ports )
dc8c34
 {
dc8c34
 	/* We are passed some ports---one for regular connections, one
dc8c34
@@ -1137,11 +1286,15 @@ void slapd_daemon( daemon_ports_t *ports )
dc8c34
 	}
dc8c34
 #endif /* ENABLE_LDAPI */
dc8c34
 #endif
dc8c34
-
dc8c34
 	listener_idxs = (listener_info *)slapi_ch_calloc(n_listeners, sizeof(*listener_idxs));
dc8c34
 	/* Now we write the pid file, indicating that the server is finally and listening for connections */
dc8c34
 	write_pid_file();
dc8c34
 
dc8c34
+	/*
dc8c34
+	 * Convert old DES encoded passwords to AES
dc8c34
+	 */
dc8c34
+	convert_pbe_des_to_aes();
dc8c34
+
dc8c34
 	/* The meat of the operation is in a loop on a call to select */
dc8c34
 	while(!g_get_shutdown())
dc8c34
 	{
dc8c34
diff --git a/ldap/servers/slapd/proto-slap.h b/ldap/servers/slapd/proto-slap.h
dc8c34
index 3b00c80..b1e7474 100644
dc8c34
--- a/ldap/servers/slapd/proto-slap.h
dc8c34
+++ b/ldap/servers/slapd/proto-slap.h
dc8c34
@@ -1083,6 +1083,7 @@ void slapd_pk11_DestroyPublicKey(SECKEYPublicKey *key);
dc8c34
 PRBool slapd_pk11_DoesMechanism(PK11SlotInfo *slot, CK_MECHANISM_TYPE type);
dc8c34
 PK11SymKey *slapd_pk11_PubUnwrapSymKeyWithFlagsPerm(SECKEYPrivateKey *wrappingKey, SECItem *wrappedKey, CK_MECHANISM_TYPE target, CK_ATTRIBUTE_TYPE operation, int keySize, CK_FLAGS flags, PRBool isPerm);
dc8c34
 PK11SymKey *slapd_pk11_TokenKeyGenWithFlags(PK11SlotInfo *slot, CK_MECHANISM_TYPE type, SECItem *param, int keySize, SECItem *keyid, CK_FLAGS opFlags, PK11AttrFlags attrFlags, void *wincx);
dc8c34
+CK_MECHANISM_TYPE slapd_PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **params, SECItem *pwitem);
dc8c34
 
dc8c34
 /*
dc8c34
  * start_tls_extop.c
dc8c34
diff --git a/ldap/servers/slapd/pw.c b/ldap/servers/slapd/pw.c
dc8c34
index ab624e7..d5785ba 100644
dc8c34
--- a/ldap/servers/slapd/pw.c
dc8c34
+++ b/ldap/servers/slapd/pw.c
dc8c34
@@ -385,9 +385,8 @@ pw_encodevals_ext( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals )
dc8c34
 		if ((!enc) && (( enc = (*pws_enc)( (char*)slapi_value_get_string(vals[ i ]) )) == NULL )) {
dc8c34
 			return( -1 );
dc8c34
 		}
dc8c34
-
dc8c34
-                slapi_value_free(&vals[ i ]);
dc8c34
-                vals[ i ] = slapi_value_new_string_passin(enc);
dc8c34
+		slapi_value_free(&vals[ i ]);
dc8c34
+		vals[ i ] = slapi_value_new_string_passin(enc);
dc8c34
 	}
dc8c34
 
dc8c34
 	return( 0 );
dc8c34
@@ -397,28 +396,57 @@ pw_encodevals_ext( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals )
dc8c34
  * Check if the prefix of the cipher is the one that is supposed to be 
dc8c34
  * Extract from the whole cipher the encrypted password (remove the prefix)
dc8c34
  */
dc8c34
-int checkPrefix(char *cipher, char *schemaName, char **encrypt)
dc8c34
+int checkPrefix(char *cipher, char *schemaName, char **encrypt, char **algid)
dc8c34
 {
dc8c34
 	int namelen;
dc8c34
 	/* buf contains the extracted schema name */
dc8c34
 	char *end, buf[ 3*PWD_MAX_NAME_LEN + 1 ];
dc8c34
+	char *delim = NULL;
dc8c34
 
dc8c34
 	if ( (*cipher == PWD_HASH_PREFIX_START) &&
dc8c34
-		 ((end = strchr(cipher, PWD_HASH_PREFIX_END)) != NULL) &&
dc8c34
-		 ((namelen = end - cipher - 1 ) <= (3*PWD_MAX_NAME_LEN)) )
dc8c34
+		 (end = strchr(cipher, PWD_HASH_PREFIX_END)) != NULL)
dc8c34
 	{
dc8c34
-		memcpy( buf, cipher + 1, namelen );
dc8c34
-		buf[ namelen ] = '\0';
dc8c34
-		if ( strcasecmp( buf, schemaName) != 0 )
dc8c34
-		{
dc8c34
-			/* schema names are different, error */
dc8c34
-			return 1;
dc8c34
-		}
dc8c34
-		else
dc8c34
-		{
dc8c34
-			/* extract the encrypted password */
dc8c34
-			*encrypt = cipher + strlen(schemaName) + 2;
dc8c34
-			return 0;
dc8c34
+		if((delim = strchr(cipher, PWD_PBE_DELIM)) != NULL){
dc8c34
+			/*
dc8c34
+			 * We have an algid in the prefix:
dc8c34
+			 *
dc8c34
+			 * {AES-<BASE64_ALG_ID>}<ENCODED PASSWORD>
dc8c34
+			 */
dc8c34
+			if((namelen = delim - cipher - 1) <= (3*PWD_MAX_NAME_LEN)){
dc8c34
+				memcpy( buf, cipher + 1, namelen );
dc8c34
+				buf[ namelen ] = '\0';
dc8c34
+
dc8c34
+				if ( strcasecmp( buf, schemaName) != 0 ){
dc8c34
+					/* schema names are different, error */
dc8c34
+					return 1;
dc8c34
+				} else {
dc8c34
+					char algid_buf[256];
dc8c34
+
dc8c34
+					/* extract the algid (length is never greater than 216 */
dc8c34
+					memcpy(algid_buf, delim + 1 , (end - delim));
dc8c34
+					algid_buf[end - delim - 1] = '\0';
dc8c34
+					*algid = strdup(algid_buf);
dc8c34
+
dc8c34
+					/* extract the encrypted password */
dc8c34
+					*encrypt = cipher + strlen(*algid) + strlen (schemaName) + 3;
dc8c34
+					return 0;
dc8c34
+				}
dc8c34
+			}
dc8c34
+		} else if ((namelen = end - cipher - 1 ) <= (3*PWD_MAX_NAME_LEN)){
dc8c34
+			/* no delimiter - must be old school DES */
dc8c34
+			memcpy( buf, cipher + 1, namelen );
dc8c34
+			buf[ namelen ] = '\0';
dc8c34
+			if ( strcasecmp( buf, schemaName) != 0 )
dc8c34
+			{
dc8c34
+				/* schema names are different, error */
dc8c34
+				return 1;
dc8c34
+			}
dc8c34
+			else
dc8c34
+			{
dc8c34
+				/* extract the encrypted password */
dc8c34
+				*encrypt = cipher + strlen(schemaName) + 2;
dc8c34
+				return 0;
dc8c34
+			}
dc8c34
 		}
dc8c34
 	}
dc8c34
 	/* cipher is not prefixed, already in clear ? */
dc8c34
@@ -444,6 +472,7 @@ pw_rever_decode(char *cipher, char **plain, const char * attr_name)
dc8c34
 		char *L_attr = NULL;
dc8c34
 		int i = 0;
dc8c34
 		char *encrypt = NULL;
dc8c34
+		char *algid = NULL;
dc8c34
 		int prefixOK = -1;
dc8c34
 
dc8c34
 		/* Get the appropriate decoding function */
dc8c34
@@ -451,10 +480,9 @@ pw_rever_decode(char *cipher, char **plain, const char * attr_name)
dc8c34
 		{
dc8c34
 			if (slapi_attr_types_equivalent(L_attr, attr_name))
dc8c34
 			{
dc8c34
-				typedef char * (*ENCFP)(char *);
dc8c34
+				typedef char * (*ENCFP)(char *, char *);
dc8c34
 
dc8c34
 				pwsp =  (struct pw_scheme *) slapi_ch_calloc (1, sizeof(struct pw_scheme));
dc8c34
-
dc8c34
 				pwsp->pws_dec = (ENCFP)p->plg_pwdstorageschemedec;
dc8c34
 				pwsp->pws_name = slapi_ch_strdup( p->plg_pwdstorageschemename );
dc8c34
 				pwsp->pws_len = strlen(pwsp->pws_name) ;
dc8c34
@@ -462,7 +490,7 @@ pw_rever_decode(char *cipher, char **plain, const char * attr_name)
dc8c34
 				{
dc8c34
 					/* check that the prefix of the cipher is the same name
dc8c34
 						as the scheme name */
dc8c34
-					prefixOK = checkPrefix(cipher, pwsp->pws_name, &encrypt);
dc8c34
+					prefixOK = checkPrefix(cipher, pwsp->pws_name, &encrypt, &algid);
dc8c34
 					if ( prefixOK == -1 )
dc8c34
 					{
dc8c34
 						/* no prefix, already in clear ? */
dc8c34
@@ -472,13 +500,15 @@ pw_rever_decode(char *cipher, char **plain, const char * attr_name)
dc8c34
 					}
dc8c34
 					else if ( prefixOK == 1 )
dc8c34
 					{
dc8c34
-						/* scheme names are different */
dc8c34
+						/* scheme names are different, try the next plugin */
dc8c34
 						ret_code = -1;
dc8c34
-						goto free_and_return;
dc8c34
+						free_pw_scheme( pwsp );
dc8c34
+						pwsp = NULL;
dc8c34
+						continue;
dc8c34
 					}
dc8c34
 					else
dc8c34
 					{
dc8c34
-						if ( ( *plain = (pwsp->pws_dec)( encrypt )) == NULL ) 
dc8c34
+						if ( ( *plain = (pwsp->pws_dec)( encrypt, algid )) == NULL )
dc8c34
 						{
dc8c34
 							/* pb during decoding */
dc8c34
 							ret_code = -1;
dc8c34
@@ -519,10 +549,10 @@ pw_rever_encode(Slapi_Value **vals, char * attr_name)
dc8c34
 	for ( p = get_plugin_list(PLUGIN_LIST_REVER_PWD_STORAGE_SCHEME); p != NULL; p = p->plg_next )
dc8c34
 	{
dc8c34
 		char *L_attr = NULL;
dc8c34
-		int i = 0;
dc8c34
+		int i = 0, ii = 0;
dc8c34
 
dc8c34
 		/* Get the appropriate encoding function */
dc8c34
-		for ( L_attr = p->plg_argv[i]; i<p->plg_argc; L_attr = p->plg_argv[++i] )
dc8c34
+		for ( L_attr = p->plg_argv[ii]; ii<p->plg_argc; L_attr = p->plg_argv[++ii] )
dc8c34
 		{
dc8c34
 			if (slapi_attr_types_equivalent(L_attr, attr_name))
dc8c34
 			{
dc8c34
@@ -537,11 +567,13 @@ pw_rever_encode(Slapi_Value **vals, char * attr_name)
dc8c34
 					for ( i = 0; vals[i] != NULL; ++i ) 
dc8c34
 					{
dc8c34
 						char *encrypt = NULL;
dc8c34
+						char *algid = NULL;
dc8c34
 						int prefixOK;
dc8c34
 
dc8c34
 						prefixOK = checkPrefix((char*)slapi_value_get_string(vals[i]), 
dc8c34
 												pwsp->pws_name,
dc8c34
-												&encrypt);
dc8c34
+												&encrypt, &algid);
dc8c34
+						slapi_ch_free_string(&algid);
dc8c34
 						if ( prefixOK == 0 )
dc8c34
 						{
dc8c34
 							/* Don't touch already encoded value */
dc8c34
diff --git a/ldap/servers/slapd/pw.h b/ldap/servers/slapd/pw.h
dc8c34
index 9bb5cc7..87d300c 100644
dc8c34
--- a/ldap/servers/slapd/pw.h
dc8c34
+++ b/ldap/servers/slapd/pw.h
dc8c34
@@ -55,35 +55,13 @@
dc8c34
 #define PWD_HASH_PREFIX_END	'}'
dc8c34
 
dc8c34
 /*
dc8c34
- * 
dc8c34
- * structure for holding password scheme info.
dc8c34
- */
dc8c34
-struct pw_scheme {
dc8c34
-	/* case-insensitive name used in prefix of passwords that use scheme */
dc8c34
-	char	*pws_name;
dc8c34
-
dc8c34
-	/* length of pws_name */
dc8c34
-	int	pws_len;
dc8c34
-
dc8c34
-	/* thread-safe comparison function; returns 0 for positive matches */
dc8c34
-	/* userpwd is value sent over LDAP bind; dbpwd is from the database */
dc8c34
-	int	(*pws_cmp)( char *userpwd, char *dbpwd );
dc8c34
-
dc8c34
-	/* thread-safe encoding function (returns pointer to malloc'd string) */
dc8c34
-	char	*(*pws_enc)( char *pwd );
dc8c34
-
dc8c34
-	/* thread-safe decoding function (returns pointer to malloc'd string) */
dc8c34
-	char	*(*pws_dec)( char *pwd );
dc8c34
-};
dc8c34
-
dc8c34
-/*
dc8c34
  * Public functions from pw.c:
dc8c34
  */
dc8c34
 struct pw_scheme *pw_name2scheme( char *name );
dc8c34
 struct pw_scheme *pw_val2scheme( char *val, char **valpwdp, int first_is_default );
dc8c34
 int pw_encodevals( Slapi_Value **vals );
dc8c34
 int pw_encodevals_ext( Slapi_PBlock *pb, const Slapi_DN *sdn, Slapi_Value **vals );
dc8c34
-int checkPrefix(char *cipher, char *schemaName, char **encrypt);
dc8c34
+int checkPrefix(char *cipher, char *schemaName, char **encrypt, char **algid);
dc8c34
 struct passwordpolicyarray *new_passwdPolicy ( Slapi_PBlock *pb, const char *dn );
dc8c34
 void delete_passwdPolicy( struct passwordpolicyarray **pwpolicy);
dc8c34
 int pw_is_pwp_admin(Slapi_PBlock *pb, struct passwordpolicyarray *pwp);
dc8c34
diff --git a/ldap/servers/slapd/security_wrappers.c b/ldap/servers/slapd/security_wrappers.c
dc8c34
index 33d512f..4ffda8b 100644
dc8c34
--- a/ldap/servers/slapd/security_wrappers.c
dc8c34
+++ b/ldap/servers/slapd/security_wrappers.c
dc8c34
@@ -409,3 +409,9 @@ PK11SymKey *slapd_pk11_TokenKeyGenWithFlags(PK11SlotInfo *slot,
dc8c34
 	return PK11_TokenKeyGenWithFlags(slot, type, param, keySize, keyid, 
dc8c34
 	                                 opFlags, attrFlags, wincx);
dc8c34
 }
dc8c34
+
dc8c34
+CK_MECHANISM_TYPE
dc8c34
+slapd_PK11_GetPBECryptoMechanism(SECAlgorithmID *algid, SECItem **params, SECItem *pwitem)
dc8c34
+{
dc8c34
+	return PK11_GetPBECryptoMechanism(algid, params, pwitem );
dc8c34
+}
dc8c34
diff --git a/ldap/servers/slapd/slap.h b/ldap/servers/slapd/slap.h
dc8c34
index a84e802..c027a72 100644
dc8c34
--- a/ldap/servers/slapd/slap.h
dc8c34
+++ b/ldap/servers/slapd/slap.h
dc8c34
@@ -53,9 +53,9 @@
dc8c34
 
dc8c34
  
dc8c34
 /* Used by SSL and DES plugin */
dc8c34
-#ifdef NEED_TOK_DES
dc8c34
-static char  tokDes[34] = "Communicator Generic Crypto Svcs";
dc8c34
-static char ptokDes[34] = "Internal (Software) Token        ";
dc8c34
+#ifdef NEED_TOK_PBE
dc8c34
+static char  tokPBE[34] = "Communicator Generic Crypto Svcs";
dc8c34
+static char ptokPBE[34] = "Internal (Software) Token        ";
dc8c34
 #endif
dc8c34
 
dc8c34
 /*
dc8c34
@@ -306,6 +306,8 @@ typedef void	(*VFPV)(); /* takes undefined arguments */
dc8c34
 
dc8c34
 #define ATTR_NETSCAPEMDSUFFIX "netscapemdsuffix"
dc8c34
 
dc8c34
+#define PWD_PBE_DELIM '-'
dc8c34
+
dc8c34
 #define REFERRAL_REMOVE_CMD "remove"
dc8c34
 
dc8c34
 /* Filenames for DSE storage */
dc8c34
@@ -1517,6 +1519,60 @@ struct slapi_task {
dc8c34
 } slapi_task;
dc8c34
 /* End of interface to support online tasks **********************************/
dc8c34
 
dc8c34
+/*
dc8c34
+ * structure for holding password scheme info.
dc8c34
+ */
dc8c34
+struct pw_scheme {
dc8c34
+    /* case-insensitive name used in prefix of passwords that use scheme */
dc8c34
+   char    *pws_name;
dc8c34
+
dc8c34
+   /* length of pws_name */
dc8c34
+   int     pws_len;
dc8c34
+
dc8c34
+   /* thread-safe comparison function; returns 0 for positive matches */
dc8c34
+   /* userpwd is value sent over LDAP bind; dbpwd is from the database */
dc8c34
+   int     (*pws_cmp)( char *userpwd, char *dbpwd );
dc8c34
+
dc8c34
+   /* thread-safe encoding function (returns pointer to malloc'd string) */
dc8c34
+   char    *(*pws_enc)( char *pwd );
dc8c34
+
dc8c34
+   /* thread-safe decoding function (returns pointer to malloc'd string) */
dc8c34
+   char    *(*pws_dec)( char *pwd, char *algid);
dc8c34
+};
dc8c34
+
dc8c34
+typedef struct passwordpolicyarray {
dc8c34
+  slapi_onoff_t pw_change;        /* 1 - indicates that users are allowed to change the pwd */
dc8c34
+  slapi_onoff_t pw_must_change;   /* 1 - indicates that users must change pwd upon reset */
dc8c34
+  slapi_onoff_t pw_syntax;
dc8c34
+  int pw_minlength;
dc8c34
+  int pw_mindigits;
dc8c34
+  int pw_minalphas;
dc8c34
+  int pw_minuppers;
dc8c34
+  int pw_minlowers;
dc8c34
+  int pw_minspecials;
dc8c34
+  int pw_min8bit;
dc8c34
+  int pw_maxrepeats;
dc8c34
+  int pw_mincategories;
dc8c34
+  int pw_mintokenlength;
dc8c34
+  slapi_onoff_t pw_exp;
dc8c34
+  long pw_maxage;
dc8c34
+  long pw_minage;
dc8c34
+  long pw_warning;
dc8c34
+  slapi_onoff_t pw_history;
dc8c34
+  int pw_inhistory;
dc8c34
+  slapi_onoff_t pw_lockout;
dc8c34
+  int pw_maxfailure;
dc8c34
+  slapi_onoff_t pw_unlock;
dc8c34
+  long pw_lockduration;
dc8c34
+  long pw_resetfailurecount;
dc8c34
+  int pw_gracelimit;
dc8c34
+  slapi_onoff_t pw_is_legacy;
dc8c34
+  slapi_onoff_t pw_track_update_time;
dc8c34
+  struct pw_scheme *pw_storagescheme;
dc8c34
+  Slapi_DN *pw_admin;
dc8c34
+  Slapi_DN **pw_admin_user;
dc8c34
+} passwdPolicy;
dc8c34
+
dc8c34
 typedef struct slapi_pblock {
dc8c34
 	/* common */
dc8c34
 	Slapi_Backend		*pb_backend;
dc8c34
@@ -2060,39 +2116,6 @@ typedef struct _slapdEntryPoints {
dc8c34
 
dc8c34
 #define MAX_ALLOWED_TIME_IN_SECS	2147483647
dc8c34
 
dc8c34
-typedef struct passwordpolicyarray {
dc8c34
-  int pw_change;        /* 1 - indicates that users are allowed to change the pwd */
dc8c34
-  int pw_must_change;   /* 1 - indicates that users must change pwd upon reset */
dc8c34
-  int pw_syntax;
dc8c34
-  int pw_minlength;
dc8c34
-  int pw_mindigits;
dc8c34
-  int pw_minalphas;
dc8c34
-  int pw_minuppers;
dc8c34
-  int pw_minlowers;
dc8c34
-  int pw_minspecials;
dc8c34
-  int pw_min8bit;
dc8c34
-  int pw_maxrepeats;
dc8c34
-  int pw_mincategories;
dc8c34
-  int pw_mintokenlength;
dc8c34
-  int pw_exp;
dc8c34
-  long pw_maxage;
dc8c34
-  long pw_minage;
dc8c34
-  long pw_warning;
dc8c34
-  int pw_history;
dc8c34
-  int pw_inhistory;
dc8c34
-  int pw_lockout;
dc8c34
-  int pw_maxfailure;
dc8c34
-  int pw_unlock;
dc8c34
-  long pw_lockduration;
dc8c34
-  long pw_resetfailurecount;
dc8c34
-  int pw_gracelimit;
dc8c34
-  int pw_is_legacy;
dc8c34
-  int pw_track_update_time;
dc8c34
-  struct pw_scheme *pw_storagescheme;
dc8c34
-  Slapi_DN *pw_admin;
dc8c34
-  Slapi_DN **pw_admin_user;
dc8c34
-} passwdPolicy;
dc8c34
-
dc8c34
 typedef struct _slapdFrontendConfig {
dc8c34
   Slapi_RWLock     *cfg_rwlock;       /* read/write lock to serialize access */
dc8c34
   struct pw_scheme *rootpwstoragescheme;
dc8c34
diff --git a/ldap/servers/slapd/slapi-plugin.h b/ldap/servers/slapd/slapi-plugin.h
dc8c34
index 912d407..c36822d 100644
dc8c34
--- a/ldap/servers/slapd/slapi-plugin.h
dc8c34
+++ b/ldap/servers/slapd/slapi-plugin.h
dc8c34
@@ -200,6 +200,8 @@ NSPR_API(PRUint32) PR_fprintf(struct PRFileDesc* fd, const char *fmt, ...)
dc8c34
 #define SLAPI_OP_FLAG_NEVER_CHAIN	0x000800 /* Do not chain the operation */
dc8c34
 #define SLAPI_OP_FLAG_NO_ACCESS_CHECK	0x10000 /* Do not check for access control - bypass them */
dc8c34
 #define SLAPI_OP_FLAG_BYPASS_REFERRALS	0x40000 /* Useful for performing internal operations on read-only replica */
dc8c34
+#define SLAPI_OP_FLAG_NEVER_CACHE	0x200000 /* added entry should not be kept in cache */
dc8c34
+#define SLAPI_OP_FLAG_IGNORE_UNINDEXED		0x800000 /* Do not log unindexed search */
dc8c34
 
dc8c34
 #define SLAPI_OC_FLAG_REQUIRED	0x0001
dc8c34
 #define SLAPI_OC_FLAG_ALLOWED	0x0002
dc8c34
diff --git a/ldap/servers/slapd/ssl.c b/ldap/servers/slapd/ssl.c
dc8c34
index 529dbc6..1f64be0 100644
dc8c34
--- a/ldap/servers/slapd/ssl.c
dc8c34
+++ b/ldap/servers/slapd/ssl.c
dc8c34
@@ -63,7 +63,7 @@
dc8c34
 #include <string.h>
dc8c34
 #include <errno.h>
dc8c34
 
dc8c34
-#define NEED_TOK_DES /* defines tokDes and ptokDes - see slap.h */
dc8c34
+#define NEED_TOK_PBE /* defines tokPBE and ptokPBE - see slap.h */
dc8c34
 #include "slap.h"
dc8c34
 
dc8c34
 #include "svrcore.h"
dc8c34
@@ -713,7 +713,7 @@ slapd_nss_init(int init_ssl, int config_available)
dc8c34
 	/******** Initialise NSS *********/
dc8c34
     
dc8c34
 	nssFlags &= (~NSS_INIT_READONLY);
dc8c34
-	slapd_pk11_configurePKCS11(NULL, NULL, tokDes, ptokDes, NULL, NULL, NULL, NULL, 0, 0 );
dc8c34
+	slapd_pk11_configurePKCS11(NULL, NULL, tokPBE, ptokPBE, NULL, NULL, NULL, NULL, 0, 0 );
dc8c34
 	secStatus = NSS_Initialize(certdir, NULL, NULL, "secmod.db", nssFlags);
dc8c34
 
dc8c34
 	dongle_file_name = PR_smprintf("%s/pin.txt", certdir);
dc8c34
diff --git a/ldap/servers/slapd/task.c b/ldap/servers/slapd/task.c
dc8c34
index 0488640..e595ad0 100644
dc8c34
--- a/ldap/servers/slapd/task.c
dc8c34
+++ b/ldap/servers/slapd/task.c
dc8c34
@@ -75,6 +75,7 @@ static int shutting_down = 0;
dc8c34
 #define TASK_WORK_NAME          "nsTaskTotalItems"
dc8c34
 
dc8c34
 #define DEFAULT_TTL     "120"   /* seconds */
dc8c34
+#define TASK_DES2AES "des2aes task"
dc8c34
 
dc8c34
 #define LOG_BUFFER              256
dc8c34
 /* if the cumul. log gets larger than this, it's truncated: */
dc8c34
@@ -105,6 +106,9 @@ static const char *fetch_attr(Slapi_Entry *e, const char *attrname,
dc8c34
                               const char *default_val);
dc8c34
 static Slapi_Entry *get_internal_entry(Slapi_PBlock *pb, char *dn);
dc8c34
 static void modify_internal_entry(char *dn, LDAPMod **mods);
dc8c34
+static void task_des2aes_thread(void *arg);
dc8c34
+static void des2aes_task_destructor(Slapi_Task *task);
dc8c34
+
dc8c34
 
dc8c34
 /***********************************
dc8c34
  * Public Functions
dc8c34
@@ -1883,6 +1887,339 @@ out:
dc8c34
     return SLAPI_DSE_CALLBACK_OK;
dc8c34
 }
dc8c34
 
dc8c34
+/*
dc8c34
+ * des2aes Task
dc8c34
+ *
dc8c34
+ * Convert any DES passwords to AES
dc8c34
+ *
dc8c34
+ * dn: cn=convertPasswords, cn=des2aes,cn=tasks,cn=config
dc8c34
+ * objectclass: top
dc8c34
+ * objectclass: extensibleObject
dc8c34
+ * suffix: dc=example,dc=com (If empty all backends are checked)
dc8c34
+ * suffix: dc=other,dc=suffix
dc8c34
+ */
dc8c34
+struct task_des2aes_data
dc8c34
+{
dc8c34
+    char **suffixes;
dc8c34
+    Slapi_Task *task;
dc8c34
+};
dc8c34
+
dc8c34
+static int
dc8c34
+task_des2aes(Slapi_PBlock *pb, Slapi_Entry *e, Slapi_Entry *eAfter,
dc8c34
+             int *returncode, char *returntext, void *arg)
dc8c34
+{
dc8c34
+    struct task_des2aes_data *task_data = NULL;
dc8c34
+    PRThread *thread = NULL;
dc8c34
+    Slapi_Task *task = NULL;
dc8c34
+    char **suffix = NULL;
dc8c34
+    char **bases = NULL;
dc8c34
+    int rc = SLAPI_DSE_CALLBACK_OK;
dc8c34
+
dc8c34
+    /* Get the suffixes */
dc8c34
+    if((suffix = slapi_entry_attr_get_charray(e, "suffix"))){
dc8c34
+        int i;
dc8c34
+        for (i = 0; suffix && suffix[i]; i++){
dc8c34
+            /* Make sure "suffix" is NUL terminated string */
dc8c34
+            char *dn = slapi_create_dn_string("%s", suffix[i]);
dc8c34
+
dc8c34
+            if(dn){
dc8c34
+                if(slapi_dn_syntax_check(pb, dn, 1)){
dc8c34
+                    /* invalid suffix name */
dc8c34
+                    PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
dc8c34
+                        "Invalid DN syntax (%s) specified for \"suffix\"\n",
dc8c34
+                        suffix[i]);
dc8c34
+                    *returncode = LDAP_INVALID_DN_SYNTAX;
dc8c34
+                    slapi_ch_free_string(&dn;;
dc8c34
+                    rc = SLAPI_DSE_CALLBACK_ERROR;
dc8c34
+                    goto error;
dc8c34
+                } else {
dc8c34
+                    slapi_ch_array_add(&bases, dn);
dc8c34
+                }
dc8c34
+            } else{
dc8c34
+                PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
dc8c34
+                    "Invalid DN (%s) specified for \"suffix\"\n", suffix[i]);
dc8c34
+                    *returncode = LDAP_INVALID_DN_SYNTAX;
dc8c34
+                rc = SLAPI_DSE_CALLBACK_ERROR;
dc8c34
+                goto error;
dc8c34
+            }
dc8c34
+        }
dc8c34
+    }
dc8c34
+
dc8c34
+    /* Build the task data and fire off a thread to perform the conversion */
dc8c34
+    task = slapi_new_task(slapi_entry_get_ndn(e));
dc8c34
+
dc8c34
+    /* register our destructor for cleaning up our private data */
dc8c34
+    slapi_task_set_destructor_fn(task, des2aes_task_destructor);
dc8c34
+    task_data = (struct task_des2aes_data *)slapi_ch_calloc(1, sizeof(struct task_des2aes_data));
dc8c34
+    task_data->suffixes = bases;
dc8c34
+    task_data->task = task;
dc8c34
+
dc8c34
+    /* Start the conversion thread */
dc8c34
+    thread = PR_CreateThread(PR_USER_THREAD, task_des2aes_thread,
dc8c34
+                             (void *)task_data, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD,
dc8c34
+                             PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE);
dc8c34
+    if (thread == NULL) {
dc8c34
+        PR_snprintf(returntext, SLAPI_DSE_RETURNTEXT_SIZE,
dc8c34
+                "unable to create des2aes thread!\n");
dc8c34
+        slapi_log_error(SLAPI_LOG_FATAL, TASK_DES2AES,
dc8c34
+                        "unable to create des2aes thread!\n");
dc8c34
+        *returncode = LDAP_OPERATIONS_ERROR;
dc8c34
+        slapi_task_finish(task, *returncode);
dc8c34
+        rc = SLAPI_DSE_CALLBACK_ERROR;
dc8c34
+    }
dc8c34
+
dc8c34
+error:
dc8c34
+    if (rc == SLAPI_DSE_CALLBACK_ERROR){
dc8c34
+        slapi_ch_array_free(bases);
dc8c34
+        slapi_ch_array_free(suffix);
dc8c34
+        slapi_ch_free((void **)&task_data);
dc8c34
+    }
dc8c34
+    return rc;
dc8c34
+}
dc8c34
+
dc8c34
+static void
dc8c34
+task_des2aes_thread(void *arg)
dc8c34
+{
dc8c34
+    struct task_des2aes_data *task_data = arg;
dc8c34
+    Slapi_PBlock *pb = NULL;
dc8c34
+    Slapi_Entry **entries = NULL;
dc8c34
+    Slapi_Task *task = task_data->task;
dc8c34
+    struct slapdplugin *plugin = NULL;
dc8c34
+    char **attrs = NULL;
dc8c34
+    char **backends = NULL;
dc8c34
+    char *val = NULL;
dc8c34
+    int converted_des_passwd = 0;
dc8c34
+    int result = -1;
dc8c34
+    int have_aes = 0;
dc8c34
+    int have_des = 0;
dc8c34
+    int i = 0, ii = 0, be_idx = 0;
dc8c34
+    int rc = 0;
dc8c34
+
dc8c34
+    /*
dc8c34
+     * Check that AES plugin is enabled, and grab all the unique
dc8c34
+     * password attributes.
dc8c34
+     */
dc8c34
+    for ( plugin = get_plugin_list(PLUGIN_LIST_REVER_PWD_STORAGE_SCHEME);
dc8c34
+          plugin != NULL;
dc8c34
+          plugin = plugin->plg_next )
dc8c34
+    {
dc8c34
+        char *plugin_arg = NULL;
dc8c34
+
dc8c34
+        if(strcasecmp(plugin->plg_name, "AES") == 0){
dc8c34
+            /* We have the AES plugin, and its enabled */
dc8c34
+            have_aes = 1;
dc8c34
+        }
dc8c34
+        if(strcasecmp(plugin->plg_name, "DES") == 0){
dc8c34
+            /* We have the DES plugin, and its enabled */
dc8c34
+            have_des = 1;
dc8c34
+        }
dc8c34
+        /* Gather all the unique password attributes from all the PBE plugins */
dc8c34
+        for ( i = 0, plugin_arg = plugin->plg_argv[i];
dc8c34
+              i < plugin->plg_argc;
dc8c34
+              plugin_arg = plugin->plg_argv[++i] )
dc8c34
+        {
dc8c34
+            if(charray_inlist(attrs, plugin_arg)){
dc8c34
+                continue;
dc8c34
+            }
dc8c34
+            charray_add(&attrs, slapi_ch_strdup(plugin_arg));
dc8c34
+        }
dc8c34
+    }
dc8c34
+
dc8c34
+    if(have_aes && have_des){
dc8c34
+        if(task_data->suffixes == NULL){
dc8c34
+            /*
dc8c34
+             * Build a list of all the backend dn's
dc8c34
+             */
dc8c34
+            Slapi_Backend *be = NULL;
dc8c34
+            char *cookie = NULL;
dc8c34
+
dc8c34
+            slapi_log_error(SLAPI_LOG_FATAL, TASK_DES2AES,
dc8c34
+                "Checking for DES passwords to convert to AES...\n");
dc8c34
+            slapi_task_log_notice(task,
dc8c34
+                "Checking for DES passwords to convert to AES...\n");
dc8c34
+
dc8c34
+            be = slapi_get_first_backend(&cookie);
dc8c34
+            while (be){               
dc8c34
+                PR_Lock(be->be_suffixlock);
dc8c34
+                for (i = 0; be->be_suffix && i < be->be_suffixcount; i++) {
dc8c34
+                    char *suffix = (char *)slapi_sdn_get_ndn(be->be_suffix[i]);
dc8c34
+                    if(charray_inlist(backends, suffix) || strlen(suffix) == 0){
dc8c34
+                        continue;
dc8c34
+                    }
dc8c34
+                    charray_add(&backends, slapi_ch_strdup(suffix));;
dc8c34
+                }
dc8c34
+                be = slapi_get_next_backend (cookie);
dc8c34
+            }
dc8c34
+            slapi_ch_free ((void **)&cookie);
dc8c34
+        } else {
dc8c34
+            backends = task_data->suffixes;
dc8c34
+        }
dc8c34
+
dc8c34
+        /*
dc8c34
+         * Search for the password attributes
dc8c34
+         */
dc8c34
+        for (i = 0; attrs && attrs[i]; i++){
dc8c34
+            char *filter = PR_smprintf("%s=*", attrs[i]);
dc8c34
+            /*
dc8c34
+             * Loop over all the backends looking for the password attribute
dc8c34
+             */
dc8c34
+            for(be_idx = 0; backends && backends[be_idx]; be_idx++){
dc8c34
+                pb = slapi_pblock_new();
dc8c34
+                slapi_search_internal_set_pb(pb, backends[be_idx],
dc8c34
+                        LDAP_SCOPE_SUBTREE, filter, NULL, 0, NULL, NULL,
dc8c34
+                        (void *)plugin_get_default_component_id(),
dc8c34
+                        SLAPI_OP_FLAG_IGNORE_UNINDEXED);
dc8c34
+                slapi_search_internal_pb(pb);
dc8c34
+                slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
dc8c34
+                if (LDAP_SUCCESS != result) {
dc8c34
+                    slapi_log_error(SLAPI_LOG_FATAL, "convert_pbe_des_to_aes: ",
dc8c34
+                        "Failed to search for password attribute (%s) error (%d), skipping suffix (%s)\n",
dc8c34
+                        attrs[i], result, backends[be_idx]);
dc8c34
+                    slapi_task_log_notice(task,
dc8c34
+                        "Failed to search for password attribute (%s) error (%d), skipping suffix (%s)\n",
dc8c34
+                        attrs[i], result, backends[be_idx]);
dc8c34
+                    slapi_free_search_results_internal(pb);
dc8c34
+                    slapi_pblock_destroy(pb);
dc8c34
+                    pb = NULL;
dc8c34
+                    continue;
dc8c34
+                }
dc8c34
+                slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
dc8c34
+                for (ii = 0; entries && entries[ii]; ii++){
dc8c34
+                    if((val = slapi_entry_attr_get_charptr(entries[ii], attrs[i]))){
dc8c34
+                        if(strlen(val) >= 5 && strncmp(val,"{DES}", 5) == 0){
dc8c34
+                            /*
dc8c34
+                             * We have a DES encoded password, convert it AES
dc8c34
+                             */
dc8c34
+                            Slapi_PBlock *mod_pb = NULL;
dc8c34
+                            Slapi_Value *sval = NULL;
dc8c34
+                            LDAPMod mod_replace;
dc8c34
+                            LDAPMod *mods[2];
dc8c34
+                            char *replace_val[2];
dc8c34
+                            char *passwd = NULL;
dc8c34
+
dc8c34
+                            /* Decode the DES password */
dc8c34
+                            if(pw_rever_decode(val, &passwd, attrs[i]) == -1){
dc8c34
+                                slapi_log_error(SLAPI_LOG_FATAL, TASK_DES2AES,
dc8c34
+                                        "Failed to decode existing DES password for (%s)\n",
dc8c34
+                                        slapi_entry_get_dn(entries[ii]));
dc8c34
+                                slapi_task_log_notice(task,
dc8c34
+                                    "Failed to decode existing DES password for (%s)\n",
dc8c34
+                                    slapi_entry_get_dn(entries[ii]));
dc8c34
+                                rc = 1;
dc8c34
+                                goto done;
dc8c34
+                            }
dc8c34
+
dc8c34
+                            /* Encode the password */
dc8c34
+                            sval = slapi_value_new_string(passwd);
dc8c34
+                            if(pw_rever_encode(&sval, attrs[i]) == -1){
dc8c34
+                                slapi_log_error(SLAPI_LOG_FATAL, TASK_DES2AES,
dc8c34
+                                    "failed to encode AES password for (%s)\n",
dc8c34
+                                    slapi_entry_get_dn(entries[ii]));
dc8c34
+                                slapi_task_log_notice(task,
dc8c34
+                                    "failed to encode AES password for (%s)\n",
dc8c34
+                                    slapi_entry_get_dn(entries[ii]));
dc8c34
+                                slapi_ch_free_string(&passwd);
dc8c34
+                                slapi_value_free(&sval);
dc8c34
+                                rc = 1;
dc8c34
+                                goto done;
dc8c34
+                            }
dc8c34
+
dc8c34
+                            /* Replace the attribute in the entry */
dc8c34
+                            replace_val[0] = (char *)slapi_value_get_string(sval);
dc8c34
+                            replace_val[1] = NULL;
dc8c34
+                            mod_replace.mod_op = LDAP_MOD_REPLACE;
dc8c34
+                            mod_replace.mod_type = attrs[i];
dc8c34
+                            mod_replace.mod_values = replace_val;
dc8c34
+                            mods[0] = &mod_replace;
dc8c34
+                            mods[1] = 0;
dc8c34
+
dc8c34
+                            mod_pb = slapi_pblock_new();
dc8c34
+                            slapi_modify_internal_set_pb(mod_pb, slapi_entry_get_dn(entries[ii]),
dc8c34
+                                    mods, 0, 0, (void *)plugin_get_default_component_id(), 0);
dc8c34
+                            slapi_modify_internal_pb(mod_pb);
dc8c34
+
dc8c34
+                            slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
dc8c34
+                            if (LDAP_SUCCESS != result) {
dc8c34
+                                slapi_log_error(SLAPI_LOG_FATAL, TASK_DES2AES,
dc8c34
+                                    "Failed to convert password for (%s) error (%d)\n",
dc8c34
+                                    slapi_entry_get_dn(entries[ii]), result);
dc8c34
+                                slapi_task_log_notice(task,
dc8c34
+                                    "Failed to convert password for (%s) error (%d)\n",
dc8c34
+                                    slapi_entry_get_dn(entries[ii]), result);
dc8c34
+                                rc = 1;
dc8c34
+                            } else {
dc8c34
+                                slapi_log_error(SLAPI_LOG_FATAL, TASK_DES2AES,
dc8c34
+                                    "Successfully converted password for (%s)\n",
dc8c34
+                                     slapi_entry_get_dn(entries[ii]));
dc8c34
+                                slapi_task_log_notice(task,
dc8c34
+                                   "Successfully converted password for (%s)\n",
dc8c34
+                                    slapi_entry_get_dn(entries[ii]));
dc8c34
+                                converted_des_passwd = 1;
dc8c34
+                            }
dc8c34
+                            slapi_ch_free_string(&passwd);
dc8c34
+                            slapi_value_free(&sval);
dc8c34
+                            slapi_pblock_destroy(mod_pb);
dc8c34
+                        }
dc8c34
+                        slapi_ch_free_string(&val;;
dc8c34
+                    }
dc8c34
+                }
dc8c34
+                slapi_free_search_results_internal(pb);
dc8c34
+                slapi_pblock_destroy(pb);
dc8c34
+                pb = NULL;
dc8c34
+            }
dc8c34
+            slapi_ch_free_string(&filter);
dc8c34
+        }
dc8c34
+        if (!converted_des_passwd){
dc8c34
+            slapi_log_error(SLAPI_LOG_FATAL, TASK_DES2AES,
dc8c34
+                "No DES passwords found to convert.\n");
dc8c34
+            slapi_task_log_notice(task, "No DES passwords found to convert.\n");
dc8c34
+        }
dc8c34
+    } else {
dc8c34
+        /* No AES/DES */
dc8c34
+        if (!have_des){
dc8c34
+            slapi_log_error(SLAPI_LOG_FATAL, TASK_DES2AES,
dc8c34
+                            "DES plugin not enabled\n");
dc8c34
+            slapi_task_log_notice(task, "DES plugin not enabled\n");
dc8c34
+        }
dc8c34
+        if (!have_aes){
dc8c34
+            slapi_log_error(SLAPI_LOG_FATAL, TASK_DES2AES,
dc8c34
+                        "AES plugin not enabled\n");
dc8c34
+            slapi_task_log_notice(task, "AES plugin not enabled\n");
dc8c34
+        }
dc8c34
+        slapi_log_error(SLAPI_LOG_FATAL, TASK_DES2AES,
dc8c34
+            "Unable to convert passwords\n");
dc8c34
+        slapi_task_log_notice(task, "Unable to convert passwords\n");
dc8c34
+        rc = 1;
dc8c34
+    }
dc8c34
+
dc8c34
+done:
dc8c34
+    charray_free(attrs);
dc8c34
+    charray_free(backends);
dc8c34
+    slapi_free_search_results_internal(pb);
dc8c34
+    slapi_pblock_destroy(pb);
dc8c34
+    slapi_task_finish(task, rc);
dc8c34
+}
dc8c34
+
dc8c34
+static void
dc8c34
+des2aes_task_destructor(Slapi_Task *task)
dc8c34
+{
dc8c34
+    slapi_log_error(SLAPI_LOG_TRACE, TASK_DES2AES,
dc8c34
+                    "des2aes_task_destructor -->\n" );
dc8c34
+    if (task) {
dc8c34
+        struct task_des2aes_data *task_data = (struct task_des2aes_data *)slapi_task_get_data(task);
dc8c34
+        while (slapi_task_get_refcount(task) > 0) {
dc8c34
+            /* Yield to wait for the task to finish. */
dc8c34
+            DS_Sleep (PR_MillisecondsToInterval(100));
dc8c34
+        }
dc8c34
+        if (task_data) {
dc8c34
+            slapi_ch_array_free(task_data->suffixes);
dc8c34
+            slapi_ch_free((void **)&task_data);
dc8c34
+        }
dc8c34
+    }
dc8c34
+    slapi_log_error(SLAPI_LOG_TRACE, TASK_DES2AES,
dc8c34
+                    "des2aes_task_destructor <--\n" );
dc8c34
+}
dc8c34
+
dc8c34
 /* cleanup old tasks that may still be in the DSE from a previous session
dc8c34
  * (this can happen if the server crashes [no matter how unlikely we like
dc8c34
  * to think that is].)
dc8c34
@@ -1962,6 +2299,7 @@ void task_init(void)
dc8c34
     slapi_task_register_handler("restore", task_restore_add);
dc8c34
     slapi_task_register_handler("index", task_index_add);
dc8c34
     slapi_task_register_handler("upgradedb", task_upgradedb_add);
dc8c34
+    slapi_task_register_handler("des2aes", task_des2aes);
dc8c34
 }
dc8c34
 
dc8c34
 /* called when the server is shutting down -- abort all existing tasks */
dc8c34
-- 
dc8c34
2.4.11
dc8c34