From 89184bfa3cb86b2e46a9998b85bbaef357f979df Mon Sep 17 00:00:00 2001
From: Rich Megginson <rmeggins@redhat.com>
Date: Mon, 14 Sep 2009 16:09:53 -0600
Subject: [PATCH] Add support for new ds base update framework
 setup-ds-admin.pl -u will now use the new ds update
 framework.  The user will notice no change.
 There is now a script in the framework which will convert the
 configuration entries and files that used Fedora branding, and
 convert them to use 389 branding.

---
 Makefile.am                                  |   22 ++-
 Makefile.in                                  |  101 +++++++++--
 admserv/newinst/src/25changefedorato389.pl   |  250 ++++++++++++++++++++++++++
 admserv/newinst/src/30updateglobalpref.pl.in |   54 ++++++
 admserv/newinst/src/AdminUtil.pm.in          |    1 +
 admserv/newinst/src/setup-ds-admin.pl.in     |   76 +++++++-
 admserv/newinst/src/setup-ds-admin.res.in    |    4 +
 configure                                    |   26 ++--
 configure.ac                                 |    5 +-
 9 files changed, 498 insertions(+), 41 deletions(-)
 create mode 100644 admserv/newinst/src/25changefedorato389.pl
 create mode 100644 admserv/newinst/src/30updateglobalpref.pl.in

diff --git a/Makefile.am b/Makefile.am
index 30129a4..29b6b26 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -89,6 +89,7 @@ logdir = $(localstatedir)@admlogdir@
 else
 logdir = $(localstatedir)@admlogdir@/$(instancename)
 endif
+updatedir = $(datadir)@updatedir@
 
 libbase_a_SOURCES = lib/base/file.cpp lib/base/nscperror.c \
 	lib/base/system.cpp lib/base/nscputil.cpp
@@ -212,6 +213,21 @@ dist_man_MANS = man/man8/migrate-ds-admin.pl.8 \
 	man/man8/setup-ds-admin.pl.8 \
 	man/man8/remove-ds-admin.pl.8
 
+#------------------------
+# updates
+# the directory server package contains examples
+# perl files and LDIF files are DATA - not executable
+# processed by the update script
+# shell scripts and other files are SCRIPTS - executable
+#------------------------
+update_DATA = admserv/newinst/src/25changefedorato389.pl \
+	admserv/newinst/src/30updateglobalpref.pl
+
+update_SCRIPTS = 
+
+#------------------------
+# libraries
+#------------------------
 libds_admin_serv_la_SOURCES = $(libbase_a_SOURCES) $(libsi18n_a_SOURCES) $(libadmin_a_SOURCES)
 libds_admin_serv_la_LINK = $(MYLINK)
 libds_admin_serv_la_LIBADD = \
@@ -477,7 +493,8 @@ fixupcmd = sed \
         -e 's,@dslibdir\@,$(dslibdir),g' \
         -e 's,@ldifdir\@,$(ldifdir),g' \
         -e 's,@adminutilpath\@,$(adminutilpath),g' \
-        -e 's,@initconfigdir\@,$(initconfigdir),g'
+        -e 's,@initconfigdir\@,$(initconfigdir),g' \
+        -e 's,@updatedir\@,$(updatedir),g'
 else
 fixupcmd = sed \
 	-e 's,@ECHO_C\@,$(ECHO_C),g' \
@@ -529,7 +546,8 @@ fixupcmd = sed \
 	-e 's,@dslibdir\@,$(dslibdir),g' \
 	-e 's,@ldifdir\@,$(ldifdir),g' \
 	-e 's,@adminutilpath\@,$(adminutilpath),g' \
-	-e 's,@initconfigdir\@,$(initconfigdir),g'
+	-e 's,@initconfigdir\@,$(initconfigdir),g' \
+	-e 's,@updatedir\@,$(updatedir),g'
 endif
 
 # because the source may be either httpd.conf.in or httpd-2.2.conf.in
diff --git a/Makefile.in b/Makefile.in
index 55d211f..37c26a7 100644
--- a/Makefile.in
+++ b/Makefile.in
@@ -94,12 +94,13 @@ am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
 am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(cgibindir)" \
 	"$(DESTDIR)$(cgibindir)" "$(DESTDIR)$(cmdbindir)" \
 	"$(DESTDIR)$(initdir)" "$(DESTDIR)$(cmdbindir)" \
-	"$(DESTDIR)$(man8dir)" "$(DESTDIR)$(helpdir)" \
-	"$(DESTDIR)$(htmldir)" "$(DESTDIR)$(icondir)" \
-	"$(DESTDIR)$(infdir)" "$(DESTDIR)$(initconfigdir)" \
-	"$(DESTDIR)$(ldifdir)" "$(DESTDIR)$(configdir)" \
-	"$(DESTDIR)$(propertydir)" "$(DESTDIR)$(perldir)" \
-	"$(DESTDIR)$(propertydir)"
+	"$(DESTDIR)$(updatedir)" "$(DESTDIR)$(man8dir)" \
+	"$(DESTDIR)$(helpdir)" "$(DESTDIR)$(htmldir)" \
+	"$(DESTDIR)$(icondir)" "$(DESTDIR)$(infdir)" \
+	"$(DESTDIR)$(initconfigdir)" "$(DESTDIR)$(ldifdir)" \
+	"$(DESTDIR)$(configdir)" "$(DESTDIR)$(propertydir)" \
+	"$(DESTDIR)$(perldir)" "$(DESTDIR)$(propertydir)" \
+	"$(DESTDIR)$(updatedir)"
 libLTLIBRARIES_INSTALL = $(INSTALL)
 LTLIBRARIES = $(lib_LTLIBRARIES)
 libds_admin_serv_la_DEPENDENCIES =
@@ -202,8 +203,9 @@ cgibinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 cmdbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 initSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 nodist_cmdbinSCRIPT_INSTALL = $(INSTALL_SCRIPT)
+updateSCRIPT_INSTALL = $(INSTALL_SCRIPT)
 SCRIPTS = $(cgibin_SCRIPTS) $(cmdbin_SCRIPTS) $(init_SCRIPTS) \
-	$(nodist_cmdbin_SCRIPTS)
+	$(nodist_cmdbin_SCRIPTS) $(update_SCRIPTS)
 DEFAULT_INCLUDES = -I. -I$(srcdir) -I.
 depcomp = $(SHELL) $(top_srcdir)/depcomp
 am__depfiles_maybe = depfiles
@@ -264,10 +266,11 @@ nodist_configDATA_INSTALL = $(INSTALL_DATA)
 nodist_propertyDATA_INSTALL = $(INSTALL_DATA)
 perlDATA_INSTALL = $(INSTALL_DATA)
 propertyDATA_INSTALL = $(INSTALL_DATA)
+updateDATA_INSTALL = $(INSTALL_DATA)
 DATA = $(dist_help_DATA) $(dist_html_DATA) $(dist_icon_DATA) \
 	$(inf_DATA) $(initconfig_DATA) $(ldif_DATA) \
 	$(nodist_config_DATA) $(nodist_property_DATA) $(perl_DATA) \
-	$(property_DATA)
+	$(property_DATA) $(update_DATA)
 ETAGS = etags
 CTAGS = ctags
 DIST_SUBDIRS = mod_admserv mod_restartd
@@ -463,6 +466,7 @@ sharedstatedir = @sharedstatedir@
 subdirs = @subdirs@
 sysconfdir = @sysconfdir@
 target_alias = @target_alias@
+updatedir = $(datadir)@updatedir@
 vendor = @vendor@
 
 # BEGIN COPYRIGHT BLOCK
@@ -605,6 +609,22 @@ dist_man_MANS = man/man8/migrate-ds-admin.pl.8 \
 	man/man8/setup-ds-admin.pl.8 \
 	man/man8/remove-ds-admin.pl.8
 
+
+#------------------------
+# updates
+# the directory server package contains examples
+# perl files and LDIF files are DATA - not executable
+# processed by the update script
+# shell scripts and other files are SCRIPTS - executable
+#------------------------
+update_DATA = admserv/newinst/src/25changefedorato389.pl \
+	admserv/newinst/src/30updateglobalpref.pl
+
+update_SCRIPTS = 
+
+#------------------------
+# libraries
+#------------------------
 libds_admin_serv_la_SOURCES = $(libbase_a_SOURCES) $(libsi18n_a_SOURCES) $(libadmin_a_SOURCES)
 libds_admin_serv_la_LINK = $(MYLINK)
 libds_admin_serv_la_LIBADD = \
@@ -823,7 +843,8 @@ property_DATA = admserv/newinst/src/setup-ds-admin.res \
 @BUNDLE_FALSE@	-e 's,@dslibdir\@,$(dslibdir),g' \
 @BUNDLE_FALSE@	-e 's,@ldifdir\@,$(ldifdir),g' \
 @BUNDLE_FALSE@	-e 's,@adminutilpath\@,$(adminutilpath),g' \
-@BUNDLE_FALSE@	-e 's,@initconfigdir\@,$(initconfigdir),g'
+@BUNDLE_FALSE@	-e 's,@initconfigdir\@,$(initconfigdir),g' \
+@BUNDLE_FALSE@	-e 's,@updatedir\@,$(updatedir),g'
 
 
 # these are for the config files and scripts that we need to generate and replace
@@ -884,7 +905,8 @@ property_DATA = admserv/newinst/src/setup-ds-admin.res \
 @BUNDLE_TRUE@        -e 's,@dslibdir\@,$(dslibdir),g' \
 @BUNDLE_TRUE@        -e 's,@ldifdir\@,$(ldifdir),g' \
 @BUNDLE_TRUE@        -e 's,@adminutilpath\@,$(adminutilpath),g' \
-@BUNDLE_TRUE@        -e 's,@initconfigdir\@,$(initconfigdir),g'
+@BUNDLE_TRUE@        -e 's,@initconfigdir\@,$(initconfigdir),g' \
+@BUNDLE_TRUE@        -e 's,@updatedir\@,$(updatedir),g'
 
 all: config.h
 	$(MAKE) $(AM_MAKEFLAGS) all-recursive
@@ -1316,6 +1338,25 @@ uninstall-nodist_cmdbinSCRIPTS:
 	  echo " rm -f '$(DESTDIR)$(cmdbindir)/$$f'"; \
 	  rm -f "$(DESTDIR)$(cmdbindir)/$$f"; \
 	done
+install-updateSCRIPTS: $(update_SCRIPTS)
+	@$(NORMAL_INSTALL)
+	test -z "$(updatedir)" || $(mkdir_p) "$(DESTDIR)$(updatedir)"
+	@list='$(update_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 " $(updateSCRIPT_INSTALL) '$$d$$p' '$(DESTDIR)$(updatedir)/$$f'"; \
+	    $(updateSCRIPT_INSTALL) "$$d$$p" "$(DESTDIR)$(updatedir)/$$f"; \
+	  else :; fi; \
+	done
+
+uninstall-updateSCRIPTS:
+	@$(NORMAL_UNINSTALL)
+	@list='$(update_SCRIPTS)'; for p in $$list; do \
+	  f=`echo "$$p" | sed 's|^.*/||;$(transform)'`; \
+	  echo " rm -f '$(DESTDIR)$(updatedir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(updatedir)/$$f"; \
+	done
 
 mostlyclean-compile:
 	-rm -f *.$(OBJEXT)
@@ -1965,6 +2006,23 @@ uninstall-propertyDATA:
 	  echo " rm -f '$(DESTDIR)$(propertydir)/$$f'"; \
 	  rm -f "$(DESTDIR)$(propertydir)/$$f"; \
 	done
+install-updateDATA: $(update_DATA)
+	@$(NORMAL_INSTALL)
+	test -z "$(updatedir)" || $(mkdir_p) "$(DESTDIR)$(updatedir)"
+	@list='$(update_DATA)'; for p in $$list; do \
+	  if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
+	  f=$(am__strip_dir) \
+	  echo " $(updateDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(updatedir)/$$f'"; \
+	  $(updateDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(updatedir)/$$f"; \
+	done
+
+uninstall-updateDATA:
+	@$(NORMAL_UNINSTALL)
+	@list='$(update_DATA)'; for p in $$list; do \
+	  f=$(am__strip_dir) \
+	  echo " rm -f '$(DESTDIR)$(updatedir)/$$f'"; \
+	  rm -f "$(DESTDIR)$(updatedir)/$$f"; \
+	done
 
 # This directory's subdirectories are mostly independent; you can cd
 # into them and run `make' without going through this Makefile.
@@ -2246,7 +2304,7 @@ all-am: Makefile $(LIBRARIES) $(LTLIBRARIES) $(PROGRAMS) $(SCRIPTS) \
 		$(MANS) $(DATA) config.h
 installdirs: installdirs-recursive
 installdirs-am:
-	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(cgibindir)" "$(DESTDIR)$(cgibindir)" "$(DESTDIR)$(cmdbindir)" "$(DESTDIR)$(initdir)" "$(DESTDIR)$(cmdbindir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(helpdir)" "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(icondir)" "$(DESTDIR)$(infdir)" "$(DESTDIR)$(initconfigdir)" "$(DESTDIR)$(ldifdir)" "$(DESTDIR)$(configdir)" "$(DESTDIR)$(propertydir)" "$(DESTDIR)$(perldir)" "$(DESTDIR)$(propertydir)"; do \
+	for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(cgibindir)" "$(DESTDIR)$(cgibindir)" "$(DESTDIR)$(cmdbindir)" "$(DESTDIR)$(initdir)" "$(DESTDIR)$(cmdbindir)" "$(DESTDIR)$(updatedir)" "$(DESTDIR)$(man8dir)" "$(DESTDIR)$(helpdir)" "$(DESTDIR)$(htmldir)" "$(DESTDIR)$(icondir)" "$(DESTDIR)$(infdir)" "$(DESTDIR)$(initconfigdir)" "$(DESTDIR)$(ldifdir)" "$(DESTDIR)$(configdir)" "$(DESTDIR)$(propertydir)" "$(DESTDIR)$(perldir)" "$(DESTDIR)$(propertydir)" "$(DESTDIR)$(updatedir)"; do \
 	  test -z "$$dir" || $(mkdir_p) "$$dir"; \
 	done
 install: install-recursive
@@ -2314,7 +2372,8 @@ install-data-am: install-cgibinPROGRAMS install-cgibinSCRIPTS \
 	install-initSCRIPTS install-initconfigDATA install-ldifDATA \
 	install-man install-nodist_cmdbinSCRIPTS \
 	install-nodist_configDATA install-nodist_propertyDATA \
-	install-perlDATA install-propertyDATA
+	install-perlDATA install-propertyDATA install-updateDATA \
+	install-updateSCRIPTS
 	@$(NORMAL_INSTALL)
 	$(MAKE) $(AM_MAKEFLAGS) install-data-hook
 
@@ -2354,7 +2413,8 @@ uninstall-am: uninstall-cgibinPROGRAMS uninstall-cgibinSCRIPTS \
 	uninstall-libLTLIBRARIES uninstall-man \
 	uninstall-nodist_cmdbinSCRIPTS uninstall-nodist_configDATA \
 	uninstall-nodist_propertyDATA uninstall-perlDATA \
-	uninstall-propertyDATA
+	uninstall-propertyDATA uninstall-updateDATA \
+	uninstall-updateSCRIPTS
 
 uninstall-info: uninstall-info-recursive
 
@@ -2377,12 +2437,12 @@ uninstall-man: uninstall-man8
 	install-libLTLIBRARIES install-man install-man8 \
 	install-nodist_cmdbinSCRIPTS install-nodist_configDATA \
 	install-nodist_propertyDATA install-perlDATA \
-	install-propertyDATA install-strip installcheck \
-	installcheck-am installdirs installdirs-am maintainer-clean \
-	maintainer-clean-generic maintainer-clean-recursive \
-	mostlyclean mostlyclean-compile mostlyclean-generic \
-	mostlyclean-libtool mostlyclean-recursive pdf pdf-am ps ps-am \
-	tags tags-recursive uninstall uninstall-am \
+	install-propertyDATA install-strip install-updateDATA \
+	install-updateSCRIPTS installcheck installcheck-am installdirs \
+	installdirs-am maintainer-clean maintainer-clean-generic \
+	maintainer-clean-recursive mostlyclean mostlyclean-compile \
+	mostlyclean-generic mostlyclean-libtool mostlyclean-recursive \
+	pdf pdf-am ps ps-am tags tags-recursive uninstall uninstall-am \
 	uninstall-cgibinPROGRAMS uninstall-cgibinSCRIPTS \
 	uninstall-cmdbinSCRIPTS uninstall-dist_helpDATA \
 	uninstall-dist_htmlDATA uninstall-dist_iconDATA \
@@ -2391,7 +2451,8 @@ uninstall-man: uninstall-man8
 	uninstall-libLTLIBRARIES uninstall-man uninstall-man8 \
 	uninstall-nodist_cmdbinSCRIPTS uninstall-nodist_configDATA \
 	uninstall-nodist_propertyDATA uninstall-perlDATA \
-	uninstall-propertyDATA
+	uninstall-propertyDATA uninstall-updateDATA \
+	uninstall-updateSCRIPTS
 
 define NL
 \\n
diff --git a/admserv/newinst/src/25changefedorato389.pl b/admserv/newinst/src/25changefedorato389.pl
new file mode 100644
index 0000000..2e94b26
--- /dev/null
+++ b/admserv/newinst/src/25changefedorato389.pl
@@ -0,0 +1,250 @@
+
+use AdminUtil;
+use Util qw(debug);
+# load perldap
+use Mozilla::LDAP::Conn;
+use Mozilla::LDAP::Utils qw(normalizeDN);
+use Mozilla::LDAP::API qw(:constant ldap_url_parse ldap_explode_dn);
+
+sub pre {
+    my ($inf, $configdir) = @_;
+    my @errs;
+    # for each server being updated, we need to convert any information
+    # under o=NetscapeRoot for that server from Fedora xxx to 389 xxx
+    # e.g. cn=Fedora Directory Server -> cn=389 Directory Server
+    # then the rest of the update process will update the version, build
+    # number, etc.
+
+    # start with the isie from the adm.conf
+    # see if there is already a configds
+    my $admConf = AdminUtil::getAdmConf("$configdir/admin-serv");
+
+    if (!$admConf) {
+        return ('error_reading_conffile', "$configdir/admin-serv/adm.conf", $!);
+    }
+
+    my $basedn = $admConf->{isie};
+
+    if (!$basedn) {
+        return ('error_admconf_isie', "$configdir/admin-serv/adm.conf");
+    }
+
+    # look for the Fedora branded entries
+    $basedn =~ s/cn=389/cn=Fedora/g;
+
+    # start at the host entry - two rdns up from the isie
+    my @rdns = ldap_explode_dn($basedn, 0);
+    $basedn = join(',', @rdns[-3..-1]);
+    my $domaindn = join(',', @rdns[-2..-1]);
+
+    my @ents;
+    my $conn = $inf->{configdsconn};
+    my $ent = $conn->search($basedn, 'sub', '(objectclass=*)');
+    my $rc = $conn->getErrorCode();
+    if (($rc != LDAP_SUCCESS) or (!$ent)) {
+        if ($rc != LDAP_NO_SUCH_OBJECT) {
+            my $errstr = $conn->getErrorString();
+            return ('error_finding_isie', $basedn, $conn->{host}, $conn->{port},
+                    (($errstr eq "Success") ? 'unknown error' : $errstr));
+        } else {
+            # nothing to do - just return
+            debug(1, "Fedora branded entry $basedn not found - skipping\n");
+            return ();
+        }
+    }
+    my @sielist;
+    my $count = 0;
+    while ($ent) {
+        my $olddn = $ent->getDN();
+        my $newdn = $olddn;
+        $count += ($newdn =~ s/cn=Fedora/cn=389/g);
+        $ent->setDN($newdn);
+        for my $attr (keys %{$ent}) {
+            my @newvals = $ent->getValues($attr);
+            for my $val (@newvals) {
+                $count += ($val =~ s/cn=Fedora/cn=389/g); # fix DNs
+                $count += ($val =~ s/\@fedora-admin/\@389-admin/g); # fix jar names
+                $count += ($val =~ s/\@fedora-ds/\@389-ds/g); # fix jar names
+                $count += ($val =~ s/Fedora Project/389 Project/g);
+                $count += ($val =~ s/Fedora Administration Server/389 Administration Server/g);
+                $count += ($val =~ s/Fedora Directory Server/389 Directory Server/g);
+            }
+            $ent->setValues($attr, @newvals);
+        }
+        # save the sie
+        if ($ent->hasValue('objectclass', 'netscapeServer', 1)) {
+            push @sielist, $olddn;
+        }
+        # save the old DN
+        $ent->{_olddn_} = $olddn;
+        # add to the list of entries
+        push @ents, $ent;
+        $ent = $conn->nextEntry();
+    }
+
+    if (!$count) {
+        # nothing to do - just return
+        debug(1, "No Fedora branding found - skipping\n");
+        return ();
+    }
+
+    # if a prior installation was messed up, there will be both
+    # a Fedora branded entry and a 389 branded entry - in this
+    # case, the 389 entry is bogus and must be replaced with
+    # the converted Fedora->389 entry from above - so we must
+    # delete them first - we have to do the deletion in reverse
+    # order
+    for my $ent (reverse @ents) {
+        $conn->delete($ent);
+        my $rc = $conn->getErrorCode();
+        if ($rc == LDAP_NOT_ALLOWED_ON_NONLEAF) {
+            # just update it instead
+            if ($conn->update($ent)) {
+                $rc = LDAP_SUCCESS;
+            } else {
+                $rc = $conn->getErrorCode();
+            }
+        }
+        if ($rc != LDAP_SUCCESS) {
+            if ($rc == LDAP_NO_SUCH_OBJECT) {
+                debug(1, "Entry ", $ent->getDN(), " does not exist - skipping\n");
+            } else {
+                return ('error_deleteall_entries', $ent->getDN(), $conn->getErrorString());
+            }
+        }
+    }
+
+    # found and fixed all of them, deleted old bogus entries, now try to add
+    # if we get Already Exists, just skip
+    my @dnstodel = ();
+    if ($count) { # have at least one change to make
+        for my $ent (@ents) {
+            $conn->add($ent);
+            my $rc = $conn->getErrorCode();
+            if ($rc == LDAP_TYPE_OR_VALUE_EXISTS) {
+                # as a result of our corrections above, we have some
+                # duplicate values - let's remove them
+                # this is a list of attributes that may have DN syntax
+                # and are multi valued - we have to normalize them first
+                my %mydnattrs = (owner => 'owner', roleoccupant => 'roleoccupant',
+                                 member => 'member', seealso => 'seealso',
+                                 uniquemember => 'uniquemember',
+                                 parentorganization => 'parentorganization',
+                                 secretary => 'secretary', manager => 'manager',
+                                 aliasedobjectname => 'aliasedobjectname',
+                                 associatedname => 'associatedname',
+                                 distinguishedname => 'distinguishedname',
+                                 documentauthor => 'documentauthor',
+                                 nsroledn => 'nsroledn',
+                                 nsadminsiedn => 'nsadminsiedn',
+                                 nsdirectoryinforef => 'nsdirectoryinforef',
+                                 mailenhanceduniquemember => 'mailenhanceduniquemember');
+                my %skipattrs = (objectclass => 'objectclass');
+                for my $attr (keys %{$ent}) {
+                    next if ($skipattrs{lc $attr});
+                    my @newvals = $ent->getValues($attr);
+                    my %uniq = ();
+                    # the keys of the uniq hash will be the normalized values
+                    # the hash table will just throw away dups, so the
+                    # resultant table will have as the keys the unique
+                    # normalized values, and will have as the values the
+                    # original unique un-normalized values
+                    if ($mydnattrs{lc $attr}) {
+                        %uniq = map { normalizeDN($_) => $_ } @newvals;
+                    } else {
+                        %uniq = map { lc $_ => $_ } @newvals;
+                    }
+                    $ent->setValues($attr, values %uniq);
+                }
+                if ($conn->update($ent)) {
+                    $rc = LDAP_SUCCESS;
+                } else {
+                    $rc = $conn->getErrorCode();
+                }
+            } elsif ($rc == LDAP_SUCCESS) {
+                push @dnstodel, $ent->{_olddn_};
+            }
+            if ($rc != LDAP_SUCCESS) {
+                if ($rc != LDAP_ALREADY_EXISTS) {
+                    # just bail - it's unlikely that we would get this error from
+                    # far down in the tree, if we didn't already get this at
+                    # the top level
+                    return ('error_adding_entry', $ent->getDN(), $conn->getErrorString());
+                } else {
+                    debug(1, "Entry ", $ent->getDN(), " already exists - skipping\n");
+                }
+            }
+        }
+    }
+
+    # now fix adm.conf and local.conf
+    $count = 0; # reset
+    while (my ($key, $val) = each %{$admConf}) {
+        $count += ($val =~ s/cn=Fedora/cn=389/g); # fix DNs
+        $count += ($val =~ s/\@fedora-admin/\@389-admin/g); # fix jar names
+        $count += ($val =~ s/\@fedora-ds/\@389-ds/g); # fix jar names
+        $admConf->{$key} = $val;
+    }
+    if (($count > 0) and !AdminUtil::updateAdmConf($admConf, "$configdir/admin-serv")) {
+        return ('error_updating_conffile', "$configdir/admin-serv/adm.conf", $!);
+    }
+
+    my $localconf = "$configdir/admin-serv/local.conf";
+    if (!open(LOCALCONF, "$localconf")) {
+        return ('error_reading_conffile', $localconf, $!);
+    }
+    my @lines = <LOCALCONF>;
+    close LOCALCONF;
+    $count = 0; # reset
+    for my $line (@lines) {
+        $count += ($line =~ s/cn=Fedora/cn=389/g); # fix DNs
+        $count += ($line =~ s/\@fedora-admin/\@389-admin/g); # fix jar names
+        $count += ($line =~ s/\@fedora-ds/\@389-ds/g); # fix jar names
+    }
+    
+    if ($count > 0) {
+        if (!open(LOCALCONF, ">$localconf")) {
+            return ('error_updating_conffile', $localconf, $!);
+        }
+        for my $line (@lines) {
+            print LOCALCONF $line;
+        }
+        close LOCALCONF;
+    }
+
+    # config files were successfully updated - delete the old entries
+    while (@dnstodel) {
+        # use pop because we have to delete in reverse order
+        my $dn = pop @dnstodel;
+        if ($dn) {
+            $conn->delete($dn);
+            my $rc = $conn->getErrorCode();
+            if ($rc != LDAP_SUCCESS) {
+                return ('error_deleteall_entries', $dn, $conn->getErrorString());
+            }
+        }
+    }
+
+    # fix the names in this entry
+    # dn: cn=Client, ou=Admin, ou=Global Preferences, ou=%domain%, o=NetscapeRoot
+    my $dn = "cn=Client, ou=Admin, ou=Global Preferences, $domaindn";
+    $ent = $conn->search($dn, 'base', "(objectclass=*)");
+    if ($ent) {
+        $count = 0;
+        @newvals = $ent->getValues('nsNickName');
+        map { s/Fedora/389/g } @newvals;
+        $ent->setValues('nsNickName', @newvals);
+        $conn->update($ent);
+    }    
+
+    # remove the sie entries under ou=User Preferences, ou=%domain%, o=NetscapeRoot
+    # they will be recreated
+    for my $siedn (@sielist) {
+        $ent = $conn->search($domaindn, 'sub', "(|(ou=$siedn)(ou=\"$siedn\"))");
+        if ($ent) {
+            $conn->delete($ent);
+        }
+    }
+
+    return ();
+}
diff --git a/admserv/newinst/src/30updateglobalpref.pl.in b/admserv/newinst/src/30updateglobalpref.pl.in
new file mode 100644
index 0000000..9fa0b92
--- /dev/null
+++ b/admserv/newinst/src/30updateglobalpref.pl.in
@@ -0,0 +1,54 @@
+# BEGIN COPYRIGHT BLOCK
+# Copyright (C) 2009 Red Hat, Inc.
+# All rights reserved.
+#
+# 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., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301, USA.
+#
+# END COPYRIGHT BLOCK
+
+use DSUpdate;
+use AdminUtil;
+use Util qw(debug);
+# load perldap
+use Mozilla::LDAP::Conn;
+use Mozilla::LDAP::Utils qw(normalizeDN);
+use Mozilla::LDAP::API qw(:constant ldap_url_parse ldap_explode_dn);
+
+sub pre {
+    my ($inf, $configdir) = @_;
+
+    my $setupinf = new Inf("@infdir@/setup.inf");
+    my $admininf = new Inf("@infdir@/admin.inf");
+    # there are several tokens in the map that we don't
+    # use for 02globalpreferences - so just add dummy
+    # values setupinf to make the map happy
+    $setupinf->{General}->{ServerIdentifier} = 'notused';
+    $setupinf->{General}->{ServerPort} = 'notused';
+    $setupinf->{General}->{Suffix} = 'notused';
+
+    my $upd = { path => '@ldifdir@/02globalpreferences.ldif.tmpl',
+                mapper => "@infdir@/configdsroot.map",
+                infary => [ $setupinf, $admininf ]
+              };
+                   
+    return DSUpdate::applyLDIFUpdate($upd, $inf->{configdsconn}, $inf);
+}
+
+# emacs settings
+# Local Variables:
+# mode:perl
+# indent-tabs-mode: nil
+# tab-width: 4
+# End:
diff --git a/admserv/newinst/src/AdminUtil.pm.in b/admserv/newinst/src/AdminUtil.pm.in
index d6c78a8..30885e8 100644
--- a/admserv/newinst/src/AdminUtil.pm.in
+++ b/admserv/newinst/src/AdminUtil.pm.in
@@ -117,6 +117,7 @@ sub getAdmpw {
     if (-f $fname) {
         open( ADMPW, "$fname" ) || die "Can't open $fname: $!";
         while (<ADMPW>) {
+            chop;
             ($ret->{ServerAdminID}, $ret->{ServerAdminPwd}) = split /:/;
             last;
         }
diff --git a/admserv/newinst/src/setup-ds-admin.pl.in b/admserv/newinst/src/setup-ds-admin.pl.in
index e526adb..2d36e35 100644
--- a/admserv/newinst/src/setup-ds-admin.pl.in
+++ b/admserv/newinst/src/setup-ds-admin.pl.in
@@ -27,6 +27,7 @@ use Inf;
 use Resource;
 use DialogManager;
 use DSCreate;
+use DSUpdate;
 use AdminUtil;
 use AdminServer;
 use Util;
@@ -258,13 +259,13 @@ if (!$setup->{update}) {
         $setup->doExit(1);
     }
 } else {
-    # register all instances
-    $setup->msg('registering_dirserver_instances');
-    if (!registerManyDSWithConfigDS($setup->{inf}, \@errs,
-                                    $setup->{configdir},
-                                    $setup->getDirServers())) {
-        $setup->msg($FATAL, @errs);
-        $setup->doExit(1);
+    doUpdate($setup, \@errs);
+    if (@errs) {
+        $setup->msg(@errs);
+        if (!$setup->{force}) {
+            $setup->msg($FATAL, 'error_reconfig_adminserver');
+            $setup->doExit(1);
+        }
     }
 }
 
@@ -292,6 +293,67 @@ END {
     }
 }
 
+sub doUpdate {
+    my ($setup, $errs) = @_;
+
+    my $inf = $setup->{inf};
+
+    # first, acquire a connection to the config DS
+    my $conn = getConfigDSConn($inf->{General}->{ConfigDirectoryLdapURL},
+                               $inf->{General}->{ConfigDirectoryAdminID},
+                               $inf->{General}->{ConfigDirectoryAdminPwd},
+                               $setup->{configdir} . "/admin-serv", $errs);
+
+    if (!$conn) {
+        return;
+    }
+
+    # update DS first
+    # use the admin DN + password to update the DS - requires
+    # the servers are online
+    unless(defined($setup->{inf}->{General}->{UpdateMode})) {
+        $setup->{inf}->{General}->{UpdateMode} = 'online';
+    }
+    # this assumes all of the directory servers are already registered with
+    # the config ds and being managed by them
+    # a nice enhancement would be to detect if the instance is being managed
+    # if not, shut it down, configure it for registration, then register it
+    for my $inst ($setup->getDirServers()) {
+        unless(defined($setup->{inf}->{$inst}->{RootDN})) {
+            # adminbinddn set as a side effect of a successful getConfigDSConn
+            $setup->{inf}->{$inst}->{RootDN} = $conn->{adminbinddn};
+        }
+        unless(defined($setup->{inf}->{$inst}->{RootDNPwd})) {
+            $setup->{inf}->{$inst}->{RootDNPwd} = $setup->{inf}->{General}->{ConfigDirectoryAdminPwd};
+        }
+    }
+
+    # stuff the config ds conn in the inf for update use
+    $setup->{inf}->{configdsconn} = $conn;
+
+    my @localerrs;
+    if (@localerrs = updateDS($setup, ["@updatedir@"])) {
+        push @{$errs}, @localerrs;
+        if (!$setup->{force}) {
+            return;
+        }
+    }
+    
+    $conn->close();
+
+    # register all instances
+    $setup->msg('registering_dirserver_instances');
+    if (!registerManyDSWithConfigDS($setup->{inf}, $errs,
+                                    $setup->{configdir},
+                                    $setup->getDirServers())) {
+        if (!$setup->{force}) {
+            return;
+        }
+    }
+
+    return;
+}
+
 # emacs settings
 # Local Variables:
 # mode:perl
diff --git a/admserv/newinst/src/setup-ds-admin.res.in b/admserv/newinst/src/setup-ds-admin.res.in
index 78b0176..463b2ea 100644
--- a/admserv/newinst/src/setup-ds-admin.res.in
+++ b/admserv/newinst/src/setup-ds-admin.res.in
@@ -139,3 +139,7 @@ cacert_already_exists = The certificate database in '%s' already contains a CA c
 error_connection_failed = Error: failed to open an LDAP connection to host '%s' port '%s' as user '%s'.  Error: %s.\n
 registering_dirserver_instances = Registering the directory server instances with the configuration directory server . . .\n
 error_finding_pta = Unable to find Pass Through Authentication Plug-In config entry.  Error: %s.\n
+error_finding_isie = Unable to find the software configuration entry '%s' in server '%s:%s'.  Error: %s\n
+error_updating_conffile = Unable to update the config file '%s'.  Error: %s\n
+error_reading_conffile = Unable to read the config file '%s'.  Error: %s\n
+error_admconf_isie = Unable to find the isie attribute in the config file '%s'\nPlease make sure you have registerd this server with the configuration Directory Server.\n\n
diff --git a/configure b/configure
index cb6a091..c91a202 100755
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.59 for dirsrv-admin 1.1.8.
+# Generated by GNU Autoconf 2.59 for dirsrv-admin 1.1.9.
 #
 # Report bugs to <http://bugzilla.redhat.com/>.
 #
@@ -423,8 +423,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='dirsrv-admin'
 PACKAGE_TARNAME='dirsrv-admin'
-PACKAGE_VERSION='1.1.8'
-PACKAGE_STRING='dirsrv-admin 1.1.8'
+PACKAGE_VERSION='1.1.9'
+PACKAGE_STRING='dirsrv-admin 1.1.9'
 PACKAGE_BUGREPORT='http://bugzilla.redhat.com/'
 
 ac_unique_file="admserv/cgi-src40/viewlog.c"
@@ -468,7 +468,7 @@ ac_includes_default="\
 ac_default_prefix=/opt/dirsrv
 ac_subdirs_all="$ac_subdirs_all mod_admserv"
 ac_subdirs_all="$ac_subdirs_all mod_restartd"
-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 PACKAGE_BASE_NAME PACKAGE_BASE_VERSION debug_defs BUNDLE_TRUE BUNDLE_FALSE LIBSOCKET LIBNSL LIBCSTD LIBCRUN initdir perlexec CXXLINK_REQUIRED_TRUE CXXLINK_REQUIRED_FALSE HPUX_TRUE HPUX_FALSE SOLARIS_TRUE SOLARIS_FALSE initconfigdir HTTPD APXS APR_CONFIG PKG_CONFIG ICU_CONFIG nsspcache instconfigdir dslibdir nspr_inc nspr_lib nspr_libdir nss_inc nss_lib nss_libdir sasl_inc sasl_lib sasl_libdir ldapsdk_inc ldapsdk_lib ldapsdk_libdir adminutil_inc adminutil_lib adminutil_libdir adminutil_ver icu_lib icu_libdir icu_inc icu_bin instancename cgibindir cmdbindir moddir modnssbindir propertydir htmldir icondir manualdir httpdconf httpdconfdir mimemagic httpduser httpdgroup admlogdir piddir pidfile admservport admservip ldifdir admmoddir nssmoddir infdir perldir brand capbrand vendor WINNT_TRUE WINNT_FALSE APACHE22_TRUE APACHE22_FALSE subdirs MOD_ADMSERV_TRUE MOD_ADMSERV_FALSE MOD_RESTARTD_TRUE MOD_RESTARTD_FALSE 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 PACKAGE_BASE_NAME PACKAGE_BASE_VERSION debug_defs BUNDLE_TRUE BUNDLE_FALSE LIBSOCKET LIBNSL LIBCSTD LIBCRUN initdir perlexec CXXLINK_REQUIRED_TRUE CXXLINK_REQUIRED_FALSE HPUX_TRUE HPUX_FALSE SOLARIS_TRUE SOLARIS_FALSE initconfigdir HTTPD APXS APR_CONFIG PKG_CONFIG ICU_CONFIG nsspcache instconfigdir dslibdir nspr_inc nspr_lib nspr_libdir nss_inc nss_lib nss_libdir sasl_inc sasl_lib sasl_libdir ldapsdk_inc ldapsdk_lib ldapsdk_libdir adminutil_inc adminutil_lib adminutil_libdir adminutil_ver icu_lib icu_libdir icu_inc icu_bin instancename cgibindir cmdbindir moddir modnssbindir propertydir htmldir icondir manualdir httpdconf httpdconfdir mimemagic httpduser httpdgroup admlogdir piddir pidfile admservport admservip ldifdir admmoddir nssmoddir infdir perldir updatedir brand capbrand vendor WINNT_TRUE WINNT_FALSE APACHE22_TRUE APACHE22_FALSE subdirs MOD_ADMSERV_TRUE MOD_ADMSERV_FALSE MOD_RESTARTD_TRUE MOD_RESTARTD_FALSE LTLIBOBJS'
 ac_subst_files=''
 
 # Initialize some variables set by options.
@@ -957,7 +957,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures dirsrv-admin 1.1.8 to adapt to many kinds of systems.
+\`configure' configures dirsrv-admin 1.1.9 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1023,7 +1023,7 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of dirsrv-admin 1.1.8:";;
+     short | recursive ) echo "Configuration of dirsrv-admin 1.1.9:";;
    esac
   cat <<\_ACEOF
 
@@ -1202,7 +1202,7 @@ fi
 test -n "$ac_init_help" && exit 0
 if $ac_init_version; then
   cat <<\_ACEOF
-dirsrv-admin configure 1.1.8
+dirsrv-admin configure 1.1.9
 generated by GNU Autoconf 2.59
 
 Copyright (C) 2003 Free Software Foundation, Inc.
@@ -1216,7 +1216,7 @@ cat >&5 <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by dirsrv-admin $as_me 1.1.8, which was
+It was created by dirsrv-admin $as_me 1.1.9, which was
 generated by GNU Autoconf 2.59.  Invocation command line was
 
   $ $0 $@
@@ -1860,7 +1860,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='dirsrv-admin'
- VERSION='1.1.8'
+ VERSION='1.1.9'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -24976,6 +24976,7 @@ if test "$with_fhs_opt" = "yes"; then
   icondir=/icons
   manualdir=/manual
   ldifdir=/data
+  updatedir=/updates-admin
   # relative to libdir
   # CGI program directory
   cgibindir=/cgi-bin
@@ -25002,6 +25003,7 @@ else
   icondir=/$PACKAGE_BASE_NAME/icons
   manualdir=/$PACKAGE_BASE_NAME/manual
   ldifdir=/$PACKAGE_BASE_NAME/data
+  updatedir=/$PACKAGE_BASE_NAME/updates-admin
   # relative to libdir
   # CGI program directory
   cgibindir=/$PACKAGE_BASE_NAME/cgi-bin
@@ -25073,6 +25075,7 @@ pidfile=$instancename.pid
 
 
 
+
 # WINNT should be true if building on Windows system not using
 # cygnus, mingw, or the like and using cmd.exe as the shell
 
@@ -25619,7 +25622,7 @@ _ASBOX
 } >&5
 cat >&5 <<_CSEOF
 
-This file was extended by dirsrv-admin $as_me 1.1.8, which was
+This file was extended by dirsrv-admin $as_me 1.1.9, which was
 generated by GNU Autoconf 2.59.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -25682,7 +25685,7 @@ _ACEOF
 
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-dirsrv-admin config.status 1.1.8
+dirsrv-admin config.status 1.1.9
 configured by $0, generated by GNU Autoconf 2.59,
   with options \\"`echo "$ac_configure_args" | sed 's/[\\""\`\$]/\\\\&/g'`\\"
 
@@ -26020,6 +26023,7 @@ s,@admmoddir@,$admmoddir,;t t
 s,@nssmoddir@,$nssmoddir,;t t
 s,@infdir@,$infdir,;t t
 s,@perldir@,$perldir,;t t
+s,@updatedir@,$updatedir,;t t
 s,@brand@,$brand,;t t
 s,@capbrand@,$capbrand,;t t
 s,@vendor@,$vendor,;t t
diff --git a/configure.ac b/configure.ac
index 64e0b6b..d403ccc 100644
--- a/configure.ac
+++ b/configure.ac
@@ -2,7 +2,7 @@
 # Process this file with autoconf to produce a configure script.
 
 AC_PREREQ(2.59)
-AC_INIT([dirsrv-admin], [1.1.8], [http://bugzilla.redhat.com/])
+AC_INIT([dirsrv-admin], [1.1.9], [http://bugzilla.redhat.com/])
 AC_CONFIG_SRCDIR([admserv/cgi-src40/viewlog.c])
 AM_INIT_AUTOMAKE([1.9 foreign subdir-objects])
 AM_MAINTAINER_MODE
@@ -281,6 +281,7 @@ if test "$with_fhs_opt" = "yes"; then
   icondir=/icons
   manualdir=/manual
   ldifdir=/data
+  updatedir=/updates-admin
   # relative to libdir
   # CGI program directory
   cgibindir=/cgi-bin
@@ -309,6 +310,7 @@ else
   icondir=/$PACKAGE_BASE_NAME/icons
   manualdir=/$PACKAGE_BASE_NAME/manual
   ldifdir=/$PACKAGE_BASE_NAME/data
+  updatedir=/$PACKAGE_BASE_NAME/updates-admin
   # relative to libdir
   # CGI program directory
   cgibindir=/$PACKAGE_BASE_NAME/cgi-bin
@@ -375,6 +377,7 @@ AC_SUBST(admmoddir)
 AC_SUBST(nssmoddir)
 AC_SUBST(infdir)
 AC_SUBST(perldir)
+AC_SUBST(updatedir)
 
 AC_SUBST(brand)
 AC_SUBST(capbrand)
-- 
1.5.5.6

