ソースを参照

Resolves: bug 245815
Description: DS Admin Migration framework
Reviewed by: nhosoi (Thanks!)
Fix Description: Created a Migration class that is very similar to the Setup class - to act as a sort of global context for the migration process. Moved most of the guts of migrateTo11 into the new DSMigration class and the new migrate-ds.pl - we should deprecate migrateTo11 in favor of migrate-ds.pl. I had to enhance the check_and_add_entry function to handle pseudo-LDIF change records - pseudo because mozilla perldap LDIF has no real LDIF change record support.
Fixed a bug in create_instance.c - creating an instance without starting it was not working if the port number of an existing directory server was supplied.
Added a new method createDSInstance to Util - this just wraps ds_newinst.pl for now.
Platforms tested: RHEL4
Doc: Yes. We will need to document the migration procedures.
Flag day: Yes. Autotool file changes.

Rich Megginson 18 年 前
コミット
ad85c482b2

+ 7 - 3
Makefile.am

@@ -186,7 +186,8 @@ bin_SCRIPTS = $(srcdir)/ldap/servers/slapd/tools/rsearch/scripts/dbgen.pl \
 	ldap/admin/src/scripts/cl-dump.pl \
 	wrappers/repl-monitor \
 	ldap/admin/src/scripts/repl-monitor.pl \
-	ldap/admin/src/scripts/setup-ds.pl
+	ldap/admin/src/scripts/setup-ds.pl \
+	ldap/admin/src/scripts/migrate-ds.pl
 
 perl_SCRIPTS = ldap/admin/src/scripts/SetupLog.pm \
 	ldap/admin/src/scripts/Resource.pm \
@@ -197,9 +198,12 @@ perl_SCRIPTS = ldap/admin/src/scripts/SetupLog.pm \
 	ldap/admin/src/scripts/DialogManager.pm \
 	ldap/admin/src/scripts/Dialog.pm \
 	ldap/admin/src/scripts/DSDialogs.pm \
-	ldap/admin/src/scripts/Setup.pm
+	ldap/admin/src/scripts/Setup.pm \
+	ldap/admin/src/scripts/Migration.pm \
+	ldap/admin/src/scripts/DSMigration.pm
 
-property_DATA = ldap/admin/src/scripts/setup-ds.res
+property_DATA = ldap/admin/src/scripts/setup-ds.res \
+	ldap/admin/src/scripts/migrate-ds.res
 
 task_SCRIPTS = ldap/admin/src/scripts/template-bak2db \
 	ldap/admin/src/scripts/template-db2bak \

+ 9 - 3
Makefile.in

@@ -877,6 +877,7 @@ PACKAGE_VERSION = @PACKAGE_VERSION@
 PATH_SEPARATOR = @PATH_SEPARATOR@
 PKG_CONFIG = @PKG_CONFIG@
 RANLIB = @RANLIB@
+SED = @SED@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
 SOLARIS_FALSE = @SOLARIS_FALSE@
@@ -1122,7 +1123,8 @@ bin_SCRIPTS = $(srcdir)/ldap/servers/slapd/tools/rsearch/scripts/dbgen.pl \
 	ldap/admin/src/scripts/cl-dump.pl \
 	wrappers/repl-monitor \
 	ldap/admin/src/scripts/repl-monitor.pl \
-	ldap/admin/src/scripts/setup-ds.pl
+	ldap/admin/src/scripts/setup-ds.pl \
+	ldap/admin/src/scripts/migrate-ds.pl
 
 perl_SCRIPTS = ldap/admin/src/scripts/SetupLog.pm \
 	ldap/admin/src/scripts/Resource.pm \
@@ -1133,9 +1135,13 @@ perl_SCRIPTS = ldap/admin/src/scripts/SetupLog.pm \
 	ldap/admin/src/scripts/DialogManager.pm \
 	ldap/admin/src/scripts/Dialog.pm \
 	ldap/admin/src/scripts/DSDialogs.pm \
-	ldap/admin/src/scripts/Setup.pm
+	ldap/admin/src/scripts/Setup.pm \
+	ldap/admin/src/scripts/Migration.pm \
+	ldap/admin/src/scripts/DSMigration.pm
+
+property_DATA = ldap/admin/src/scripts/setup-ds.res \
+	ldap/admin/src/scripts/migrate-ds.res
 
-property_DATA = ldap/admin/src/scripts/setup-ds.res
 task_SCRIPTS = ldap/admin/src/scripts/template-bak2db \
 	ldap/admin/src/scripts/template-db2bak \
 	ldap/admin/src/scripts/template-db2index \

+ 28 - 6
aclocal.m4

@@ -1578,10 +1578,27 @@ linux*)
   # before this can be enabled.
   hardcode_into_libs=yes
 
+  # find out which ABI we are using
+  libsuff=
+  case "$host_cpu" in
+  x86_64*|s390x*|powerpc64*)
+    echo '[#]line __oline__ "configure"' > conftest.$ac_ext
+    if AC_TRY_EVAL(ac_compile); then
+      case `/usr/bin/file conftest.$ac_objext` in
+      *64-bit*)
+        libsuff=64
+        sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+        ;;
+      esac
+    fi
+    rm -rf conftest*
+    ;;
+  esac
+
   # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
-    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \[$]2)); skip = 1; } { if (!skip) print \[$]0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra"
   fi
 
   # We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -4288,6 +4305,9 @@ CC=$lt_[]_LT_AC_TAGVAR(compiler, $1)
 # Is the compiler the GNU C compiler?
 with_gcc=$_LT_AC_TAGVAR(GCC, $1)
 
+gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\`
+gcc_ver=\`gcc -dumpversion\`
+
 # An ERE matcher.
 EGREP=$lt_EGREP
 
@@ -4421,11 +4441,11 @@ striplib=$lt_striplib
 
 # Dependencies to place before the objects being linked to create a
 # shared library.
-predep_objects=$lt_[]_LT_AC_TAGVAR(predep_objects, $1)
+predep_objects=\`echo $lt_[]_LT_AC_TAGVAR(predep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Dependencies to place after the objects being linked to create a
 # shared library.
-postdep_objects=$lt_[]_LT_AC_TAGVAR(postdep_objects, $1)
+postdep_objects=\`echo $lt_[]_LT_AC_TAGVAR(postdep_objects, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Dependencies to place before the objects being linked to create a
 # shared library.
@@ -4437,7 +4457,7 @@ postdeps=$lt_[]_LT_AC_TAGVAR(postdeps, $1)
 
 # The library search path used internally by the compiler when linking
 # a shared library.
-compiler_lib_search_path=$lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1)
+compiler_lib_search_path=\`echo $lt_[]_LT_AC_TAGVAR(compiler_lib_search_path, $1) | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Method to check whether dependent libraries are shared objects.
 deplibs_check_method=$lt_deplibs_check_method
@@ -4517,7 +4537,7 @@ variables_saved_for_relink="$variables_saved_for_relink"
 link_all_deplibs=$_LT_AC_TAGVAR(link_all_deplibs, $1)
 
 # Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Run-time system search path for libraries
 sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
@@ -6353,6 +6373,7 @@ do
     done
   done
 done
+IFS=$as_save_IFS
 lt_ac_max=0
 lt_ac_count=0
 # Add /usr/xpg4/bin/sed as it is typically found on Solaris
@@ -6385,6 +6406,7 @@ for lt_ac_sed in $lt_ac_sed_list /usr/xpg4/bin/sed; do
 done
 ])
 SED=$lt_cv_path_SED
+AC_SUBST([SED])
 AC_MSG_RESULT([$SED])
 ])
 

+ 155 - 53
configure

@@ -465,7 +465,7 @@ ac_includes_default="\
 #endif"
 
 ac_default_prefix=/opt/$PACKAGE_NAME
-ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT build build_cpu build_vendor build_os host host_cpu host_vendor host_os CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CC CFLAGS ac_ct_CC CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBOBJS debug_defs BUNDLE_TRUE BUNDLE_FALSE enable_pam_passthru_TRUE enable_pam_passthru_FALSE enable_dna_TRUE enable_dna_FALSE enable_ldapi_TRUE enable_ldapi_FALSE enable_bitwise_TRUE enable_bitwise_FALSE configdir sampledatadir propertydir schemadir serverdir serverplugindir scripttemplatedir perldir infdir defaultuser defaultgroup instconfigdir WINNT_TRUE WINNT_FALSE LIBSOCKET LIBNSL LIBDL LIBCSTD LIBCRUN initdir HPUX_TRUE HPUX_FALSE SOLARIS_TRUE SOLARIS_FALSE PKG_CONFIG ICU_CONFIG NETSNMP_CONFIG PACKAGE_BASE_VERSION nspr_inc nspr_lib nspr_libdir nss_inc nss_lib nss_libdir ldapsdk_inc ldapsdk_lib ldapsdk_libdir ldapsdk_bindir db_inc db_incdir db_lib db_libdir db_bindir db_libver sasl_inc sasl_lib sasl_libdir svrcore_inc svrcore_lib icu_lib icu_inc icu_bin netsnmp_inc netsnmp_lib netsnmp_libdir netsnmp_link brand capbrand vendor LTLIBOBJS'
+ac_subst_vars='SHELL PATH_SEPARATOR PACKAGE_NAME PACKAGE_TARNAME PACKAGE_VERSION PACKAGE_STRING PACKAGE_BUGREPORT exec_prefix prefix program_transform_name bindir sbindir libexecdir datadir sysconfdir sharedstatedir localstatedir libdir includedir oldincludedir infodir mandir build_alias host_alias target_alias DEFS ECHO_C ECHO_N ECHO_T LIBS INSTALL_PROGRAM INSTALL_SCRIPT INSTALL_DATA CYGPATH_W PACKAGE VERSION ACLOCAL AUTOCONF AUTOMAKE AUTOHEADER MAKEINFO install_sh STRIP ac_ct_STRIP INSTALL_STRIP_PROGRAM mkdir_p AWK SET_MAKE am__leading_dot AMTAR am__tar am__untar MAINTAINER_MODE_TRUE MAINTAINER_MODE_FALSE MAINT build build_cpu build_vendor build_os host host_cpu host_vendor host_os CXX CXXFLAGS LDFLAGS CPPFLAGS ac_ct_CXX EXEEXT OBJEXT DEPDIR am__include am__quote AMDEP_TRUE AMDEP_FALSE AMDEPBACKSLASH CXXDEPMODE am__fastdepCXX_TRUE am__fastdepCXX_FALSE CC CFLAGS ac_ct_CC CCDEPMODE am__fastdepCC_TRUE am__fastdepCC_FALSE SED EGREP LN_S ECHO AR ac_ct_AR RANLIB ac_ct_RANLIB CPP CXXCPP F77 FFLAGS ac_ct_F77 LIBTOOL LIBOBJS debug_defs BUNDLE_TRUE BUNDLE_FALSE enable_pam_passthru_TRUE enable_pam_passthru_FALSE enable_dna_TRUE enable_dna_FALSE enable_ldapi_TRUE enable_ldapi_FALSE enable_bitwise_TRUE enable_bitwise_FALSE configdir sampledatadir propertydir schemadir serverdir serverplugindir scripttemplatedir perldir infdir defaultuser defaultgroup instconfigdir WINNT_TRUE WINNT_FALSE LIBSOCKET LIBNSL LIBDL LIBCSTD LIBCRUN initdir HPUX_TRUE HPUX_FALSE SOLARIS_TRUE SOLARIS_FALSE PKG_CONFIG ICU_CONFIG NETSNMP_CONFIG PACKAGE_BASE_VERSION nspr_inc nspr_lib nspr_libdir nss_inc nss_lib nss_libdir ldapsdk_inc ldapsdk_lib ldapsdk_libdir ldapsdk_bindir db_inc db_incdir db_lib db_libdir db_bindir db_libver sasl_inc sasl_lib sasl_libdir svrcore_inc svrcore_lib icu_lib icu_inc icu_bin netsnmp_inc netsnmp_lib netsnmp_libdir netsnmp_link brand capbrand vendor LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -3836,6 +3836,7 @@ do
     done
   done
 done
+IFS=$as_save_IFS
 lt_ac_max=0
 lt_ac_count=0
 # Add /usr/xpg4/bin/sed as it is typically found on Solaris
@@ -3870,6 +3871,7 @@ done
 fi
 
 SED=$lt_cv_path_SED
+
 echo "$as_me:$LINENO: result: $SED" >&5
 echo "${ECHO_T}$SED" >&6
 
@@ -4310,7 +4312,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 4313 "configure"' > conftest.$ac_ext
+  echo '#line 4315 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -5445,7 +5447,7 @@ fi
 
 
 # Provide some information about the compiler.
-echo "$as_me:5448:" \
+echo "$as_me:5450:" \
      "checking for Fortran 77 compiler version" >&5
 ac_compiler=`set X $ac_compile; echo $2`
 { (eval echo "$as_me:$LINENO: \"$ac_compiler --version </dev/null >&5\"") >&5
@@ -6508,11 +6510,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6511: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:6513: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:6515: \$? = $ac_status" >&5
+   echo "$as_me:6517: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -6776,11 +6778,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6779: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:6781: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:6783: \$? = $ac_status" >&5
+   echo "$as_me:6785: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -6880,11 +6882,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:6883: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:6885: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:6887: \$? = $ac_status" >&5
+   echo "$as_me:6889: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -8345,10 +8347,31 @@ linux*)
   # before this can be enabled.
   hardcode_into_libs=yes
 
+  # find out which ABI we are using
+  libsuff=
+  case "$host_cpu" in
+  x86_64*|s390x*|powerpc64*)
+    echo '#line 8354 "configure"' > conftest.$ac_ext
+    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+      case `/usr/bin/file conftest.$ac_objext` in
+      *64-bit*)
+        libsuff=64
+        sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+        ;;
+      esac
+    fi
+    rm -rf conftest*
+    ;;
+  esac
+
   # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
-    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra"
   fi
 
   # We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -9225,7 +9248,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 9228 "configure"
+#line 9251 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -9325,7 +9348,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 9328 "configure"
+#line 9351 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -9656,6 +9679,9 @@ CC=$lt_compiler
 # Is the compiler the GNU C compiler?
 with_gcc=$GCC
 
+gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\`
+gcc_ver=\`gcc -dumpversion\`
+
 # An ERE matcher.
 EGREP=$lt_EGREP
 
@@ -9789,11 +9815,11 @@ striplib=$lt_striplib
 
 # Dependencies to place before the objects being linked to create a
 # shared library.
-predep_objects=$lt_predep_objects
+predep_objects=\`echo $lt_predep_objects | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Dependencies to place after the objects being linked to create a
 # shared library.
-postdep_objects=$lt_postdep_objects
+postdep_objects=\`echo $lt_postdep_objects | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Dependencies to place before the objects being linked to create a
 # shared library.
@@ -9805,7 +9831,7 @@ postdeps=$lt_postdeps
 
 # The library search path used internally by the compiler when linking
 # a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path
+compiler_lib_search_path=\`echo $lt_compiler_lib_search_path | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Method to check whether dependent libraries are shared objects.
 deplibs_check_method=$lt_deplibs_check_method
@@ -9885,7 +9911,7 @@ variables_saved_for_relink="$variables_saved_for_relink"
 link_all_deplibs=$link_all_deplibs
 
 # Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Run-time system search path for libraries
 sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
@@ -11665,11 +11691,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11668: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11694: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:11672: \$? = $ac_status" >&5
+   echo "$as_me:11698: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -11769,11 +11795,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:11772: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:11798: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:11776: \$? = $ac_status" >&5
+   echo "$as_me:11802: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -12301,10 +12327,31 @@ linux*)
   # before this can be enabled.
   hardcode_into_libs=yes
 
+  # find out which ABI we are using
+  libsuff=
+  case "$host_cpu" in
+  x86_64*|s390x*|powerpc64*)
+    echo '#line 12334 "configure"' > conftest.$ac_ext
+    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+      case `/usr/bin/file conftest.$ac_objext` in
+      *64-bit*)
+        libsuff=64
+        sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+        ;;
+      esac
+    fi
+    rm -rf conftest*
+    ;;
+  esac
+
   # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
-    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra"
   fi
 
   # We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -12688,6 +12735,9 @@ CC=$lt_compiler_CXX
 # Is the compiler the GNU C compiler?
 with_gcc=$GCC_CXX
 
+gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\`
+gcc_ver=\`gcc -dumpversion\`
+
 # An ERE matcher.
 EGREP=$lt_EGREP
 
@@ -12821,11 +12871,11 @@ striplib=$lt_striplib
 
 # Dependencies to place before the objects being linked to create a
 # shared library.
-predep_objects=$lt_predep_objects_CXX
+predep_objects=\`echo $lt_predep_objects_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Dependencies to place after the objects being linked to create a
 # shared library.
-postdep_objects=$lt_postdep_objects_CXX
+postdep_objects=\`echo $lt_postdep_objects_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Dependencies to place before the objects being linked to create a
 # shared library.
@@ -12837,7 +12887,7 @@ postdeps=$lt_postdeps_CXX
 
 # The library search path used internally by the compiler when linking
 # a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path_CXX
+compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_CXX | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Method to check whether dependent libraries are shared objects.
 deplibs_check_method=$lt_deplibs_check_method
@@ -12917,7 +12967,7 @@ variables_saved_for_relink="$variables_saved_for_relink"
 link_all_deplibs=$link_all_deplibs_CXX
 
 # Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Run-time system search path for libraries
 sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
@@ -13339,11 +13389,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13342: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13392: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:13346: \$? = $ac_status" >&5
+   echo "$as_me:13396: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -13443,11 +13493,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:13446: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:13496: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:13450: \$? = $ac_status" >&5
+   echo "$as_me:13500: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -14888,10 +14938,31 @@ linux*)
   # before this can be enabled.
   hardcode_into_libs=yes
 
+  # find out which ABI we are using
+  libsuff=
+  case "$host_cpu" in
+  x86_64*|s390x*|powerpc64*)
+    echo '#line 14945 "configure"' > conftest.$ac_ext
+    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+      case `/usr/bin/file conftest.$ac_objext` in
+      *64-bit*)
+        libsuff=64
+        sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+        ;;
+      esac
+    fi
+    rm -rf conftest*
+    ;;
+  esac
+
   # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
-    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra"
   fi
 
   # We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -15275,6 +15346,9 @@ CC=$lt_compiler_F77
 # Is the compiler the GNU C compiler?
 with_gcc=$GCC_F77
 
+gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\`
+gcc_ver=\`gcc -dumpversion\`
+
 # An ERE matcher.
 EGREP=$lt_EGREP
 
@@ -15408,11 +15482,11 @@ striplib=$lt_striplib
 
 # Dependencies to place before the objects being linked to create a
 # shared library.
-predep_objects=$lt_predep_objects_F77
+predep_objects=\`echo $lt_predep_objects_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Dependencies to place after the objects being linked to create a
 # shared library.
-postdep_objects=$lt_postdep_objects_F77
+postdep_objects=\`echo $lt_postdep_objects_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Dependencies to place before the objects being linked to create a
 # shared library.
@@ -15424,7 +15498,7 @@ postdeps=$lt_postdeps_F77
 
 # The library search path used internally by the compiler when linking
 # a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path_F77
+compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_F77 | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Method to check whether dependent libraries are shared objects.
 deplibs_check_method=$lt_deplibs_check_method
@@ -15504,7 +15578,7 @@ variables_saved_for_relink="$variables_saved_for_relink"
 link_all_deplibs=$link_all_deplibs_F77
 
 # Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Run-time system search path for libraries
 sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
@@ -15646,11 +15720,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15649: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15723: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15653: \$? = $ac_status" >&5
+   echo "$as_me:15727: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -15914,11 +15988,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:15917: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:15991: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:15921: \$? = $ac_status" >&5
+   echo "$as_me:15995: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -16018,11 +16092,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16021: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16095: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:16025: \$? = $ac_status" >&5
+   echo "$as_me:16099: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -17483,10 +17557,31 @@ linux*)
   # before this can be enabled.
   hardcode_into_libs=yes
 
+  # find out which ABI we are using
+  libsuff=
+  case "$host_cpu" in
+  x86_64*|s390x*|powerpc64*)
+    echo '#line 17564 "configure"' > conftest.$ac_ext
+    if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
+  (eval $ac_compile) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+      case `/usr/bin/file conftest.$ac_objext` in
+      *64-bit*)
+        libsuff=64
+        sys_lib_search_path_spec="/lib${libsuff} /usr/lib${libsuff} /usr/local/lib${libsuff}"
+        ;;
+      esac
+    fi
+    rm -rf conftest*
+    ;;
+  esac
+
   # Append ld.so.conf contents to the search path
   if test -f /etc/ld.so.conf; then
-    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
-    sys_lib_dlsearch_path_spec="/lib /usr/lib $lt_ld_extra"
+    lt_ld_extra=`awk '/^include / { system(sprintf("cd /etc; cat %s 2>/dev/null", \$2)); skip = 1; } { if (!skip) print \$0; skip = 0; }' < /etc/ld.so.conf | $SED -e 's/#.*//;s/[:,	]/ /g;s/=[^=]*$//;s/=[^= ]* / /g;/^$/d' | tr '\n' ' '`
+    sys_lib_dlsearch_path_spec="/lib${libsuff} /usr/lib${libsuff} $lt_ld_extra"
   fi
 
   # We used to test for /lib/ld.so.1 and disable shared libraries on
@@ -17870,6 +17965,9 @@ CC=$lt_compiler_GCJ
 # Is the compiler the GNU C compiler?
 with_gcc=$GCC_GCJ
 
+gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\`
+gcc_ver=\`gcc -dumpversion\`
+
 # An ERE matcher.
 EGREP=$lt_EGREP
 
@@ -18003,11 +18101,11 @@ striplib=$lt_striplib
 
 # Dependencies to place before the objects being linked to create a
 # shared library.
-predep_objects=$lt_predep_objects_GCJ
+predep_objects=\`echo $lt_predep_objects_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Dependencies to place after the objects being linked to create a
 # shared library.
-postdep_objects=$lt_postdep_objects_GCJ
+postdep_objects=\`echo $lt_postdep_objects_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Dependencies to place before the objects being linked to create a
 # shared library.
@@ -18019,7 +18117,7 @@ postdeps=$lt_postdeps_GCJ
 
 # The library search path used internally by the compiler when linking
 # a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path_GCJ
+compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_GCJ | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Method to check whether dependent libraries are shared objects.
 deplibs_check_method=$lt_deplibs_check_method
@@ -18099,7 +18197,7 @@ variables_saved_for_relink="$variables_saved_for_relink"
 link_all_deplibs=$link_all_deplibs_GCJ
 
 # Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Run-time system search path for libraries
 sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
@@ -18351,6 +18449,9 @@ CC=$lt_compiler_RC
 # Is the compiler the GNU C compiler?
 with_gcc=$GCC_RC
 
+gcc_dir=\`gcc -print-file-name=. | $SED 's,/\.$,,'\`
+gcc_ver=\`gcc -dumpversion\`
+
 # An ERE matcher.
 EGREP=$lt_EGREP
 
@@ -18484,11 +18585,11 @@ striplib=$lt_striplib
 
 # Dependencies to place before the objects being linked to create a
 # shared library.
-predep_objects=$lt_predep_objects_RC
+predep_objects=\`echo $lt_predep_objects_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Dependencies to place after the objects being linked to create a
 # shared library.
-postdep_objects=$lt_postdep_objects_RC
+postdep_objects=\`echo $lt_postdep_objects_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Dependencies to place before the objects being linked to create a
 # shared library.
@@ -18500,7 +18601,7 @@ postdeps=$lt_postdeps_RC
 
 # The library search path used internally by the compiler when linking
 # a shared library.
-compiler_lib_search_path=$lt_compiler_lib_search_path_RC
+compiler_lib_search_path=\`echo $lt_compiler_lib_search_path_RC | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Method to check whether dependent libraries are shared objects.
 deplibs_check_method=$lt_deplibs_check_method
@@ -18580,7 +18681,7 @@ variables_saved_for_relink="$variables_saved_for_relink"
 link_all_deplibs=$link_all_deplibs_RC
 
 # Compile-time system search path for libraries
-sys_lib_search_path_spec=$lt_sys_lib_search_path_spec
+sys_lib_search_path_spec=\`echo $lt_sys_lib_search_path_spec | \$SED -e "s@\${gcc_dir}@\\\${gcc_dir}@g;s@\${gcc_ver}@\\\${gcc_ver}@g"\`
 
 # Run-time system search path for libraries
 sys_lib_dlsearch_path_spec=$lt_sys_lib_dlsearch_path_spec
@@ -25895,6 +25996,7 @@ s,@ac_ct_CC@,$ac_ct_CC,;t t
 s,@CCDEPMODE@,$CCDEPMODE,;t t
 s,@am__fastdepCC_TRUE@,$am__fastdepCC_TRUE,;t t
 s,@am__fastdepCC_FALSE@,$am__fastdepCC_FALSE,;t t
+s,@SED@,$SED,;t t
 s,@EGREP@,$EGREP,;t t
 s,@LN_S@,$LN_S,;t t
 s,@ECHO@,$ECHO,;t t

+ 1 - 1
ldap/admin/src/create_instance.c

@@ -437,7 +437,7 @@ static char *sanity_check(server_config_s *cf, char *param_name)
     /* if we don't need to start the server right away, we can skip the
     port number checks
     */
-    if (!needToStartServer(cf))
+    if (needToStartServer(cf))
     {
         if( (t = create_instance_checkports(cf)))
         {

+ 0 - 32
ldap/admin/src/migrateTo11.in

@@ -294,38 +294,6 @@ sub copyDatabases {
 #    updateDBguardian($newdbdir);
 }
 
-sub copySecurityFiles {
-    my $oldroot = shift;
-    my $inst = shift;
-    my $destdir = shift;
-    
-    if (! -d "$oldroot/alias") {
-        debug(0, "Error: security file directory $oldroot/alias not found\n");
-    } elsif (! -d $destdir) {
-        debug(0, "Error: new security file directory $destdir not found\n");
-    } else {
-        debug(1, "Copying $oldroot/alias/$inst-cert8.db to $destdir/cert8.db\n");
-        system ("cp -p $oldroot/alias/$inst-cert8.db $destdir/cert8.db") == 0 or
-            die "Error: could not copy $oldroot/alias/$inst-cert8.db to $destdir/cert8.db: $!";
-        debug(1, "Copying $oldroot/alias/$inst-key3.db to $destdir/key3.db\n");
-        system ("cp -p $oldroot/alias/$inst-key3.db $destdir/key3.db") == 0 or
-            die "Error: could not copy $oldroot/alias/$inst-key3.db to $destdir/key3.db: $!";
-        debug(1, "Copying $oldroot/alias/secmod.db to $destdir/secmod.db\n");
-        system ("cp -p $oldroot/alias/secmod.db $destdir/secmod.db") == 0 or
-            die "Error: could not copy $oldroot/alias/secmod.db to $destdir/secmod.db: $!";
-        if (-f "$oldroot/alias/$inst-pin.txt") {
-            debug(1, "Copying $oldroot/alias/$inst-pin.txt to $destdir/pin.txt\n");
-                system ("cp -p $oldroot/alias/$inst-pin.txt $destdir/pin.txt") == 0 or
-                die "Error: could not copy $oldroot/alias/$inst-pin.txt to $destdir/pin.txt: $!";
-        }
-        if (-f "$oldroot/shared/config/certmap.conf") {
-            debug(1, "Copying $oldroot/shared/config/certmap.conf to $destdir/certmap.conf\n");
-                system ("cp -p $oldroot/shared/config/certmap.conf $destdir/certmap.conf") == 0 or
-                die "Error: could not copy $oldroot/shared/config/certmap.conf to $destdir/certmap.conf: $!";
-        }
-    }
-}
-
 sub copyChangelogDB {
     my $oldroot = shift;
     my $inst = shift;

+ 437 - 0
ldap/admin/src/scripts/DSMigration.pm.in

@@ -0,0 +1,437 @@
+# 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) 2007 Red Hat, Inc.
+# All rights reserved.
+# END COPYRIGHT BLOCK
+#
+
+###########################
+#
+# This perl module provides a way to set up a new installation after
+# the binaries have already been extracted.  This is typically after
+# using native packaging support to install the package e.g. RPM,
+# pkgadd, depot, etc.  This script will show the license, readme,
+# dsktune, then run the usual setup pre and post installers.
+#
+##########################
+
+package DSMigration;
+use Migration;
+use Util;
+use Inf;
+
+# tempfiles
+use File::Temp qw(tempfile tempdir);
+
+# load perldap
+use Mozilla::LDAP::Conn;
+use Mozilla::LDAP::Utils qw(normalizeDN);
+use Mozilla::LDAP::API qw(ldap_explode_dn);
+use Mozilla::LDAP::LDIF;
+
+use Exporter;
+@ISA       = qw(Exporter);
+@EXPORT    = qw(migrateDS);
+@EXPORT_OK = qw(migrateDS);
+
+use strict;
+
+use SetupLog;
+use Util;
+
+# these are the attributes for which we will always use
+# the new value, or which do not apply anymore
+my %ignoreOld =
+(
+ 'nsslapd-errorlog'                => 'nsslapd-errorlog',
+ 'nsslapd-accesslog'               => 'nsslapd-accesslog',
+ 'nsslapd-auditlog'                => 'nsslapd-auditlog',
+ 'nskeyfile'                       => 'nsKeyfile',
+ 'nscertfile'                      => 'nsCertfile',
+ 'nsslapd-pluginpath'              => 'nsslapd-pluginPath',
+ 'nsslapd-plugintype'              => 'nsslapd-pluginType',
+ 'nsslapd-pluginversion'           => 'nsslapd-pluginVersion',
+ 'nsslapd-plugin-depends-on-named' => 'nsslapd-plugin-depends-on-named',
+# these are new attrs that we should just pass through
+ 'nsslapd-schemadir'               => 'nsslapd-schemadir',
+ 'nsslapd-lockdir'                 => 'nsslapd-lockdir',
+ 'nsslapd-tmpdir'                  => 'nsslapd-tmpdir',
+ 'nsslapd-certdir'                 => 'nsslapd-certdir',
+ 'nsslapd-ldapifilepath'           => 'nsslapd-ldapifilepath',
+ 'nsslapd-ldapilisten'             => 'nsslapd-ldapilisten',
+ 'nsslapd-ldapiautobind'           => 'nsslapd-ldapiautobind',
+ 'nsslapd-ldapimaprootdn'          => 'nsslapd-ldapimaprootdn',
+ 'nsslapd-ldapimaptoentries'       => 'nsslapd-ldapimaptoentries',
+ 'nsslapd-ldapiuidnumbertype'      => 'nsslapd-ldapiuidnumbertype',
+ 'nsslapd-ldapigidnumbertype'      => 'nsslapd-ldapigidnumbertype',
+ 'nsslapd-ldapientrysearchbase'    => 'nsslapd-ldapientrysearchbase',
+ 'nsslapd-ldapiautodnsuffix'       => 'nsslapd-ldapiautodnsuffix'
+);
+
+# these are the attributes for which we will always use
+# the old value
+my %alwaysUseOld =
+(
+ 'aci'      => 'aci'
+);
+
+my $pkgname; # global used in several different places - set in migrateDS
+my $oldsroot; # global used in several different places - set in migrateDS
+
+sub getNewDbDir {
+    my ($ent, $attr, $inst) = @_;
+    my %objclasses = map { lc($_) => $_ } $ent->getValues('objectclass');
+    my $cn = $ent->getValues('cn');
+    my $newval;
+    if ($objclasses{nsbackendinstance}) {
+        $newval = "@localstatedir@/lib/$pkgname/$inst/db/$cn";
+    } elsif (lc $cn eq 'config') {
+        $newval = "@localstatedir@/lib/$pkgname/$inst/db";
+    } elsif (lc $cn eq 'changelog5') {
+        $newval = "@localstatedir@/lib/$pkgname/$inst/cldb";
+    }
+    debug(2, "New value [$newval] for attr $attr in entry ", $ent->getDN(), "\n");
+    return $newval;
+}
+
+sub migrateCredentials {
+    my ($ent, $attr, $inst) = @_;
+    my $oldval = $ent->getValues($attr);
+    debug(3, "Executing migratecred -o $oldsroot/$inst -n @instconfigdir@/$inst -c $oldval . . .\n");
+    my $newval = `migratecred -o $oldsroot/$inst -n @instconfigdir@/$inst -c $oldval`;
+    debug(3, "Converted old value [$oldval] to new value [$newval] for attr $attr in entry ", $ent->getDN(), "\n");
+    return $newval;
+}
+
+# these are attributes that we have to transform from
+# the old value to the new value (e.g. a pathname)
+# The key of this hash is the attribute name.  The value
+# is an anonymous sub which takes two arguments - the entry
+# and the old value.  The return value of the sub is
+# the new value
+my %transformAttr =
+(
+ 'nsslapd-directory' => \&getNewDbDir,
+ 'nsslapd-db-logdirectory' => \&getNewDbDir,
+ 'nsslapd-changelogdir' => \&getNewDbDir,
+ 'nsds5replicacredentials' => \&migrateCredentials,
+ 'nsmultiplexorcredentials' => \&migrateCredentials
+);
+
+sub copyDatabaseDirs {
+    my $srcdir = shift;
+    my $destdir = shift;
+    if (-d $srcdir && ! -d $destdir) {
+        debug(1, "Copying database directory $srcdir to $destdir\n");
+        system ("cp -p -r $srcdir $destdir") == 0 or
+            die "Could not copy database directory $srcdir to $destdir: $?";
+    } elsif (! -d $srcdir) {
+        die "Error: database directory $srcdir does not exist";
+    } else {
+        debug(1, "The destination directory $destdir already exists, copying files/dirs individually\n");
+        foreach my $file (glob("$srcdir/*")) {
+            debug(3, "Copying $file to $destdir\n");
+            if (-f $file) {
+                system ("cp -p $file $destdir") == 0 or
+                    die "Error: could not copy $file to $destdir: $!";
+            } elsif (-d $file) {
+                system ("cp -p -r $file $destdir") == 0 or
+                    die "Error: could not copy $file to $destdir: $!";
+            }
+        }
+    }
+}
+
+sub copyDatabases {
+    my $oldroot = shift;
+    my $inst = shift;
+    my $newdbdir = shift;
+
+    # global config and instance specific config are children of this entry
+    my $basedbdn = normalizeDN("cn=ldbm database,cn=plugins,cn=config");
+    # get the list of databases, their index and transaction log locations
+    my $fname = "$oldroot/$inst/config/dse.ldif";
+    open( DSELDIF, "$fname" ) || die "Can't open $fname: $!";
+    my $in = new Mozilla::LDAP::LDIF(*DSELDIF);
+    my $targetdn = normalizeDN("cn=config,cn=ldbm database,cn=plugins,cn=config");
+    while (my $ent = readOneEntry $in) {
+        next if (!$ent->getDN()); # just skip root dse
+        # look for the one level children of $basedbdn
+        my @rdns = ldap_explode_dn($ent->getDN(), 0);
+        my $parentdn = normalizeDN(join(',', @rdns[1..$#rdns]));
+        if ($parentdn eq $basedbdn) {
+            my $cn = $ent->getValues('cn');
+            my %objclasses = map { lc($_) => $_ } $ent->getValues('objectclass');
+            if ($cn eq 'config') { # global config
+                debug(1, "Found ldbm database plugin config entry ", $ent->getDN(), "\n");
+                my $dir = $ent->getValues('nsslapd-directory');
+                my $homedir = $ent->getValues('nsslapd-db-home-directory');
+                my $logdir = $ent->getValues('nsslapd-db-logdirectory');
+                debug(1, "old db dir = $dir homedir = $homedir logdir = $logdir\n");
+                my $srcdir = $homedir || $dir || "$oldroot/$inst/db";
+                copyDatabaseDirs($srcdir, $newdbdir);
+                copyDatabaseDirs($logdir, $newdbdir) if ($logdir && $logdir ne $srcdir);
+            } elsif ($objclasses{nsbackendinstance}) {
+                debug(1, "Found ldbm database instance entry ", $ent->getDN(), "\n");
+                my $dir = $ent->getValues('nsslapd-directory');
+                # the default db instance directory is
+                # $oldroot/$inst/$cn
+                debug(1, "old instance $cn dbdir $dir\n");
+                my $srcdir = $dir || "$oldroot/$inst/db/$cn";
+                copyDatabaseDirs($srcdir, "$newdbdir/$cn");
+            } # else just ignore for now
+        }
+    }
+    close DSELDIF;
+}
+
+sub copyChangelogDB {
+    my $oldroot = shift;
+    my $inst = shift;
+    my $newdbdir = shift;
+    # changelog config entry
+    my $cldn = normalizeDN("cn=changelog5, cn=config");
+    my $fname = "$oldroot/$inst/config/dse.ldif";
+    open( DSELDIF, "$fname" ) || die "Can't open $fname: $!";
+    my $in = new Mozilla::LDAP::LDIF(*DSELDIF);
+    while (my $ent = readOneEntry $in) {
+        my $targetdn = normalizeDN($ent->getDN());
+        if ($targetdn eq $cldn) {
+            my $oldcldir = $ent->getValues('nsslapd-changelogdir');
+            debug(1, "old cldb dir = $oldcldir\n");
+            my $srcdir = $oldcldir || "$oldroot/$inst/cldb";
+            copyDatabaseDirs($srcdir, $newdbdir);
+            last;
+        }
+    }
+    close DSELDIF;
+}
+
+sub fixAttrsInEntry {
+    my ($ent, $inst) = @_;
+    for my $attr (keys %{$ent}) {
+        my $lcattr = lc $attr;
+        if ($transformAttr{$lcattr}) {
+            $ent->setValues($attr, &{$transformAttr{$lcattr}}($ent, $attr, $inst));
+        }
+    }
+}
+
+sub mergeEntries {
+    my ($old, $new, $inst) = @_;
+    my %inoldonly; # attrs in old entry but not new one
+    my %innewonly; # attrs in new entry but not old one
+    my @attrs; # attrs common to old and new
+    # if the attribute exists in the old entry but not the new one
+    # we should probably add it (checking for special cases first)
+    # if the attribute exists in the new entry but not the old one
+    # we might have to delete it from the new entry
+    # first, get a list of all attributes
+    foreach my $attr (keys %{$old}) {
+        if (! $new->exists($attr)) {
+            $inoldonly{$attr} = $attr;
+        } else {
+            push @attrs, $attr;
+        }
+    }
+    foreach my $attr (keys %{$new}) {
+        if (! $old->exists($attr)) {
+            $innewonly{$attr} = $attr;
+        }
+    }
+            
+    # iterate through the attr lists
+    my $cn = lc $new->getValues("cn");
+    foreach my $attr (keys %inoldonly, keys %innewonly, @attrs) {
+        my $lcattr = lc $attr;
+        if ($ignoreOld{$lcattr}) {
+            next; # use new value or just omit if attr is obsolete
+        } elsif ($transformAttr{$lcattr}) {
+            # only transform if the value is in the old entry
+            if (!$innewonly{$attr}) {
+                $new->setValues($attr, &{$transformAttr{$lcattr}}($old, $attr, $inst));
+            }
+        } elsif ($cn eq "internationalization plugin" and $lcattr eq "nsslapd-pluginarg0") {
+            next; # use the new value of this path name
+        } elsif ($cn eq "referential integrity postoperation" and $lcattr eq "nsslapd-pluginarg1") {
+            next; # use the new value of this path name
+        } elsif ($innewonly{$attr}) {
+            $new->remove($attr); # in new but not old - just remove it
+        } else {
+            $new->setValues($attr, $old->getValues($attr)); # use old value
+        }
+    }
+}
+
+sub mergeDseLdif {
+    my $oldroot = shift;
+    my $inst = shift;
+    my $ent;
+
+    # first, read in old file
+    my %olddse; # map of normalized DN to Entry
+    my @olddns; # the DNs in their original order
+    my $fname = "$oldroot/$inst/config/dse.ldif";
+    open( OLDDSELDIF, $fname ) || die "Can't open $fname: $!";
+    my $in = new Mozilla::LDAP::LDIF(*OLDDSELDIF);
+    while ($ent = readOneEntry $in) {
+        my $dn = normalizeDN($ent->getDN());
+        push @olddns, $dn;
+        $olddse{$dn} = $ent;
+    }
+    close OLDDSELDIF;
+
+    # next, read in new file
+    my %newdse; # map of normalized DN to Entry
+    my @newdns; # the DNs in their original order that are not in olddns
+    $fname = "@instconfigdir@/$inst/dse.ldif";
+    open( NEWDSELDIF, $fname ) || die "Can't open $fname: $!";
+    $in = new Mozilla::LDAP::LDIF(*NEWDSELDIF);
+    while ($ent = readOneEntry $in) {
+        my $dn = normalizeDN($ent->getDN());
+        $newdse{$dn} = $ent;
+        if (! exists $olddse{$dn}) {
+            push @newdns, $dn;
+        }
+    }
+    close NEWDSELDIF;
+
+    # temp file for new, merged dse.ldif
+    my ($dsefh, $tmpdse) = tempfile(SUFFIX => '.ldif');
+    # now, compare entries
+    # if the entry exists in the old tree but not the new, add it
+    # if the entry exists in the new tree but not the old, delete it
+    # otherwise, merge the entries
+    # @olddns contains the dns in the old dse.ldif, including ones that
+    # may also be in the new dse.ldif
+    # @newdns contains dns that are only in the new dse.ldif
+    for my $dn (@olddns, @newdns) {
+        my $oldent = $olddse{$dn};
+        my $newent = $newdse{$dn};
+        my $outputent;
+        if ($oldent && !$newent) {
+            # may have to fix up some values in the old entry
+            fixAttrsInEntry($oldent, $inst);
+            # output $oldent
+            $outputent = $oldent;
+        } elsif (!$oldent && $newent) {
+            next if ($dn =~ /o=deleteAfterMigration/i);
+            # output $newent
+            $outputent = $newent;
+        } else { #merge
+            # $newent will contain the merged entry
+            mergeEntries($oldent, $newent, $inst);
+            $outputent = $newent;
+        }
+        # special fix for rootDSE - perldap doesn't like "" for a dn
+        if (! $outputent->getDN()) {
+            my $ary = $outputent->getLDIFrecords();
+            shift @$ary; # remove "dn"
+            shift @$ary; # remove the empty dn value
+            print $dsefh "dn:\n";
+            print $dsefh (Mozilla::LDAP::LDIF::pack_LDIF (78, $ary), "\n");
+        } else {
+            Mozilla::LDAP::LDIF::put_LDIF($dsefh, 78, $outputent);
+        }
+    }
+    close $dsefh;
+
+    return $tmpdse;
+}
+
+sub migrateDS {
+    my $mig = shift;
+    $pkgname = $mig->{pkgname}; # set globals
+    $oldsroot = $mig->{oldsroot}; # set globals
+
+    # for each instance
+    foreach my $inst (@{$mig->{instances}}) {
+        if (-f "@instconfigdir@/$inst/dse.ldif") {
+            $mig->msg($WARN, 'instance_already_exists', "@instconfigdir@/$inst/dse.ldif");
+            next;
+        }
+        # set instance specific defaults
+        my $newdbdir = "@localstatedir@/lib/$pkgname/$inst/db";
+        my $newcertdir = "@instconfigdir@/$inst";
+        my $newcldbdir = "@localstatedir@/lib/$pkgname/$inst/cldb";
+
+        # extract the information needed for ds_newinst.pl
+        my $configdir = "$oldsroot/$inst/config";
+        my $inf = createInfFromConfig($configdir, $inst);
+        debug(2, "Using inffile $inf->{filename} created from $configdir\n");
+
+        # create the new instance
+        my ($rc, $output) = createDSInstance($inf);
+        unlink($inf->{filename});
+        if ($rc) {
+            $mig->msg($FATAL, 'error_creating_dsinstance', $rc, $output);
+            return 0;
+        } else {
+            $mig->msg('created_dsinstance', $output);
+        }
+
+        # copy over the files/directories
+        # copy the databases
+        copyDatabases($oldsroot, $inst, $newdbdir);
+
+        # copy the security related files
+        $mig->migrateSecurityFiles($inst, $newcertdir);
+
+        # copy the repl changelog database
+        copyChangelogDB($oldsroot, $inst, $newcldbdir);
+
+        # merge the old info into the new dse.ldif
+        my $tmpdse = mergeDseLdif($oldsroot, $inst);
+
+        # get user/group of new dse
+        my ($dev, $ino, $mode, $uid, $gid, @rest) = stat "@instconfigdir@/$inst/dse.ldif";
+        # save the original new dse.ldif
+        system("cp -p @instconfigdir@/$inst/dse.ldif @instconfigdir@/$inst/dse.ldif.premigrate");
+        # copy the new one
+        system("cp $tmpdse @instconfigdir@/$inst/dse.ldif");
+        # change owner/group
+        chmod $mode, "@instconfigdir@/$inst/dse.ldif";
+        chown $uid, $gid, "@instconfigdir@/$inst/dse.ldif";
+
+        # remove the temp one
+        unlink($tmpdse);
+    }
+
+    return 1;
+}
+
+#############################################################################
+# Mandatory TRUE return value.
+#
+1;

+ 294 - 0
ldap/admin/src/scripts/Migration.pm.in

@@ -0,0 +1,294 @@
+# 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) 2007 Red Hat, Inc.
+# All rights reserved.
+# END COPYRIGHT BLOCK
+#
+
+###########################
+#
+# This perl module provides a way to set up a new installation after
+# the binaries have already been extracted.  This is typically after
+# using native packaging support to install the package e.g. RPM,
+# pkgadd, depot, etc.  This script will show the license, readme,
+# dsktune, then run the usual setup pre and post installers.
+#
+##########################
+
+package Migration;
+use Setup;
+
+use Exporter ();
+@ISA       = qw(Exporter Setup);
+@EXPORT    = qw();
+@EXPORT_OK = qw();
+
+# tempfiles
+use File::Temp qw(tempfile tempdir);
+
+# hostname
+use Net::Domain qw(hostfqdn);
+
+# load perldap
+use Mozilla::LDAP::Conn;
+use Mozilla::LDAP::Utils qw(normalizeDN);
+use Mozilla::LDAP::API qw(ldap_explode_dn);
+use Mozilla::LDAP::LDIF;
+
+use Getopt::Long;
+
+use File::Temp qw(tempfile tempdir);
+
+use SetupLog;
+use Util;
+
+# process command line options
+Getopt::Long::Configure(qw(bundling)); # bundling allows -ddddd
+
+sub VersionMessage {
+    print "@capbrand@ Directory Server Migration Program Version @PACKAGE_VERSION@\n";
+}
+
+sub HelpMessage {
+    print <<EOF;
+
+INTRODUCTION
+
+This script will copy instances (data and configuration) from the old
+server root directory to their new FHS locations.  This script does a
+copy only - the data in the old instances will be left untouched.  The
+old instances must be shutdown first to ensure that the databases are
+copied safely.  The new instances will not be started by migration,
+but can be started after running migration.
+
+USAGE
+
+ $0 [--options] -- [args]
+
+options:
+    --help        This message
+    --version     Print the version and exit
+    --debug       Turn on debugging
+    --oldsroot    The old server root directory to migrate from
+    --actualsroot This is the old location of the old server root.  See below.
+    --silent      Use silent setup - no user input
+    --file=name   Use the file 'name' in .inf format to supply the default answers
+    --keepcache   Do not delete the temporary .inf file generated by this program
+    --logfile     Log migration messages to this file - otherwise, a temp file will be used
+    --instance    By default, all directory server instances will be migrated.  You can use
+                  this argument to specify one or more (e.g. -i slapd-foo -i slapd-bar) if
+                  you do not want to migrate all of them.
+For all options, you can also use the short name e.g. -h, -d, etc.  For the -d argument,
+specifying it more than once will increase the debug level e.g. -ddddd
+
+args:
+You can supply default .inf data in this format:
+    section.param=value
+e.g.
+    General.FullMachineName=foo.example.com
+or
+    "slapd.Suffix=dc=example, dc=com"
+Values passed in this manner will override values in an .inf file given with the -f argument.
+
+actualsroot:
+This is used when you must migrate from one machine to another.  The
+usual case is that you have mounted the old server root on a different
+root directory, either via a network mount, or by copying a tarball
+made using a relative directory on the source machine to the
+destination machine and untarring it.
+
+For example: machineA is a 32bit machine, and you want to migrate your
+servers to a new 64bit machine.  Lets assume your old server root on
+machineA was /opt/myds, and your new machine also wants to use a
+server root of /opt/myds.  There are a couple of different ways to
+proceed.  Either make a tarball of opt/myds from machineA using a
+relative path (i.e. NOT /opt/myds) or use NFS to mount
+machineA:/opt/myds on a different mount point
+(e.g. machineB:/migration/opt/myds).
+
+If you do this, you should give the old "real" server root (/opt/myds)
+as the --actualsroot argument, and use /migration/opt/myds for the
+--oldsroot argument.  That is, the oldsroot is the physical location of
+the files on disk.  The actualsroot is the old value of the server root
+on the source machine.
+EOF
+}
+
+sub init {
+    my $self = shift;
+    $self->{res} = shift;
+    my ($silent, $inffile, $keep, $preonly, $logfile, $oldsroot, $actualsroot);
+    my @instances;
+
+    GetOptions('help|h|?' => sub { VersionMessage(); HelpMessage(); exit 0 },
+               'version|v' => sub { VersionMessage(); exit 0 },
+               'debug|d+' => \$Util::debuglevel,
+               'silent|s' => \$silent,
+               'file|f=s' => \$inffile,
+               'keepcache|k' => \$keep,
+               'preonly|p' => \$preonly,
+               'logfile|l=s' => \$logfile,
+               'oldsroot|o=s' => \$oldsroot,
+               'actualsroot|a=s' => \$actualsroot,
+               'instance|i=s' => \@instances
+               );
+
+    my $pkgname = "@package_name@";
+	# this is the new pkgname which may be something like
+	# fedora-ds-base - we have to strip off the -suffix
+    if ($pkgname =~ /-(core|base)$/) {
+        $pkgname =~ s/-(core|base)$//;
+    }
+    my $oldpkgname = $pkgname;
+
+    $self->{pkgname} = $pkgname;
+    $self->{oldsroot} = $oldsroot || "/opt/$oldpkgname";
+    $self->{actualsroot} = $actualsroot || $oldsroot;
+    $self->{silent} = $silent;
+    $self->{inffile} = $inffile;
+    $self->{keep} = $keep;
+    $self->{preonly} = $preonly;
+    $self->{logfile} = $logfile;
+    $self->{log} = new SetupLog($self->{logfile}, "migrate");
+    # if user supplied inf file, use that to initialize
+    if (defined($self->{inffile})) {
+        $self->{inf} = new Inf($self->{inffile});
+    } else {
+        $self->{inf} = new Inf;
+    }
+    my $fh;
+    # create a temp inf file for writing for other processes
+    # never overwrite the user supplied inf file
+    ($fh, $self->{inffile}) = tempfile("migrateXXXXXX", UNLINK => !$keep,
+                                       SUFFIX => ".inf", OPEN => 0,
+                                       DIR => File::Spec->tmpdir);
+    $self->{inf}->{filename} = $self->{inffile};
+
+    # see if user passed in default inf values - also, command line
+    # arguments override those passed in via an inf file - this
+    # allows the reuse of .inf files with some parameters overridden
+    for (@ARGV) {
+        if (/^([\w_-]+)\.([\w_-]+)=(.*)$/) { # e.g. section.param=value
+            $self->{inf}->{$1}->{$2} = $3;
+        } else { # error
+            print STDERR "Error: unknown command line option $_\n";
+            usage();
+            exit 1;
+        }
+    }
+
+    # this is the base config directory - the directory containing
+    # the slapd-instance instance specific config directories
+    $self->{configdir} = $ENV{DS_CONFIG_DIR} || "@instconfigdir@";
+
+	# get list of instances to migrate
+    if (! @instances) {
+        # an instance must be a directory called $oldsroot/slapd-something and the file
+        # $oldsroot/slapd-something/config/dse.ldif must exist
+        @instances = grep { -d && -f "$_/config/dse.ldif" && ($_ =~ s,$self->{oldsroot}/,,) }
+        	glob("$self->{oldsroot}/slapd-*");
+    }
+
+    die "No instances found to migrate" unless (@instances);
+
+    $self->{instances} = \@instances;
+}
+
+sub doExit {
+    my $self = shift;
+    $self->msg($FATAL, 'migration_exiting', $self->{log}->{filename});
+	exit 1;
+}
+
+sub migrateSecurityFiles {
+    my $self = shift;
+    my $inst = shift;
+    my $destdir = shift;
+    my $oldroot = $self->{oldsroot};
+    
+    if (! -d "$oldroot/alias") {
+        $self->msg('old_secdir_error', "$oldroot/alias", $!);
+        return 0;
+    } elsif (! -d $destdir) {
+        $self->msg('new_secdir_error', $destdir, $!);
+        return 0;
+    } else {
+        $self->log($INFO, "Copying $oldroot/alias/$inst-cert8.db to $destdir/cert8.db\n");
+        if (system ("cp -p $oldroot/alias/$inst-cert8.db $destdir/cert8.db")) {
+            $self->msg($FATAL, 'error_copying_certdb', "$oldroot/alias/$inst-cert8.db",
+                       "$destdir/cert8.db", $!);
+            return 0;
+        }
+        $self->log($INFO, "Copying $oldroot/alias/$inst-key3.db to $destdir/key3.db\n");
+        if (system ("cp -p $oldroot/alias/$inst-key3.db $destdir/key3.db")) {
+            $self->msg($FATAL, 'error_copying_keydb', "$oldroot/alias/$inst-key3.db",
+                       "$destdir/key3.db", $!);
+            return 0;
+        }
+        $self->log($INFO, "Copying $oldroot/alias/secmod.db to $destdir/secmod.db\n");
+        if (system ("cp -p $oldroot/alias/secmod.db $destdir/secmod.db")) {
+            $self->msg($FATAL, 'error_copying_secmoddb', "$oldroot/alias/secmod.db",
+                       "$destdir/secmod.db", $!);
+            return 0;
+        }
+        if (-f "$oldroot/alias/$inst-pin.txt") {
+            $self->log($INFO, "Copying $oldroot/alias/$inst-pin.txt to $destdir/pin.txt\n");
+            if (system ("cp -p $oldroot/alias/$inst-pin.txt $destdir/pin.txt")) {
+                $self->msg($FATAL, 'error_copying_pinfile', "$oldroot/alias/$inst-pin.txt",
+                           "$destdir/pin.txt", $!);
+                return 0;
+            }
+        } else {
+            $self->log($INFO, "No $oldroot/alias/$inst-pin.txt to migrate\n");
+        }
+            
+        if (-f "$oldroot/shared/config/certmap.conf") {
+            $self->log($INFO, "Copying $oldroot/shared/config/certmap.conf to $destdir/certmap.conf\n");
+            if (system ("cp -p $oldroot/shared/config/certmap.conf $destdir/certmap.conf")) {
+                $self->msg($FATAL, 'error_copying_certmap', "$oldroot/shared/config/certmap.conf",
+                           "$destdir/certmap.conf", $!);
+                return 0;
+            }
+        } else {
+            $self->log($INFO, "No $oldroot/shared/config/certmap.conf to migrate\n");
+        }
+    }
+
+    return 1;
+}
+
+#############################################################################
+# Mandatory TRUE return value.
+#
+1;

+ 14 - 7
ldap/admin/src/scripts/Setup.pm.in

@@ -69,6 +69,11 @@ use Getopt::Long;
 use File::Temp qw(tempfile tempdir);
 
 use SetupLog;
+use Util;
+use Inf;
+
+use strict;
+use vars qw($EXPRESS $TYPICAL $CUSTOM $SILENT);
 
 # the setup types
 $EXPRESS = 1;
@@ -111,13 +116,19 @@ EOF
 sub new {
     my $type = shift;
     my $self = {};
+    $self = bless $self, $type;
+    $self->init(@_);
+    return $self;
+}
+
+sub init {
+    my $self = shift;
     $self->{res} = shift;
-    my ($debuglevel, $silent, $inffile, $keep, $preonly, $logfile);
-    my @otherargs;
+    my ($silent, $inffile, $keep, $preonly, $logfile);
 
     GetOptions('help|h|?' => sub { VersionMessage(); HelpMessage(); exit 0 },
                'version|v' => sub { VersionMessage(); exit 0 },
-               'debug|d+' => \$debuglevel,
+               'debug|d+' => \$Util::debuglevel,
                'silent|s' => \$silent,
                'file|f=s' => \$inffile,
                'keepcache|k' => \$keep,
@@ -125,7 +136,6 @@ sub new {
                'logfile|l=s' => \$logfile
                );
 
-    $self->{debuglevel} = $debuglevel;
     $self->{silent} = $silent;
     $self->{inffile} = $inffile;
     $self->{keep} = $keep;
@@ -162,9 +172,6 @@ sub new {
     # this is the base config directory - the directory containing
     # the slapd-instance instance specific config directories
     $self->{configdir} = $ENV{DS_CONFIG_DIR} || "@instconfigdir@";
-
-    $self = bless $self, $type;
-    return $self;
 }
 
 # log only goes the the logfile

+ 2 - 1
ldap/admin/src/scripts/SetupLog.pm

@@ -59,11 +59,12 @@ $DEBUG    = "Debug";
 sub new {
     my $type = shift;
     my $filename = shift;
+    my $prefix = shift || "setup";
     my $self = {};
     my $fh;
 
     if (!$filename) {
-        ($fh, $filename) = tempfile("setupXXXXXX", UNLINK => 0,
+        ($fh, $filename) = tempfile("${prefix}XXXXXX", UNLINK => 0,
                                     SUFFIX => ".log", DIR => File::Spec->tmpdir);
     } else {
         open LOGFILE, ">$filename" or die "Error: could not open logfile $filename: $!";

+ 111 - 62
ldap/admin/src/scripts/Util.pm.in

@@ -47,15 +47,28 @@ require Exporter;
 @ISA       = qw(Exporter);
 @EXPORT    = qw(portAvailable getAvailablePort isValidDN addSuffix getMappedEntries
                 process_maptbl check_and_add_entry getMappedEntries
-                getHashedPassword);
+                getHashedPassword debug createDSInstance createInfFromConfig);
 @EXPORT_OK = qw(portAvailable getAvailablePort isValidDN addSuffix getMappedEntries
                 process_maptbl check_and_add_entry getMappedEntries
-                getHashedPassword);
+                getHashedPassword debug createDSInstance createInfFromConfig);
 
 use strict;
 
 use Socket;
 
+use File::Temp qw(tempfile tempdir);
+
+$Util::debuglevel = 0;
+# use like this:
+# debug(3, "message");
+# this will only print "message" if $debuglevel is 3 or higher (-ddd on the command line)
+sub debug {
+    my ($level, @rest) = @_;
+    if ($level <= $Util::debuglevel) {
+        print STDERR "+" x $level, @rest;
+    }
+}
+
 # return true if the given port number is available, false otherwise
 sub portAvailable {
     my $port = shift;
@@ -89,10 +102,6 @@ sub isValidDN {
     return ($dn =~ /^[0-9a-zA-Z_-]+=.*$/);
 }
 
-sub debug {
-#    print @_, "\n";
-}
-
 # delete the subtree starting from the passed entry
 sub delete_all
 {
@@ -217,9 +226,18 @@ sub check_and_add_entry
     my $verbose = $context->[2];
     my @ctypes = $aentry->getValues("changetype");
     my $sentry = $conn->search($aentry->{dn}, "base", "(objectclass=*)", 0, ("*", "aci"));
+    if ($sentry) {
+        debug(3, "check_and_add_entry: Found entry " . $sentry->getDN() . "\n");
+    } else {
+        debug(3, "check_and_add_entry: Entry not found " . $aentry->{dn} .
+              " error " . $conn->getErrorString() . "\n");
+    }
     do
     {
         my $needtoadd;
+        my @addtypes; # list of attr types for mod add
+        my @reptypes; # list of attr types for mod replace
+        my @deltypes; # list of attr types for mod delete
         my $MOD_NONE = 0;
         my $MOD_ADD = 1;
         my $MOD_REPLACE = 2;
@@ -248,19 +266,18 @@ sub check_and_add_entry
             {
                 $needtoadd = 0;
                 $needtomod = $MOD_ADD;
+                @addtypes = keys %{$aentry}; # add all attrs
             }
             elsif ( $sentry && $sentry->{dn} )
             {
                 # $fresh || $rc == -1
                 # an entry having the same DN exists, but the attributes do not
                 # match.  remove the entry and the subtree underneath.
-                if ( $verbose )
-                {
-                    print "Deleting an entry dn: $sentry->{dn} ...\n";
-                }
+                debug(1, "Deleting an entry dn: $sentry->{dn} ...\n");
                 $rc = delete_all($conn, $sentry);
                 if ( 0 != $rc )
                 {
+                    debug(1, "Error deleting $sentry->{dn}\n");
                     return 0;
                 }
             }
@@ -270,28 +287,10 @@ sub check_and_add_entry
             $needtoadd = 0;
             if ( $sentry )
             {
-                my @atypes = $aentry->getValues("add");
-                if ( 0 <= $#atypes )
-                {
-                    $needtomod = $MOD_ADD;
-                }
-                else
-                {
-                    @atypes = $aentry->getValues("replace");
-                    if ( 0 <= $#atypes )
-                    {
-                        $needtomod = $MOD_REPLACE;
-                    }
-                    else
-                    {
-                        @atypes = $aentry->getValues("delete");
-                        if ( 0 <= $#atypes )
-                        {
-                            print "\"delete\" is not supported; ignoring...\n";
-                        }
-                        $needtomod = $MOD_NONE;
-                    }
-                }
+                @addtypes = $aentry->getValues("add");
+                @reptypes = $aentry->getValues("replace");
+                @deltypes = $aentry->getValues("delete");
+                $needtomod = $MOD_REPLACE;
             }
             else
             {
@@ -305,63 +304,62 @@ sub check_and_add_entry
             my $rc = $conn->getErrorCode();
             if ( $rc != 0 )
             {
-                print "ERROR: adding an entry $aentry->{dn} failed, error code: $rc\n";
+                my $string = $conn->getErrorString();
+                print "ERROR: adding an entry $aentry->{dn} failed, error: $string\n";
                 print "[entry]\n";
                 $aentry->printLDIF();
                 $conn->close();
                 return 0;
             }
-            debug("Entry $aentry->{dn} is added\n");
+            debug(1, "Entry $aentry->{dn} is added\n");
         }
         elsif ( 0 < $needtomod )    # $sentry exists
         {
+            my $attr;
             if ( $needtomod == $MOD_SPECIAL )
             {
-                foreach my $attr ( keys %speciallist )
+                debug(3, "Doing MOD_SPECIAL for entry $aentry->{dn}\n");
+                foreach $attr ( keys %speciallist )
                 {
                     foreach my $nval ( @{$aentry->{$attr}} )
                     {
                         $sentry->addValue( $attr, $nval );
                     }
                 }
-                $conn->update($sentry);
             }
-            elsif ( $needtomod == $MOD_ADD )
+            foreach $attr ( @addtypes )
             {
-                foreach my $attr ( keys %{$aentry} )
-                {
-                    next if $attr =~ /add|changetype/;
-                    foreach my $nval ( @{$aentry->{$attr}} )
-                    {
-                        $sentry->addValue( $attr, $nval );
-                    }
-                }
-                $conn->update($sentry);
+                debug(3, "Adding attr=$attr values=" . $aentry->getValues($attr) . " to entry $aentry->{dn}\n");
+                $sentry->addValue( $attr, $aentry->getValues($attr) );
             }
-            elsif ( $needtomod == $MOD_REPLACE )
+            foreach $attr ( @reptypes )
             {
-                my $entry = new Mozilla::LDAP::Entry();
-                $entry->setDN($aentry->getDN());
-                foreach my $attr ( keys %{$aentry} )
+                debug(3, "Replacing attr=$attr values=" . $aentry->getValues($attr) . " to entry $aentry->{dn}\n");
+                $sentry->setValues($attr, $aentry->getValues($attr));
+            }
+            foreach $attr ( @deltypes )
+            {
+                # removeValue takes a single value only
+                if (!$aentry->size($attr))
                 {
-                    next if $attr =~ /replace|changetype/;
-                    foreach my $nval ( @{$aentry->{$attr}} )
+                    debug(3, "Deleting attr=$attr from entry $aentry->{dn}\n");
+                    $sentry->remove($attr); # just delete the attribute
+                }
+                else
+                {
+                    debug(3, "Deleting attr=$attr values=" . $aentry->getValues($attr) . " from entry $aentry->{dn}\n");
+                    foreach my $val ($aentry->getValues($attr))
                     {
-                        $entry->addValue( $attr, $nval );
+                        $sentry->removeValue($attr, $val);
                     }
                 }
-                $conn->update($entry);
-            }
-            else
-            {
-                print "ERROR: needtomod == $needtomod is not supported.\n";
-                $conn->close();
-                return 0;
             }
+            $conn->update($sentry);
             my $rc = $conn->getErrorCode();
             if ( $rc != 0 )
             {
-                print "ERROR: updating an entry $sentry->{dn} failed, error code: $rc\n";
+                my $string = $conn->getErrorString();
+                print "ERROR: updating an entry $sentry->{dn} failed, error: $string\n";
                 print "[entry]\n";
                 $aentry->printLDIF();
                 $conn->close();
@@ -455,7 +453,7 @@ sub getMappedEntries {
     foreach my $ldiffile (@{$ldiffiles}) {
         open(MYLDIF, "< $ldiffile") or die "Can't open $ldiffile : $!";
         my $in = new Mozilla::LDAP::LDIF(*MYLDIF);
-        debug("Processing $ldiffile ...");
+        debug(1, "Processing $ldiffile ...\n");
         ENTRY: while (my $entry = Mozilla::LDAP::LDIF::readOneEntry($in)) {
             # first, fix the DN
             my $dn = $entry->getDN();
@@ -709,4 +707,55 @@ sub getHashedPassword {
     return $hashedpwd;
 }
 
+sub createDSInstance {
+    my $inf = shift;
+# find ds_newinst.pl - in same directory as this script or in PATH
+    my $ds_newinst;
+    ($ds_newinst = $0) =~ s|/[^/]+$|/ds_newinst.pl|;
+    if (! -x $ds_newinst) {
+        $ds_newinst = "@bindir@/ds_newinst.pl";
+    }
+    if (! -x $ds_newinst) {
+        $ds_newinst = "ds_newinst.pl"; # just get from path
+    }
+    $? = 0; # clear error condition
+    my $output = `$ds_newinst $inf->{filename}`;
+    return ($?, $output);
+}
+
+# this creates an Inf suitable for passing to createDSInstance
+sub createInfFromConfig {
+    my $configdir = shift;
+    my $inst = shift;
+    my $fname = "$configdir/dse.ldif";
+    my $id;
+    ($id = $inst) =~ s/^slapd-//;
+    open( DSELDIF, "$fname" ) || die "Can't open $fname: $!";
+    my ($outfh, $inffile) = tempfile(SUFFIX => '.inf');
+    my $in = new Mozilla::LDAP::LDIF(*DSELDIF) ;
+    while (my $ent = readOneEntry $in) {
+        my $dn = $ent->getDN();
+        if ($dn =~ /cn=config/) {
+            print $outfh "[General]\n";
+            print $outfh "FullMachineName = ", $ent->getValues('nsslapd-localhost'), "\n";
+            print $outfh "SuiteSpotUserID = ", $ent->getValues('nsslapd-localuser'), "\n";
+            print $outfh "ServerRoot = @serverdir@\n";
+            print $outfh "[slapd]\n";
+            print $outfh "RootDN = ", $ent->getValues('nsslapd-rootdn'), "\n";
+            print $outfh "RootDNPwd = ", $ent->getValues('nsslapd-rootpw'), "\n";
+            print $outfh "ServerPort = ", $ent->getValues('nsslapd-port'), "\n";
+            print $outfh "ServerIdentifier = $id\n";
+            print $outfh "Suffix = o=deleteAfterMigration\n";
+            print $outfh "start_server= 0\n";
+            last;
+        }
+    }
+    close $outfh;
+    close DSELDIF;
+
+    my $inf = new Inf($inffile);
+
+    return $inf;
+}
+
 1;

+ 65 - 0
ldap/admin/src/scripts/migrate-ds.pl.in

@@ -0,0 +1,65 @@
+#!/usr/bin/env perl
+# 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) 2007 Red Hat, Inc.
+# All rights reserved.
+# END COPYRIGHT BLOCK
+#
+
+###########################
+#
+# This perl module provides a way to set up a new installation after
+# the binaries have already been extracted.  This is typically after
+# using native packaging support to install the package e.g. RPM,
+# pkgadd, depot, etc.  This script will show the license, readme,
+# dsktune, then run the usual setup pre and post installers.
+#
+##########################
+
+use lib '@perldir@';
+
+use strict;
+
+use DSMigration;
+use Migration;
+use Resource;
+
+my $res = new Resource("@propertydir@/migrate-ds.res",
+                       "@propertydir@/setup-ds.res");
+
+my $mig = new Migration($res);
+
+$mig->msg('begin_ds_migration', $mig->{oldsroot});
+migrateDS($mig);
+$mig->msg('end_ds_migration');

+ 4 - 0
ldap/admin/src/scripts/migrate-ds.res

@@ -0,0 +1,4 @@
+begin_ds_migration = Beginning migration of directory server instances in %s . . .\n
+end_ds_migration = Directory server migration is complete.  Please check output and log files for details.\n
+migration_exiting = Exiting . . .\nLog file is '%s'\n\n
+instance_already_exists = The target directory server instance already exists at %s.  Skipping migration.\n\

+ 7 - 1
ldap/admin/src/scripts/setup-ds.pl.in

@@ -45,6 +45,7 @@ use Setup;
 use Inf;
 use Resource;
 use DialogManager;
+use Util;
 
 my $res = new Resource("@propertydir@/setup-ds.res");
 
@@ -68,6 +69,11 @@ if (!$setup->{silent}) {
     $setup->{inf}->write();
 }
 
-system("@bindir@/ds_newinst.pl $setup->{inffile}");
+my ($rc, $output) = createDSInstance($setup->{inf});
+if ($rc) {
+    $setup->msg($FATAL, 'error_creating_dsinstance', $rc, $output);
+} else {
+    $setup->msg('created_dsinstance', $output);
+}
 
 $setup->doExit();

+ 2 - 0
ldap/admin/src/scripts/setup-ds.res.in

@@ -87,3 +87,5 @@ error_creating_suffix_backend = Could not create the suffix '%s'.  There was an
 error_creating_suffix = Could not create the suffix '%s'.  Error: %s\n\n
 
 setup_exiting = Exiting . . .\nLog file is '%s'\n\n
+error_creating_dsinstance = Error: Could not create directory server instance.  Error code %s.  Output:\n%s\n
+created_dsinstance = Your new DS instance was successfully created.  Output:\n%s\n