Author: rmeggins
Update of /cvs/dirsec/adminserver/admserv/newinst/src
In directory cvs-int.fedora.redhat.com:/tmp/cvs-serv16478/adminserver/admserv/newinst/src
Modified Files:
ASDialogs.pm.in AdminUtil.pm.in ConfigDSDialogs.pm
setup-ds-admin.pl.in setup-ds-admin.res.in
Added Files:
AdminServer.pm.in adminserver.map.in dirserver.map.in
Log Message:
Resolves: bug 237356
Bug Description: Move DS Admin Code into Admin Server - admin server setup
Reviewed by: nhosoi (Thanks!)
Fix Description: This implements support for admin server configuration and
reconfiguration, so that we can remove setuputil related code from admserv/newinst/src.
The basic flow is this:
Ask user basic information.
Ask user if they want to either use an existing config ds or setup a new one. If the user
selects No, the code will gather information, create the directory server, and set it up
to be the configuration DS. Otherwise, it will just create the directory server and
register it with the existing config DS. The code will also create and setup and start
the admin server, or reconfigure it and restart it as needed. Note that setup-ds-admin.pl
assumes that a config DS is to be used. If you want to setup a directory server instance
without using a config ds, use setup-ds.pl instead.
Platforms tested: RHEL4
Flag Day: Yes - autotool changes
Doc impact: Yes.
--- NEW FILE AdminServer.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 AdminServer;
require Exporter;
@ISA = qw(Exporter);
@EXPORT = qw(createAdminServer reconfigAdminServer registerDSWithConfigDS);
@EXPORT_OK = qw(createAdminServer reconfigAdminServer registerDSWithConfigDS);
use File::Path;
# tempfiles
use File::Temp qw(tempfile tempdir);
# load perldap
use Mozilla::LDAP::Conn;
use Mozilla::LDAP::Utils qw(normalizeDN);
use Mozilla::LDAP::API qw(ldap_url_parse);
use Mozilla::LDAP::LDIF;
use Util;
use Inf;
use Setup;
use AdminUtil;
sub checkRequiredParameters {
my $setup = shift;
for my $asparam (qw(Port SysUser ServerAdminID ServerAdminPwd)) {
if (!defined($setup->{inf}->{admin}->{$asparam})) {
$setup->msg($FATAL, "missing_adminserver_param", $asparam);
return 0;
}
}
for my $general (qw(SuiteSpotUserID SuiteSpotGroup ConfigDirectoryLdapURL)) {
if (!defined($setup->{inf}->{General}->{$general})) {
$setup->msg($FATAL, "missing_general_param", $general);
return 0;
}
}
return 1;
}
sub createASFilesAndDirs {
my $setup = shift;
my $configdir = shift;
my $securitydir = shift;
my $logdir = shift;
my $rundir = shift;
my $uid = getpwnam $setup->{inf}->{admin}->{SysUser};
my $gid = getgrnam $setup->{inf}->{General}->{SuiteSpotGroup};
$setup->msg('create_adminserver_filesdirs');
# these paths are owned exclusively by admin sever
for ($configdir, $securitydir, $logdir) {
$! = 0; # clear errno
if (! -d $_) {
mkpath($_, 1, 0700);
} else {
chmod 0700, $_;
}
if (! -d $_) {
$setup->msg($FATAL, 'error_creating_directory', $_, $!);
return 0;
}
$! = 0; # clear errno
chown $uid, -1, $_;
if ($!) {
$setup->msg($FATAL, 'error_chowning_directory', $_,
$setup->{inf}->{admin}->{SysUser}, $!);
return 0;
}
}
# these paths are shared by SuiteSpotGroup members
$! = 0; # clear errno
if (! -d $rundir) {
mkpath($rundir, 0, 0770);
} else {
chmod 0770, $rundir;
}
if (! -d $rundir) {
$setup->msg($FATAL, 'error_creating_directory', $rundir, $!);
return 0;
}
$! = 0; # clear errno
chown -1, $gid, $rundir;
if ($!) {
$setup->msg($FATAL, 'error_chgrping_directory', $rundir,
$setup->{inf}->{General}->{SuiteSpotGroup}, $!);
return 0;
}
my @start_slapd;
if ($setup->{inf}->{slapd}->{SlapdConfigForMC} =~ /yes/i) {
my $slapdid = $setup->{inf}->{slapd}->{ServerIdentifier};
@start_slapd = ('ldapStart', "slapd-$slapdid/start-slapd");
}
$setup->msg('updating_admconf');
my $rc = updateAdmConf({ldapurl =>
$setup->{inf}->{General}->{ConfigDirectoryLdapURL},
SuiteSpotUserID =>
$setup->{inf}->{General}->{SuiteSpotUserID},
SuiteSpotGroup =>
$setup->{inf}->{General}->{SuiteSpotGroup},
sysuser => $setup->{inf}->{admin}->{SysUser},
sysgroup =>
$setup->{inf}->{General}->{SuiteSpotGroup},
AdminDomain =>
$setup->{inf}->{General}->{AdminDomain},
@start_slapd},
$configdir);
if (!$rc) {
$setup->msg($FATAL, 'error_updating_admconf', $!);
return 0;
}
$setup->msg('updating_admpw');
$rc = updateAdmpw($setup->{inf}->{admin}->{ServerAdminID},
$setup->{inf}->{admin}->{ServerAdminPwd},
$configdir);
if (!$rc) {
$setup->msg($FATAL, 'error_updating_admpw');
return 0;
}
return 1;
}
# This is how we extract the sie and isie as the as entries are
# being added
sub registercb {
my ($context, $entry) = @_;
my $rc = check_and_add_entry([$context->{conn}], $entry);
my $setup = $context->{setup};
if ($rc) {
if ($entry->hasValue('objectclass', 'nsApplication', 1)) {
$context->{isie} = $entry->getDN();
} elsif ($entry->hasValue('objectclass', 'nsAdminServer', 1))
{
$context->{sie} = $entry->getDN();
}
if ($context->{sie}) {
$rc = updateLocalConf($entry, $context->{sie}, $context->{localfh});
if (!$rc) {
$setup->msg($FATAL, 'error_updating_localconf_entry',
$entry->getDN());
}
}
} else {
$setup->msg($FATAL, 'error_adding_adminserver_config_entry',
$entry->getDN());
}
return $rc;
}
sub registerASWithConfigDS {
my $setup = shift;
my $inf = $setup->{inf};
my $configdir = shift;
my @errs;
$setup->msg('registering_adminserver');
# 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;
}
# add the Admin Server configuration entries
my @ldiffiles = ("@ldifdir(a)/20asdata.ldif.tmpl",
"@ldifdir(a)/21astasks.ldif.tmpl",
"@ldifdir(a)/22ascommands.ldif.tmpl"
);
my $setupinf = new Inf("@infdir(a)/setup.inf");
my $admininf = new Inf("@infdir(a)/admin.inf");
my $mapper = new Inf("@infdir(a)/adminserver.map");
$mapper = process_maptbl($mapper, ($inf, $admininf, $setupinf));
if (!$mapper) {
$conn->close();
$setup->msg($FATAL, 'error_creating_adminserver_maptbl');
return 0;
}
# context will get filled in with isie and sie in registercb
my $localconf = "$configdir/local.conf";
my $isnew;
if (! -f $localconf) {
$isnew = 1;
}
if (!open(LOCALCONF, ">$localconf")) {
$setup->msg($FATAL, 'error_updating_localconf', $localconf, $!);
return 0;
}
my $context = {conn => $conn, localfh => \*LOCALCONF, setup => $setup};
getMappedEntries($mapper, \@ldiffiles, \®istercb, $context);
close(LOCALCONF);
if ($isnew) {
my $admConf = getAdmConf($configdir);
my $uid = getpwnam $admConf->{sysuser};
chmod 0600, "$localconf";
chown $uid, -1, "$localconf";
}
$setup->msg('updating_admconf_configds');
if ($context->{sie} or $context->{isie}) {
if (!updateAdmConf({sie => $context->{sie},
isie => $context->{isie},
userdn => $conn->{adminbinddn}},
$configdir)) {
$setup->msg($FATAL, 'error_updating_admconf', $!);
return 0;
}
}
$conn->close();
return 1;
}
# 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 */
sub updateHttpConfFiles {
my $serverAddress = shift;
my $port = shift;
my $configdir = shift;
my $origport = shift;
my $admConf = getAdmConf($configdir);
my $user = $admConf->{sysuser};
my $cmd = "@cgibindir@/config op=set
configuration.nsSuiteSpotUser=\"$user\"";
if ($origport && ($port != $origport)) {
$cmd .= " configuration.nsServerPort=\"$port\"";
}
if ($serverAddress) {
$cmd .= " configuration.nsServerAddress=\"$serverAddress\"";
}
if (system($cmd)) {
return 0;
}
return 1;
}
sub startAdminServer {
my $setup = shift;
my $configdir = shift;
my $logdir = shift;
my $rundir = shift;
my $isrunning;
$pidfile = "$rundir/@pidfile@";
if (-f $pidfile) {
open(PIDFILE, $pidfile);
my $pid = <PIDFILE>;
close(PIDFILE);
if (kill 0, $pid) {
$isrunning = 1;
}
}
my ($fh, $filename) = tempfile("asstartupXXXXXX", UNLINK => 1,
SUFFIX => ".log", DIR =>
File::Spec->tmpdir);
close($fh);
my $rc;
if ($isrunning) {
$setup->msg('restarting_adminserver');
$rc = system("@cmdbindir@/restart-ds-admin > $filename
2>&1");
} else {
$setup->msg('starting_adminserver');
$rc = system("@cmdbindir@/start-ds-admin > $filename 2>&1");
}
open(STARTLOG, "$filename");
while (<STARTLOG>) {
$setup->msg('adminserver_startup_output', $_);
}
close(STARTLOG);
unlink($filename);
if ($rc) {
$setup->msg($FATAL, 'error_starting_adminserver', $rc);
return 0;
}
$setup->msg('success_starting_adminserver');
return 1;
}
sub createAdminServer {
my $setup = shift;
my $reconfig = shift;
# setup has inf, res, and log
if ($reconfig) {
$setup->msg('begin_reconfig_adminserver');
} else {
$setup->msg('begin_create_adminserver');
}
if (!checkRequiredParameters($setup)) {
return 0;
}
my $configdir = $setup->{inf}->{admin}->{config_dir} ||
$ENV{ADMSERV_CONF_DIR} ||
$setup->{configdir} . "/admin-serv";
my $securitydir = $setup->{inf}->{admin}->{security_dir} ||
$configdir;
my $logdir = $setup->{inf}->{admin}->{log_dir} ||
$ENV{ADMSERV_LOG_DIR} ||
"@logdir@";
my $rundir = $setup->{inf}->{admin}->{run_dir} ||
$ENV{ADMSERV_PID_DIR} ||
"@piddir@";
if (!createASFilesAndDirs($setup, $configdir, $securitydir, $logdir, $rundir)) {
return 0;
}
if (!registerASWithConfigDS($setup, $configdir)) {
return 0;
}
$setup->msg('updating_httpconf');
if (!updateHttpConfFiles($setup->{inf}->{admin}->{ServerIpAddress},
$setup->{inf}->{admin}->{Port},
$configdir, $setup->{asorigport})) {
$setup->msg($FATAL, 'error_updating_httpconf');
return 0;
}
if (!startAdminServer($setup, $configdir, $logdir, $rundir)) {
return 0;
}
if ($reconfig) {
$setup->msg('end_reconfig_adminserver');
} else {
$setup->msg('end_create_adminserver');
}
return 1;
}
sub reconfigAdminServer {
my $setup = shift;
return createAdminServer($setup, 1);
}
sub registerDSWithConfigDS {
my $setup = shift;
my $inf = $setup->{inf};
my $configdir = shift;
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);
if (@errs) {
$setup->msg($FATAL, @errs);
return 0;
}
# add the Admin Server configuration entries
my @ldiffiles = ("@ldifdir(a)/10dsdata.ldif.tmpl",
"@ldifdir(a)/11dstasks.ldif.tmpl"
);
my $setupinf = new Inf("@infdir(a)/setup.inf");
my $slapdinf = new Inf("@infdir(a)/slapd.inf");
my $mapper = new Inf("@infdir(a)/dirserver.map");
$mapper = process_maptbl($mapper, ($inf, $slapdinf, $setupinf));
if (!$mapper) {
$conn->close();
$setup->msg($FATAL, 'error_creating_dirserver_maptbl');
return 0;
}
my $context = [$conn];
getMappedEntries($mapper, \@ldiffiles, \&check_and_add_entry, $context);
$conn->close();
return 1;
}
--- NEW FILE adminserver.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@. 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
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_version%.jar"
as_help_path = "@helpdir@"
as_user = SysUser
as_version = Version
as_buildnum = BuildNumber
as_installedlocation = "AS INSTALLED LOCATION -- replace me"
as_serverroot = "AS SERVER ROOT-- replace me"
as_sie = "cn=admin-serv-%asid%, cn=%brand% Administration Server, cn=Server Group,
cn=%fqdn%, ou=%domain%, o=NetscapeRoot"
--- NEW FILE dirserver.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@. 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
vendor = Vendor
configroot = "CONFIG ROOT -- replace me"
asid = `use Net::Domain qw(hostname); $returnvalue = hostname();`
as_sie = "cn=admin-serv-%asid%, cn=%brand% Administration Server, cn=Server Group,
cn=%fqdn%, ou=%domain%, o=NetscapeRoot"
ds_version = Version
dsid = ServerIdentifier
ds_user = SuiteSpotUserID
ds_port = ServerPort
ds_secure_port ="636"
rootdn = RootDN
ds_suffix = Suffix
ds_buildnum = BuildNumber
ds_console_jar ="%normbrand%-ds-%ds_version%.jar"
ds_installedlocation = "DS INSTALLED LOCATION -- replace me"
ds_serverroot = "DS SERVER ROOT-- replace me"
ds_sie = "cn=slapd-%dsid%, cn=%brand% Directory Server, cn=Server Group, cn=%fqdn%,
ou=%domain%, o=NetscapeRoot"
Index: ASDialogs.pm.in
===================================================================
RCS file: /cvs/dirsec/adminserver/admserv/newinst/src/ASDialogs.pm.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- ASDialogs.pm.in 15 Jun 2007 22:16:28 -0000 1.2
+++ ASDialogs.pm.in 19 Jun 2007 18:32:28 -0000 1.3
@@ -76,8 +76,10 @@
if (!defined($port)) {
$port = @admservport@;
}
- if (!portAvailable($port)) {
- $port = getAvailablePort();
+ if (!$self->{manager}->{setup}->{reconfigas}) {
+ if (!portAvailable($port)) {
+ $port = getAvailablePort();
+ }
}
return $port;
},
@@ -85,9 +87,10 @@
my $self = shift;
my $ans = shift;
my $res = $DialogManager::SAME;
+ my $reconf = $self->{manager}->{setup}->{reconfigas};
if ($ans !~ /\d+/) {
$self->{manager}->alert("dialog_asport_error", $ans);
- } elsif (!portAvailable($ans)) {
+ } elsif (!$reconf && !portAvailable($ans)) {
$self->{manager}->alert("dialog_asport_error", $ans);
} else {
$res = $DialogManager::NEXT;
Index: AdminUtil.pm.in
===================================================================
RCS file: /cvs/dirsec/adminserver/admserv/newinst/src/AdminUtil.pm.in,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- AdminUtil.pm.in 15 Jun 2007 22:16:28 -0000 1.1
+++ AdminUtil.pm.in 19 Jun 2007 18:32:28 -0000 1.2
@@ -39,51 +39,40 @@
package AdminUtil;
require Exporter;
@ISA = qw(Exporter);
-@EXPORT = qw(getConf createConfigDS);
-@EXPORT_OK = qw(getConf createConfigDS);
+@EXPORT = qw(getAdmConf getConfigDSConn createConfigDS updateAdmConf updateAdmpw
updateLocalConf);
+@EXPORT_OK = qw(getAdmConf getConfigDSConn createConfigDS updateAdmConf updateAdmpw
updateLocalConf);
# load perldap
use Mozilla::LDAP::Conn;
use Mozilla::LDAP::Utils qw(normalizeDN);
-use Mozilla::LDAP::API qw(ldap_url_parse);
-use Mozilla::LDAP::LDIF;
+use Mozilla::LDAP::API qw(:constant ldap_url_parse ldap_explode_dn);
+use Mozilla::LDAP::LDIF qw(enlist_values);
use Util;
use Inf;
+use strict;
+
# get the adminutil client configuration (adm.conf)
# the file is in LDIF format
# just return as a hash ref for easy key/value access
# single valued attributes will have a single string value
# multi valued attributes will have an array ref value
-sub getConf {
- my $dir = shift;
+sub getAdmConf {
+ my $dir = shift || "@configdir@";
my $ret = {};
- if (! -d $dir) {
- warn "Config directory $dir does not exist";
- return $ret;
- }
- $dir = "$dir/admin-serv";
- if (! -d $dir) {
- warn "Config directory $dir does not exist";
- return $ret;
- }
my $fname = "$dir/adm.conf";
if (-f $fname) {
open( ADMCONF, "$fname" ) || die "Can't open $fname:
$!";
- my $in = new Mozilla::LDAP::LDIF(*ADMCONF);
- while (my $ent = readOneEntry $in) {
- foreach my $attr (keys %{$ent}) {
- my @vals = $ent->getValues($attr);
- if (@vals > 1) {
- $ret->{$attr} = \@vals; # value is array ref
- } else {
- $ret->{$attr} = $vals[0]; # value is single string
- }
- }
+ my $in = Mozilla::LDAP::LDIF->new(*ADMCONF, \&read_file_URL_or_name);
+ my @records = $in->get(undef); # read to end of file
+ close(ADMCONF);
+ @records = enlist_values(@records);
+ for (@records) { # there should only be 1 record
+ my %h = @{$_}; # cast $_ to an array and use that to init hash
+ $ret = \%h;
}
- close ADMCONF;
$ret->{configdir} = $dir;
}
@@ -93,12 +82,20 @@
# pset info is from the local.conf file, also in LDIF format
sub getPset {
my $admConf = shift;
+ my $configdir;
+ if ($admConf) {
+ if (ref($admConf)) {
+ $configdir = $admConf->{configdir} || "@configdir@";
+ } else {
+ $configdir = $admConf || "@configdir@";
+ }
+ }
my $ret = {};
- my $fname = "$admConf->{configdir}/local.conf";
+ my $fname = "$configdir/local.conf";
if (-f $fname) {
open( LOCALCONF, "$fname" ) || die "Can't open $fname:
$!";
my $in = new Mozilla::LDAP::LDIF(*LOCALCONF);
- while ($ent = readOneEntry $in) {
+ while (my $ent = readOneEntry $in) {
foreach my $attr (keys %{$ent}) {
my @vals = $ent->getValues($attr);
if (@vals > 1) {
@@ -116,11 +113,19 @@
sub getAdmpw {
my $admConf = shift;
+ my $configdir;
+ if ($admConf) {
+ if (ref($admConf)) {
+ $configdir = $admConf->{configdir} || "@configdir@";
+ } else {
+ $configdir = $admConf || "@configdir@";
+ }
+ }
my $ret = {};
- my $fname = "$admConf->{configdir}/admpw";
+ my $fname = "$configdir/admpw";
if (-f $fname) {
open( ADMPW, "$fname" ) || die "Can't open $fname: $!";
- while (my $line = <ADMPW>) {
+ while (<ADMPW>) {
($ret->{ServerAdminID}, $ret->{ServerAdminPwd}) = split /:/;
last;
}
@@ -144,6 +149,12 @@
my $errs = shift; # for output errs - an array ref
my $certdir;
+ if (!$url or !$id) {
+ my $admConf = getAdmConf($configdir);
+ $url = $url || $admConf->{ldapurl};
+ $id = $id || $admConf->{userdn};
+ }
+
my $h = ldap_url_parse($url);
my $host = $h->{host};
my $port = $h->{port};
@@ -192,8 +203,13 @@
} else {
push @{$errs}, 'configds_bind_error', $id, $url, (($errstr eq
"Success") ? 'unknown error' : $errstr);
}
+ return $conn;
}
+ $conn->setDefaultRebindProc($id, $pwd, LDAP_AUTH_SIMPLE);
+ # store the binddn for later use
+ $conn->{adminbinddn} = $id;
+
return $conn;
}
@@ -216,18 +232,18 @@
# and make it into a configuration directory server
sub createConfigDS {
my $inf = shift;
- my $res = shift;
+ my $errs = shift;
# open a connection to the directory server
my $conn = new Mozilla::LDAP::Conn($inf->{General}->{FullMachineName},
$inf->{slapd}->{ServerPort},
$inf->{slapd}->{RootDN},
- $inf->{slapd}->{RootDNPwd});
+ $inf->{slapd}->{RootDNPwd},
+ $inf->{General}->{certdir});
# add the NetscapeRoot suffix
- my @errs = addSuffix($conn, "o=NetscapeRoot", "NetscapeRoot");
- if (@errs) {
- print $res->getText(@errs);
+ @{$errs} = addSuffix($conn, "o=NetscapeRoot", "NetscapeRoot");
+ if (@{$errs}) {
$conn->close();
return 0;
}
@@ -244,13 +260,136 @@
$mapper = process_maptbl($mapper, ($inf, $dsinf, $admininf, $setupinf));
if (!$mapper) {
$conn->close();
- print $res->getText('error_creating_configds_maptbl');
+ @{$errs} = ('error_creating_configds_maptbl');
return 0;
}
getMappedEntries($mapper, \@ldiffiles, \&check_and_add_entry,
- [$conn, 1]);
+ [$conn]);
$conn->close();
return 1;
}
+
+sub updateAdmConf {
+ my $params = shift; # hashref
+ my $configdir = shift || "@configdir@";
+ my $admConf = getAdmConf($configdir);
+ my $isnew = 0;
+ if (!$admConf || !%{$admConf}) {
+ $isnew = 1; # create it
+ }
+
+ # update values in admConf with the passed in params
+ while (my ($key,$val) = each %{$params}) {
+ $admConf->{$key} = $val;
+ }
+
+ # write it out
+ my $filename = "$configdir/adm.conf";
+ delete $admConf->{configdir}; # don't write this
+ open(ADMCONF, "> $filename") || die "Can't write $filename:
$!";
+ while (my ($key,$val) = each %{$admConf}) {
+ if (ref($val)) {
+ for my $vv (@{$val}) {
+ print ADMCONF "$key: $vv\n";
+ }
+ } else {
+ print ADMCONF "$key: $val\n";
+ }
+ }
+ close(ADMCONF);
+
+ if ($isnew) {
+ my $uid = getpwnam $admConf->{sysuser};
+ chmod 0600, "$filename";
+ chown $uid, -1, "$filename";
+ }
+
+ return 1;
+}
+
+sub updateAdmpw {
+ my $userid = shift;
+ my $pwd = shift;
+ my $configdir = shift || "@configdir@";
+ my $filename = "$configdir/admpw";
+ my $isnew = 0;
+ if (! -f $filename) {
+ $isnew = 1;
+ }
+
+ $pwd = getHashedPassword($pwd, "SHA");
+
+ open(ADMPW, ">$filename") or die "Error: can't write file
$filename: $!";
+ print ADMPW "$userid:$pwd\n";
+ close(ADMPW);
+
+ if ($isnew) {
+ my $admConf = getAdmConf($configdir);
+ my $uid = getpwnam $admConf->{sysuser};
+ chmod 0600, "$filename";
+ chown $uid, -1, "$filename";
+ }
+
+ return 1;
+}
+
+# this is the prefix used for attribute names in the pset file
+sub getAttrNamePrefix {
+ my $dn = shift;
+ my $rootdn = shift; # the sie DN
+
+ my @dnList = ldap_explode_dn($dn, 1);
+ my @rootdnList = ldap_explode_dn($rootdn, 1);
+
+ my $attrLen = scalar(@dnList) - scalar(@rootdnList);
+ my $attrName = "";
+ while ($attrLen > 0) {
+ if ($attrLen == 1) {
+ $attrName .= $dnList[0];
+ } else {
+ $attrName .= $dnList[$attrLen-1] . ".";
+ }
+ $attrLen--;
+ }
+
+ return $attrName;
+}
+
+# these are attributes not written to the pset
+my %nopsetattrs = (
+ cn => 'cn',
+ aci => 'aci'
+);
+
+# This is only used during setup.
+# When the admin server is running, changes
+# occur online, and the file contains a cache
+# of those changes
+# but during setup, we need to create the
+# local.conf as a bootstrap for the server
+sub updateLocalConf {
+ my $entry = shift;
+ my $siedn = shift;
+ my $localfh = shift;
+
+ # convert entry to pset format
+ my $prefix = getAttrNamePrefix($entry->getDN(), $siedn);
+
+ # write values to file
+ foreach my $attr (keys %{$entry}) {
+ next if $nopsetattrs{lc($attr)};
+ my $attrName;
+ if ($prefix) {
+ $attrName = $prefix . "." . $attr;
+ } else {
+ $attrName = $attr;
+ }
+ foreach my $val ($entry->getValues($attr)) {
+ print $localfh "$attrName: $val\n";
+ }
+ }
+
+ return 1;
+}
Index: ConfigDSDialogs.pm
===================================================================
RCS file: /cvs/dirsec/adminserver/admserv/newinst/src/ConfigDSDialogs.pm,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -r1.1 -r1.2
--- ConfigDSDialogs.pm 15 Jun 2007 22:16:28 -0000 1.1
+++ ConfigDSDialogs.pm 19 Jun 2007 18:32:28 -0000 1.2
@@ -83,7 +83,7 @@
}
my $configdsinfo = new Dialog (
- $TYPICAL,
+ $EXPRESS,
'dialog_configdsinfo_text',
sub {
my $self = shift;
@@ -264,7 +264,7 @@
);
my $useconfigds = new DialogYesNo (
- $TYPICAL,
+ $EXPRESS,
'dialog_useconfigds_text',
sub {
my $self = shift;
Index: setup-ds-admin.pl.in
===================================================================
RCS file: /cvs/dirsec/adminserver/admserv/newinst/src/setup-ds-admin.pl.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- setup-ds-admin.pl.in 15 Jun 2007 22:16:28 -0000 1.2
+++ setup-ds-admin.pl.in 19 Jun 2007 18:32:28 -0000 1.3
@@ -47,17 +47,18 @@
use Resource;
use DialogManager;
use AdminUtil;
-
-my $setup = new Setup;
+use AdminServer;
my $res = new Resource("@propertydir(a)/setup-ds.res",
"@propertydir(a)/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::getConf($setup->{configdir});
+my $admConf = AdminUtil::getAdmConf("$setup->{configdir}/admin-serv");
# set defaults
if ($admConf && %{$admConf}) {
@@ -71,8 +72,9 @@
# read additional config from config DS
my $pset = AdminUtil::getPset($admConf);
if ($pset && %{$pset}) {
- $setup->{inf}->{admin}->{Port} =
$pset->{"configuration.nsServerPort"};
- $setup->{inf}->{admin}->{ServerIpAddress} =
$pset->{"configuration.nsServerAddress"};
+ $setup->{inf}->{admin}->{Port} =
$pset->{"configuration.nsserverport"};
+ $setup->{asorigport} = $pset->{"configuration.nsserverport"}; #
save orig. port
+ $setup->{inf}->{admin}->{ServerIpAddress} =
$pset->{"configuration.nsserveraddress"};
}
my $admpw = AdminUtil::getAdmpw($admConf);
if ($admpw && %{$admpw}) {
@@ -83,6 +85,7 @@
# default to using the existing config DS
$setup->{inf}->{slapd}->{UseExistingMC} = 1;
$setup->{inf}->{slapd}->{SlapdConfigForMC} = 0;
+ $setup->{reconfigas} = 1; # allow AS reconfig
}
if (!$setup->{silent}) {
@@ -105,13 +108,13 @@
sub {
my $self = shift;
my $ans = shift;
- my $res = $self->handleResponse($ans);
- if ($res == $DialogManager::NEXT) {
+ my $resp = $self->handleResponse($ans);
+ if ($resp == $DialogManager::NEXT) {
if (!$self->isYes()) {
- $res = $DialogManager::BACK;
+ $resp = $DialogManager::BACK;
}
}
- return $res;
+ return $resp;
},
['dialog_readytoproceed_prompt'],
);
@@ -123,8 +126,6 @@
if ($rc) {
$setup->doExit();
}
-
- print "\n\n";
}
if (!$setup->{inf}->{slapd}->{UseExistingMC} or
@@ -139,29 +140,53 @@
$setup->{inf}->write();
+$setup->msg('create_dirserver');
+
# create a directory server instance
if (system("@bindir(a)/ds_newinst.pl $setup->{inffile}")) {
- print STDERR "Failed to create directory server instance\n";
- $setup->{log}->logMessage($FATAL, "Setup", "Failed to create
directory server instance");
+ $setup->msg($FATAL, 'error_create_dirserver');
+ exit 1;
}
# setup directory server instance to be the configuration DS
if ($setup->{inf}->{slapd}->{SlapdConfigForMC} =~ /yes/i) {
- createConfigDS($setup->{inf}, $res);
+ my @errs = ();
+ $setup->msg('create_configds');
+ if (!createConfigDS($setup->{inf}, \@errs)) {
+ $setup->msg($FATAL, @errs);
+ $setup->msg($FATAL, 'error_create_configds');
+ exit 1;
+ }
}
# register ds instances with config DS
+if (!registerDSWithConfigDS($setup)) {
+ $setup->msg($FATAL, 'error_register_dirserver');
+ exit 1;
+}
+
-# configure the admin server instance
-if (system("@cmdbindir@/ds-admin-update -f $setup->{inffile}")) {
- print STDERR "Failed to configure administration server\n";
- $setup->{log}->logMessage($FATAL, "Setup", "Failed to configure
administration server");
+# configure and register the admin server instance
+if (!$setup->{reconfigas}) {
+ if (!createAdminServer($setup)) {
+ $setup->msg($FATAL, 'error_create_adminserver');
+ exit 1;
+ }
+} else {
+ if (!reconfigAdminServer($setup)) {
+ $setup->msg($FATAL, 'error_reconfig_adminserver');
+ exit 1;
+ }
}
+$setup->msg($SUCCESS, 'setup_complete');
+
END {
- if (!$setup->{keep}) {
- unlink $setup->{inffile};
- }
+ if ($setup) {
+ if (!$setup->{keep}) {
+ unlink $setup->{inffile};
+ }
- $setup->doExit();
+ $setup->doExit();
+ }
}
Index: setup-ds-admin.res.in
===================================================================
RCS file: /cvs/dirsec/adminserver/admserv/newinst/src/setup-ds-admin.res.in,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -r1.2 -r1.3
--- setup-ds-admin.res.in 15 Jun 2007 22:16:28 -0000 1.2
+++ setup-ds-admin.res.in 19 Jun 2007 18:32:28 -0000 1.3
@@ -80,3 +80,44 @@
dialog_readytoproceed_text = The interactive phase is complete. The script will now set
up your\
servers. Enter No or go Back if you want to change something.\n\n
dialog_readytoproceed_prompt = Are you ready to set up your servers?
+
+# post install
+begin_create_adminserver = Beginning Admin Server creation . . .\n
+begin_reconfig_adminserver = Beginning Admin Server reconfiguration . . .\n
+create_adminserver_filesdirs = Creating Admin Server files and directories . . .\n
+creating_admpw = Could not create the admin server password file '%s': Error
%s\n
+missing_adminserver_param = Missing required Admin Server setup parameter '%s'.
Cannot continue.\n
+missing_general_param = Missing required General setup parameter '%s'. Cannot
continue.\n
+creating_admpw = Could not create the Admin Server password file '%s'. Error
%s\n
+error_create_dirserver = Failed to create directory server instance\n
+error_create_configds = Failed to create the configuration directory server\n
+error_create_adminserver = Failed to create and configure the admin server\n
+error_creating_directory = Could not create admin server directory '%s'. Error:
%s\n
+error_chowning_directory = Could not change ownership of directory '%s' to userid
'%s': Error: %s\n
+error_chgrping_directory = Could not change group of directory '%s' to group
'%s': Error: %s\n
+updating_admconf = Updating adm.conf . . .\n
+error_updating_admconf = Could not update adm.conf. Error: %s\n
+updating_admpw = Updating admpw . . .\n
+error_updating_admpw = Could not update admpw. Error: %s\n
+error_creating_adminserver_maptbl = Could not create the map table for registering the
Admin Server with the configuration directory server.\n
+error_updating_localconf = Could not update the local admin server configuration file
'%s'. Error: %s\n
+error_starting_adminserver = Could not start the admin server. Error: %s\n
+registering_adminserver = Registering admin server with the configuration directory
server . . .\n
+error_adding_adminserver_config_entry = Could not add the admin server configuration
entry '%s'.\nCheck the configuration directory server access and error log for
more details.\n
+error_updating_localconf_entry = Could not update the local admin server configuration
file for the configuration entry '%s'.\n
+updating_admconf_configds = Updating adm.conf with information from configuration
directory server . . .\n
+updating_httpconf = Updating the configuration for the httpd engine . . .\n
+error_updating_httpconf = Could not update the httpd engine configuration.\n
+restarting_adminserver = Restarting admin server . . .\n
+starting_adminserver = Starting admin server . . .\n
+adminserver_startup_output = output: %s
+success_starting_adminserver = The admin server was successfully started.\n
+end_create_adminserver = Admin server was successfully created, configured, and
started.\n
+end_reconfig_adminserver = Admin server was successfully reconfigured and started.\n
+create_dirserver = Creating directory server . . .\n
+create_configds = Creating the configuration directory server . . .\n
+setup_complete = Setup is complete.\n\n
+error_register_dirserver = Could not register the directory server with the configuration
directory server.\n
+registering_dirserver = Registering directory server with the configuration directory
server . . .\n
+error_creating_dirserver_maptbl = Could not create the map table for registering the
directory server with the configuration directory server.\n
+error_reconfig_adminserver = Could not reconfigure the admin server.\n