[Fedora-directory-commits] adminserver/admserv/newinst/src AdminMigration.pm.in, NONE, 1.1 asmigrate.map.in, NONE, 1.1 migrate-ds-admin.pl.in, NONE, 1.1 migrate-ds-admin.res.in, NONE, 1.1 AdminServer.pm.in, 1.3, 1.4 AdminUtil.pm.in, 1.6, 1.7 setup-ds-admin.pl.in, 1.5, 1.6

Richard Allen Megginson (rmeggins) fedora-directory-commits at redhat.com
Fri Jun 29 21:29:08 UTC 2007


Author: rmeggins

Update of /cvs/dirsec/adminserver/admserv/newinst/src
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv16700/adminserver/admserv/newinst/src

Modified Files:
	AdminServer.pm.in AdminUtil.pm.in setup-ds-admin.pl.in 
Added Files:
	AdminMigration.pm.in asmigrate.map.in migrate-ds-admin.pl.in 
	migrate-ds-admin.res.in 
Log Message:
Resolves: bug 245815
Description: DS Admin Migration framework - Admin Server Migration
Reviewed by: nhosoi (Thanks!)
Fix Description: Created an AdminMigration class to handle all of the Admin Server and Configuration DS specific parts of migration.  This should work for both the NES based Admin Server and the Apache based (FDS 1.0) Admin Server.
A lot of the code in AdminServer.pm was reused, or made more generic for use in migration as well as creation/setup.
Added a function to register all directory server instances with the configuration DS.  This can be used for update/reconfig too.
Platforms tested: RHEL4
Doc: Yes.  We will need to document the migration procedures.
Flag day: Yes.  Autotool file changes.



--- NEW FILE AdminMigration.pm.in ---
# 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 AdminMigration;
require Exporter;
@ISA       = qw(Exporter);
@EXPORT    = qw(migrateAdminServer);
@EXPORT_OK = qw(migrateAdminServer);

# load perldap
use Mozilla::LDAP::Conn;
use Mozilla::LDAP::Utils qw(normalizeDN);
use Mozilla::LDAP::API qw(:constant ldap_url_parse ldap_explode_dn);

use Migration;
use AdminServer;
use AdminUtil;
use Util;
use SetupLog;

use File::Path;
# tempfiles
use File::Temp qw(tempfile tempdir);

use strict;

# This gathers all of the old information from the old
# scattered config files and updates the corresponding
# parameters in the $mig->{inf}
sub getOldFileInfo {
    my $mig = shift;

    # assume the config DS has already been migrated
    # we need to get our data out of there, and fix it
    # as needed
    my $oldAdmConf = getAdmConf($mig->{oldsroot} . "/admin-serv/config");
    $mig->{inf}->{admin}->{sie} = $oldAdmConf->{sie};
    $mig->{inf}->{admin}->{isie} = $oldAdmConf->{isie};
    if (defined($oldAdmConf->{ldapStart})) {
        $mig->{inf}->{admin}->{ldapStart} = $oldAdmConf->{ldapStart};
    }

    if (!defined($mig->{inf}->{General}->{FullMachineName}) or
        !defined($mig->{inf}->{admin}->{ServerIpAddress}) or
        !defined($mig->{inf}->{admin}->{Port})) {
        my $oldPset = getPset($oldAdmConf);
        if (!defined($mig->{inf}->{General}->{FullMachineName})) {
            $mig->{inf}->{General}->{FullMachineName} = $oldPset->{serverhostname};
        }
        if (!defined($mig->{inf}->{admin}->{ServerIpAddress})) {
            $mig->{inf}->{admin}->{ServerIpAddress} = $oldPset->{'configuration.nsserveraddress'};
        }
        if (!defined($mig->{inf}->{admin}->{Port})) {
            $mig->{inf}->{admin}->{Port} = $oldPset->{'configuration.nsserverport'};
        }
    }

    # need sie, isie, config ds url, admin id
    if (!defined($mig->{inf}->{General}->{ConfigDirectoryLdapURL})) {
        if (!open(DBSWITCH, $mig->{oldsroot} . "/shared/config/dbswitch.conf")) {
            $mig->msg('error_opening_dbswitch', $mig->{oldsroot} . "/shared/config/dbswitch.conf", $!);
            return 0;
        }
        while (<DBSWITCH>) {
            if (/^directory default (.*)$/) {
                $mig->{inf}->{General}->{ConfigDirectoryLdapURL} = $1;
            }
        }
        close(DBSWITCH);
    }
    if (!defined($mig->{inf}->{General}->{ConfigDirectoryAdminID})) {
        if (!open(LDAPCONF, $mig->{oldsroot} . "/shared/config/ldap.conf")) {
            $mig->msg('error_opening_ldapconf', $mig->{oldsroot} . "/shared/config/ldap.conf", $!);
            return 0;
        }
        while (<LDAPCONF>) {
            if (/^admnm\s+(.*)$/) {
                $mig->{inf}->{General}->{ConfigDirectoryAdminID} = $1;
            }
        }
        close(LDAPCONF);
    }
    if (!defined($mig->{inf}->{General}->{SuiteSpotGroup}) or
        !defined($mig->{inf}->{General}->{SuiteSpotUserID})) {
        if (!open(SSUSERS, $mig->{oldsroot} . "/shared/config/ssusers.conf")) {
            $mig->msg('error_opening_ssusersconf', $mig->{oldsroot} . "/shared/config/ssusers.conf", $!);
            return 0;
        }
        while (<SSUSERS>) {
            if (/^SuiteSpotGroup\s+(.*)$/) {
                if (!defined($mig->{inf}->{General}->{SuiteSpotGroup})) {
                    $mig->{inf}->{General}->{SuiteSpotGroup} = $1;
                }
            }
            if (/^SuiteSpotUser\s+(.*)$/) {
                if (!defined($mig->{inf}->{General}->{SuiteSpotUserID})) {
                    $mig->{inf}->{General}->{SuiteSpotUserID} = $1;
                }
            }
        }
        close(SSUSERS);
    }
    if (!defined($mig->{inf}->{General}->{AdminDomain})) {
        my @rdns = ldap_explode_dn($mig->{inf}->{admin}->{isie}, 1);
        $mig->{inf}->{General}->{AdminDomain} = $rdns[-2];
    }

    # the old admin server used to run as root - we cannot do that anymore
    # with Apache based admin server, so by default just use the SuiteSpotUserID
    # i.e. the same user id that the directory server uses
    # and if that is not defined, we'll just have to use the default
    if (!defined($mig->{inf}->{admin}->{SysUser})) {
        $mig->{inf}->{admin}->{SysUser} = $mig->{inf}->{General}->{SuiteSpotUserID} ||
            "@httpduser@";
    }

    if (!defined($mig->{inf}->{General}->{SuiteSpotGroup})) {
        $mig->{inf}->{General}->{SuiteSpotGroup} = "@httpdgroup@";
    }

    return 1;
}
     

# This is how we extract the sie and isie as the as entries are
# being added
sub migratecb {
	my ($context, $entry) = @_;

    my @arycontext = ($context);
    # always replace the tasks and commands with the new ones
    my $dn = $entry->getDN();
    if (($entry->getDN() =~ /^cn=Tasks/i) or
        ($entry->getDN() =~ /^cn=Commands/i)) {
        push @arycontext, 1; # means to delete any existing entries first
    }

    my $rc = check_and_add_entry(\@arycontext, $entry);

    return $rc;
}

# The config DS should have already been migrated, including the old
# admin server data.  We need to update that information.  Some of the
# fields no longer apply (userPassword, configuration.encryption.nsCertFile,
# configuration.encryption.nsKeyFile, serverRoot)
# some of the fields must be removed (any ssl2 fields)
# some of the fields must be changed (nsSuiteSpotUser)
sub migratePset {
    my $mig = shift;
    my $configdir = shift;
    my $inf = $mig->{inf};
    my @errs;

    my $conn = getConfigDSConn($inf->{General}->{ConfigDirectoryLdapURL},
                               $inf->{General}->{ConfigDirectoryAdminID},
                               $inf->{General}->{ConfigDirectoryAdminPwd},
                               $configdir, \@errs);

    if (@errs) {
        $mig->msg($FATAL, @errs);
        return 0;
    }

    # add the Admin Server configuration entries
    my @ldiffiles = ("@ldifdir@/asmigrate.ldif.tmpl",
                     "@ldifdir@/21astasks.ldif.tmpl",
                     "@ldifdir@/22ascommands.ldif.tmpl"
                     );
    my $setupinf = new Inf("@infdir@/setup.inf");
    my $admininf = new Inf("@infdir@/admin.inf");

    my $mapper = new Inf("@infdir@/asmigrate.map");

    $mapper = process_maptbl($mapper, ($inf, $admininf, $setupinf));
    if (!$mapper) {
        $conn->close();
        $mig->msg($FATAL, 'error_creating_asmigration_maptbl');
        return 0;
    }

    # update isie and sie
    getMappedEntries($mapper, \@ldiffiles, \&migratecb, $conn);
    my $localconf = "$configdir/local.conf";
    my $isnew;
    if (! -f $localconf) {
        $isnew = 1;
    }
    if (!open(LOCALCONF, ">$localconf")) {
        $mig->msg($FATAL, 'error_updating_localconf', $localconf, $!);
        return 0;
    }
    # now get the entries and write them to local.conf
    my $entry = $conn->search($inf->{admin}->{sie}, "sub", "(objectclass=*)");
    while ($entry) {
        updateLocalConf($entry, $inf->{admin}->{sie}, \*LOCALCONF);
        $entry = $conn->nextEntry();
    }
    $conn->close();
    close(LOCALCONF);

    if ($isnew) {
        my $admConf = getAdmConf($configdir);
        my $uid = getpwnam $admConf->{sysuser};
        chmod 0600, "$localconf";
        chown $uid, -1, "$localconf";        
    }

    return 1;
}

sub migrateSecurityFiles {
    my $mig = shift;
    my $configdir = shift;

    my $admConf = getAdmConf($configdir);
    my $sie = $admConf->{sie};
    my @rdns = ldap_explode_dn($sie, 1);
    my $inst = $rdns[0];
    my $rc = $mig->migrateSecurityFiles($inst, $configdir);
    my $haspinfile;
    if (-f $mig->{oldsroot} . "/admin-serv/config/password.conf") {
        if (system ("cp -p $mig->{oldsroot}/admin-serv/config/password.conf $configdir/pin.txt")) {
            $mig->msg('error_copying_passwordconf', "$mig->{oldsroot}/admin-serv/config/password.conf", $!);
            return 0;
        }
    }

    return 1;
}

sub updateConfFileSecInfo {
    my $mig = shift;
    my $configdir = shift;

    my $haspinfile;
    for (glob("$configdir/*")) {
        if (/pin\.txt$/) {
            $haspinfile = 1;
        }
    }

    # if the user has specified a pin file, we need to let nss.conf know
    if ($haspinfile) {
        if (!open(NSSCONF, "$configdir/nss.conf")) {
            $mig->msg('error_opening_nssconf', "$configdir/nss.conf", $!);
            return 0;
        }
        my @nssconf = <NSSCONF>;
        close(NSSCONF);
        # nss.conf is usually read-only
        chmod 0600, "$configdir/nss.conf";
        if (!open(NSSCONF, ">$configdir/nss.conf")) {
            $mig->msg('error_writing_nssconf', "$configdir/nss.conf", $!);
            chmod 0400, "$configdir/nss.conf";
            return 0;
        }
        my $found;
        for (@nssconf) {
            if (/^NSSPassPhraseDialog/) {
                $found = 1;
                $_ = "NSSPassPhraseDialog file:$configdir/pin.txt\n";
            }
            print NSSCONF $_;
        }
        if (!$found) {
            print NSSCONF "NSSPassPhraseDialog file:$configdir/pin.txt\n";
        }
        close(NSSCONF);
        chmod 0400, "$configdir/nss.conf";
    }

    # update console.conf with security info
    my $pset = getPset($configdir);
    if (defined($pset->{'configuration.nsserversecurity'}) and
        ($pset->{'configuration.nsserversecurity'} =~ /on/i)) {
        my $certname = $pset->{'configuration.encryption.rsa.nssslpersonalityssl'};
        my $clientauth = $pset->{'configuration.encryption.nssslclientauth'};
        if (!open(CONSOLECONF, "$configdir/console.conf")) {
            $mig->msg('error_opening_consoleconf', "$configdir/console.conf", $!);
            return 0;
        }
        my @consoleconf = <CONSOLECONF>;
        close(CONSOLECONF);
        if (!open(CONSOLECONF, "> $configdir/console.conf")) {
            $mig->msg('error_writing_consoleconf', "$configdir/console.conf", $!);
            return 0;
        }
        for (@consoleconf) {
            if (/^NSSEngine/) {
                $_ = "NSSEngine on\n";
            } elsif (/^NSSNickname/) {
                $_ = "NSSNickname $certname\n";
            } elsif (/^NSSVerifyClient/) {
                if ($clientauth =~ /on/) {
                    $_ = "NSSVerifyClient require\n";
                } else {
                    $_ = "NSSVerifyClient none\n";
                }
            }
            print CONSOLECONF $_;
        }
        close(CONSOLECONF);
    }

    return 1;
}

sub migrateAdmpw {
    my $mig = shift;
    my $configdir = shift;
    if (-f "$mig->{oldsroot}/admin-serv/config/admpw") {
        if (system ("cp -p $mig->{oldsroot}/admin-serv/config/admpw $configdir/admpw")) {
            $mig->msg('error_copying_admpw', "$mig->{oldsroot}/admin-serv/config/admpw", $!);
            return 0;
        }
    }

    return 1;
}

sub migrateAdminServer {
    my $mig = shift;

    my $configdir = $mig->{inf}->{admin}->{config_dir} ||
        $ENV{ADMSERV_CONF_DIR} ||
        $mig->{configdir} . "/admin-serv";

    my $securitydir = $mig->{inf}->{admin}->{security_dir} ||
        $configdir;

    my $logdir = $mig->{inf}->{admin}->{log_dir} ||
        $ENV{ADMSERV_LOG_DIR} ||
        "@logdir@";

    my $rundir = $mig->{inf}->{admin}->{run_dir} ||
        $ENV{ADMSERV_PID_DIR} ||
        "@piddir@";

    if (!getOldFileInfo($mig, $configdir)) {
        return 0;
    }

    if (!createASFilesAndDirs($mig, $configdir, $securitydir, $logdir, $rundir)) {
        return 0;
    }

    if (!updateAdmConf({ldapurl => $mig->{inf}->{General}->{ConfigDirectoryLdapURL},
                        userdn => $mig->{inf}->{General}->{ConfigDirectoryAdminID},
                        SuiteSpotUserID => $mig->{inf}->{General}->{SuiteSpotUserID},
                        SuiteSpotGroup => $mig->{inf}->{General}->{SuiteSpotGroup},
                        sysuser => $mig->{inf}->{admin}->{SysUser},
                        sysgroup => $mig->{inf}->{General}->{SuiteSpotGroup},
                        AdminDomain => $mig->{inf}->{General}->{AdminDomain},
                        sie => $mig->{inf}->{admin}->{sie},
                        isie => $mig->{inf}->{admin}->{isie},
                        ldapStart => $mig->{inf}->{admin}->{ldapStart}},
                       $configdir)) {
        return 0;
    }

    if (!migrateSecurityFiles($mig, $configdir)) {
        return 0;
    }

    if (!migratePset($mig, $configdir)) {
        return 0;
    }

    if (!migrateAdmpw($mig, $configdir)) {
        return 0;
    }

    if (!updateConfFileSecInfo($mig, $configdir)) {
        return 0;
    }

    $mig->msg('updating_httpconf');
    if (!updateHttpConfFiles($mig->{inf}->{admin}->{ServerIpAddress},
                             $mig->{inf}->{admin}->{Port},
                             $configdir)) {
        $mig->msg($FATAL, 'error_updating_httpconf');
        return 0;
    }

    if (!setFileOwnerPerms($mig, $configdir)) {
        return 0;
    }

    if (!startAdminServer($mig, $configdir, $logdir, $rundir)) {
        return 0;
    }

    return 1;
}


# obligatory module true return
1;


--- NEW FILE asmigrate.map.in ---
# 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
#
# register_param.map: 
# This file is used by the register_server.pl script to register the server
# info to the Configuration Directory Server.  The server info is stored in
# the (template) ldif files located in @ldifdir at . In case a server entry has
# %...% format parameters, this map table is used to resolve it and replace
# the parameter with the value defined in this file.
#
# [Parameter resolution rules]
# * If the right-hand value is in ` (backquote), the value is eval'ed by perl.
#   The output should be stored in $returnvalue to pass to the internal hash.
# * If the right-hand value is in " (doublequote), the value is passed as is.
# * If the right-hand value is not in any quote, the value should be found
#   in either of the setup inf file (static) or the install inf file (dynamic).
# * Variables surrounded by @ (e.g., @configdir@) are replaced with the 
#   system path at the compile time.
# * The right-hand value can contain variables surrounded by % (e.g., %asid%)
#   which refers the right-hand value (key) of this map file.
# 
fqdn =			FullMachineName
domain =		AdminDomain
brand =			Brand
normbrand =			NormBrand
hostname =		`use Net::Domain qw(hostname); $returnvalue = hostname();`
vendor =		Vendor
timestamp = 	`use Time::gmtime; my $gm = gmtime; $returnvalue = sprintf ("%04d%02d%02d%02d%02d%02dZ", 1900+$gm->year, 1+$gm->mon, $gm->mday, $gm->hour, $gm->min, $gm->sec);`

asid =			`use Net::Domain qw(hostname); $returnvalue = hostname();`
as_port =		Port
admpw =			"@configdir@/admpw"
as_error =		"@logdir@/errors"
as_access =		"@logdir@/access"
as_pid =		"@pidfile@"
as_console_jar =	"%normbrand%-admserv-%as_baseversion%.jar"
as_help_path =	"@helpdir@"
as_user =		SysUser
as_version =	Version
as_baseversion =	BaseVersion
as_buildnum =	BuildNumber
as_sie =		"cn=admin-serv-%asid%, cn=%brand% Administration Server, cn=Server Group, cn=%fqdn%, ou=%domain%, o=NetscapeRoot"


--- NEW FILE migrate-ds-admin.pl.in ---
#!/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 AdminMigration;
use AdminUtil;
use AdminServer;
use Migration;
use Resource;
use DSMigration;

my $res = new Resource("@propertydir@/migrate-ds-admin.res",
                       "@propertydir@/migrate-ds.res",
                       "@propertydir@/setup-ds-admin.res",
                       "@propertydir@/setup-ds.res");

my $mig = new Migration($res); # parse cmd line etc.

$mig->msg('begin_dsadmin_migration', $mig->{oldsroot});

if (!$mig->{inf}->{General}->{ConfigDirectoryAdminPwd}) {
    $mig->msg('error_configds_adminpwd_required');
    exit 1;
}

# first, migrate directory server instances
# either the config ds will be one of them, or we
# should have already migrated the config DS
$mig->msg('begin_ds_migration', $mig->{oldsroot});
migrateDS($mig);

# if the config ds is on the local machine, shut down the old one
# and bring up the new one - the rest of migration needs to update it

my $configdsinst = getLocalConfigDS("$mig->{oldsroot}/admin-serv/config");
if ($configdsinst) {
    system("$mig->{oldsroot}/slapd-$configdsinst/stop-slapd");
    system("@dslibdir@/slapd-$configdsinst/start-slapd");
}

# next, migrate the admin server - this also registers the directory servers
$mig->msg('begin_as_migration', $mig->{oldsroot});
migrateAdminServer($mig);

# next, register/update the new directory servers
# in the config ds
registerManyDSWithConfigDS($mig, "$mig->{configdir}/admin-serv", @{$mig->{instances}});

$mig->msg('end_dsadmin_migration');

END {
    if ($mig) {
        if (!$mig->{keep}) {
            unlink $mig->{inffile};
        }

        $mig->doExit();
    }
}


--- NEW FILE migrate-ds-admin.res.in ---
begin_dsadmin_migration = Beginning migration of Directory and Administration servers from %s . . .\n
end_dsadmin_migration = Directory and Administration servers migration is complete.  Please check output and log files for details.\n
begin_as_migration = Beginning migration of Administration server from %s . . .\n
error_configds_adminpwd_required = The password for the configuration directory server admin is required.\
This is usually the password for the user you use to login to the\
console.  You can provide this value in one of two ways:\
\
In a .inf file - you can provide migration with a .inf file\
containing this and other data like so:\
 [General]\
 ...\
 ConfigDirectoryAdminPwd = thepasswordvalue\
 ...\
then run migration with -f yourfile.inf
\
On the command line like so:\
 command .... General.ConfigDirectoryAdminPwd=thepasswordvalue\n

error_opening_nssconf = Error: could not open NSS config file %s.  Error: %s\n
error_writing_nssconf = Error: could not write NSS config file %s.  Error: %s\n
registering_dirserver_instances = Registering the migrated directory server instances with the configuration directory server . . .\n


Index: AdminServer.pm.in
===================================================================
RCS file: /cvs/dirsec/adminserver/admserv/newinst/src/AdminServer.pm.in,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -r1.3 -r1.4
--- AdminServer.pm.in	22 Jun 2007 01:34:19 -0000	1.3
+++ AdminServer.pm.in	29 Jun 2007 21:29:05 -0000	1.4
@@ -39,8 +39,12 @@
 package AdminServer;
 require Exporter;
 @ISA       = qw(Exporter);
- at EXPORT    = qw(createAdminServer reconfigAdminServer registerDSWithConfigDS);
- at EXPORT_OK = qw(createAdminServer reconfigAdminServer registerDSWithConfigDS);
+ at EXPORT    = qw(createAdminServer reconfigAdminServer registerDSWithConfigDS
+                createASFilesAndDirs setFileOwnerPerms updateHttpConfFiles
+                startAdminServer registerManyDSWithConfigDS);
+ at EXPORT_OK = qw(createAdminServer reconfigAdminServer registerDSWithConfigDS
+                createASFilesAndDirs setFileOwnerPerms updateHttpConfFiles
+                startAdminServer registerManyDSWithConfigDS);
 
 use File::Path;
 # tempfiles
@@ -76,6 +80,39 @@
     return 1;
 }
 
+sub setFileOwnerPerms {
+    my $setup = shift;
+    my $configdir = shift;
+    my $admConf = getAdmConf($configdir);
+    my $uid = getpwnam $admConf->{sysuser};
+
+    # chown and chmod other files appropriately
+    for (glob("$configdir/*")) {
+        # these are owned by root
+        next if (/httpd.conf$/);
+        next if (/nss.conf$/);
+        next if (/admserv.conf$/);
+        next if (! -f $_); # should never happen
+        # all other files should be owned by SysUser
+        $! = 0; # clear errno
+        chown $uid, -1, $_;
+        if ($!) {
+            $setup->msg($FATAL, 'error_chowning_file', $_,
+                        $admConf->{sysuser}, $!);
+            return 0;
+        }
+        # the files should be writable
+        $! = 0; # clear errno
+        chmod 0600, $_;
+        if ($!) {
+            $setup->msg($FATAL, 'error_chmoding_file', $_, $!);
+            return 0;
+        }
+    }
+
+    return 1;
+}
+
 sub createASFilesAndDirs {
     my $setup = shift;
     my $configdir = shift;
@@ -128,6 +165,13 @@
         return 0;
     }
 
+    return 1;
+}
+
+sub makeConfFiles {
+    my $setup = shift;
+    my $configdir = shift;
+
     my @start_slapd;
     if ($setup->{inf}->{slapd}->{SlapdConfigForMC} =~ /yes/i) {
         my $slapdid = $setup->{inf}->{slapd}->{ServerIdentifier};
@@ -156,36 +200,6 @@
         return 0;
     }
 
-    # chown and chmod other files appropriately
-    for (glob("$configdir/*")) {
-        # these are owned by root
-        next if (/httpd.conf$/);
-        next if (/nss.conf$/);
-        next if (/admserv.conf$/);
-        # these should have been handled above
-        next if (/adm.conf$/);
-        next if (/admpw$/);
-        next if (/local.conf$/);
-        next if (! -f $_); # should never happen
-        # all other files should be owned by SysUser
-        $! = 0; # clear errno
-        chown $uid, -1, $_;
-        if ($!) {
-            $setup->msg($FATAL, 'error_chowning_file', $_,
-                        $setup->{inf}->{admin}->{SysUser}, $!);
-            return 0;
-        }
-        # the files should be writable
-        $! = 0; # clear errno
-        my ($ignore, $ignore, $mode, @rest) = stat $_;
-        $mode &= 0700; # disallow access to non-owner
-        chmod $mode, $_;
-        if ($!) {
-            $setup->msg($FATAL, 'error_chmoding_file', $_, $!);
-            return 0;
-        }
-    }
-
     return 1;
 }
 
@@ -290,7 +304,7 @@
 # update other config files - these are the fields which users typically want to
 # change during an install or an upgrade, that also must be synced to the Apache
 # style config files - we use the config CGI in command line mode because it
-# already has all of the logic to update the files correctly */
+# already has all of the logic to update the files correctly
 sub updateHttpConfFiles {
     my $serverAddress = shift;
     my $port = shift;
@@ -304,7 +318,7 @@
     $ENV{LD_LIBRARY_PATH} = "@LIBPATH@:$savepath";
     $ENV{SHLIB_PATH} = $ENV{LD_LIBRARY_PATH};
     my $cmd = "@cgibindir@/config op=set configuration.nsSuiteSpotUser=\"$user\"";
-    if ($port != $origport) { # need to change the port number
+    if (!defined($origport) or ($port != $origport)) { # need to change the port number
         $cmd .= " configuration.nsServerPort=\"$port\"";
     }
     if ($serverAddress) {
@@ -401,6 +415,10 @@
         return 0;
     }
 
+    if (!makeConfFiles($setup, $configdir)) {
+        return 0;
+    }
+
     if (!registerASWithConfigDS($setup, $configdir)) {
         return 0;
     }
@@ -413,6 +431,10 @@
         return 0;
     }
 
+    if (!setFileOwnerPerms($setup, $configdir)) {
+        return 0;
+    }
+
     if (!startAdminServer($setup, $configdir, $logdir, $rundir)) {
         return 0;
     }
@@ -432,16 +454,21 @@
 
 sub registerDSWithConfigDS {
     my $setup = shift;
-    my $inf = $setup->{inf};
-    my $configdir = shift;
+    my $inf = shift || $setup->{inf};
+    my $configdir = shift || "$setup->{configdir}/admin-serv";
     my @errs;
 
     $setup->msg('registering_dirserver');
     # open a connection to the configuration directory server
-    my $conn = getConfigDSConn($inf->{General}->{ConfigDirectoryLdapURL},
-                               $inf->{General}->{ConfigDirectoryAdminID},
-                               $inf->{General}->{ConfigDirectoryAdminPwd},
-                               $configdir, \@errs);
+    my $conn;
+    if (ref($configdir)) {
+        $conn = $configdir;
+    } else {
+        $conn = getConfigDSConn($inf->{General}->{ConfigDirectoryLdapURL},
+                                $inf->{General}->{ConfigDirectoryAdminID},
+                                $inf->{General}->{ConfigDirectoryAdminPwd},
+                                $configdir, \@errs);
+    }
 
     if (@errs) {
         $setup->msg($FATAL, @errs);
@@ -457,6 +484,11 @@
 
     my $mapper = new Inf("@infdir@/dirserver.map");
 
+    if (!$inf->{General}->{ConfigDirectoryLdapURL}) {
+        $inf->{General}->{ConfigDirectoryLdapURL} =
+            $setup->{inf}->{General}->{ConfigDirectoryLdapURL};
+    }
+
     $mapper = process_maptbl($mapper, ($inf, $slapdinf, $setupinf));
     if (!$mapper) {
         $conn->close();
@@ -467,6 +499,50 @@
     my $context = [$conn];
     getMappedEntries($mapper, \@ldiffiles, \&check_and_add_entry, $context);
 
-    $conn->close();
+    if (!ref($configdir)) {
+        $conn->close();
+    }
+
     return 1;
 }
+
+# this takes a list of DS instances and registers all of them
+# with the config DS
+sub registerManyDSWithConfigDS {
+    my $setup = shift;
+    my $configdir = shift;
+    my @instances = @_;
+    my @errs;
+    my $inf = $setup->{inf};
+
+    if (!@instances) {
+        return 1;
+    }
+
+    $setup->msg('registering_dirserver_instances');
+    # open a connection to the configuration directory server
+    my $conn = getConfigDSConn($inf->{General}->{ConfigDirectoryLdapURL},
+                               $inf->{General}->{ConfigDirectoryAdminID},
+                               $inf->{General}->{ConfigDirectoryAdminPwd},
+                               $configdir, \@errs);
+
+    if (@errs) {
+        $setup->msg($FATAL, @errs);
+        return 0;
+    }
+
+    my $admConf = getAdmConf($configdir);
+
+    for (@instances) {
+        my $instinf = createInfFromConfig("$setup->{configdir}/$_", $_);
+        $instinf->{General}->{AdminDomain} = $admConf->{AdminDomain};
+        unlink($instinf->{filename});
+        if (!registerDSWithConfigDS($setup, $instinf, $conn)) {
+            return 0;
+        }
+    }
+
+    $conn->close();
+
+    return 0;
+}


Index: AdminUtil.pm.in
===================================================================
RCS file: /cvs/dirsec/adminserver/admserv/newinst/src/AdminUtil.pm.in,v
retrieving revision 1.6
retrieving revision 1.7
diff -u -r1.6 -r1.7
--- AdminUtil.pm.in	28 Jun 2007 16:24:41 -0000	1.6
+++ AdminUtil.pm.in	29 Jun 2007 21:29:05 -0000	1.7
@@ -40,9 +40,11 @@
 require Exporter;
 @ISA       = qw(Exporter);
 @EXPORT    = qw(getAdmConf getConfigDSConn createConfigDS createSubDS
-                updateAdmConf updateAdmpw updateLocalConf importCACert);
+                updateAdmConf updateAdmpw updateLocalConf importCACert
+                getLocalConfigDS getPset);
 @EXPORT_OK = qw(getAdmConf getConfigDSConn createConfigDS createSubDS 
-                updateAdmConf updateAdmpw updateLocalConf importCACert);
+                updateAdmConf updateAdmpw updateLocalConf importCACert
+                getLocalConfigDS getPset);
 
 # load perldap
 use Mozilla::LDAP::Conn;
@@ -334,6 +336,7 @@
     delete $admConf->{configdir}; # don't write this
     open(ADMCONF, "> $filename") || die "Can't write $filename: $!";
     while (my ($key,$val) = each %{$admConf}) {
+        next if (!defined($key) or !defined($val));
         if (ref($val)) {
             for my $vv (@{$val}) {
                 print ADMCONF "$key: $vv\n";
@@ -431,6 +434,7 @@
             $attrName = $attr;
         }
         foreach my $val ($entry->getValues($attr)) {
+            debug(3, "updateLocalConf: writing $attrName: $val\n");
             print $localfh "$attrName: $val\n";
         }
     }
@@ -488,3 +492,22 @@
 
     return @errs;
 }
+
+# if the config ds is local to this machine, return
+# the instance name (e.g. "localhost" for slapd-localhost)
+# if not, return null
+sub getLocalConfigDS {
+    my $configdir = shift;
+    my $admConf = getAdmConf($configdir);
+    my $ldapStart = $admConf->{ldapStart};
+    my $inst;
+    if (!$ldapStart) {
+        return $inst; # empty
+    }
+
+    if ($ldapStart =~ /slapd-(.+?)\//) {
+        $inst = $1;
+    }
+
+    return $inst;
+}


Index: setup-ds-admin.pl.in
===================================================================
RCS file: /cvs/dirsec/adminserver/admserv/newinst/src/setup-ds-admin.pl.in,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -r1.5 -r1.6
--- setup-ds-admin.pl.in	28 Jun 2007 16:24:41 -0000	1.5
+++ setup-ds-admin.pl.in	29 Jun 2007 21:29:05 -0000	1.6
@@ -48,15 +48,13 @@
 use DialogManager;
 use AdminUtil;
 use AdminServer;
+use Util;
 
 my $res = new Resource("@propertydir@/setup-ds.res",
                        "@propertydir@/setup-ds-admin.res");
 
 my $setup = new Setup($res);
 
-# see what directory server instances we already have configured
-my @dirservers = $setup->getDirServers();
-
 # see if there is already a configds
 my $admConf = AdminUtil::getAdmConf("$setup->{configdir}/admin-serv");
 
@@ -147,9 +145,12 @@
 $setup->msg('create_dirserver');
 
 # create a directory server instance
-if (system("@bindir@/ds_newinst.pl $setup->{inffile}")) {
-    $setup->msg($FATAL, 'error_create_dirserver');
+my ($rc, $output) = createDSInstance($setup->{inf});
+if ($rc) {
+    $setup->msg($FATAL, 'error_creating_dsinstance', $rc, $output);
     exit 1;
+} else {
+    $setup->msg('created_dsinstance', $output);
 }
 
 # setup directory server instance to be the configuration DS




More information about the Fedora-directory-commits mailing list