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