Răsfoiți Sursa

Resolves: bug 237356
Description: Move DS Admin Code into Admin Server
Fix Description: This adds the setup related perl modules, scripts, and resource files to the DS base code. This will allow a user to interactively setup (create an instance of) a directory server. This will also form the base of the work to add the console and admin server related setup code.
New files/directories:
$libdir/fedora-ds/perl - this is where the perl modules (Setup.pm, etc.) will be installed.
$bindir/setup-ds.pl - the script to use to interactively create an instance of directory server. This has use lib '$libdir/fedora-ds/perl' hard coded into it at build time, in order to find the "private" setup perl modules. If you invoke this script in silent mode (setup-ds.pl -s) then it is exactly the same as just using ds_newinst.pl.
$sysconfdir/fedora-ds/property/setup-ds.res - Resources for setup-ds.pl and the associated modules.
I also fixed a problem with the libns-dshttpd linkage.
Platforms tested: RHEL4
Flag Day: no
Doc impact: Yes. All of these new items will need to be documented.

Rich Megginson 18 ani în urmă
părinte
comite
7f686305a9

+ 27 - 4
Makefile.am

@@ -74,6 +74,7 @@ serverplugindir = $(libdir)@serverplugindir@
 taskdir = $(datadir)@scripttemplatedir@
 initdir = $(sysconfdir)@initdir@
 instconfigdir = @instconfigdir@
+perldir = $(libdir)@perldir@
 
 #------------------------
 # Build Products
@@ -167,7 +168,21 @@ bin_SCRIPTS = $(srcdir)/ldap/servers/slapd/tools/rsearch/scripts/dbgen.pl \
 	wrappers/cl-dump \
 	ldap/admin/src/scripts/cl-dump.pl \
 	wrappers/repl-monitor \
-	ldap/admin/src/scripts/repl-monitor.pl
+	ldap/admin/src/scripts/repl-monitor.pl \
+	ldap/admin/src/scripts/setup-ds.pl
+
+perl_SCRIPTS = ldap/admin/src/scripts/SetupLog.pm \
+	ldap/admin/src/scripts/Resource.pm \
+	ldap/admin/src/scripts/Util.pm \
+	ldap/admin/src/scripts/Setup.pm \
+	ldap/admin/src/scripts/SetupDialogs.pm \
+	ldap/admin/src/scripts/Inf.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
+
+property_DATA = ldap/admin/src/scripts/setup-ds.res
 
 task_SCRIPTS = ldap/admin/src/scripts/template-bak2db \
 	ldap/admin/src/scripts/template-db2bak \
@@ -327,7 +342,7 @@ libns_dshttpd_la_SOURCES = lib/libaccess/access_plhash.cpp \
 	$(libldaputil_a_SOURCES)
 
 libns_dshttpd_la_CPPFLAGS = -I$(srcdir)/include/base $(AM_CPPFLAGS) -I$(srcdir)/lib/ldaputil @ldapsdk_inc@ @nss_inc@ @nspr_inc@
-libns_dshttpd_la_LIBADD = $(LDAPSDK_LINK) $(NSS_LINK) $(NSPR_LINK)
+libns_dshttpd_la_LIBADD = $(LDAPSDK_LINK) $(SASL_LINK) $(NSS_LINK) $(NSPR_LINK)
 
 #------------------------
 # libslapd
@@ -997,7 +1012,11 @@ fixupcmd = sed \
 	-e 's,@package_name\@,$(PACKAGE_NAME),g' \
 	-e 's,@instconfigdir\@,$(instconfigdir),g' \
 	-e 's,@ECHO_N\@,$(ECHO_N),g' \
-	-e 's,@ECHO_C\@,$(ECHO_C),g'
+	-e 's,@ECHO_C\@,$(ECHO_C),g' \
+	-e 's,@brand\@,$(brand),g' \
+	-e 's,@capbrand\@,$(capbrand),g' \
+	-e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
+	-e 's,@perldir\@,$(perldir),g'
 else
 fixupcmd = sed \
 	-e 's,@bindir\@,$(bindir),g' \
@@ -1023,7 +1042,11 @@ fixupcmd = sed \
 	-e 's,@package_name\@,$(PACKAGE_NAME),g' \
 	-e 's,@instconfigdir\@,$(instconfigdir),g' \
 	-e 's,@ECHO_N\@,$(ECHO_N),g' \
-	-e 's,@ECHO_C\@,$(ECHO_C),g'
+	-e 's,@ECHO_C\@,$(ECHO_C),g' \
+	-e 's,@brand\@,$(brand),g' \
+	-e 's,@capbrand\@,$(capbrand),g' \
+	-e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
+	-e 's,@perldir\@,$(perldir),g'
 endif
 
 %: %.in

+ 88 - 18
Makefile.in

@@ -94,8 +94,9 @@ am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
 am__installdirs = "$(DESTDIR)$(serverdir)" \
 	"$(DESTDIR)$(serverplugindir)" "$(DESTDIR)$(bindir)" \
 	"$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)" \
-	"$(DESTDIR)$(initdir)" "$(DESTDIR)$(taskdir)" \
-	"$(DESTDIR)$(configdir)" "$(DESTDIR)$(propertydir)" \
+	"$(DESTDIR)$(initdir)" "$(DESTDIR)$(perldir)" \
+	"$(DESTDIR)$(taskdir)" "$(DESTDIR)$(configdir)" \
+	"$(DESTDIR)$(propertydir)" "$(DESTDIR)$(propertydir)" \
 	"$(DESTDIR)$(sampledatadir)" "$(DESTDIR)$(schemadir)"
 serverLTLIBRARIES_INSTALL = $(INSTALL)
 serverpluginLTLIBRARIES_INSTALL = $(INSTALL)
@@ -268,7 +269,8 @@ am_libhttp_client_plugin_la_OBJECTS = ldap/servers/plugins/http/libhttp_client_p
 libhttp_client_plugin_la_OBJECTS =  \
 	$(am_libhttp_client_plugin_la_OBJECTS)
 libns_dshttpd_la_DEPENDENCIES = $(am__DEPENDENCIES_1) \
-	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1)
+	$(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
+	$(am__DEPENDENCIES_1)
 am__objects_1 = lib/ldaputil/libns_dshttpd_la-cert.lo \
 	lib/ldaputil/libns_dshttpd_la-certmap.lo \
 	lib/ldaputil/libns_dshttpd_la-dbconf.lo \
@@ -711,8 +713,10 @@ rsearch_bin_DEPENDENCIES = $(am__DEPENDENCIES_1) $(am__DEPENDENCIES_1) \
 	$(am__DEPENDENCIES_1)
 binSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 initSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+perlSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 taskSCRIPT_INSTALL = $(INSTALL_SCRIPT)
-SCRIPTS = $(bin_SCRIPTS) $(init_SCRIPTS) $(task_SCRIPTS)
+SCRIPTS = $(bin_SCRIPTS) $(init_SCRIPTS) $(perl_SCRIPTS) \
+	$(task_SCRIPTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
@@ -786,10 +790,11 @@ DIST_SOURCES = $(libavl_a_SOURCES) $(libldaputil_a_SOURCES) \
 	$(rsearch_bin_SOURCES)
 configDATA_INSTALL = $(INSTALL_DATA)
 nodist_propertyDATA_INSTALL = $(INSTALL_DATA)
+propertyDATA_INSTALL = $(INSTALL_DATA)
 sampledataDATA_INSTALL = $(INSTALL_DATA)
 schemaDATA_INSTALL = $(INSTALL_DATA)
-DATA = $(config_DATA) $(nodist_property_DATA) $(sampledata_DATA) \
-	$(schema_DATA)
+DATA = $(config_DATA) $(nodist_property_DATA) $(property_DATA) \
+	$(sampledata_DATA) $(schema_DATA)
 ETAGS = etags
 CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
@@ -892,11 +897,13 @@ am__quote = @am__quote@
 am__tar = @am__tar@
 am__untar = @am__untar@
 bindir = @bindir@
+brand = @brand@
 build = @build@
 build_alias = @build_alias@
 build_cpu = @build_cpu@
 build_os = @build_os@
 build_vendor = @build_vendor@
+capbrand = @capbrand@
 
 #------------------------
 # Install Paths
@@ -952,6 +959,7 @@ nss_inc = @nss_inc@
 nss_lib = @nss_lib@
 nss_libdir = @nss_libdir@
 oldincludedir = @oldincludedir@
+perldir = $(libdir)@perldir@
 prefix = @prefix@
 program_transform_name = @program_transform_name@
 propertydir = $(sysconfdir)@propertydir@
@@ -969,6 +977,7 @@ svrcore_inc = @svrcore_inc@
 svrcore_lib = @svrcore_lib@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
+vendor = @vendor@
 
 # look for included m4 files in the ./m4/ directory
 ACLOCAL_AMFLAGS = -I m4
@@ -1092,8 +1101,21 @@ bin_SCRIPTS = $(srcdir)/ldap/servers/slapd/tools/rsearch/scripts/dbgen.pl \
 	wrappers/cl-dump \
 	ldap/admin/src/scripts/cl-dump.pl \
 	wrappers/repl-monitor \
-	ldap/admin/src/scripts/repl-monitor.pl
-
+	ldap/admin/src/scripts/repl-monitor.pl \
+	ldap/admin/src/scripts/setup-ds.pl
+
+perl_SCRIPTS = ldap/admin/src/scripts/SetupLog.pm \
+	ldap/admin/src/scripts/Resource.pm \
+	ldap/admin/src/scripts/Util.pm \
+	ldap/admin/src/scripts/Setup.pm \
+	ldap/admin/src/scripts/SetupDialogs.pm \
+	ldap/admin/src/scripts/Inf.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
+
+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 \
@@ -1243,7 +1265,7 @@ libns_dshttpd_la_SOURCES = lib/libaccess/access_plhash.cpp \
 	$(libldaputil_a_SOURCES)
 
 libns_dshttpd_la_CPPFLAGS = -I$(srcdir)/include/base $(AM_CPPFLAGS) -I$(srcdir)/lib/ldaputil @ldapsdk_inc@ @nss_inc@ @nspr_inc@
-libns_dshttpd_la_LIBADD = $(LDAPSDK_LINK) $(NSS_LINK) $(NSPR_LINK)
+libns_dshttpd_la_LIBADD = $(LDAPSDK_LINK) $(SASL_LINK) $(NSS_LINK) $(NSPR_LINK)
 
 #------------------------
 # libslapd
@@ -1883,7 +1905,11 @@ rsearch_bin_LDADD = $(NSPR_LINK) $(NSS_LINK) $(LDAPSDK_LINK) $(SASL_LINK) $(LIBS
 @BUNDLE_FALSE@	-e 's,@package_name\@,$(PACKAGE_NAME),g' \
 @BUNDLE_FALSE@	-e 's,@instconfigdir\@,$(instconfigdir),g' \
 @BUNDLE_FALSE@	-e 's,@ECHO_N\@,$(ECHO_N),g' \
-@BUNDLE_FALSE@	-e 's,@ECHO_C\@,$(ECHO_C),g'
+@BUNDLE_FALSE@	-e 's,@ECHO_C\@,$(ECHO_C),g' \
+@BUNDLE_FALSE@	-e 's,@brand\@,$(brand),g' \
+@BUNDLE_FALSE@	-e 's,@capbrand\@,$(capbrand),g' \
+@BUNDLE_FALSE@	-e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
+@BUNDLE_FALSE@	-e 's,@perldir\@,$(perldir),g'
 
 
 # these are for the config files and scripts that we need to generate and replace
@@ -1916,7 +1942,11 @@ rsearch_bin_LDADD = $(NSPR_LINK) $(NSS_LINK) $(LDAPSDK_LINK) $(SASL_LINK) $(LIBS
 @BUNDLE_TRUE@	-e 's,@package_name\@,$(PACKAGE_NAME),g' \
 @BUNDLE_TRUE@	-e 's,@instconfigdir\@,$(instconfigdir),g' \
 @BUNDLE_TRUE@	-e 's,@ECHO_N\@,$(ECHO_N),g' \
-@BUNDLE_TRUE@	-e 's,@ECHO_C\@,$(ECHO_C),g'
+@BUNDLE_TRUE@	-e 's,@ECHO_C\@,$(ECHO_C),g' \
+@BUNDLE_TRUE@	-e 's,@brand\@,$(brand),g' \
+@BUNDLE_TRUE@	-e 's,@capbrand\@,$(capbrand),g' \
+@BUNDLE_TRUE@	-e 's,@PACKAGE_VERSION\@,$(PACKAGE_VERSION),g' \
+@BUNDLE_TRUE@	-e 's,@perldir\@,$(perldir),g'
 
 all: $(BUILT_SOURCES) config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-am
@@ -3753,6 +3783,25 @@ uninstall-initSCRIPTS:
 	  echo " rm -f '$(DESTDIR)$(initdir)/$$f'"; \
 	  rm -f "$(DESTDIR)$(initdir)/$$f"; \
 	done
+install-perlSCRIPTS: $(perl_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	test -z "$(perldir)" || $(mkdir_p) "$(DESTDIR)$(perldir)"
+	@list='$(perl_SCRIPTS)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  if test -f $$d$$p; then \
+	    f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+	    echo " $(perlSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(perldir)/$$f'"; \
+	    $(perlSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(perldir)/$$f"; \
+	  else :; fi; \
+	done
+
+uninstall-perlSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(perl_SCRIPTS)'; for p in $$list; do \
+	  f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+	  echo " rm -f '$(DESTDIR)$(perldir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(perldir)/$$f"; \
+	done
 install-taskSCRIPTS: $(task_SCRIPTS)
 	@$(NORMAL_INSTALL)
 	test -z "$(taskdir)" || $(mkdir_p) "$(DESTDIR)$(taskdir)"
@@ -8768,6 +8817,23 @@ uninstall-nodist_propertyDATA:
 	  echo " rm -f '$(DESTDIR)$(propertydir)/$$f'"; \
 	  rm -f "$(DESTDIR)$(propertydir)/$$f"; \
 	done
+install-propertyDATA: $(property_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(propertydir)" || $(mkdir_p) "$(DESTDIR)$(propertydir)"
+	@list='$(property_DATA)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f=$(am__strip_dir) \
+	  echo " $(propertyDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(propertydir)/$$f'"; \
+	  $(propertyDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(propertydir)/$$f"; \
+	done
+
+uninstall-propertyDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(property_DATA)'; for p in $$list; do \
+	  f=$(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(propertydir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(propertydir)/$$f"; \
+	done
 install-sampledataDATA: $(sampledata_DATA)
 	@$(NORMAL_INSTALL)
 	test -z "$(sampledatadir)" || $(mkdir_p) "$(DESTDIR)$(sampledatadir)"
@@ -8984,7 +9050,7 @@ check: $(BUILT_SOURCES)
 all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) \
 		$(DATA) config.h
 installdirs:
-	for dir in "$(DESTDIR)$(serverdir)" "$(DESTDIR)$(serverplugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(initdir)" "$(DESTDIR)$(taskdir)" "$(DESTDIR)$(configdir)" "$(DESTDIR)$(propertydir)" "$(DESTDIR)$(sampledatadir)" "$(DESTDIR)$(schemadir)"; do \
+	for dir in "$(DESTDIR)$(serverdir)" "$(DESTDIR)$(serverplugindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(sbindir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(initdir)" "$(DESTDIR)$(perldir)" "$(DESTDIR)$(taskdir)" "$(DESTDIR)$(configdir)" "$(DESTDIR)$(propertydir)" "$(DESTDIR)$(propertydir)" "$(DESTDIR)$(sampledatadir)" "$(DESTDIR)$(schemadir)"; do \
 	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
 	done
 install: $(BUILT_SOURCES)
@@ -9113,9 +9179,10 @@ info: info-am
 info-am:
 
 install-data-am: install-configDATA install-initSCRIPTS \
-	install-nodist_propertyDATA install-sampledataDATA \
-	install-schemaDATA install-serverLTLIBRARIES \
-	install-serverpluginLTLIBRARIES install-taskSCRIPTS
+	install-nodist_propertyDATA install-perlSCRIPTS \
+	install-propertyDATA install-sampledataDATA install-schemaDATA \
+	install-serverLTLIBRARIES install-serverpluginLTLIBRARIES \
+	install-taskSCRIPTS
 
 install-exec-am: install-binPROGRAMS install-binSCRIPTS \
 	install-sbinPROGRAMS
@@ -9148,7 +9215,8 @@ ps-am:
 
 uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
 	uninstall-configDATA uninstall-info-am uninstall-initSCRIPTS \
-	uninstall-nodist_propertyDATA uninstall-sampledataDATA \
+	uninstall-nodist_propertyDATA uninstall-perlSCRIPTS \
+	uninstall-propertyDATA uninstall-sampledataDATA \
 	uninstall-sbinPROGRAMS uninstall-schemaDATA \
 	uninstall-serverLTLIBRARIES uninstall-serverpluginLTLIBRARIES \
 	uninstall-taskSCRIPTS
@@ -9165,7 +9233,8 @@ uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
 	install-binPROGRAMS install-binSCRIPTS install-configDATA \
 	install-data install-data-am install-exec install-exec-am \
 	install-info install-info-am install-initSCRIPTS install-man \
-	install-nodist_propertyDATA install-sampledataDATA \
+	install-nodist_propertyDATA install-perlSCRIPTS \
+	install-propertyDATA install-sampledataDATA \
 	install-sbinPROGRAMS install-schemaDATA \
 	install-serverLTLIBRARIES install-serverpluginLTLIBRARIES \
 	install-strip install-taskSCRIPTS installcheck installcheck-am \
@@ -9174,7 +9243,8 @@ uninstall-am: uninstall-binPROGRAMS uninstall-binSCRIPTS \
 	mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
 	uninstall-am uninstall-binPROGRAMS uninstall-binSCRIPTS \
 	uninstall-configDATA uninstall-info-am uninstall-initSCRIPTS \
-	uninstall-nodist_propertyDATA uninstall-sampledataDATA \
+	uninstall-nodist_propertyDATA uninstall-perlSCRIPTS \
+	uninstall-propertyDATA uninstall-sampledataDATA \
 	uninstall-sbinPROGRAMS uninstall-schemaDATA \
 	uninstall-serverLTLIBRARIES uninstall-serverpluginLTLIBRARIES \
 	uninstall-taskSCRIPTS

+ 16 - 1
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 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 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 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 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 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 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.
@@ -23054,6 +23054,10 @@ fi
 # the default prefix - override with --prefix or --with-fhs
 
 
+brand=fedora
+capbrand=Fedora
+vendor="Fedora Project"
+
 # BEGIN COPYRIGHT BLOCK
 # Copyright (C) 2006 Red Hat, Inc.
 # All rights reserved.
@@ -23177,6 +23181,9 @@ configdir=/$PACKAGE_NAME/config
 propertydir=/$PACKAGE_NAME/property
 # relative to sysconfdir
 schemadir=/$PACKAGE_NAME/schema
+# relative to libdir
+perldir=/$PACKAGE_NAME/perl
+
 
 
 
@@ -25142,6 +25149,10 @@ fi
 
 
 
+
+
+
+
 
 
 
@@ -25978,6 +25989,7 @@ s,@schemadir@,$schemadir,;t t
 s,@serverdir@,$serverdir,;t t
 s,@serverplugindir@,$serverplugindir,;t t
 s,@scripttemplatedir@,$scripttemplatedir,;t t
+s,@perldir@,$perldir,;t t
 s,@instconfigdir@,$instconfigdir,;t t
 s,@WINNT_TRUE@,$WINNT_TRUE,;t t
 s,@WINNT_FALSE@,$WINNT_FALSE,;t t
@@ -26022,6 +26034,9 @@ s,@netsnmp_inc@,$netsnmp_inc,;t t
 s,@netsnmp_lib@,$netsnmp_lib,;t t
 s,@netsnmp_libdir@,$netsnmp_libdir,;t t
 s,@netsnmp_link@,$netsnmp_link,;t t
+s,@brand@,$brand,;t t
+s,@capbrand@,$capbrand,;t t
+s,@vendor@,$vendor,;t t
 s,@LTLIBOBJS@,$LTLIBOBJS,;t t
 CEOF
 

+ 11 - 0
configure.ac

@@ -139,6 +139,10 @@ AM_CONDITIONAL(enable_bitwise,test "$enable_bitwise" = "yes")
 # the default prefix - override with --prefix or --with-fhs
 AC_PREFIX_DEFAULT([/opt/$PACKAGE_NAME])
 
+brand=fedora
+capbrand=Fedora
+vendor="Fedora Project"
+
 m4_include(m4/fhs.m4)
 
 # installation paths - by default, we store everything
@@ -186,6 +190,8 @@ configdir=/$PACKAGE_NAME/config
 propertydir=/$PACKAGE_NAME/property
 # relative to sysconfdir
 schemadir=/$PACKAGE_NAME/schema
+# relative to libdir
+perldir=/$PACKAGE_NAME/perl
 
 AC_SUBST(configdir)
 AC_SUBST(sampledatadir)
@@ -194,6 +200,7 @@ AC_SUBST(schemadir)
 AC_SUBST(serverdir)
 AC_SUBST(serverplugindir)
 AC_SUBST(scripttemplatedir)
+AC_SUBST(perldir)
 
 # check for --with-instconfigdir
 AC_MSG_CHECKING(for --with-instconfigdir)
@@ -332,6 +339,10 @@ AC_SUBST(netsnmp_lib)
 AC_SUBST(netsnmp_libdir)
 AC_SUBST(netsnmp_link)
 
+AC_SUBST(brand)
+AC_SUBST(capbrand)
+AC_SUBST(vendor)
+
 AC_DEFINE([LDAP_DEBUG], [1], [LDAP debug flag])
 AC_DEFINE([LDAP_DONT_USE_SMARTHEAP], [1], [Don't use smartheap])
 

+ 256 - 0
ldap/admin/src/scripts/DSDialogs.pm

@@ -0,0 +1,256 @@
+# 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
+#
+
+package DSDialogs;
+
+use strict;
+
+use Net::Domain qw(hostname hostfqdn);
+use DialogManager;
+use Setup;
+use Dialog;
+use Util;
+
+my $dsport = new Dialog (
+    $TYPICAL,
+    'dialog_dsport_text',
+    sub {
+        my $self = shift;
+        my $port = $self->{manager}->{inf}->{slapd}->{ServerPort};
+        if (!defined($port)) {
+            $port = 389;
+        }
+        if (!portAvailable($port)) {
+            $port = getAvailablePort();
+        }
+        return $port;
+    },
+    sub {
+        my $self = shift;
+        my $ans = shift;
+        my $res = $DialogManager::SAME;
+        if ($ans !~ /\d+/) {
+            $self->{manager}->alert("dialog_dsport_error", $ans);
+        } elsif (!portAvailable($ans)) {
+            $self->{manager}->alert("dialog_dsport_error", $ans);
+        } else {
+            $res = $DialogManager::NEXT;
+            $self->{manager}->{inf}->{slapd}->{ServerPort} = $ans;
+        }
+        return $res;
+    },
+    ['dialog_dsport_prompt']
+);
+
+my $dsserverid = new Dialog (
+    $TYPICAL,
+    'dialog_dsserverid_text',
+    sub {
+        my $self = shift;
+        my $serverid = $self->{manager}->{inf}->{slapd}->{ServerIdentifier};
+        if (!defined($serverid)) {
+            $serverid = $self->{manager}->{inf}->{General}->{FullMachineName};
+            if (!defined($serverid)) {
+                $serverid = hostname;
+            } else { # strip out the leftmost domain component
+                $serverid =~ s/\..*$//;
+            }
+        }
+        return $serverid;
+    },
+    sub {
+        my $self = shift;
+        my $ans = shift;
+        my $res = $DialogManager::SAME;
+        my $path = $self->{manager}->{setup}->{configdir} . "/slapd-" . $ans;
+        if ($ans !~ /^[0-9a-zA-Z_-]+$/) {
+            $self->{manager}->alert("dialog_dsserverid_error", $ans);
+        } elsif (-d $path) {
+            $self->{manager}->alert("dialog_dsserverid_inuse", $ans);
+        } else {
+            $res = $DialogManager::NEXT;
+            $self->{manager}->{inf}->{slapd}->{ServerIdentifier} = $ans;
+        }
+        return $res;
+    },
+    ['dialog_dsserverid_prompt']
+);
+
+my $dssuffix = new Dialog (
+    $TYPICAL,
+    'dialog_dssuffix_text',
+    sub {
+        my $self = shift;
+        my $suffix = $self->{manager}->{inf}->{slapd}->{Suffix};
+        if (!defined($suffix)) {
+            $suffix = $self->{manager}->{inf}->{General}->{FullMachineName};
+            if (!defined($suffix)) {
+                $suffix = hostfqdn;
+            }
+            # convert fqdn to dc= domain components
+            $suffix = "dc=$suffix";
+            $suffix =~ s/\./, dc=/g;
+        }
+        return $suffix;
+    },
+    sub {
+        my $self = shift;
+        my $ans = shift;
+        my $res = $DialogManager::SAME;
+        if (!isValidDN($ans)) {
+            $self->{manager}->alert("dialog_dssuffix_error", $ans);
+        } else {
+            $res = $DialogManager::NEXT;
+            $self->{manager}->{inf}->{slapd}->{Suffix} = $ans;
+        }
+        return $res;
+    },
+    ['dialog_dssuffix_prompt']
+);
+
+my $dsrootdn = new Dialog (
+    $EXPRESS,
+    'dialog_dsrootdn_text',
+    sub {
+        my $self = shift;
+        my $index = shift;
+        my $rootdn;
+        if ($index == 0) { # return undef for password defaults
+            $rootdn = $self->{manager}->{inf}->{slapd}->{RootDN};
+            if (!defined($rootdn)) {
+                $rootdn = "cn=Directory Manager";
+            }
+        }
+        return $rootdn;
+    },
+    sub {
+        my $self = shift;
+        my $ans = shift;
+        my $index = shift;
+        my $res = $DialogManager::SAME;
+        if ($index == 0) { # verify DN
+            if (!isValidDN($ans)) {
+                $self->{manager}->alert("dialog_dsrootdn_error", $ans);
+            } else {
+                $res = $DialogManager::NEXT;
+                $self->{manager}->{inf}->{slapd}->{RootDN} = $ans;
+            }
+        } elsif ($index == 1) { # verify initial password
+            my $test = $ans;
+            if ($test) {
+                $test =~ s/\s//g;
+            }
+            if (!$ans or (length($ans) < 8)) {
+                $self->{manager}->alert("dialog_dsrootpw_tooshort", 8);
+            } elsif (length($test) != length($ans)) {
+                $self->{manager}->alert("dialog_dsrootpw_invalid");
+            } else {
+                $res = $DialogManager::NEXT;
+                $self->{firstpassword} = $ans; # save for next index
+            }
+        } elsif ($index == 2) { # verify second password
+            if ($ans ne $self->{firstpassword}) {
+                $self->{manager}->alert("dialog_dsrootpw_nomatch");
+            } else {
+                $self->{manager}->{inf}->{slapd}->{RootDNPwd} = $ans;
+                $res = $DialogManager::NEXT;
+            }
+        }
+        return $res;
+    },
+    ['dialog_dsrootdn_prompt'], ['dialog_dsrootpw_prompt1', 1], ['dialog_dsrootpw_prompt2', 1]
+);
+
+my $dssample = new DialogYesNo (
+    $CUSTOM,
+    'dialog_dssample_text',
+    0,
+    sub {
+        my $self = shift;
+        my $ans = shift;
+        my $res = $self->handleResponse($ans);
+        if ($res == $DialogManager::NEXT) {
+            $self->{manager}->{inf}->{slapd}->{AddSampleEntries} = ($self->isYes() ? 'Yes' : 'No');
+        }
+        return $res;
+    },
+    ['dialog_dssample_prompt'],
+);
+
+my $dspopulate = new Dialog (
+    $CUSTOM,
+    'dialog_dspopulate_text',
+    sub {
+        my $self = shift;
+        my $val = $self->{manager}->{inf}->{slapd}->{InstallLdifFile};
+        if (!defined($val)) {
+            $val = 'none';
+        }
+        return $val;
+    },
+    sub {
+        my $self = shift;
+        my $ans = shift;
+        my $res = $DialogManager::SAME;
+        if ($ans eq 'none') {
+            $self->{manager}->{inf}->{slapd}->{InstallLdifFile} = 'none';
+            $self->{manager}->{inf}->{slapd}->{AddOrgEntries} = 'No';
+            $res = $DialogManager::NEXT;
+        } elsif ($ans eq 'suggest') {
+            $self->{manager}->{inf}->{slapd}->{InstallLdifFile} = 'suggest';
+            $self->{manager}->{inf}->{slapd}->{AddOrgEntries} = 'Yes';
+            $res = $DialogManager::NEXT;
+        } else { # a file
+            if (! -f $ans) {
+                $self->{manager}->alert("dialog_dspopulate_error", $ans);
+            } else {
+                $self->{manager}->{inf}->{slapd}->{InstallLdifFile} = $ans;
+                $self->{manager}->{inf}->{slapd}->{AddOrgEntries} = 'No';
+                $res = $DialogManager::NEXT;
+            }
+        }
+        return $res;
+    },
+    ['dialog_dspopulate_prompt']
+);
+
+sub getDialogs {
+    return ($dsport, $dsserverid, $dssuffix, $dsrootdn, $dssample, $dspopulate);
+}
+
+1;

+ 242 - 0
ldap/admin/src/scripts/Dialog.pm

@@ -0,0 +1,242 @@
+# 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
+#
+
+package Dialog;
+
+use DialogManager;
+
+#require    Exporter;
+#@ISA       = qw(Exporter);
+#@EXPORT    = qw();
+
+# NOTE: This "class" is an "abstract" class.  There are two methods which
+# must be provided by subclasses:
+# $ans = $dialog->defaultAns($promptindex);
+# where $promptindex is the index into the array of prompts given when
+# constructing the Dialog object
+# The dialog will typically use a default answer either hardcoded in
+# or from some key in the setup cache (.inf) file
+# 
+# $resp = $dialog->handleResponse($ans, $index);
+# The dialog uses this method to perform validation of the input, set the value
+# in the setup cache, display errors or warnings, and tell the dialog manager
+# if the prompt needs to be redisplayed, or if there was an unrecoverable error
+# $resp should be $SAME to reprompt, $ERR to abort, or $NEXT to continue
+# the $ans and defaultAns should be in the native charset, so the dialog
+# may have to convert to/from utf8 as needed.
+
+# a dialog consists of a title, some explanatory text, and one or more prompts
+# each prompt has a default value.  An example of a dialog with more than
+# one prompt would be a dialog asking the user for the new root DN and password -
+# in that case, there would be 3 prompts - one for the DN, one for the password,
+# and one to verify the password
+# The text and prompts are given as resource keys.  Usually the resource value
+# will be a simple string, in which case the resource key is passed in as a simple
+# string.  However, if the resource string contains replaceable parameters, the
+# resource key is passed as an array ref consisting of the resource key as the
+# first element and the parameters to use for replacement as the subsequent
+# array elements e.g.
+# $foo = new Dialog(['RESOURCE_KEY_CONFIG_LDAP_URL', $secure, $host, $port, $suffix], ...);
+# but usually for simple cases like this:
+# $foo = new Dialog('RESOURCE_KEY_WELCOME', ...);
+# The manager contains the context for all of the dialogs - the setup type, the resource
+# file, setup log, other context shared among the dialogs
+# the type is the setup type - 1, 2, or 3 for express, typical, or custom
+# type is used to say which types use this dialog
+sub new {
+    my $type = shift;
+    my $self = {};
+
+    $self->{type} = shift;
+    $self->{text} = shift;
+    $self->{defaultAns} = shift;
+    $self->{handleResp} = shift;
+    $self->{prompts} = \@_;
+
+    $self = bless $self, $type;
+
+    return $self;
+}
+
+sub setManager {
+    my $self = shift;
+    $self->{"manager"} = shift;
+}
+
+# returns true if this dialog is to be displayed for the current setup type
+# false otherwise
+sub isDisplayed {
+    my $self = shift;
+
+    return $self->{type} <= $self->{"manager"}->{type};
+}
+
+# each prompt looks like this:
+# [ 'resource key', is pwd ]
+# The resource key is the string key of the resource
+# is pwd is optional - if present, the prompt is for a password
+# and should not echo the answer
+# e.g.
+# ['RESOURCE_USERNAME'], ['RESOURCE_PASSWORD', 1], ['RESOURCE_PASSWORD_AGAIN', 1]
+sub run {
+    my $self = shift;
+    my $resp = $DialogManager::SAME;
+
+    # display the dialog text
+    if ($self->isDisplayed()) {
+        $self->{manager}->showText($self->{text});
+    }
+
+    # display each prompt for this dialog
+    my $index = 0;
+    my @prompts = @{$self->{prompts}};
+    for (my $index = 0; $index < @prompts; ++$index) {
+        my $prompt = $prompts[$index];
+        my $defaultans = $self->{defaultAns}($self, $index);
+        my $ans;
+        if ($self->isDisplayed()) {
+            $ans = $self->{manager}->showPrompt($prompt->[0], $defaultans, $prompt->[1]);
+        } else {
+            $ans = $defaultans;
+        }
+
+        # see if this is the special BACK response, and finish if so
+        if ($self->{"manager"}->isBack($ans)) {
+            $resp = $DialogManager::BACK;
+            last;
+        }
+
+        # figure out what action to take based on the users response
+        # this will set values in the setup info file
+        # this will also validate input, and display errors if the
+        # input is not correct - in that case, the resp will be
+        # SAME to reprompt, or ERR if unrecoverable
+        # NOTE: user cannot BACK from prompt to prompt - BACK
+        # always means BACK to the previous dialog
+        $resp = $self->{handleResp}($self, $ans, $index);
+        if ($resp == $DialogManager::SAME) {
+            if (!$self->isDisplayed()) {
+                $self->{manager}->alert('dialog_use_different_type');
+                $resp = $DialogManager::ERR;
+            } else {
+                $index--; # reprompt
+            }
+        } elsif ($resp == $DialogManager::ERR) {
+            last;
+        }
+    }
+
+    return $resp;
+}
+
+package DialogYesNo;
+
+@ISA       = qw(Dialog);
+
+sub new {
+    my $type = shift;
+    my $setuptype = shift;
+    my $text = shift;
+    my $defaultIsYes = shift;
+    my $handler = shift || \&handleResponse;
+    my $prompt = shift || ['prompt_yes_no'];
+    my $self = Dialog->new($setuptype, $text,
+                           \&defaultAns, $handler, $prompt);
+
+    $self->{defaultIsYes} = $defaultIsYes;
+    
+    $self = bless $self, $type;
+
+    return $self;
+}
+
+sub setDefaultYes {
+    my $self = shift;
+    $self->{default} = $self->{"manager"}->getText("yes");
+}
+
+sub setDefaultNo {
+    my $self = shift;
+    $self->{default} = $self->{"manager"}->getText("no");
+}
+
+sub defaultAns {
+    my $self = shift;
+    if (exists($self->{ans})) {
+        return $self->{ans};
+    }
+    if (!exists($self->{default})) {
+        if ($self->{defaultIsYes}) {
+            $self->{default} = $self->{"manager"}->getText("yes");
+        } else {
+            $self->{default} = $self->{"manager"}->getText("no");
+        }
+    }
+    return $self->{default};
+}
+
+sub isYes {
+    my $self = shift;
+    return $self->{ans} eq $self->{"manager"}->getText("yes");
+}
+
+sub handleResponse {
+    my $self = shift;
+    my $ans = shift;
+    my $resp = $DialogManager::SAME;
+    my $yes = $self->{"manager"}->getText("yes");
+    my $nno = $self->{"manager"}->getText("no");
+
+    # the regexp allows us to use y or ye or yes for "yes"
+    if ($nno =~ /^$ans/) {
+        $resp = $DialogManager::NEXT;
+        $self->{ans} = $nno;
+    } elsif ($yes =~ /^$ans/) {
+        $resp = $DialogManager::NEXT;
+        $self->{ans} = $yes;
+    } else {
+        $self->{"manager"}->alert("yes_no_error");
+    }
+
+    return $resp;
+}
+
+#############################################################################
+# Mandatory TRUE return value.
+#
+1;

+ 229 - 0
ldap/admin/src/scripts/DialogManager.pm

@@ -0,0 +1,229 @@
+# 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
+#
+
+package DialogManager;
+use Exporter ();
+@ISA       = qw(Exporter);
+@EXPORT    = qw($BACK $SAME $NEXT $ERR);
+@EXPORT_OK = qw($BACK $SAME $NEXT $ERR);
+
+use Dialog;
+use SetupLog;
+
+# Dialog responses
+$BACK = -1;
+$SAME = 0;
+$NEXT = 1;
+$ERR = 2;
+
+# The DialogManager controls the flow of the dialogs and contains context shared
+# among all of the dialogs (resources, logs, current setup type, etc.)
+# all of these are optional
+sub new {
+    my $type = shift;
+    my $self = {};
+
+    $self->{setup} = shift;
+    $self->{res} = shift;
+    $self->{type} = shift;
+
+    $self->{log} = $self->{setup}->{log};
+    $self->{inf} = $self->{setup}->{inf};
+
+    $self = bless $self, $type;
+
+    return $self;
+}
+
+sub getType {
+    my $self = shift;
+    return $self->{type};
+}
+
+sub setType {
+    my $self = shift;
+    $self->{type} = shift;
+}
+
+sub addDialog {
+    my $self = shift;
+    for my $dialog (@_) {
+        $dialog->setManager($self);
+        push @{$self->{dialogs}}, $dialog;
+    }
+}
+
+# see if the user answered with the special BACK answer
+sub isBack {
+    my $self = shift;
+    my $ans = shift;
+
+    # the word "back"
+    if ($ans =~ /back/i) {
+        return 1;
+    }
+    # a Ctrl-B sequence
+    if ($ans eq '') {
+        return 1;
+    }
+
+    return 0;
+}
+
+sub log {
+    my $self = shift;
+    if (!$self->{log}) {
+        print @_;
+    } else {
+        $self->{log}->logMessage($INFO, "Setup", @_);
+    }
+}
+
+sub getText {
+    my $self = shift;
+    return $self->{res}->getText(@_);
+}
+
+sub handleError {
+    my $self = shift;
+    my $msg = $self->{res}->getText('setup_err_exit');
+    $self->{log}->logMessage($FATAL, "Setup", $msg);
+}
+
+sub showText {
+    my $self = shift;
+    my $msg = shift;
+    my $text = $self->getText($msg);
+    print "\n", ("=" x 78), "\n";
+    # display it,
+    print $text;
+    # log it
+    $self->log($text);
+}
+
+sub showPrompt {
+    my $self = shift;
+    my $msg = shift;
+    my $defaultans = shift;
+    my $ispwd = shift;
+
+    my $text = $self->getText($msg);
+    # display it,
+    print $text;
+    # log it
+    $self->log($text . "\n");
+    # display the default answer
+    if ($defaultans) {
+        print " [$defaultans]";
+    }
+    print ": ";
+    # if we are prompting for a password, disable console echo
+    if ($ispwd) {
+        system("stty -echo");
+    }
+    # read the answer
+    my $ans = <STDIN>;
+    # if we are prompting for a password, enable console echo
+    if ($ispwd) {
+        system("stty echo");
+        print "\n";
+    }
+    chop($ans); # trim trailing newline
+
+    # see if this is the special BACK response, and finish if so
+    if ($self->isBack($ans)) {
+        $self->log("BACK\n");
+        return $ans;
+    }
+
+    if (!length($ans)) {
+        $ans = $defaultans;
+    }
+
+    # log the response, if not a password
+    if (!$ispwd) {
+        $self->log($ans . "\n");
+    }
+
+    return $ans;
+}
+
+sub alert {
+    my $self = shift;
+    my $msg = $self->{res}->getText(@_);
+    print $msg;
+    $self->{log}->logMessage($WARN, "Setup", $msg);
+}
+
+sub run {
+    my $self = shift;
+    my $done;
+    my $index = 0;
+    my $incr = 1;
+    my $rc = 0;
+
+    while (!$done) {
+        my $dialog = $self->{dialogs}->[$index];
+        my $resp = $NEXT;
+        $resp = $dialog->run();
+        if ($resp == $BACK) {
+            $incr = -1;
+        } elsif ($resp == $NEXT) {
+            $incr = 1;
+        } elsif ($resp == $SAME) {
+            $incr = 0;
+        } else {
+            $self->handleError($resp);
+            $done = 1;
+            $rc = 1;
+        }
+        $index += $incr;
+        if ($index < 0) {
+            $index = 0;
+        } elsif ($index >= @{$self->{dialogs}}) {
+            $done = 1;
+        }
+    }
+
+    return $rc;
+}
+
+#############################################################################
+# Mandatory TRUE return value.
+#
+1;

+ 146 - 0
ldap/admin/src/scripts/Inf.pm

@@ -0,0 +1,146 @@
+# 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
+#
+
+# manages inf files - gets values
+# given keys
+
+package Inf;
+
+#require    Exporter;
+#@ISA       = qw(Exporter);
+#@EXPORT    = qw();
+
+sub new {
+    my $type = shift;
+    my $self = {};
+
+    $self->{filename} = shift;
+
+    $self = bless $self, $type;
+
+    if ($self->{filename}) {
+        $self->read();
+    }
+
+    return $self;
+}
+
+sub read {
+# each key in the table is a section name
+# the value is a hash ref of the items in that section
+#   in that hash ref, each key is the config param name,
+#   and the value is the config param value
+    my $self = shift;
+    my $filename = shift;
+    my $curSection;
+
+    if ($filename) {
+        $self->{filename} = $filename;
+    } else {
+        $filename = $self->{filename};
+    }
+
+    open INF, $filename or die "Error: could not open inf file $filename: $!";
+    while (<INF>) {
+        # e.g. [General]
+        if (/^\[(.*?)\]/) {
+            $curSection = $1;
+        } elsif (/^\s*$/) {
+            next; # skip blank lines
+        } elsif (/^\s*\#/) {
+            next; # skip comment lines
+        } elsif (/^\s*(.*?)\s*=\s*(.*?)\s*$/) {
+            $self->{$curSection}->{$1} = $2;
+        }
+	}
+    close INF;
+}
+
+sub section {
+    my $self = shift;
+    my $key = shift;
+
+    if (!exists($self->{$key})) {
+        print "Error: unknown inf section $key\n";
+        return undef;
+    }
+
+    return $self->{$key};
+}
+
+sub writeSection {
+    my $self = shift;
+    my $name = shift;
+    my $fh = shift;
+    my $section = $self->{$name};
+    if (ref($section) eq 'HASH') {
+        print $fh "[$name]\n";
+        for my $key (keys %{$section}) {
+            if (defined($section->{$key})) {
+                print $fh "$key = ", $section->{$key}, "\n";
+            }
+        }
+    }
+}
+
+sub write {
+    my $self = shift;
+    my $filename = shift;
+
+    if ($filename) {
+        $self->{filename} = $filename;
+    } else {
+        $filename = $self->{filename};
+    }
+
+    open INF, ">$filename" or die "Error: could not write inf file $filename: $!";
+    # write General section first
+    $self->writeSection('General', \*INF);
+    print INF "\n";
+    for my $key (keys %{$self}) {
+        next if ($key eq 'General');
+        $self->writeSection($key, \*INF);
+        print INF "\n";
+    }
+    close INF;
+}
+
+#############################################################################
+# Mandatory TRUE return value.
+#
+1;

+ 134 - 0
ldap/admin/src/scripts/Resource.pm

@@ -0,0 +1,134 @@
+# 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
+#
+
+# manages resource bundle files - gets values
+# given keys
+
+package Resource;
+
+use strict;
+
+#require    Exporter;
+#@ISA       = qw(Exporter);
+#@EXPORT    = qw();
+
+sub new {
+    my $type = shift;
+    my $self = {};
+
+    $self->{filename} = shift;
+
+    $self = bless $self, $type;
+
+    if ($self->{filename}) {
+        $self->read();
+    }
+
+    return $self;
+}
+
+sub read {
+    my $self = shift;
+    my $filename = shift;
+
+    if ($filename) {
+        $self->{filename} = $filename;
+    } else {
+        $filename = $self->{filename};
+    }
+
+    open RES, $filename or die "Error: could not open resource file $filename: $!";
+    while (<RES>) {
+        next if (/^\s*$/); # skip blank lines
+        next if (/^\s*\#/); # skip comment lines
+        # read name = value pairs like this
+        # bol whitespace* name whitespace* '=' whitespace* value eol
+        # the value will include any trailing whitespace
+        if (/^\s*(.*?)\s*=\s*(.*?)$/) {
+            $self->{res}->{$1} = $2;
+            # replace \n with real newline
+            $self->{res}->{$1} =~ s/\\n/\n/g;
+        }
+	}
+    close RES;
+}
+
+# given a resource key and optional args, return the value
+# $text = $res->getText('key');
+# or
+# $text = $res->getText('key', @args);
+# or
+# $text = $res->getText($arrayref)
+# where $arrayref is ['key', @args]
+sub getText {
+    my $self = shift;
+    my $key = shift;
+    my @args = @_;
+
+    if (ref($key) eq 'ARRAY') {
+        my $tmpkey = shift @{$key};
+        @args = @{$key};
+        $key = $tmpkey;
+    }
+
+    if (!exists($self->{res}->{$key})) {
+        print "Error: unknown resource key $key\n";
+        return undef;
+    }
+
+    if (!defined($self->{res}->{$key})) {
+        print "Error: resource key $key has no value\n";
+        return undef;
+    }
+
+    # see if the args themselves are resource keys
+    for (my $ii = 0; $ii < @args; ++$ii) {
+        if (exists($self->{res}->{$args[$ii]})) {
+            $args[$ii] = $self->{res}->{$args[$ii]};
+        }
+    }
+
+    my $text = sprintf $self->{res}->{$key}, @args;
+
+    return $text;
+}
+
+#############################################################################
+# Mandatory TRUE return value.
+#
+1;

+ 208 - 0
ldap/admin/src/scripts/Setup.pm.in

@@ -0,0 +1,208 @@
+# 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 Setup;
+use Exporter ();
+@ISA       = qw(Exporter);
+@EXPORT    = qw($SILENT $EXPRESS $TYPICAL $CUSTOM);
+@EXPORT_OK = qw($SILENT $EXPRESS $TYPICAL $CUSTOM);
+
+# 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;
+
+# the setup types
+$SILENT = 0;
+$EXPRESS = 1;
+$TYPICAL = 2;
+$CUSTOM = 3;
+
+# process command line options
+Getopt::Long::Configure(qw(bundling)); # bundling allows -ddddd
+
+sub VersionMessage {
+    print "@capbrand@ Directory Server Setup Program Version @PACKAGE_VERSION@\n";
+}
+
+sub HelpMessage {
+    print <<EOF;
+Usage: $0 [--options] -- [args]
+options:
+    --help       This message
+    --version    Print the version and exit
+    --debug      Turn on debugging
+    --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 setup messages to this file - otherwise, a temp file will be used
+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.
+EOF
+}
+
+sub new {
+    my $type = shift;
+    my $self = {};
+    my ($debuglevel, $silent, $inffile, $keep, $preonly, $logfile);
+    my @otherargs;
+
+    GetOptions('help|h|?' => sub { VersionMessage(); HelpMessage(); exit 0 },
+               'version|v' => sub { VersionMessage(); exit 0 },
+               'debug|d+' => \$debuglevel,
+               'silent|s' => \$silent,
+               'file|f=s' => \$inffile,
+               'keepcache|k' => \$keep,
+               'preonly|p' => \$preonly,
+               'logfile|l=s' => \$logfile
+               );
+
+    $self->{debuglevel} = $debuglevel;
+    $self->{silent} = $silent;
+    $self->{inffile} = $inffile;
+    $self->{keep} = $keep;
+    $self->{preonly} = $preonly;
+    $self->{logfile} = $logfile;
+    $self->{log} = new SetupLog($self->{logfile});
+    if (!$self->{inffile}) {
+        my ($fh, $filename) = tempfile("setupXXXXXX", UNLINK => !$keep,
+                                       SUFFIX => ".inf", OPEN => 0,
+                                       DIR => File::Spec->tmpdir);
+        $self->{inffile} = $filename;
+        $self->{inf} = new Inf;
+        $self->{inf}->{filename} = $self->{inffile};
+    } else {
+        $self->{inf} = new Inf($self->{inffile});
+        $self->{keep} = 1; # do not delete user supplied inf file
+    }
+
+    # 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;
+        }
+    }
+
+    $self->{configdir} = $ENV{DS_CONFIG_DIR} || "@instconfigdir@";
+
+    $self = bless $self, $type;
+    return $self;
+}
+
+# log only goes the the logfile
+sub log {
+    my $self = shift;
+    my $level = shift;
+    $self->{log}->logMessage($level, "Setup", @_);
+}
+
+# msg does to the screen and optionally to the log file
+# if you use msg like this:
+# msg(0, "some message")
+# it will go only to the screen
+# if you use msg like this:
+# msg($WARN, "some message")
+# it will go to the screen and to the log at the $WARN level
+sub msg {
+    my $self = shift;
+    my $level = shift;
+    my @text = @_;
+    if (!$level && @text) {
+        # e.g. msg(0, "string") - no logging
+    } elsif ($level and @text and grep {/^$level$/} $self->{log}->levels()) {
+        # e.g. msg($WARN, "string") - print and log
+    } else {
+        # log at default INFO level
+        unshift @text, $level;
+        $level = $INFO;
+    }
+    if ($level) {
+        $self->log($level, @text);
+    }
+    print @text;
+}
+
+sub doExit {
+    my $self = shift;
+    $self->msg($FATAL, "Exiting . . .\n");
+    $self->msg("Log file is " . $self->{log}->{filename} . "\n");
+	exit 1;
+}
+
+#############################################################################
+# Mandatory TRUE return value.
+#
+1;

+ 255 - 0
ldap/admin/src/scripts/SetupDialogs.pm

@@ -0,0 +1,255 @@
+# 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
+#
+
+package SetupDialogs;
+
+use strict;
+
+use DialogManager;
+use Setup;
+use Dialog;
+use Net::Domain qw(hostfqdn);
+
+my $welcome = new DialogYesNo (
+    $EXPRESS,
+    ['dialog_welcome_text', 'brand', 'brand'],
+    1,
+    sub {
+        my $self = shift;
+        my $ans = shift;
+        my $res = $self->handleResponse($ans);
+        if ($res == $DialogManager::NEXT) {
+            $res = $DialogManager::ERR if (!$self->isYes());
+        }
+        return $res;
+    },
+    ['dialog_welcome_prompt'],
+);
+
+my $license = new DialogYesNo (
+    $EXPRESS,
+    'dialog_license_text',
+    0,
+    sub {
+        my $self = shift;
+        my $ans = shift;
+        my $res = $self->handleResponse($ans);
+        if ($res == $DialogManager::NEXT) {
+            $res = $DialogManager::ERR if (!$self->isYes());
+        }
+        return $res;
+    },
+    ['dialog_license_prompt']
+);
+
+my $setuptype = new Dialog (
+    $EXPRESS,
+    'dialog_setuptype_text',
+    sub {
+        my $self = shift;
+        return $self->{manager}->getType();
+    },
+    sub {
+        my $self = shift;
+        my $ans = shift;
+        my $res = $DialogManager::SAME;
+        if ($ans < $EXPRESS or $ans > $CUSTOM) {
+            $self->{manager}->alert("dialog_setuptype_error");
+        } else {
+            $res = $DialogManager::NEXT;
+            $self->{manager}->setType($ans);
+        }
+        return $res;
+    },
+    ['dialog_setuptype_prompt']
+);
+
+my $hostdlg = new Dialog (
+    $TYPICAL,
+    'dialog_hostname_text',
+    sub {
+        my $self = shift;
+        return $self->{manager}->{inf}->{General}->{FullMachineName} ||
+            hostfqdn;
+    },
+    sub {
+        my $self = shift;
+        my $ans = shift;
+        my $res = $DialogManager::NEXT;
+        if ($ans !~ /\./) {
+            $self->{manager}->alert("dialog_hostname_warning", $ans);
+        }
+        $self->{manager}->{inf}->{General}->{FullMachineName} = $ans;
+        return $res;
+    },
+    ['dialog_hostname_prompt']
+);
+
+# must verify that the user or uid specified by the user to run the server as
+# is a valid uid
+sub verifyUserChoice {
+    my $self = shift;
+    my $ans = shift;
+    my $res = $DialogManager::NEXT;
+    # convert numeric uid to string
+    my $strans = $ans;
+    if ($ans =~ /^\d/) { # numeric - convert to string
+        $strans = getpwuid $ans;
+        if (!$strans) {
+            $self->{manager}->alert("dialog_ssuser_error", $ans);
+            return $DialogManager::SAME;
+        }
+    }
+    if ($> != 0) { # if not root, the user must be our uid
+        my $username = getlogin;
+        if ($strans ne $username) {
+            $self->{manager}->alert("dialog_ssuser_must_be_same", $username);
+            return $DialogManager::SAME;
+        }
+    } else { # user is root - verify id
+        my $nuid = getpwnam $strans;
+        if (!defined($nuid)) {
+            $self->{manager}->alert("dialog_ssuser_error", $ans);
+            return $DialogManager::SAME;
+        }
+        if (!$nuid) {
+            $self->{manager}->alert("dialog_ssuser_root_warning");
+        }
+    }
+    $self->{manager}->{inf}->{General}->{SuiteSpotUserID} = $ans;
+    return $res;
+}
+
+# must verify that the given group is one of the groups the given user
+# belongs to
+sub verifyGroupChoice {
+    my $self = shift;
+    my $ans = shift;
+    my $res = $DialogManager::NEXT;
+    my ($dummy, $memstr);
+    my $strgrp;
+    my $numgrp;
+    if ($ans =~ /^\d/) { # numeric
+        $numgrp = $ans;
+        ($strgrp, $dummy, $dummy, $memstr) = getgrgid $ans;
+    } else {
+        $strgrp = $ans;
+        ($dummy, $dummy, $numgrp, $memstr) = getgrnam $ans;
+    }
+
+    if (!defined($strgrp) or !defined($numgrp)) {
+        $self->{manager}->alert("dialog_ssgroup_error", $ans);
+        return $DialogManager::SAME;
+    }
+
+    # get the user id, and then get the user's default group id
+    my $uid = $self->{manager}->{inf}->{General}->{SuiteSpotUserID};
+    my $usergid;
+    if ($uid =~ /^\d/) { # numeric
+        ($uid, $dummy, $dummy, $usergid, $dummy) = getpwuid $uid;
+    } else { # string
+        ($uid, $dummy, $dummy, $usergid, $dummy) = getpwnam $uid;
+    }
+
+    if ($numgrp == $usergid) {
+        $self->{manager}->{inf}->{General}->{SuiteSpotGroup} = $ans;
+    } elsif ($memstr) { # see if the user is in the member list
+        if ($memstr =~ /\b$uid\b/) { # uid exactly matches one of the users in the member string
+            $self->{manager}->{inf}->{General}->{SuiteSpotGroup} = $ans;
+        } else { # no match
+            $self->{manager}->alert("dialog_ssgroup_no_match",
+                                   $self->{manager}->{inf}->{General}->{SuiteSpotUserID},
+                                   $ans, $memstr);
+            $res = $DialogManager::SAME;
+        }
+    } else { # user not in group
+        $self->{manager}->alert("dialog_ssgroup_no_user",
+                                $self->{manager}->{inf}->{General}->{SuiteSpotUserID},
+                                $ans);
+        $res = $DialogManager::SAME;
+    }
+    return $res;
+}
+
+my $usergroup = new Dialog (
+    $TYPICAL,
+    'dialog_ssuser_text',
+    sub {
+        my $self = shift;
+        my $index = shift;
+        if ($index == 0) {
+            my $username = $self->{manager}->{inf}->{General}->{SuiteSpotUserID};
+            if (!$username) {
+                if ($> == 0) { # if root, use the default user
+                    $username = "\@defaultuser\@";
+                } else { # if not root, use the user's uid
+                    $username = getlogin;
+                }
+            }
+            return $username;
+        } else { # group
+            my $groupname = $self->{manager}->{inf}->{General}->{SuiteSpotGroup};
+            if (!$groupname) {
+                if ($> == 0) { # if root, use the default group
+                    $groupname = "\@defaultgroup\@";
+                } else { # if not root, use the user's gid
+                    $groupname = getgrgid $(;
+                }
+            }
+            return $groupname;
+        }
+    },
+    sub {
+        my $self = shift;
+        my $ans = shift;
+        my $index = shift;
+        if ($index == 0) {
+            return verifyUserChoice($self, $ans);
+        } else {
+            return verifyGroupChoice($self, $ans);
+        }
+    },
+    ['dialog_ssuser_prompt'], ['dialog_ssgroup_prompt']
+);
+
+
+sub getDialogs {
+    return ($welcome, $license, $setuptype, $hostdlg, $usergroup);
+}
+
+1;

+ 99 - 0
ldap/admin/src/scripts/SetupLog.pm

@@ -0,0 +1,99 @@
+# 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 implements SetupLog from setuputil InstallLog in perl
+#
+package SetupLog;
+use Exporter ();
+@ISA       = qw(Exporter);
+@EXPORT    = qw($FATAL $START $SUCCESS $WARN $INFO $DEBUG);
+@EXPORT_OK = qw($FATAL $START $SUCCESS $WARN $INFO $DEBUG);
+
+use POSIX qw(strftime);
+
+# tempfiles
+use File::Temp qw(tempfile tempdir);
+
+# exported variables
+$FATAL    = "Fatal";
+$START    = "Start";
+$SUCCESS  = "Success";
+$WARN     = "Warning";
+$INFO     = "Info";
+$DEBUG    = "Debug";
+
+sub new {
+    my $type = shift;
+    my $filename = shift;
+    my $self = {};
+    my $fh;
+
+    if (!$filename) {
+        ($fh, $filename) = tempfile("setupXXXXXX", UNLINK => 0,
+                                    SUFFIX => ".log", DIR => File::Spec->tmpdir);
+    } else {
+        open LOGFILE, ">$filename" or die "Error: could not open logfile $filename: $!";
+        $fh = \*LOGFILE;
+    }
+    $self->{fh} = $fh;
+    $self->{filename} = $filename;
+    $self = bless $self, $type;
+
+    return $self;
+}
+
+sub logMessage {
+    my ($self, $level, $who, $msg, @rest) = @_;
+    if (!$self->{fh}) {
+        return;
+    }
+
+    my $string = strftime "[%y/%m/%d:%H:%M:%S] - ", localtime;
+    $string .= "[$who] $level ";
+    $string .= sprintf $msg, @rest;
+    print { $self->{fh} } $string;
+}
+
+sub levels {
+    my $self = shift;
+    return ($FATAL, $START, $SUCCESS, $WARN, $INFO, $DEBUG);
+}
+
+#############################################################################
+# Mandatory TRUE return value.
+#
+1;

+ 82 - 0
ldap/admin/src/scripts/Util.pm

@@ -0,0 +1,82 @@
+# 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
+#
+
+package Util;
+require Exporter;
+@ISA       = qw(Exporter);
+@EXPORT    = qw(portAvailable getAvailablePort isValidDN);
+@EXPORT_OK = qw(portAvailable getAvailablePort isValidDN);
+
+use strict;
+
+use Socket;
+
+# return true if the given port number is available, false otherwise
+sub portAvailable {
+    my $port = shift;
+    my $proto = getprotobyname('tcp');
+    my $rc = socket(SOCK, PF_INET, SOCK_STREAM, $proto);
+    if ($rc == 1) {
+        $rc = bind(SOCK, sockaddr_in($port, INADDR_ANY));
+    }
+    close(SOCK);
+    return $rc and ($rc == 1);
+}
+
+# returns a randomly assigned port number, or -1
+# if not able to find an available port
+sub getAvailablePort {
+    my $MINPORT = 1024;
+    my $MAXPORT = 65535;
+
+    srand( time() ^ ($$ + ($$ << 15)) );
+    while (1) {
+        my $port = $MINPORT + int(rand($MAXPORT-$MINPORT));
+
+        if (portAvailable($port)) {
+            return $port;
+        }
+    }
+}
+
+sub isValidDN {
+    my $dn = shift;
+    return ($dn =~ /^[0-9a-zA-Z_-]+=.*$/);
+}
+
+1;

+ 75 - 0
ldap/admin/src/scripts/setup-ds.pl.in

@@ -0,0 +1,75 @@
+#!/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
+#
+
+use lib '@perldir@';
+
+use strict;
+
+use Setup;
+use Inf;
+use Resource;
+use DialogManager;
+
+my $setup = new Setup;
+
+if (!$setup->{silent}) {
+    my $res = new Resource("@propertydir@/setup-ds.res");
+    my $dialogmgr = new DialogManager($setup, $res, $TYPICAL);
+
+    require SetupDialogs;
+    require DSDialogs;
+
+    my @dialogs = SetupDialogs->getDialogs();
+    push @dialogs, DSDialogs->getDialogs();
+
+    $dialogmgr->addDialog(@dialogs);
+
+    my $rc = $dialogmgr->run();
+    if ($rc) {
+        $setup->doExit();
+    }
+    $setup->{inf}->write();
+}
+
+system("@bindir@/ds_newinst.pl $setup->{inffile}");
+if (!$setup->{keep}) {
+    unlink $setup->{inffile};
+}
+
+$setup->doExit();

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

@@ -0,0 +1,81 @@
+# ------------ Global Resources -----------
+brand = @capbrand@
+yes = yes
+no = no
+yes_no_error = Please answer "yes" or "no"\n\n
+setup_err_exit = Setup cannot proceed.  Exiting.\n\n
+dialog_use_different_type = When using Silent or Express mode, some of the\ndialogs are skipped, but validation is still performed\non the default or given answers.  You should run this program again and\nchoose Typical or Custom mode in order to provide a valid input\nfor the problem dialog.\n\n
+
+# ------------ Welcome Dialog Resource ------------
+dialog_welcome_text = This program will setup the %s Directory Server.\n\nIt is recommended that you have "root" privilege to setup the software.\nTips for using this  program:\n  - Press "Enter" to choose the default and go to the next screen\n  - Type "Control-B" then "Enter" to go back to the previous screen\n  - Type "Control-C" to cancel the setup program\n  - You can enter multiple items using commas to separate them.\n    For example: 1, 2, 3 \n\n
+# %s -> brand
+
+dialog_welcome_prompt = Would you like to continue with setup?
+
+# ----------- License Dialog Resource  -----------
+dialog_license_text = BY SETTING UP AND USING THIS SOFTWARE YOU ARE CONSENTING TO BE BOUND BY\nAND ARE BECOMING A PARTY TO THE AGREEMENT FOUND IN THE\nLICENSE.TXT FILE. IF YOU DO NOT AGREE TO ALL OF THE TERMS\nOF THIS AGREEMENT, PLEASE DO NOT SETUP OR USE THIS SOFTWARE.\n\n
+
+dialog_license_prompt = Do you agree to the license terms?
+
+
+# ----------- Setup Type Dialog Resource  ----------------
+dialog_setuptype_text = Choose a setup type:\n\n   1. Express\n       Allows you to quickly setup the servers using the most\n       common options and pre-defined defaults. Useful for quick\n       evaluation of the products.\n\n   2. Typical\n       Allows you to specify common defaults and options.\n\n   3. Custom\n       Allows you to specify more advanced options. This is \n       recommended for experienced server administrators only.\n\nTo accept the default shown in brackets, press the Enter key.\n\n
+
+dialog_setuptype_prompt = Choose a setup type
+
+dialog_setuptype_error = Invalid setup type\n\n
+
+
+# ----------- HostName Dialog Resource  ----------------
+dialog_hostname_text = Enter the fully qualified domain name of the computer\non which you're setting up server software. Using the form\n<hostname>.<domainname>\nExample: eros.example.com.\n\nTo accept the default shown in brackets, press the Enter key.\n\n
+
+dialog_hostname_prompt = Computer name
+
+dialog_hostname_warning = The hostname %s does not look like a\nfully qualified host and domain name.\nIf you feel you have made a mistake,\nplease go back to this dialog and enter another name.\n\n
+
+# ----------- SSUser Dialog Resource  ----------------
+dialog_ssuser_text = The server must run as a specific user in a specific group.\nIt is strongly recommended that this user should have no privileges\non the computer (i.e. a non-root user).  The Administration Server\nwill give this user/group some permissions in specific paths/files\nto perform server-specific operations.\n\nIf you have not yet created a user and group for the server,\ncreate this user and group using your native operating\nsystem utilities.\n\n
+
+dialog_ssuser_prompt = System User
+dialog_ssuser_error = The user '%s' is invalid.\n\n
+dialog_ssuser_must_be_same = Since you are not running setup as root, the System User must be the same as your userid '%s'.\n\n
+dialog_ssuser_root_warning = You are strongly discouraged to use a non-root user for the server uid.\nIf you feel you have made a mistake,\nplease go back to this dialog and enter another system user.\n\n
+dialog_ssgroup_prompt = System Group
+dialog_ssgroup_error = The group '%s' is invalid.\n\n
+dialog_ssgroup_no_match = The system user '%s' does not belong to the group '%s'.\n\nThis is the list of users of the given group: %s\n\n
+dialog_ssgroup_no_user = The system user '%s' does not belong to the group '%s'.\n\n
+
+# ----------- DS port Dialog Resource  ----------------
+dialog_dsport_text = The standard directory server network port number is 389.  However, if\nyou are not logged as the superuser, or port 389 is in use, the\ndefault value will be a random unused port number greater than 1024.\nIf you want to use port 389, make sure that you are logged in as the\nsuperuser, that port 389 is not in use.\n\n
+dialog_dsport_prompt = Directory server network port
+dialog_dsport_error = The port %s is in use or not available.  Please choose another port.\n\n
+
+# ----------- DS server ID Dialog Resource  ----------------
+dialog_dsserverid_text = Each instance of a directory server requires a unique identifier.\nThis identifier is used to name the various\ninstance specific files and directories in the file system,\nas well as for other uses as a server instance identifier.\n\n
+dialog_dsserverid_prompt = Directory server identifier
+dialog_dsserverid_error = The server identifier '%s' is not valid.  Please choose another one.\n\n
+dialog_dsserverid_inuse = The server identifier '%s' is already in use.  Please choose another one.\n\n
+
+# ----------- DS suffix Dialog Resource  ----------------
+dialog_dssuffix_text = The suffix is the root of your directory tree.  The suffix must be a valid DN.\nIt is recommended that you use the dc=domaincomponent suffix convention.\nFor example, if your domain is example.com,\nyou should use dc=example,dc=com for your suffix.\nSetup will create this initial suffix for you,\nbut you may have more than one suffix.\nUse the directory server utilities to create additional suffixes.\n\n
+dialog_dssuffix_prompt = Suffix
+dialog_dssuffix_error = The suffix '%s' is not a valid DN.  Please choose another one.\n\n
+
+# ----------- DS Root DN and password Dialog Resource  ----------------
+dialog_dsrootdn_text = Certain directory server operations require an administrative user.\nThis user is referred to as the Directory Manager and typically has a\nbind Distinguished Name (DN) of cn=Directory Manager.\nYou will also be prompted for the password for this user.  The password must\nbe at least 8 characters long, and contain no spaces.\n\n
+dialog_dsrootdn_prompt = Directory Manager DN
+dialog_dsrootdn_error = The input '%s' is not a valid DN.  Please choose another one.\n\n
+dialog_dsrootpw_prompt1 = Password
+dialog_dsrootpw_prompt2 = Password (again)
+dialog_dsrootpw_invalid = The password contains invalid characters.  Please choose another one.\n\n
+dialog_dsrootpw_tooshort = The password must be at least %s characters long.  Please choose another one.\n\n
+dialog_dsrootpw_nomatch = The passwords do not match.  Please try again.\n\n
+
+# ----------- DS Sample Data Dialog Resource  ----------------
+dialog_dssample_text = You may install some sample entries in this directory instance.  These\nentries will be installed in a separate suffix and will not interfere\nwith the normal operation of the directory server.\n\n
+dialog_dssample_prompt = Do you want to install the sample entries?
+
+# ----------- DS Populate Data Dialog Resource  ----------------
+dialog_dspopulate_text = You may wish to populate your new directory instance with some data.\n"You may already have a file in LDIF format to use or some suggested\nentries can be added.  If you want to import entries from an LDIF\nfile, you may type in the full path and filename at the prompt.  If\nyou want the setup program to add the suggested entries, type the\nword suggest at the prompt.  The suggested entries are common\ncontainer entries under your specified suffix, such as ou=People and\nou=Groups, which are commonly used to hold the entries for the persons\nand groups in your organization.  If you do not want to add any of\nthese entries, type the word none at the prompt.\n\n
+dialog_dspopulate_prompt = Type the full path and filename, the word suggest, or the word none
+dialog_dspopulate_error = The file '%s' was not found.  Please choose another one.\n\n