summaryrefslogtreecommitdiffstats
path: root/base/setup
diff options
context:
space:
mode:
authorEndi Sukma Dewata <edewata@redhat.com>2012-03-24 02:27:47 -0500
committerEndi Sukma Dewata <edewata@redhat.com>2012-03-26 11:43:54 -0500
commit621d9e5c413e561293d7484b93882d985b3fe15f (patch)
tree638f3d75761c121d9a8fb50b52a12a6686c5ac5c /base/setup
parent40d3643b8d91886bf210aa27f711731c81a11e49 (diff)
downloadpki-621d9e5c413e561293d7484b93882d985b3fe15f.tar.gz
pki-621d9e5c413e561293d7484b93882d985b3fe15f.tar.xz
pki-621d9e5c413e561293d7484b93882d985b3fe15f.zip
Removed unnecessary pki folder.
Previously the source code was located inside a pki folder. This folder was created during svn migration and is no longer needed. This folder has now been removed and the contents have been moved up one level. Ticket #131
Diffstat (limited to 'base/setup')
-rw-r--r--base/setup/CMakeLists.txt43
-rw-r--r--base/setup/LICENSE291
-rw-r--r--base/setup/jars/resteasy-jettison-provider-2.3-RC1.jarbin0 -> 32378 bytes
-rwxr-xr-xbase/setup/pki-setup-proxy499
-rwxr-xr-xbase/setup/pkicommon.pm3580
-rwxr-xr-xbase/setup/pkicreate3479
-rwxr-xr-xbase/setup/pkiremove680
-rw-r--r--base/setup/scripts/functions1121
-rwxr-xr-xbase/setup/scripts/pki_apache_initscript246
-rwxr-xr-xbase/setup/scripts/pkicontrol73
10 files changed, 10012 insertions, 0 deletions
diff --git a/base/setup/CMakeLists.txt b/base/setup/CMakeLists.txt
new file mode 100644
index 000000000..2ed50ee62
--- /dev/null
+++ b/base/setup/CMakeLists.txt
@@ -0,0 +1,43 @@
+project(setup)
+
+install(
+ FILES
+ pkicreate
+ pkiremove
+ pki-setup-proxy
+ scripts/pkicontrol
+ DESTINATION
+ ${BIN_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+install(
+ FILES
+ pkicommon.pm
+ scripts/functions
+ scripts/pki_apache_initscript
+ DESTINATION
+ ${DATA_INSTALL_DIR}/scripts/
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+install(
+ FILES
+ jars/resteasy-jettison-provider-2.3-RC1.jar
+ DESTINATION
+ ${JAVA_JAR_INSTALL_DIR}
+ PERMISSIONS
+ OWNER_EXECUTE OWNER_WRITE OWNER_READ
+ GROUP_EXECUTE GROUP_READ
+ WORLD_EXECUTE WORLD_READ
+)
+
+# install empty directories
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${VAR_INSTALL_DIR}/lock/pki)")
+install(CODE "file(MAKE_DIRECTORY \$ENV{DESTDIR}${VAR_INSTALL_DIR}/run/pki)")
diff --git a/base/setup/LICENSE b/base/setup/LICENSE
new file mode 100644
index 000000000..e281f4362
--- /dev/null
+++ b/base/setup/LICENSE
@@ -0,0 +1,291 @@
+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.
+
+ GNU GENERAL PUBLIC LICENSE
+ Version 2, June 1991
+
+ Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
+ 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
+ Everyone is permitted to copy and distribute verbatim copies
+ of this license document, but changing it is not allowed.
+
+ Preamble
+
+ The licenses for most software are designed to take away your
+freedom to share and change it. By contrast, the GNU General Public
+License is intended to guarantee your freedom to share and change free
+software--to make sure the software is free for all its users. This
+General Public License applies to most of the Free Software
+Foundation's software and to any other program whose authors commit to
+using it. (Some other Free Software Foundation software is covered by
+the GNU Lesser General Public License instead.) You can apply it to
+your programs, too.
+
+ When we speak of free software, we are referring to freedom, not
+price. Our General Public Licenses are designed to make sure that you
+have the freedom to distribute copies of free software (and charge for
+this service if you wish), that you receive source code or can get it
+if you want it, that you can change the software or use pieces of it
+in new free programs; and that you know you can do these things.
+
+ To protect your rights, we need to make restrictions that forbid
+anyone to deny you these rights or to ask you to surrender the rights.
+These restrictions translate to certain responsibilities for you if you
+distribute copies of the software, or if you modify it.
+
+ For example, if you distribute copies of such a program, whether
+gratis or for a fee, you must give the recipients all the rights that
+you have. You must make sure that they, too, receive or can get the
+source code. And you must show them these terms so they know their
+rights.
+
+ We protect your rights with two steps: (1) copyright the software, and
+(2) offer you this license which gives you legal permission to copy,
+distribute and/or modify the software.
+
+ Also, for each author's protection and ours, we want to make certain
+that everyone understands that there is no warranty for this free
+software. If the software is modified by someone else and passed on, we
+want its recipients to know that what they have is not the original, so
+that any problems introduced by others will not reflect on the original
+authors' reputations.
+
+ Finally, any free program is threatened constantly by software
+patents. We wish to avoid the danger that redistributors of a free
+program will individually obtain patent licenses, in effect making the
+program proprietary. To prevent this, we have made it clear that any
+patent must be licensed for everyone's free use or not licensed at all.
+
+ The precise terms and conditions for copying, distribution and
+modification follow.
+
+ GNU GENERAL PUBLIC LICENSE
+ TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
+
+ 0. This License applies to any program or other work which contains
+a notice placed by the copyright holder saying it may be distributed
+under the terms of this General Public License. The "Program", below,
+refers to any such program or work, and a "work based on the Program"
+means either the Program or any derivative work under copyright law:
+that is to say, a work containing the Program or a portion of it,
+either verbatim or with modifications and/or translated into another
+language. (Hereinafter, translation is included without limitation in
+the term "modification".) Each licensee is addressed as "you".
+
+Activities other than copying, distribution and modification are not
+covered by this License; they are outside its scope. The act of
+running the Program is not restricted, and the output from the Program
+is covered only if its contents constitute a work based on the
+Program (independent of having been made by running the Program).
+Whether that is true depends on what the Program does.
+
+ 1. You may copy and distribute verbatim copies of the Program's
+source code as you receive it, in any medium, provided that you
+conspicuously and appropriately publish on each copy an appropriate
+copyright notice and disclaimer of warranty; keep intact all the
+notices that refer to this License and to the absence of any warranty;
+and give any other recipients of the Program a copy of this License
+along with the Program.
+
+You may charge a fee for the physical act of transferring a copy, and
+you may at your option offer warranty protection in exchange for a fee.
+
+ 2. You may modify your copy or copies of the Program or any portion
+of it, thus forming a work based on the Program, and copy and
+distribute such modifications or work under the terms of Section 1
+above, provided that you also meet all of these conditions:
+
+ a) You must cause the modified files to carry prominent notices
+ stating that you changed the files and the date of any change.
+
+ b) You must cause any work that you distribute or publish, that in
+ whole or in part contains or is derived from the Program or any
+ part thereof, to be licensed as a whole at no charge to all third
+ parties under the terms of this License.
+
+ c) If the modified program normally reads commands interactively
+ when run, you must cause it, when started running for such
+ interactive use in the most ordinary way, to print or display an
+ announcement including an appropriate copyright notice and a
+ notice that there is no warranty (or else, saying that you provide
+ a warranty) and that users may redistribute the program under
+ these conditions, and telling the user how to view a copy of this
+ License. (Exception: if the Program itself is interactive but
+ does not normally print such an announcement, your work based on
+ the Program is not required to print an announcement.)
+
+These requirements apply to the modified work as a whole. If
+identifiable sections of that work are not derived from the Program,
+and can be reasonably considered independent and separate works in
+themselves, then this License, and its terms, do not apply to those
+sections when you distribute them as separate works. But when you
+distribute the same sections as part of a whole which is a work based
+on the Program, the distribution of the whole must be on the terms of
+this License, whose permissions for other licensees extend to the
+entire whole, and thus to each and every part regardless of who wrote it.
+
+Thus, it is not the intent of this section to claim rights or contest
+your rights to work written entirely by you; rather, the intent is to
+exercise the right to control the distribution of derivative or
+collective works based on the Program.
+
+In addition, mere aggregation of another work not based on the Program
+with the Program (or with a work based on the Program) on a volume of
+a storage or distribution medium does not bring the other work under
+the scope of this License.
+
+ 3. You may copy and distribute the Program (or a work based on it,
+under Section 2) in object code or executable form under the terms of
+Sections 1 and 2 above provided that you also do one of the following:
+
+ a) Accompany it with the complete corresponding machine-readable
+ source code, which must be distributed under the terms of Sections
+ 1 and 2 above on a medium customarily used for software interchange; or,
+
+ b) Accompany it with a written offer, valid for at least three
+ years, to give any third party, for a charge no more than your
+ cost of physically performing source distribution, a complete
+ machine-readable copy of the corresponding source code, to be
+ distributed under the terms of Sections 1 and 2 above on a medium
+ customarily used for software interchange; or,
+
+ c) Accompany it with the information you received as to the offer
+ to distribute corresponding source code. (This alternative is
+ allowed only for noncommercial distribution and only if you
+ received the program in object code or executable form with such
+ an offer, in accord with Subsection b above.)
+
+The source code for a work means the preferred form of the work for
+making modifications to it. For an executable work, complete source
+code means all the source code for all modules it contains, plus any
+associated interface definition files, plus the scripts used to
+control compilation and installation of the executable. However, as a
+special exception, the source code distributed need not include
+anything that is normally distributed (in either source or binary
+form) with the major components (compiler, kernel, and so on) of the
+operating system on which the executable runs, unless that component
+itself accompanies the executable.
+
+If distribution of executable or object code is made by offering
+access to copy from a designated place, then offering equivalent
+access to copy the source code from the same place counts as
+distribution of the source code, even though third parties are not
+compelled to copy the source along with the object code.
+
+ 4. You may not copy, modify, sublicense, or distribute the Program
+except as expressly provided under this License. Any attempt
+otherwise to copy, modify, sublicense or distribute the Program is
+void, and will automatically terminate your rights under this License.
+However, parties who have received copies, or rights, from you under
+this License will not have their licenses terminated so long as such
+parties remain in full compliance.
+
+ 5. You are not required to accept this License, since you have not
+signed it. However, nothing else grants you permission to modify or
+distribute the Program or its derivative works. These actions are
+prohibited by law if you do not accept this License. Therefore, by
+modifying or distributing the Program (or any work based on the
+Program), you indicate your acceptance of this License to do so, and
+all its terms and conditions for copying, distributing or modifying
+the Program or works based on it.
+
+ 6. Each time you redistribute the Program (or any work based on the
+Program), the recipient automatically receives a license from the
+original licensor to copy, distribute or modify the Program subject to
+these terms and conditions. You may not impose any further
+restrictions on the recipients' exercise of the rights granted herein.
+You are not responsible for enforcing compliance by third parties to
+this License.
+
+ 7. If, as a consequence of a court judgment or allegation of patent
+infringement or for any other reason (not limited to patent issues),
+conditions are imposed on you (whether by court order, agreement or
+otherwise) that contradict the conditions of this License, they do not
+excuse you from the conditions of this License. If you cannot
+distribute so as to satisfy simultaneously your obligations under this
+License and any other pertinent obligations, then as a consequence you
+may not distribute the Program at all. For example, if a patent
+license would not permit royalty-free redistribution of the Program by
+all those who receive copies directly or indirectly through you, then
+the only way you could satisfy both it and this License would be to
+refrain entirely from distribution of the Program.
+
+If any portion of this section is held invalid or unenforceable under
+any particular circumstance, the balance of the section is intended to
+apply and the section as a whole is intended to apply in other
+circumstances.
+
+It is not the purpose of this section to induce you to infringe any
+patents or other property right claims or to contest validity of any
+such claims; this section has the sole purpose of protecting the
+integrity of the free software distribution system, which is
+implemented by public license practices. Many people have made
+generous contributions to the wide range of software distributed
+through that system in reliance on consistent application of that
+system; it is up to the author/donor to decide if he or she is willing
+to distribute software through any other system and a licensee cannot
+impose that choice.
+
+This section is intended to make thoroughly clear what is believed to
+be a consequence of the rest of this License.
+
+ 8. If the distribution and/or use of the Program is restricted in
+certain countries either by patents or by copyrighted interfaces, the
+original copyright holder who places the Program under this License
+may add an explicit geographical distribution limitation excluding
+those countries, so that distribution is permitted only in or among
+countries not thus excluded. In such case, this License incorporates
+the limitation as if written in the body of this License.
+
+ 9. The Free Software Foundation may publish revised and/or new versions
+of the General Public License from time to time. Such new versions will
+be similar in spirit to the present version, but may differ in detail to
+address new problems or concerns.
+
+Each version is given a distinguishing version number. If the Program
+specifies a version number of this License which applies to it and "any
+later version", you have the option of following the terms and conditions
+either of that version or of any later version published by the Free
+Software Foundation. If the Program does not specify a version number of
+this License, you may choose any version ever published by the Free Software
+Foundation.
+
+ 10. If you wish to incorporate parts of the Program into other free
+programs whose distribution conditions are different, write to the author
+to ask for permission. For software which is copyrighted by the Free
+Software Foundation, write to the Free Software Foundation; we sometimes
+make exceptions for this. Our decision will be guided by the two goals
+of preserving the free status of all derivatives of our free software and
+of promoting the sharing and reuse of software generally.
+
+ NO WARRANTY
+
+ 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
+FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
+OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
+PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
+OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
+TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
+PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
+REPAIR OR CORRECTION.
+
+ 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
+WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
+REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
+INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
+OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
+TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
+YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
+PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
+POSSIBILITY OF SUCH DAMAGES.
diff --git a/base/setup/jars/resteasy-jettison-provider-2.3-RC1.jar b/base/setup/jars/resteasy-jettison-provider-2.3-RC1.jar
new file mode 100644
index 000000000..da7106ddd
--- /dev/null
+++ b/base/setup/jars/resteasy-jettison-provider-2.3-RC1.jar
Binary files differ
diff --git a/base/setup/pki-setup-proxy b/base/setup/pki-setup-proxy
new file mode 100755
index 000000000..0222eab46
--- /dev/null
+++ b/base/setup/pki-setup-proxy
@@ -0,0 +1,499 @@
+#!/usr/bin/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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2011 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+use strict;
+use warnings;
+
+use File::Copy;
+use Sys::Hostname;
+use Getopt::Long qw(GetOptions);
+use File::Slurp qw(read_file write_file);
+
+use lib "/usr/share/pki/scripts";
+use pkicommon;
+
+##############################################################
+# This script is used to convert an existing instance from a
+# non-proxy port configuration to a proxy port configuration.
+#
+# Sample Invocation (for CA):
+#
+# ./pki-setup-proxy -pki_instance_root=/var/lib
+# -pki_instance_name=pki-ca
+# -subsystem_type=ca
+# -ajp_redirect_port=9444
+# -ajp_port=9447
+# -proxy_secure_port=443
+# -proxy_unsecure_port=80
+# -unsecure_port=9080
+# -user=pkiuser
+# -group=pkiuser
+# -verbose
+#
+##############################################################
+
+##############################################################
+# Command-Line Variables
+##############################################################
+
+my $ARGS = ($#ARGV + 1);
+
+##############################################################
+# Local Variables
+##############################################################
+
+# Command-line variables (mandatory)
+my $pki_instance_root = undef;
+my $pki_instance_name = undef;
+my $subsystem_type = undef;
+
+# Command-line variables (optional)
+my $ajp_port = -1;
+my $ajp_redirect_port = -1;
+my $proxy_secure_port = -1;
+my $proxy_unsecure_port = -1;
+my $unsecure_port = -1;
+my $pki_user = $PKI_USER;
+my $pki_group = $PKI_GROUP;
+
+# Base subsystem directory paths
+my $pki_subsystem_conf_path = undef;
+
+# Base instance directory paths
+my $pki_instance_path = undef;
+my $pki_instance_conf_path = undef;
+my $pki_instance_webxml_path = undef;
+my $pki_instance_profile_select_path = undef;
+
+#proxy defaults
+my $PROXY_SECURE_PORT_DEFAULT = "443";
+my $PROXY_UNSECURE_PORT_DEFAULT = "80";
+my $UNSECURE_PORT_DEFAULT = "9080";
+my $AJP_PORT_DEFAULT = "9447";
+my $AJP_REDIRECT_PORT_DEFAULT = "9444";
+
+sub usage
+{
+ print STDOUT <<'EOF';
+###############################################################################
+### USAGE: CA, KRA, OCSP, or TKS subsystem proxy setup ###
+###############################################################################
+
+pki-proxy-setup \
+ -pki_instance_root=<pki_instance_root> # Instance root directory
+ # destination
+
+ -pki_instance_name=<pki_instance_id> # Unique PKI subsystem
+ # instance name
+
+ -subsystem_type=<subsystem_type> # Subsystem type
+ # [ca | kra | ocsp | tks]
+
+ [-ajp_port=<ajp_port>] # AJP port, default 9447
+
+ [-ajp_redirect_port=<ajp_redirect_port>] # AJP redirect port,
+ # default 9444
+
+ [-proxy_secure_port=<proxy_secure_port>] # Proxy secure port,
+ # default 443
+
+ [-proxy_unsecure_port=<unsecure_port>] # Proxy unsecure port,
+ # default 80
+
+ [-unsecure_port=<unsecure_port>] # UnSecure port,
+ # default 9080
+
+ [-user=<username>] # User ownership,
+ # default pkiuser
+
+ [-group=<groupname>] # Group ownership
+ # default pkiuser
+
+ [-verbose] # Print out liberal info
+ # Specify multiple times
+ # to increase verbosity.
+
+ [-help] # Print out this screen
+EOF
+
+}
+
+sub pki_instance_already_exists
+{
+ my ($name) = @_;
+ my $result = 0;
+ my $instance = "";
+
+ $instance = "/etc/sysconfig/pki"
+ . "/" . $subsystem_type
+ . "/" . $name;
+
+ if (-e $instance) {
+ $result = 1;
+ }
+
+ return $result;
+}
+
+# no args
+# return 1 - success, or
+# return 0 - failure
+sub parse_arguments
+{
+ my $l_proxy_secure_port = -1;
+ my $l_proxy_unsecure_port = -1;
+ my $l_unsecure_port = -1;
+ my $l_ajp_port = -1;
+ my $l_ajp_redirect_port = -1;
+ my $show_help = 0;
+ my $username = undef;
+ my $groupname = undef;
+
+ my $result = GetOptions("help" => \$show_help,
+ "pki_instance_root=s" => \$pki_instance_root,
+ "pki_instance_name=s" => \$pki_instance_name,
+ "subsystem_type=s" => \$subsystem_type,
+ "ajp_port:i" => \$l_ajp_port,
+ "ajp_redirect_port:i" => \$l_ajp_redirect_port,
+ "proxy_secure_port:i" => \$l_proxy_secure_port,
+ "proxy_unsecure_port:i" => \$l_proxy_unsecure_port,
+ "unsecure_port:i" => \$l_unsecure_port,
+ "user=s" => \$username,
+ "group=s" => \$groupname,
+ "verbose+" => \$verbose);
+
+ ## Optional "-help" option - no "mandatory" options are required
+ if ($show_help) {
+ usage();
+ return 0;
+ }
+
+ ## Mandatory "-pki_instance_root=s" option
+ if (!$pki_instance_root) {
+ usage();
+ emit("Must have value for -pki_instance_root!\n", "error");
+ return 0;
+ }
+
+ # Remove all trailing directory separators ('/')
+ $pki_instance_root =~ s/\/+$//;
+
+ ## Mandatory "-subsystem_type=s" option
+ if ($subsystem_type ne $CA &&
+ $subsystem_type ne $KRA &&
+ $subsystem_type ne $OCSP &&
+ $subsystem_type ne $TKS &&
+ $subsystem_type ne $RA &&
+ $subsystem_type ne $TPS) {
+ usage();
+ emit("Illegal value => $subsystem_type : for -subsystem_type!\n",
+ "error");
+ return 0;
+ }
+
+ if ($subsystem_type eq $RA ||
+ $subsystem_type eq $TPS) {
+ usage();
+ emit("Illegal value => $subsystem_type : for -subsystem_type!\n" .
+ "Proxy configuration is not yet supported for TPS and RA subsystems",
+ "error");
+ return 0;
+ }
+
+ ## Mandatory "-pki_instance_name=s" option
+ if (!$pki_instance_name) {
+ usage();
+ emit("Must have value for -pki_instance_name!\n", "error");
+ return 0;
+ }
+
+ if (! pki_instance_already_exists($pki_instance_name)) {
+ usage();
+ emit("An instance named $pki_instance_name "
+ . "does not exist; please try again.\n", "error");
+ return 0;
+ }
+
+ $pki_instance_path = "${pki_instance_root}/${pki_instance_name}";
+
+ # Capture installation information in a log file, always overwrite this file.
+ # When modifying an instance it's a fatal error if the logfile
+ # cannot be created.
+ my $logfile = "/var/log/${pki_instance_name}-proxy-setup.log";
+ if (!open_logfile($logfile, $default_file_permissions)) {
+ emit("can not create logfile ($logfile)", "error");
+ return 0;
+ }
+
+ printf(STDOUT "Capturing configuration information in %s\n", $logfile);
+
+ emit("Parsing setup_proxy arguments ...\n");
+ if ($verbose) {
+ emit(" verbose mode ENABLED (level=$verbose)\n");
+ }
+
+ if ($username) {
+ $pki_user = $username;
+ }
+ emit(" user $pki_user\n");
+
+ if ($groupname) {
+ $pki_group = $groupname;
+ }
+ emit(" group $pki_group\n");
+
+ $proxy_secure_port = ($l_proxy_secure_port >= 0) ? $l_proxy_secure_port :
+ $PROXY_SECURE_PORT_DEFAULT;
+ emit(" proxy_secure_port $proxy_secure_port\n");
+
+ $proxy_unsecure_port = ($l_proxy_unsecure_port >= 0) ? $l_proxy_unsecure_port :
+ $PROXY_UNSECURE_PORT_DEFAULT;
+ emit(" proxy_unsecure_port $proxy_unsecure_port\n");
+
+ $unsecure_port = ($l_unsecure_port >= 0) ? $l_unsecure_port :
+ $UNSECURE_PORT_DEFAULT;
+ emit(" unsecure_port $unsecure_port\n");
+
+ $ajp_port = ($l_ajp_port >= 0) ? $l_ajp_port : $AJP_PORT_DEFAULT;
+ emit(" ajp_port $ajp_port\n");
+
+ $ajp_redirect_port = ($l_ajp_redirect_port >= 0) ? $l_ajp_redirect_port :
+ $AJP_REDIRECT_PORT_DEFAULT;
+ emit(" ajp_redirect_port $ajp_redirect_port\n");
+
+ return 1;
+}
+
+# no args
+# no return
+sub initialize_paths
+{
+ $pki_instance_conf_path = "${pki_instance_path}/conf";
+ $pki_subsystem_conf_path = "/usr/share/pki/${subsystem_type}/conf";
+ $pki_instance_webxml_path = "${pki_instance_path}/webapps/${subsystem_type}" .
+ "/WEB-INF/web.xml";
+ $pki_instance_profile_select_path = "${pki_instance_path}/webapps/" .
+ "${subsystem_type}/ee/${subsystem_type}/" .
+ "ProfileSelect.template";
+}
+
+# no args
+# no return
+sub update_server_xml
+{
+ my $server_xml = "${pki_instance_conf_path}/server.xml";
+
+ my $new_match = <<EOF;
+ <!-- Define an AJP 1.3 Connector on port \\[PKI_AJP_PORT\\] -->
+<!--
+ <Connector port="\\[PKI_AJP_PORT\\]" protocol="AJP/1.3" redirectPort="\\[PKI_AJP_REDIRECT_PORT\\]" />
+-->
+EOF
+ my $old_match = <<EOF;
+ <!-- Define an AJP 1.3 Connector on port 8009 -->
+<!--
+ <Connector port="8009" protocol="AJP/1.3" redirectPort="8443" />
+-->
+EOF
+ my $new_ajp = <<EOF;
+ <!-- Define an AJP 1.3 Connector on port $ajp_port -->
+ <Connector port="$ajp_port" protocol="AJP/1.3" redirectPort="$ajp_redirect_port" />
+EOF
+
+ my $data = read_file $server_xml;
+ $data =~ s/$old_match/$new_ajp/;
+ $data =~ s/$new_match/$new_ajp/;
+
+ # back up existing server.xml
+ copy_file($server_xml, $server_xml . ".pre-proxy.$$",
+ $default_file_permissions, $pki_user, $pki_group);
+ write_file($server_xml, $data);
+ set_file_props($server_xml, $default_file_permissions,
+ $pki_user, $pki_group);
+
+}
+
+# no args
+# no return
+sub update_proxy_conf
+{
+ my $template_file = "${pki_subsystem_conf_path}/proxy.conf";
+ my $server_file = "${pki_instance_conf_path}/proxy.conf";
+
+ #backup, just in case there already was a file
+ copy_file($server_file, $server_file . ".pre-proxy.$$",
+ $default_file_permissions, $pki_user, $pki_group);
+
+ my $data = read_file $template_file;
+ my $host = hostname;
+ $data =~ s/\[PKI_MACHINE_NAME\]/$host/g;
+ $data =~ s/\[PKI_AJP_PORT\]/$ajp_port/g;
+
+ write_file($server_file, $data);
+ set_file_props($server_file, $default_file_permissions,
+ $pki_user, $pki_group);
+
+}
+
+# no args
+# no return
+sub update_web_xml
+{
+ my $data = read_file $pki_instance_webxml_path;
+
+ my $commented_proxy_stanza = <<EOF;
+<!--
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value></param-value>
+ </init-param>
+-->
+EOF
+ my $proxy_stanza = <<EOF;
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>$proxy_secure_port</param-value>
+ </init-param>
+EOF
+
+ my $commented_proxy_stanza_2 = <<EOF;
+<!--
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value></param-value>
+ </init-param>
+ <init-param>
+ <param-name>proxy_http_port</param-name>
+ <param-value></param-value>
+ </init-param>
+-->
+EOF
+ my $proxy_stanza_2 = <<EOF;
+ <init-param>
+ <param-name>proxy_port</param-name>
+ <param-value>$proxy_secure_port</param-value>
+ </init-param>
+ <init-param>
+ <param-name>proxy_http_port</param-name>
+ <param-value>$proxy_unsecure_port</param-value>
+ </init-param>
+EOF
+
+ my $ee_filter_head = <<EOF;
+ <filter>
+ <filter-name>EERequestFilter</filter-name>
+ <filter-class>com.netscape.cms.servlet.filter.EERequestFilter</filter-class>
+ <init-param>
+ <param-name>http_port</param-name>
+ <param-value>$unsecure_port</param-value>
+ </init-param>
+ <init-param>
+ <param-name>https_port</param-name>
+ <param-value>$proxy_secure_port</param-value>
+ </init-param>
+EOF
+
+ my $active_stanza = <<EOF;
+ <init-param>
+ <param-name>active</param-name>
+EOF
+
+ if ($data =~ /$commented_proxy_stanza/) {
+ $data =~ s/$commented_proxy_stanza/$proxy_stanza/g;
+ $data =~ s/$commented_proxy_stanza_2/$proxy_stanza_2/g;
+ } else {
+ $data =~ s/$active_stanza/${proxy_stanza}${active_stanza}/g;
+ $data =~ s/${ee_filter_head}${proxy_stanza}${active_stanza}/${ee_filter_head}${proxy_stanza_2}${active_stanza}/;
+ }
+
+ # backup old file
+ copy_file($pki_instance_webxml_path, $pki_instance_webxml_path . ".pre_proxy",
+ $default_file_permissions, $pki_user, $pki_group);
+
+ write_file($pki_instance_webxml_path, $data);
+ set_file_props($pki_instance_webxml_path, $default_file_permissions,
+ $pki_user, $pki_group);
+}
+
+# no args
+# no return
+sub update_cs_cfg
+{
+ my $cs_cfg = "${pki_instance_conf_path}/CS.cfg";
+ my $data = read_file $cs_cfg;
+
+ $data =~ s/proxy.securePort=[\d]*\n//g;
+ $data =~ s/proxy.unsecurePort=[\d]*\n//g;
+ chomp($data);
+ $data .= "\nproxy.securePort=$proxy_secure_port" .
+ "\nproxy.unsecurePort=$proxy_unsecure_port\n";
+
+ # backup old file
+ copy_file($cs_cfg, $cs_cfg . ".pre-proxy.$$",
+ $default_file_permissions, $pki_user, $pki_group);
+
+ write_file($cs_cfg, $data);
+ set_file_props($cs_cfg, $default_file_permissions,
+ $pki_user, $pki_group);
+}
+
+# no args
+# no return
+sub update_profile_select_template
+{
+ my $template_file = $pki_instance_profile_select_path;
+ my $data = read_file $template_file;
+
+ my $host = hostname;
+ $data =~ s/https:\/\/$host:\d*\/ca\/eeca/https:\/\/$host:$proxy_secure_port\/ca\/eeca/;
+
+ # backup old file
+ copy_file($template_file, $template_file . ".pre-proxy.$$",
+ $default_file_permissions, $pki_user, $pki_group);
+
+ write_file($template_file, $data);
+ set_file_props($template_file, $default_file_permissions,
+ $pki_user, $pki_group);
+}
+
+######################################
+# Main program
+#####################################
+
+sub main
+{
+ my $parse_result = parse_arguments();
+ if (!$parse_result) {
+ close_logfile();
+ exit 255;
+ }
+
+ initialize_paths();
+ update_server_xml();
+ update_proxy_conf();
+ update_web_xml();
+ update_cs_cfg();
+ update_profile_select_template();
+ parse_selinux_ports();
+ add_selinux_port("pki_${subsystem_type}_port_t", $ajp_port);
+}
+
+main();
+exit 0;
diff --git a/base/setup/pkicommon.pm b/base/setup/pkicommon.pm
new file mode 100755
index 000000000..6ce255303
--- /dev/null
+++ b/base/setup/pkicommon.pm
@@ -0,0 +1,3580 @@
+#!/usr/bin/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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2007-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+
+package pkicommon;
+use strict;
+use warnings;
+
+use Exporter;
+our @ISA = qw(Exporter);
+our @EXPORT = qw(
+ $lib_prefix $obj_ext $path_sep $tmp_dir
+ $pki_flavor $pki_registry_path
+ $verbose $dry_run $hostname $default_hardware_platform
+ $default_system_binaries $default_lockdir $default_system_libraries $default_system_user_binaries
+ $default_system_user_libraries
+ $default_java_path $default_pki_java_path $default_x86_64_jni_java_path $default_system_jni_java_path @default_jar_path
+ $default_security_libraries $default_certutil_command
+ $default_ldapmodify_command $default_modutil_command
+ $default_dir_permissions $default_exe_permissions $default_file_permissions
+ $default_initscripts_path $default_registry_path
+ $ROOTUID $MAX_WELL_KNOWN_PORT $MAX_RESERVED_PORT $MAX_REGISTERED_PORT $MAX_DYNAMIC_PORT
+ $FILE_PREFIX $FTP_PREFIX $HTTP_PREFIX $HTTPS_PREFIX $LDAP_PREFIX $LDAPS_PREFIX
+ $PKI_USER $PKI_GROUP $PKI_UID $PKI_GID
+ $CA $KRA $OCSP $TKS $RA $TPS
+ $CA_INITSCRIPT $KRA_INITSCRIPT $OCSP_INITSCRIPT
+ $TKS_INITSCRIPT $RA_INITSCRIPT $TPS_INITSCRIPT
+ $install_info_basename $cleanup_basename %installation_info
+ $semanage $restorecon $SELINUX_PORT_UNDEFINED $SELINUX_PORT_DEFINED $SELINUX_PORT_WRONGLY_DEFINED
+
+ add_install_info remove_install_info get_install_description
+ format_install_info get_install_info_description
+ parse_install_info parse_old_cleanup read_old_cleanup
+ read_install_info read_install_info_from_dir write_install_info_to_dir uninstall
+ is_Windows is_Linux is_Fedora is_RHEL is_RHEL4 setup_platform_dependent_parameters
+ set_library_path get_library_path fedora_release
+ check_for_root_UID user_disallows_shell
+ user_exists create_user
+ group_exists create_group user_is_a_member_of_group add_user_as_a_member_of_group
+ get_UID_from_username
+ get_FQDN check_for_valid_url_prefix
+ AreConnectorPortsValid IsLocalPortAvailable IsServerReachable
+ get_time_stamp generate_random generate_random_string password_quality_checker
+ LDAP_add LDAP_modify
+ certutil_create_databases certutil_delete_cert certutil_generate_CSR
+ certutil_generate_self_signed_cert certutil_import_cert
+ certutil_print_cert certutil_list_certs modutil_add_token
+ open_logfile get_logfile_path close_logfile
+ prompt printFile emit
+ is_path_valid is_name_valid entity_type entity_exists
+ file_exists is_file_empty create_empty_file create_file copy_file remove_file
+ set_permissions set_owner_group set_file_props
+ get_directory_files normalize_path
+ directory_exists is_directory_empty create_directory copy_directory remove_directory
+ set_owner_group_on_directory_contents
+ symlink_exists create_symlink remove_symlink set_owner_group_on_symlink
+ run_command get_cs_cfg get_registry_initscript_name
+ register_pki_instance_with_chkconfig deregister_pki_instance_with_chkconfig
+ find_jar
+ check_selinux_port parse_selinux_ports add_selinux_port add_selinux_file_context
+ );
+
+
+use File::Slurp qw(read_file write_file);
+
+##############################################################
+# This file contains shared data and subroutines for
+# the "pkicreate" and "pkiremove" Perl scripts.
+##############################################################
+
+
+##############################################################
+# Perl Version
+##############################################################
+
+my $MINIMUM_PERL_VERSION = "5.006001";
+
+my $perl_version_error_message = "ERROR: Using Perl version $] ...\n"
+ . " Must use Perl version "
+ . "$MINIMUM_PERL_VERSION or later to "
+ . "run this script!\n";
+
+die $perl_version_error_message if $] < $MINIMUM_PERL_VERSION;
+
+
+##############################################################
+# Execution Check
+##############################################################
+
+# Check to insure that this script's original
+# invocation directory has not been deleted!
+my $cwd = `/bin/pwd`;
+chomp $cwd;
+if (!$cwd) {
+ emit("Cannot invoke '$0' from non-existent directory!\n", "error");
+ exit 255;
+}
+
+
+##############################################################
+# Environment Variables
+##############################################################
+
+# untaint called subroutines
+if (($^O ne 'Windows_NT') && ($^O ne 'MSWin32')) {
+ $> = $<; # set effective user ID to real UID
+ $) = $(; # set effective group ID to real GID
+ $ENV{'PATH'} = '/bin:/usr/bin';
+ $ENV{'ENV'} = '' if !defined($ENV{'ENV'});
+}
+
+
+##############################################################
+# Perl Modules
+##############################################################
+
+use Sys::Hostname;
+use FileHandle;
+use Socket;
+use File::Copy;
+use File::Basename;
+use File::Path qw(make_path remove_tree);
+
+##############################################################
+# Global Variables
+##############################################################
+
+# Platform-dependent parameters
+our $lib_prefix = undef;
+our $obj_ext = undef;
+our $path_sep = undef;
+our $tmp_dir = undef;
+
+# Whether or not to do verbose mode
+our $verbose = 0;
+
+# Controls whether actions are executed (dry_run == false)
+# or if actions are only reported (dry_run == true).
+our $dry_run = 0;
+
+our $hostname = undef;
+
+# selinux structures
+our %selinux_ports = ();
+
+##############################################################
+# Shared Default Values
+##############################################################
+
+our $pki_flavor = undef;
+our $pki_registry_path = undef;
+
+our $default_hardware_platform = undef;
+our $default_system_binaries = undef;
+our $default_lockdir = undef;
+our $default_system_libraries = undef;
+our $default_system_user_binaries = undef;
+our $default_system_user_libraries = undef;
+our $default_java_path = undef;
+our $default_pki_java_path = undef;
+our $default_x86_64_jni_java_path = undef;
+our $default_system_jni_java_path = undef;
+our @default_jar_path = undef;
+our $default_security_libraries = undef;
+our $default_certutil_command = undef;
+our $default_ldapmodify_command = undef;
+our $default_modutil_command = undef;
+our $default_initscripts_path = undef;
+our $default_registry_path = undef;
+my $candlepin_java_path = "/usr/share/candlepin/lib";
+
+our $default_dir_permissions = 00770;
+our $default_exe_permissions = 00770;
+our $default_file_permissions = 00660;
+
+our $semanage = "/usr/sbin/semanage";
+our $restorecon = "/sbin/restorecon";
+our $SELINUX_PORT_UNDEFINED = 0;
+our $SELINUX_PORT_DEFINED = 1;
+our $SELINUX_PORT_WRONGLY_DEFINED = 2;
+
+
+
+# Use a local variable to denote IPv6
+my $is_IPv6 = 0;
+
+# Compute "hardware platform" of Operating System
+if ($^O eq "linux") {
+ $pki_flavor = "pki";
+ $default_registry_path = "/etc/sysconfig";
+ $pki_registry_path = "$default_registry_path/$pki_flavor";
+ $default_initscripts_path = "/etc/rc.d/init.d";
+ $default_lockdir = "/var/lock/$pki_flavor";
+ $default_hardware_platform = `uname -i`;
+ $default_hardware_platform =~ s/\s+$//g;
+ chomp($default_hardware_platform);
+ if ($default_hardware_platform eq "i386") {
+ # 32-bit Linux
+ $default_system_binaries = "/bin";
+ $default_system_libraries = "/lib";
+ $default_system_user_binaries = "/usr/bin";
+ $default_system_user_libraries = "/usr/lib";
+ $default_java_path = "/usr/share/java";
+ $default_pki_java_path = "/usr/share/java/pki";
+ $default_system_jni_java_path = "/usr/lib/java";
+ @default_jar_path = ($default_pki_java_path, $default_java_path, $default_system_jni_java_path, $candlepin_java_path);
+ } elsif ($default_hardware_platform eq "x86_64") {
+ # 64-bit Linux
+ $default_system_binaries = "/bin";
+ $default_system_libraries = "/lib64";
+ $default_system_user_binaries = "/usr/bin";
+ $default_system_user_libraries = "/usr/lib64";
+ $default_java_path = "/usr/share/java";
+ $default_pki_java_path = "/usr/share/java/pki";
+ $default_x86_64_jni_java_path = "/usr/lib64/java";
+ $default_system_jni_java_path = "/usr/lib/java";
+ @default_jar_path = ($default_pki_java_path, $default_java_path, $default_x86_64_jni_java_path,
+ $default_system_jni_java_path, $candlepin_java_path);
+ } else {
+ emit("Unsupported '$^O' hardware platform '$default_hardware_platform'!", "error");
+ exit 255;
+ }
+
+ # Retrieve hostname
+ if (defined($ENV{'PKI_HOSTNAME'})) {
+ # IPv6: Retrieve hostname from environment variable
+ $hostname = $ENV{'PKI_HOSTNAME'};
+ $is_IPv6 = 1;
+ } else {
+ # IPv4: Retrieve hostname using Sys::Hostname
+ $hostname = hostname;
+ }
+} else {
+ emit("Unsupported platform '$^O'!\n", "error");
+ exit 255;
+}
+
+
+$default_security_libraries = "$default_system_user_libraries/dirsec";
+
+$default_certutil_command = "$default_system_user_binaries/certutil";
+$default_ldapmodify_command = "$default_system_user_binaries/ldapmodify";
+$default_modutil_command = "$default_system_user_binaries/modutil";
+
+
+##############################################################
+# Global Constants
+##############################################################
+
+our $ROOTUID = 0;
+
+our $MAX_WELL_KNOWN_PORT = 511; # well-known ports = 0 through 511
+our $MAX_RESERVED_PORT = 1023; # reserved ports = 512 through 1023
+our $MAX_REGISTERED_PORT = 49151; # registered ports = 1024 through 49151
+our $MAX_DYNAMIC_PORT = 65535; # dynamic/private ports = 49152 through 65535
+
+our $FILE_PREFIX = "file://";
+our $FTP_PREFIX = "ftp://";
+our $HTTP_PREFIX = "http://";
+our $HTTPS_PREFIX = "https://";
+our $LDAP_PREFIX = "ldap://";
+our $LDAPS_PREFIX = "ldaps://";
+
+# Identity values
+our $PKI_USER = "pkiuser";
+our $PKI_GROUP = "pkiuser";
+our $PKI_UID = 17;
+our $PKI_GID = 17;
+
+# Subsystem names
+our $CA = "ca";
+our $KRA = "kra";
+our $OCSP = "ocsp";
+our $TKS = "tks";
+our $RA = "ra";
+our $TPS = "tps";
+
+# Subsystem init scripts
+our $CA_INITSCRIPT = "pki-cad";
+our $KRA_INITSCRIPT = "pki-krad";
+our $OCSP_INITSCRIPT = "pki-ocspd";
+our $TKS_INITSCRIPT = "pki-tksd";
+our $RA_INITSCRIPT = "pki-rad";
+our $TPS_INITSCRIPT = "pki-tpsd";
+
+
+##############################################################
+# Local Variables
+##############################################################
+
+# "identity" parameters
+my $fqdn = undef;
+
+# "logging" parameters
+my $logfd = undef;
+my $logfile_path = undef;
+
+
+
+##############################################################
+# Routines & data structures used to track &
+# manage installation information
+##############################################################
+
+# Basename of the installation info file.
+our $install_info_basename = "install_info";
+
+# Basename of the old clean up file.
+our $cleanup_basename = ".cleanup.dat";
+
+# Global hash table of installation actions
+# Each filesystem path which is modified during installation
+# is entered into this table as a key. The value associated
+# with the key is an anonymous hash table of key/value pairs,
+# e.g. the installation metadata associated with the path.
+# This table should not be directly modified, rather use
+# the utility subroutines which know how to operate on
+# on an installation info table. The utility routines can
+# operate on any installation table, but default to using
+# this single global table.
+our %installation_info = ();
+
+# Table to validate an installation type
+my %valid_install_types = ('file' => 1,
+ 'symlink' => 1,
+ 'dir' => 1);
+
+# Table to validate a install action
+my %valid_install_action = ('create' => 1,
+ 'move' => 1,
+ 'remove' => 1);
+
+# Table to validate an uninstall action
+my %valid_uninstall_action = ('remove' => 1,
+ 'preserve' => 1);
+
+# Capture information about items modified during installation
+#
+# add_install_info(path, [type='file'], [uninstall_action='remove],
+# [install_action='create])
+#
+# path the path name of the object
+# type what kind of object
+# (file, symlink, dir)
+# uninstall_action - during uninstall what should be done
+# (remove, preserve)
+# install_action what was done during install
+# (create, move, remove)
+#
+# The data structure used to capture the information is a hash
+# table whose keys are path names and whose value is a hash
+# table of key/value attributes belonging to the path object.
+sub add_install_info {
+ my ($path, $type, $uninstall_action, $install_action) = @_;
+ my ($install_info) = \%installation_info;
+ $type = 'file' unless defined($type);
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+ $install_action = 'create' unless defined($install_action);
+ my $info;
+
+ die "invalid install type ($type) for path ($path)"
+ if (!exists($valid_install_types{$type}));
+
+ die "invalid uninstall action ($uninstall_action) for path ($path)"
+ if (!exists($valid_uninstall_action{$uninstall_action}));
+
+ die "invalid install action ($install_action) for path ($path)"
+ if (!exists($valid_install_action{$install_action}));
+
+ if (exists($install_info->{$path})) {
+ $info = $install_info->{$path};
+ } else {
+ $install_info->{$path} = $info = {};
+ }
+
+ $info->{'type'} = $type;
+ $info->{'install_action'} = $install_action;
+ $info->{'uninstall_action'} = $uninstall_action;
+}
+
+# Removes the install info for the given path.
+# Used primarily after an error occurs.
+sub remove_install_info {
+ my ($path) = @_;
+ my ($install_info) = \%installation_info;
+
+ delete $install_info->{$path};
+}
+
+# return text description of installed files and directories
+sub get_install_description
+{
+ my ($install_info) = \%installation_info;
+
+ return get_install_info_description($install_info);
+}
+
+# Given a hash of installation information format it into text.
+# Each path name is in brackets at the beginning of a line
+# followed by the path's attributes, which is an indented line of
+# key = value, for each attribute
+#
+# The formatted text is referred to as a "Installation Manifest".
+#
+# returns formatted text
+#
+# Example:
+#
+# [/etc/pki-ca]
+# install_action = create
+# type = dir
+# uninstall_action = remove
+# [/etc/pki-ca/CS.cfg]
+# install_action = create
+# type = file
+# uninstall_action = remove
+#
+sub format_install_info
+{
+ my ($install_info) = @_;
+ my ($text, @paths, $path, $info, @key_names, $key, $value);
+
+ $text = "";
+ @paths = sort(keys %$install_info);
+ foreach $path (@paths) {
+ $info = $install_info->{$path};
+ $text .= sprintf("[%s]\n", $path);
+ @key_names = sort(keys %$info);
+ foreach $key (@key_names) {
+ $value = $info->{$key};
+ $text .= sprintf(" %s = %s\n", $key, $value);
+ }
+ }
+ return $text;
+}
+
+# Given a hash of installation information format it into
+# into friendly description of what was installed.
+#
+# Brief Example:
+#
+# Installed Files:
+# /etc/pki-ca/CS.cfg
+# /var/log/pki-ca-install.log
+# Installed Directories:
+# /etc/pki-ca
+# /var/log/pki-ca
+# Installed Symbolic Links:
+# /var/lib/pki-ca/logs
+# Removed Items:
+# /etc/pki-ca/noise
+#
+sub get_install_info_description
+{
+ my ($install_info) = @_;
+ my ($text, @paths, @filtered_paths, $path);
+
+ $text = '';
+ @paths = sort(keys %$install_info);
+
+ @filtered_paths = grep {my ($info) = $install_info->{$_};
+ $info->{'type'} eq 'file' &&
+ $info->{'install_action'} ne 'remove'} @paths;
+ if (@filtered_paths) {
+ $text .= "Installed Files:\n";
+ foreach $path (@filtered_paths) {
+ $text .= " ${path}\n";
+ }
+ }
+
+ @filtered_paths = grep {my ($info) = $install_info->{$_};
+ $info->{'type'} eq 'dir' &&
+ $info->{'install_action'} ne 'remove'} @paths;
+ if (@filtered_paths) {
+ $text .= "Installed Directories:\n";
+ foreach $path (@filtered_paths) {
+ $text .= " ${path}\n";
+ }
+ }
+
+ @filtered_paths = grep {my ($info) = $install_info->{$_};
+ $info->{'type'} eq 'symlink' &&
+ $info->{'install_action'} ne 'remove'} @paths;
+ if (@filtered_paths) {
+ $text .= "Installed Symbolic Links:\n";
+ foreach $path (@filtered_paths) {
+ $text .= " ${path}\n";
+ }
+ }
+
+ @filtered_paths = grep {my ($info) = $install_info->{$_};
+ $info->{'install_action'} eq 'remove'} @paths;
+ if (@filtered_paths) {
+ $text .= "Removed Items:\n";
+ foreach $path (@filtered_paths) {
+ $text .= " ${path}\n";
+ }
+ }
+
+ return $text;
+
+}
+
+# Given text as formatted by format_install_info() parse it into
+# a install info hash table where each key is a path name and whose
+# value is a hash table of key/value pairs.
+#
+# E.g. this routine parses an "Installation Manifest".
+#
+# Returns pointer to an install info hash table
+sub parse_install_info
+{
+ my ($text) = @_;
+ my ($install_info, @lines, $line, $line_num, $path, $info, $key, $value);
+
+ $install_info = {};
+ @lines = split(/\n/, $text);
+ $line_num = 0;
+ $path = undef;
+ $info = undef;
+
+ foreach $line (@lines) {
+ $line_num++;
+ $line =~ s/#.*//; # nuke comments
+ $line =~ s/\s+$//; # strip trailing whitespace
+ next if !$line; # skip blank lines
+
+ # Look for quoted path at beginning of line
+ if ($line =~ /^\s*\[(.+)\]\s*$/) {
+ $path = $1;
+ $info = {};
+ $install_info->{$path} = $info;
+ next;
+ }
+
+ if (defined($path)) {
+ # Look for key = value in section, must be preceded by whitespace
+ undef($key);
+ if ($line =~ /^\s+(\w+)\s*=\s*(.*)/) {
+ # quoted name followed by a colon followed by an action
+ $key = $1;
+ $value = $2;
+ $info->{$key} = $value;
+ }
+ }
+ }
+ return $install_info;
+}
+
+# Formerly the installation info was written as an ini style
+# file, a section for files and a section for directories.
+# Everything in the file was meant to be removed upon uninstall.
+#
+# Returns an install info style hash table (see parse_install_info)
+sub parse_old_cleanup
+{
+ my ($text) = @_;
+ my ($install_info, @lines, $line, $section, $info, $path);
+
+ $install_info = {};
+ @lines = split(/\n/, $text);
+
+ foreach $line (@lines) {
+ $line =~ s/#.*//; # nuke comments
+ $line =~ s/^\s+//; # strip leading whitespace
+ $line =~ s/\s+$//; # strip trailing whitespace
+ next if !$line; # skip blank lines
+
+ # Look for section markers
+ if ($line =~ /^\s*\[\s*(\w+)\s*\]\s*$/) {
+ $section = $1;
+ next;
+ }
+
+ # Must be path name
+ $path = $line;
+ $info = {};
+ $install_info->{$path} = $info;
+ $info->{'uninstall_action'} = 'remove';
+ if ($section eq 'files') {
+ $info->{'type'} = 'file';
+ } elsif ($section eq 'directories') {
+ $info->{'type'} = 'dir';
+ } else {
+ die "unknown cleanup section = \"$section\"\n";
+ }
+ }
+ return $install_info;
+}
+
+# Get the contents of the old cleanup file
+sub read_old_cleanup
+{
+ my ($path) = @_;
+ my ($text);
+
+ $text = read_file($path);
+ return parse_old_cleanup($text);
+}
+
+# Get the contents of an install info file
+sub read_install_info
+{
+ my ($path) = @_;
+ my ($text);
+
+ $text = read_file($path);
+ return parse_install_info($text);
+}
+
+# Get the contents of installation info from a directory.
+# Supports both the new install info format and the older
+# cleanup format. First checks for the presence of the newer
+# install info format file, if that's absent reads the older
+# cleanup format but returns it as the new install info hash table.
+sub read_install_info_from_dir
+{
+ my ($dir) = @_;
+ my ($path);
+
+ $path = "${dir}/${install_info_basename}";
+ if (-e $path) {
+ return read_install_info($path);
+ }
+
+ $path = "${dir}/${cleanup_basename}";
+ if (-e $path) {
+ return read_old_cleanup($path);
+ }
+
+ return undef;
+}
+
+# Give an install info hash table writes it formated as a
+# "Installation Manifest" into specified directory under
+# the name $install_info_basename
+#
+# Returns pathname of manifest if successful, undef otherwise.
+sub write_install_info_to_dir
+{
+ my ($dir, $install_info) = @_;
+ my ($path, $formatted);
+
+ if (! defined($dir)) {
+ emit("Cannot write installation manifest, directory unspecified", "error");
+ return undef;
+ }
+
+ if (! defined($install_info_basename)) {
+ emit("Cannot write installation manifest, file basename unspecified", "error");
+ return undef;
+ }
+
+ if (! -e $dir) {
+ emit("Cannot write installation manifest, directory ($dir) does not exist", "error");
+ return undef;
+ }
+
+ if (! -d $dir) {
+ emit("Cannot write installation manifest, directory ($dir) is not a directory", "error");
+ return undef;
+ }
+
+ if (! -w $dir) {
+ emit("Cannot write installation manifest, directory ($dir) is not writable", "error");
+ return undef;
+ }
+
+ $path = "${dir}/${install_info_basename}";
+ $formatted = format_install_info($install_info);
+ write_file($path, \$formatted);
+
+ return $path;
+}
+
+# Given an Installation Manifest (e.g. install_info) remove the items in
+# the manifest marked for removal.
+#
+# 1) Remove all files and symlinks we created.
+#
+# 2) Attempt to remove all directories we created, even if they are non-empty.
+#
+sub uninstall
+{
+ my ($install_info) = @_;
+ my ($result, @paths, @filtered_paths, $path, @dirs);
+
+ $result = 1;
+
+ @paths = sort(keys %$install_info);
+
+ # Get a list of files marked for removal.
+ @filtered_paths = grep {my ($info) = $install_info->{$_};
+ ($info->{'type'} eq 'file' || $info->{'type'} eq 'symlink') &&
+ $info->{'install_action'} ne 'remove' &&
+ $info->{'uninstall_action'} eq 'remove'} @paths;
+ # Remove the files
+ if (@filtered_paths) {
+ foreach $path (@filtered_paths) {
+ $result = 0 if !remove_file($path);
+ }
+ }
+
+ # Get a list of directories marked for removal.
+ @filtered_paths = grep {my ($info) = $install_info->{$_};
+ $info->{'type'} eq 'dir' &&
+ $info->{'uninstall_action'} eq 'remove'} @paths;
+
+ # We need to removed directories starting at the deepest level
+ # and progressively work upward, otherwise the directory might
+ # not be empty. To accomplish this we sort the directory array
+ # based on the number of path components.
+
+ # Primary sort by number of path components, longest first.
+ # When the number of path components is the same the secondary sort
+ # is lexical string comparision.
+ @dirs = sort {my ($r, @a, @b);
+ @a = split("/", $a);
+ @b = split("/", $b);
+ $r = @b <=> @a;
+ $r == 0 ? $a cmp $b : $r} @filtered_paths;
+
+ foreach $path (@dirs) {
+ $result = 0 if !remove_directory($path, 1);
+ }
+
+ return $result;
+}
+
+##############################################################
+# Generic "platform" Subroutines
+##############################################################
+
+# no args
+# return 1 - true, or
+# return 0 - false
+sub is_Windows
+{
+ if (($^O eq "Windows_NT") || ($^O eq "MSWin32")) {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+# no args
+# return 1 - true, or
+# return 0 - false
+sub is_Linux
+{
+ if ($^O eq "linux") {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+# no args
+# return 1 - true, or
+# return 0 - false
+sub is_Fedora
+{
+ if (is_Linux() && (-e "/etc/fedora-release")) {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+# no args
+# return 1 - true, or
+# return 0 - false
+sub is_RHEL {
+ if ((! is_Fedora()) && (-e "/etc/redhat-release")) {
+ return 1;
+ }
+
+ return 0;
+}
+
+
+# no args
+# return 1 - true, or
+# return 0 - false
+sub is_RHEL4 {
+ if (is_RHEL()) {
+ my $releasefd = new FileHandle;
+ if ($releasefd->open("< /etc/redhat-release")) {
+ while (defined(my $line = <$releasefd>)) {
+ if ($line =~ /Nahant/i) {
+ return 1;
+ }
+ }
+ }
+ }
+
+ return 0;
+}
+
+# no args
+# return release_number
+# return 0 if not found
+sub fedora_release {
+ my $releasefd = new FileHandle;
+ if ($releasefd->open("< /etc/fedora-release")) {
+ while (defined(my $line = <$releasefd>)) {
+ if ($line =~ /Fedora release (\d*)/) {
+ return $1;
+ }
+ }
+ }
+ return 0;
+}
+
+
+# no args
+# no return value
+sub setup_platform_dependent_parameters
+{
+ # Setup path separators, et. al., based upon platform
+ if (is_Windows()) {
+ $lib_prefix = "";
+ $obj_ext = ".dll";
+ $path_sep = ";";
+ $tmp_dir = "c:\\temp";
+ } elsif ($^O eq "hpux") {
+ $lib_prefix = "lib";
+ $obj_ext = ".sl";
+ $path_sep = ":";
+ $tmp_dir = "/tmp";
+ } else {
+ $lib_prefix = "lib";
+ $obj_ext = ".so";
+ $path_sep = ":";
+ $tmp_dir = "/tmp";
+ }
+
+ return;
+}
+
+
+# Takes an array reference containing a list of paths.
+# Any item in the list which is undefined will be ignored.
+# no return value
+sub set_library_path
+{
+ my ($paths) = @_;
+ my ($path);
+
+ $path = join($path_sep, grep(defined($_), @$paths));
+
+ if (is_Windows()) {
+ $ENV{'PATH'} = $path;
+ } elsif ($^O eq "hpux") {
+ $ENV{'SHLIB_PATH'} = $path;
+ } else {
+ $ENV{'LD_LIBRARY_PATH'} = $path;
+ }
+
+ return;
+}
+
+
+# no args
+# return Library Path Environment variable
+sub get_library_path
+{
+ if (is_Windows()) {
+ return $ENV{'PATH'};
+ } elsif ($^O eq "hpux") {
+ return $ENV{'SHLIB_PATH'};
+ } else {
+ return $ENV{'LD_LIBRARY_PATH'};
+ }
+}
+
+
+##############################################################
+# Generic "identity" Subroutines
+##############################################################
+
+# no args
+# return 1 - success, or
+# return 0 - failure
+sub check_for_root_UID
+{
+ my $result = 0;
+
+ # On Linux/UNIX, insure that this script is being run as "root";
+ # First check the "Real" UID, and then check the "Effective" UID.
+ if (!is_Windows()) {
+ if (($< != $ROOTUID) &&
+ ($> != $ROOTUID)) {
+ emit("This script must be run as root!\n", "error");
+ $result = 0;
+ } else {
+ # Success -- running script as root
+ $result = 1;
+ }
+ } else {
+ emit("Root UID makes no sense on Windows machines!\n", "error");
+ $result = 0;
+ }
+
+ return $result;
+}
+
+
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub user_exists
+{
+ my ($username) = @_;
+
+ return defined(getpwnam($username));
+}
+
+
+# Return 1 if success, 0 if failure
+sub create_user
+{
+ my ($username, $groupname) = @_;
+ my $command;
+
+ emit(sprintf("create_user(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ if (($username eq $PKI_USER) &&
+ ($groupname eq $PKI_GROUP)) {
+ # Attempt to create $PKI_USER with $PKI_UID
+ emit("create_user(): Adding default PKI user '$username' "
+ . "(uid=$PKI_UID) to '/etc/passwd'.\n", "debug");
+ if ($^O eq "linux") {
+ $command = "/usr/sbin/useradd "
+ . "-g $groupname "
+ . "-d /usr/share/pki "
+ . "-s /sbin/nologin "
+ . "-c 'Certificate System' "
+ . "-u $PKI_UID "
+ . "-r "
+ . $username;
+ } elsif ($^O eq "solaris") {
+ $command = "/usr/sbin/useradd "
+ . "-g $groupname "
+ . "-d /usr/share/pki "
+ . "-s /bin/false "
+ . "-c 'Certificate System' "
+ . "-u $PKI_UID "
+ . $username;
+ } else {
+ $command = "/usr/sbin/useradd "
+ . "-g $groupname "
+ . "-d /usr/share/pki "
+ . "-s '' "
+ . "-c 'Certificate System' "
+ . "-u $PKI_UID "
+ . $username;
+ }
+ } else {
+ # Attempt to create $username with random UID
+ emit("create_user(): Adding default PKI user '$username' "
+ . "(uid=random) to '/etc/passwd'.\n", "debug");
+ if ($^O eq "linux") {
+ $command = "/usr/sbin/useradd "
+ . "-g $groupname "
+ . "-d /usr/share/pki "
+ . "-s /sbin/nologin "
+ . "-c 'Certificate System' "
+ . $username;
+ } elsif ($^O eq "solaris") {
+ $command = "/usr/sbin/useradd "
+ . "-g $groupname "
+ . "-d /usr/share/pki "
+ . "-s /bin/false "
+ . "-c 'Certificate System' "
+ . $username;
+ } else {
+ $command = "/usr/sbin/useradd "
+ . "-g $groupname "
+ . "-d /usr/share/pki "
+ . "-s '' "
+ . "-c 'Certificate System' "
+ . $username;
+ }
+ }
+
+ return 0 if !run_command($command);
+ return user_exists($username);
+}
+
+
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub group_exists
+{
+ my ($groupname) = @_;
+
+ return defined(getgrnam($groupname));
+}
+
+
+# Return 1 if success, 0 if failure
+sub create_group
+{
+ my ($groupname) = @_;
+ my $command;
+
+ emit(sprintf("create_group(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ if ($groupname eq $PKI_GROUP) {
+ # Attempt to create $PKI_GROUP with $PKI_GID
+ emit("Adding default PKI group '$groupname' "
+ . "(gid=$PKI_GID) to '/etc/group'.\n", "debug");
+ if ($^O eq "linux") {
+ $command = "/usr/sbin/groupadd "
+ . "-g $PKI_GID "
+ . "-r "
+ . $groupname;
+ } elsif ($^O eq "solaris") {
+ $command = "/usr/sbin/groupadd "
+ . "-g $PKI_GID "
+ . $groupname;
+ } else {
+ $command = "/usr/sbin/groupadd "
+ . "-g $PKI_GID "
+ . $groupname;
+ }
+ } else {
+ # Attempt to create $groupname with random GID
+ emit("Adding default PKI group '$groupname' "
+ . "(gid=random) to '/etc/group'.\n", "debug");
+ if ($^O eq "linux") {
+ $command = "/usr/sbin/groupadd "
+ . $groupname;
+ } elsif ($^O eq "solaris") {
+ $command = "/usr/sbin/groupadd "
+ . $groupname;
+ } else {
+ $command = "/usr/sbin/groupadd "
+ . $groupname;
+ }
+ }
+
+ return 0 if !run_command($command);
+ return group_exists($groupname);
+}
+
+
+# return 1 - disallows shell, or
+# return 0 - allows shell
+sub user_disallows_shell
+{
+ my ($username) = @_;
+
+ my $result = 0;
+ my $sans_shell = "";
+
+ if ($^O eq "linux") {
+ $sans_shell="/sbin/nologin";
+ $result = 0;
+ } elsif ($^O eq "solaris") {
+ $sans_shell="/bin/false";
+ $result = 0;
+ } else {
+ $sans_shell="";
+ return 1;
+ }
+
+ if (!user_exists($username)) {
+ return $result;
+ }
+
+ my ($name, $passwd, $uid, $gid, $quota,
+ $comment, $gcos, $dir, $shell, $expire) = getpwnam($username);
+
+ if (!$shell) {
+ $result = 1;
+ } elsif ($shell eq $sans_shell) {
+ $result = 1;
+ } else {
+ # issue a warning and continue
+ emit("WARNING: Potential security hole - user '$username' is\n"
+ . " using '$shell' instead of '$sans_shell'!\n", "warning");
+ }
+
+ return $result;
+}
+
+
+# return 1 - is a member, or
+# return 0 - is NOT a member
+sub user_is_a_member_of_group
+{
+ my ($username, $groupname) = @_;
+
+ return 0 if !user_exists($username);
+ return 0 if !group_exists($groupname);
+
+ # The members list returned by getgrname may not contain the user's primary group.
+ # This is OS dependent and is typically the case when the primary gid is a
+ # "user private group". Therefore testing the group member list is insufficient,
+ # we must also test the primary group.
+ my ($pw_name, $pw_passwd, $pw_uid, $pw_gid) = getpwnam($username);
+ if (defined $pw_gid) {
+ my $primary_groupname = getgrgid($pw_gid);
+
+ return 1 if $primary_groupname eq $groupname;
+ }
+
+ # Now get the list of users in the specified group
+ # and test to see if the specified user is in that list.
+ my ($gr_name, $gr_passwd, $gr_gid, $gr_members) = getgrnam($groupname);
+ for my $member (split(' ', $gr_members)) {
+ return 1 if $member eq $username;
+ }
+
+ return 0;
+}
+
+
+# return 1 - success, or
+# return 0 - failure
+sub add_user_as_a_member_of_group
+{
+ my ($username, $groupname) = @_;
+
+ my $command = "";
+ my $result = 0;
+
+ emit(sprintf("add_user_as_a_member_of_group(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ return 0 if !user_exists($username);
+ return 0 if !group_exists($groupname);
+ return 1 if user_is_a_member_of_group($username, $groupname);
+
+ # Attempt to add user to be a member of group
+ emit("Adding user '$username' to be a member of group "
+ . "'$groupname'.\n", "debug");
+ if ($^O eq "linux") {
+ $command = "/usr/sbin/usermod "
+ . "-G $groupname "
+ . $username;
+ } elsif ($^O eq "solaris") {
+ $command = "/usr/sbin/usermod "
+ . "-G $groupname "
+ . $username;
+ } else {
+ $command = "/usr/sbin/usermod "
+ . "-G $groupname "
+ . $username;
+ }
+
+ return 0 if !run_command($command);
+ return user_is_a_member_of_group($username, $groupname);
+}
+
+
+# return UID, or
+# return (-1) - user is not in password file
+sub get_UID_from_username
+{
+ my ($username) = @_;
+
+ my ($name, $passwd, $uid) = getpwnam($username);
+
+ return $uid if defined($uid);
+ return (-1);
+ }
+
+
+# Return fully-qualified domain name (FQDN) given
+# either a hostname or an IP address
+sub get_FQDN
+{
+ my ($addr) = @_;
+
+ if (!$is_IPv6) {
+ if ($addr !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/) {
+ # Retrieve FQDN via a "mnemonic" hostname
+ ($fqdn) = gethostbyname($addr);
+ } else {
+ # Retrieve FQDN via a "4-tuple" IP address
+ $fqdn = gethostbyaddr(pack('C4', $1, $2, $3, $4), 2);
+ }
+ } else {
+ # IPv6: Don't rely upon "Socket6.pm" being present!
+ $fqdn = $addr;
+ }
+
+ return($fqdn);
+}
+
+
+##############################################################
+# Generic "availability" Subroutines
+##############################################################
+
+# return 1 - URL prefix is known (success)
+# return 0 - URL prefix is unknown (failure)
+sub check_for_valid_url_prefix
+{
+ my ($url_prefix) = @_;
+
+ if (($url_prefix eq $FILE_PREFIX) ||
+ ($url_prefix eq $FTP_PREFIX) ||
+ ($url_prefix eq $HTTP_PREFIX) ||
+ ($url_prefix eq $HTTPS_PREFIX) ||
+ ($url_prefix eq $LDAP_PREFIX) ||
+ ($url_prefix eq $LDAPS_PREFIX)) {
+ return 1;
+ }
+
+ return 0;
+}
+
+# return 1 - ports are valid (success)
+# return 0 - ports have a conflict (failure)
+sub AreConnectorPortsValid
+{
+ # parse parameters
+ my ($secure_port, $unsecure_port, $agent_secure_port,
+ $ee_secure_port, $admin_secure_port, $proxy_secure_port,
+ $proxy_unsecure_port, $ajp_port) = @_;
+
+
+ if ($secure_port == -1 && $agent_secure_port == -1)
+ {
+ return 0;
+ }
+
+ if ($secure_port >= 0 && $agent_secure_port >= 0)
+ {
+ return 0;
+ }
+
+ if ($secure_port >= 0)
+ {
+ if ($secure_port == $unsecure_port)
+ {
+ return 0;
+ }
+ return 1;
+ }
+
+ if (!portsUnique($agent_secure_port,$ee_secure_port, $admin_secure_port, $proxy_secure_port,
+ $proxy_unsecure_port, $ajp_port)) {
+ return 0;
+ }
+
+ return 1;
+
+}
+
+#return 1 - if non-negative ports are uique
+#return 0 - otherwise (failure)
+sub portsUnique
+{
+ my @ports = sort @_;
+ my $last_port = -1;
+ for my $port (@ports) {
+ next if ($port < 0);
+ if ($port == $last_port) {
+ return 0;
+ }
+ $last_port = $port;
+ }
+ return 1;
+}
+
+# return 1 - port is available (success)
+# return 0 - port is unavailable; report an error (failure)
+sub IsLocalPortAvailable
+{
+ # parse parameters
+ my ($user, $port) = @_;
+
+ # On Linux/UNIX, check well-known/reserved ports
+ if (!is_Windows()) {
+ my $uid = -1;
+
+ # retrieve the UID given the username
+ $uid = get_UID_from_username($user);
+ if ($uid == -1) {
+ emit("User '$user' is NOT in the password file!\n", "error");
+ return 0;
+ }
+
+ # insure that well-known ports cannot be used by a non-root user
+ if (($port <= $MAX_WELL_KNOWN_PORT) && ($uid != $ROOTUID)) {
+ emit("User '$user' is not allowed to bind to well-known "
+ . "port $port!\n", "error");
+ return 0;
+ }
+
+ # insure that reserved ports cannot be used by a non-root user
+ if (($port <= $MAX_RESERVED_PORT) && ($uid != $ROOTUID)) {
+ emit("User '$user' is not allowed to bind to reserved "
+ . "port $port!\n", "error");
+ return 0;
+ }
+
+ # insure that the user has not specified a port greater than
+ # the number of dynamic/private ports
+ if ($port > $MAX_DYNAMIC_PORT) {
+ emit("User '$user' is not allowed to bind to a "
+ . "port greater than $MAX_DYNAMIC_PORT!\n", "error");
+ return 0;
+ }
+
+ # if the user has specified a port greater than the number
+ # of registered ports, issue a warning and continue
+ if ($port > $MAX_REGISTERED_PORT) {
+ emit("WARNING: User '$user' is binding to port $port; use of "
+ . "a dynamic/private port is discouraged!\n", "warning");
+ }
+ }
+
+ # initialize local variables
+ my $rv = 0;
+ my $status = "AVAILABLE";
+
+ # make a local TCP server socket
+ my $proto = getprotobyname('tcp');
+ socket(SERVER, PF_INET, SOCK_STREAM, $proto);
+
+ # create a local server socket address
+ my $server_address = sockaddr_in($port, INADDR_ANY);
+
+ # attempt to bind this local server socket
+ # to this local server socket address
+ bind(SERVER, $server_address) or $status = $!;
+
+ # identify the status of this attempt to bind
+ if ($status eq "AVAILABLE") {
+ # this port is inactive
+ $rv = 1;
+ } elsif ($status eq "Address already in use") {
+ emit("Unable to bind to local port $port : $status\n", "error");
+ $rv = 0;
+ } else {
+ emit("Unable to bind to local port $port : $status\n", "error");
+ $rv = 0;
+ }
+
+ # close local server socket
+ close(SERVER);
+
+ # return result
+ return $rv;
+}
+
+
+# return 2 - warn that server is unreachable (continue)
+# return 1 - server is reachable (success)
+# return 0 - server is unreachable; report an error (failure)
+sub IsServerReachable
+{
+ # parse parameters
+ my ($prefix, $host, $port) = @_;
+
+ # check the validity of the prefix
+ my $result = 0;
+
+ $result = check_for_valid_url_prefix($prefix);
+ if (!$result) {
+ emit("Specified unknown url prefix '$prefix'!\n", "error");
+ return $result;
+ }
+
+ # create a URL from the passed-in parameters
+ my $url = $prefix . $host . ":" . $port;
+
+ # initialize the state of the Server referred to by this URL
+ my $rv = 0;
+ my $status = "ACTIVE";
+
+ # retrieve the remote host IP address
+ my $iaddr = inet_aton($host) or $status = $!;
+ if ($status ne "ACTIVE") {
+ emit("Unable to contact the Server at '$url' ($status)", "error");
+ return $rv;
+ }
+
+ # create a remote server socket address
+ my $server_address = sockaddr_in($port, $iaddr);
+
+ # make a local TCP client socket
+ my $proto = getprotobyname('tcp');
+ socket(CLIENT, PF_INET, SOCK_STREAM, $proto);
+
+ # attempt to connect this local client socket
+ # to the remote server socket address
+ connect(CLIENT, $server_address) or $status = $!;
+
+ # identify the status of this connection
+ if ($status eq "ACTIVE") {
+ # this '$host:$port' is reachable
+ $rv = 1;
+ } else {
+ emit("WARNING: Unable to contact the Server at '$url' ($status)", "warning");
+ }
+
+ # close local client socket
+ close(CLIENT);
+
+ # return result
+ return $rv;
+}
+
+
+##############################################################
+# Generic "time" Subroutines
+##############################################################
+
+# no args
+# return time stamp
+sub get_time_stamp
+{
+ my ($sec, $min, $hour, $mday,
+ $mon, $year, $wday, $yday, $isdst) = localtime(time);
+
+ my $stamp = sprintf "%4d-%02d-%02d %02d:%02d:%02d",
+ $year+1900, $mon+1, $mday, $hour, $min, $sec;
+
+ return $stamp;
+}
+
+
+##############################################################
+# Generic "random" Subroutines
+##############################################################
+
+# return random number between low & high
+sub generate_random
+{
+ my ($low, $high) = @_;
+
+ my $number = 0;
+
+ if ($low >= $high || $low < 0 || $high < 0) {
+ return -1;
+ }
+
+ $number = int(rand($high -$low +1)) + $low;
+
+ return $number;
+}
+
+
+# return random string of specified length
+sub generate_random_string
+{
+ my ($length_of_randomstring) = @_;
+
+ my @chars=('a'..'z','A'..'Z','0'..'9');
+ my $random_string;
+
+ foreach (1..$length_of_randomstring) {
+ $random_string .= $chars[rand @chars];
+ }
+
+ return $random_string;
+}
+
+
+##############################################################
+# Generic "password" Subroutines
+##############################################################
+
+# return 1 - success
+# return 0 - failure; report an error
+sub password_quality_checker
+{
+ my ($password) = @_;
+ my ($i, $letter);
+
+ # Test #1: $password MUST be > 8 characters
+ if (length($password) < 8) {
+ print("\n");
+ print("Password entered is less than 8 characters. Try again.\n");
+ return 0;
+ }
+
+
+ # Test #2: $password MUST contain at least one non-alphabetic character
+ my @alphabet = ("A", "B", "C", "D", "E", "F", "G", "H", "I", "J",
+ "K", "L", "M", "N", "O", "P", "Q", "R", "S", "T",
+ "U", "V", "W", "X", "Y", "Z", "a", "b", "c", "d",
+ "e", "f", "g", "h", "i", "j", "k", "l", "m", "n",
+ "o", "p", "q", "r", "s", "t", "u", "v", "w", "x",
+ "y", "z");
+
+ my $non_alphabetic_characters = 0;
+ for ($i = 0; $i < length($password); $i++) {
+ # always reset character type
+ my $found_alphabetic_character = 0;
+
+ # extract the next character from the $password
+ my $character = substr($password, $i, 1);
+
+ # check to see if this character is "alphabetic"
+ for $letter (@alphabet) {
+ if ($character eq $letter) {
+ $found_alphabetic_character = 1;
+ last;
+ }
+ }
+
+ # keep a count of "non-alphabetic" characters
+ if ($found_alphabetic_character == 0) {
+ $non_alphabetic_characters++;
+ }
+ }
+
+ # pass Test #2 if the $password contains any "non-alphabetic" characters
+ if ($non_alphabetic_characters > 0) {
+ return 1;
+ } else {
+ print("\n");
+ print("Password entered contains 0 non-alphabetic characters. "
+ . "Try again.\n");
+ return 0;
+ }
+}
+
+
+##############################################################
+# Generic "LDAP" Subroutines
+##############################################################
+
+# hostname - LDAP server name or IP address (default: localhost)
+# port - LDAP server TCP port number (default: 389)
+# password - bind passwd (for simple authentication)
+# file - read modifications from file (default: standard input)
+# no return value
+sub LDAP_add
+{
+ my ($tokendb_hostname, $tokendb_port, $tokendb_password, $file) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("LDAP_add(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ $command = "$default_ldapmodify_command "
+ . "-h '$tokendb_hostname' "
+ . "-p '$tokendb_port' "
+ . "-D 'cn=directory manager' "
+ . "-w '$tokendb_password' "
+ . "-a "
+ . "-f '$file'";
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# hostname - LDAP server name or IP address (default: localhost)
+# port - LDAP server TCP port number (default: 389)
+# password - bind passwd (for simple authentication)
+# file - read modifications from file (default: standard input)
+# no return value
+sub LDAP_modify
+{
+ my ($tokendb_hostname, $tokendb_port, $tokendb_password, $file) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("LDAP_modify(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ $command = "$default_ldapmodify_command "
+ . "-h '$tokendb_hostname' "
+ . "-p '$tokendb_port' "
+ . "-D 'cn=directory manager' "
+ . "-w '$tokendb_password' "
+ . "-f '$file'";
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+##############################################################
+# Generic "Security Databases" Subroutines
+##############################################################
+
+# instance path - Security databases directory (default is ~/.netscape)
+# password file - Specify the password file
+# no return value
+sub certutil_create_databases
+{
+ my ($instance_path, $pwdfile) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_create_databases(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ if (!$pwdfile) {
+ $command = "$default_certutil_command "
+ . "-N "
+ . "-d $instance_path";
+ } else {
+ $command = "$default_certutil_command "
+ . "-N "
+ . "-d $instance_path "
+ . "-f $pwdfile";
+ }
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Name of token in which to look for cert (default is internal,
+# use "all" to look for cert on all tokens)
+# nickname - The nickname of the cert to delete
+# no return value
+sub certutil_delete_cert
+{
+ my ($instance_path, $token, $nickname) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_delete_cert(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ $command = "$default_certutil_command "
+ . "-D "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-n '$nickname'";
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Name of token in which to generate key (default is internal)
+# subject - Specify the subject name (using RFC1485)
+# password file - Specify the password file
+# no return value
+sub certutil_generate_CSR
+{
+ my ($instance_path, $token, $subject, $pwdfile) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_generate_CSR(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ if (!$pwdfile) {
+ $command = "$default_certutil_command "
+ . "-R "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-s '$subject' "
+ . "-a";
+ } else {
+ $command = "$default_certutil_command "
+ . "-R "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-s '$subject' "
+ . "-a "
+ . "-f $pwdfile";
+ }
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Name of token in which to store the certificate
+# (default is internal)
+# serial number - Cert serial number
+# validity period - Months valid (default is 3)
+# subject - Specify the subject name (using RFC1485)
+# issuer name - The nickname of the issuer cert
+# nickname - Specify the nickname of the server certificate
+# trust args - Set the certificate trust attributes:
+# p valid peer
+# P trusted peer (implies p)
+# c valid CA
+# T trusted CA to issue client certs (implies c)
+# C trusted CA to issue server certs (implies c)
+# u user cert
+# w send warning
+# g make step-up cert
+# noise file - Specify the noise file to be used
+# (to introduce randomness during key generation)
+# password file - Specify the password file
+# no return value
+sub certutil_generate_self_signed_cert
+{
+ my ($instance_path, $token, $serial_number, $validity_period,
+ $subject, $issuer_name, $nickname, $trustargs, $noise_file,
+ $pwdfile) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_generate_self_signed_cert(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ if (!$pwdfile) {
+ $command = "$default_certutil_command "
+ . "-S "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-m $serial_number "
+ . "-v $validity_period "
+ . "-x "
+ . "-s '$subject' "
+ . "-c '$issuer_name' "
+ . "-n '$nickname' "
+ . "-t '$trustargs' "
+ . "-z $noise_file "
+ . "> /dev/null "
+ . "2>&1";
+ } else {
+ $command = "$default_certutil_command "
+ . "-S "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-f $pwdfile "
+ . "-m $serial_number "
+ . "-v $validity_period "
+ . "-x "
+ . "-s '$subject' "
+ . "-c '$issuer_name' "
+ . "-n '$nickname' "
+ . "-t '$trustargs' "
+ . "-z $noise_file "
+ . "> /dev/null "
+ . "2>&1";
+ }
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Name of token in which to store the certificate
+# (default is internal)
+# nickname - Specify the nickname of the server certificate
+# trust args - Set the certificate trust attributes:
+# p valid peer
+# P trusted peer (implies p)
+# c valid CA
+# T trusted CA to issue client certs (implies c)
+# C trusted CA to issue server certs (implies c)
+# u user cert
+# w send warning
+# g make step-up cert
+# (e. g. - Server Cert 'u,u,u', CA Cert 'CT,CT,CT')
+# cert - The certificate encoded in ASCII (RFC1113)
+# no return value
+sub certutil_import_cert
+{
+ my ($instance_path, $token, $nickname, $trustargs, $cert) = @_;
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_import_cert(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ open(F,
+ "|$default_certutil_command "
+ . "-A "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-n '$nickname' "
+ . "-t '$trustargs' "
+ . "-a");
+ print(F $cert);
+ close(F);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Name of token in which to look for cert (default is internal,
+# use "all" to look for cert on all tokens)
+# nickname - Pretty print named cert (list all if unspecified)
+# no return value
+sub certutil_print_cert
+{
+ my ($instance_path, $token, $nickname) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_print_cert(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ if ($token) {
+ # Raidzilla Bug #57616 - certutil is not being consistent, nickname
+ # requires token name for no reason.
+ $command = "$default_certutil_command "
+ . "-L "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-n '$token:$nickname'";
+ } else {
+ $command = "$default_certutil_command "
+ . "-L "
+ . "-d $instance_path "
+ . "-h '$token' "
+ . "-n '$nickname'";
+ }
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# no return value
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Name of token in which to look for certs (default is internal,
+# use "all" to list certs on all tokens)
+sub certutil_list_certs
+{
+ my ($instance_path, $token) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("certutil_list_certs(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ $command = "$default_certutil_command "
+ . "-L "
+ . "-d $instance_path "
+ . "-h '$token'";
+
+ system($command);
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+# instance path - Security databases directory (default is ~/.netscape)
+# token - Add the named token to the module database
+# library - The name of the file (.so or .dll) containing the
+# implementation of PKCS #11
+# no return value
+sub modutil_add_token
+{
+ my ($instance_path, $token, $library) = @_;
+
+ my $command = "";
+
+ my $original_library_path = get_library_path();
+
+ emit(sprintf("modutil_add_token(%s)\n", join(", ", @_)), "debug");
+
+ return if $dry_run;
+
+ set_library_path([$default_security_libraries,
+ $default_system_user_libraries,
+ $default_system_libraries,
+ $original_library_path]);
+
+ $command = "$default_modutil_command "
+ . "-force "
+ . "-dbdir $instance_path "
+ . "-add $token "
+ . "-libfile $library "
+ . "-nocertdb";
+
+ system("$command > /dev/null 2>&1");
+
+ set_library_path([$original_library_path]);
+
+ return;
+}
+
+
+##############################################################
+# Generic "logging" Subroutines
+##############################################################
+
+# Return 1 if success, 0 if failure
+sub open_logfile
+{
+ my ($path, $permissions, $owner, $group) = @_;
+
+
+ $logfd = FileHandle->new("> $path");
+
+ if (defined($logfd)) {
+ $logfile_path = $path;
+ } else {
+ return 0;
+ }
+
+ if (defined($permissions)) {
+ return 0 if !set_permissions($logfile_path, $permissions);
+ }
+
+ if (defined($owner) && defined($group)) {
+ return 0 if !set_owner_group($logfile_path, $owner, $group);
+ }
+
+ return 1;
+}
+
+# no return value
+sub get_logfile_path
+{
+ return $logfile_path;
+}
+
+# no return value
+sub close_logfile
+{
+ if (defined($logfd)) {
+ $logfd->close();
+ }
+
+ $logfd = undef;
+ return;
+}
+
+
+##############################################################
+# Generic "response" Subroutines
+##############################################################
+
+# return answer
+sub prompt
+{
+ my ($promptStr) = @_;
+
+ my $answer = "";
+
+ print(STDOUT "$promptStr ");
+
+ $| = 1;
+ $answer = <STDIN>;
+
+ chomp $answer;
+
+ print(STDOUT "\n");
+
+ return $answer;
+}
+
+
+##############################################################
+# Generic "reply" Subroutines
+##############################################################
+
+# no return value
+sub printFile
+{
+ my ($fileHandle) = @_;
+
+ while (<$fileHandle>) {
+ my $line = $_;
+ chomp($line);
+ print(STDOUT "$line\n");
+ }
+
+ return;
+}
+
+
+# no return value
+sub emit
+{
+ my ($string, $type) = @_;
+
+ my $force_emit = 0;
+ my $log_entry = "";
+
+ $type = "debug" if !defined($type);
+
+ if ($type eq "error" || $type eq "warning" || $type eq "info") {
+ $force_emit = 1;
+ }
+
+ return if !$string;
+
+ chomp($string);
+ my $stamp = get_time_stamp();
+
+ if ($verbose || $force_emit) {
+ # print to stdout
+ if ($type ne "log") {
+ print(STDERR "[$type] $string\n");
+ }
+ }
+
+ # If a log file exists, write all types
+ # ("debug", "error", "info", or "log")
+ # to this specified log file
+ if (defined($logfd)) {
+ $log_entry = "[$stamp] [$type] $string\n";
+ $logfd->print($log_entry);
+ }
+
+ return;
+}
+
+
+##############################################################
+# Generic "validity" Subroutines
+##############################################################
+
+# return 1 - valid, or
+# return 0 - invalid
+sub is_path_valid
+{
+ my ($path) = @_;
+
+ my @pathname = split("/", $path);
+
+ shift @pathname unless $pathname[0];
+
+ my $valid = 0;
+ my $split_path;
+
+ foreach $split_path (@pathname) {
+ chomp($split_path);
+
+ if (!($split_path !~ /^[-_.a-zA-Z0-9\[\]\@]+$/)) {
+ $valid = 1;
+ } else {
+ $valid = 0;
+ last;
+ }
+ }
+
+ return $valid;
+}
+
+
+# return 1 - valid, or
+# return 0 - invalid
+sub is_name_valid
+{
+ my ($name) = @_;
+
+ my $result = 0;
+
+ if (!($name !~ /^[-_.a-zA-Z0-9]+$/)) {
+ $result = 1;
+ }
+
+ return $result;
+}
+
+
+##############################################################
+# Generic "entity" Subroutines
+##############################################################
+
+# return type of entity
+sub entity_type
+{
+ my ($entity) = @_;
+
+ if (-b $entity) {
+ return "block special file";
+ } elsif (-c $entity) {
+ return "character special file";
+ } elsif (-d $entity) {
+ return "directory";
+ } elsif (-f $entity) {
+ if (-B $entity) {
+ return "binary file";
+ } elsif (-T $entity) {
+ return "text file";
+ } else {
+ return "plain file";
+ }
+ } elsif (-l $entity) {
+ return "symbolic link";
+ } elsif (-p $entity) {
+ return "named pipe";
+ } elsif (-S $entity) {
+ return "socket";
+ }
+
+ return "UNKNOWN";
+}
+
+
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub entity_exists
+{
+ my ($entity) = @_;
+
+ my $result = 0;
+
+ if (-e $entity) {
+ my $type = entity_type($entity);
+ $result = 1;
+ }
+
+ return $result;
+}
+
+
+##############################################################
+# Generic "file" Subroutines
+##############################################################
+
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub file_exists
+{
+ my ($file) = @_;
+
+ my $result = 0;
+
+ if (-f $file) {
+ $result = 1;
+ } elsif (-e $file) {
+ my $type = entity_type($file);
+ emit("File $file DOES NOT exist because $file is a $type!\n",
+ "error");
+ $result = 0;
+ }
+
+
+ return $result;
+}
+
+
+# return 1 - empty, or
+# return 0 - NOT empty
+sub is_file_empty
+{
+ my ($file) = @_;
+
+ my $result = 0;
+
+ if (-z $file) {
+ $result = 1;
+ }
+
+ return $result;
+}
+
+
+# Return 1 if success, 0 if failure
+sub create_empty_file
+{
+ my ($path, $permissions, $owner, $group, $uninstall_action) = @_;
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+
+ emit(sprintf("create_empty_file(%s, %s, %s, %s, %s)\n",
+ $path,
+ defined($permissions) ? sprintf("%o", $permissions) : "",
+ $owner, $group, $uninstall_action), "debug");
+
+ add_install_info($path, 'file', $uninstall_action);
+
+ if (!$dry_run) {
+ if (!open(FILE, "> $path")) {
+ emit("Cannot create empty file \"$path\" ($!)", 'error');
+ return 0;
+ }
+ close(FILE);
+ }
+
+ if (defined($permissions)) {
+ return 0 if !set_permissions($path, $permissions);
+ }
+
+ if (defined($owner) && defined($group)) {
+ return 0 if !set_owner_group($path, $owner, $group);
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub create_file
+{
+ my ($path, $contents, $permissions, $owner, $group, $uninstall_action) = @_;
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+
+ emit(sprintf("create_file(%s, %s, %s, %s, %s)\n",
+ $path,
+ defined($permissions) ? sprintf("%o", $permissions) : "",
+ $owner, $group, $uninstall_action), "debug");
+
+ add_install_info($path, 'file', $uninstall_action);
+
+ if (!$dry_run) {
+ if (!open(FILE, "> $path")) {
+ emit("could not create file \"$path\" ($!)\n", 'error');
+ return 0;
+ }
+ print(FILE $contents);
+ close(FILE);
+ }
+
+ if (defined($permissions)) {
+ return 0 if !set_permissions($path, $permissions);
+ }
+
+ if (defined($owner) && defined($group)) {
+ return 0 if !set_owner_group($path, $owner, $group);
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub copy_file
+{
+ my ($src_path, $dst_path, $permissions, $owner, $group, $uninstall_action) = @_;
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+
+ emit(sprintf("copy_file(%s, %s, %s, %s, %s, %s)\n",
+ $src_path, $dst_path,
+ defined($permissions) ? sprintf("%o", $permissions) : "",
+ $owner, $group, $uninstall_action), "debug");
+
+ add_install_info($dst_path, 'file', $uninstall_action);
+
+ if (!is_path_valid($src_path)) {
+ emit("copy_file(): illegal src path => \"$src_path\".\n",
+ "error");
+ remove_install_info($dst_path);
+ return 0;
+ }
+
+ if (!is_path_valid($dst_path)) {
+ emit("copy_file(): illegal dst path => \"$dst_path\".\n",
+ "error");
+ remove_install_info($dst_path);
+ return 0;
+ }
+
+ if (!$dry_run) {
+ if (!copy($src_path, $dst_path)) {
+ emit("copy_file(): \"$src_path\" => \"$dst_path\" ($!)\n", "error");
+ remove_install_info($dst_path);
+ return 0;
+ }
+ }
+
+ if (defined($permissions)) {
+ return 0 if !set_permissions($dst_path, $permissions);
+ }
+
+ if (defined($owner) && defined($group)) {
+ return 0 if !set_owner_group($dst_path, $owner, $group);
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub remove_file
+{
+ my ($path) = @_;
+ my $result = 0;
+
+ emit(sprintf("remove_file(%s)\n", join(", ", @_)), "debug");
+
+ add_install_info($path, 'file', 'remove', 'remove');
+
+ return 1 if $dry_run;
+
+ if (!unlink($path)) {
+ emit("remove_file(): failed to remove file \"$path\" ($!)\n", "error");
+ return 0;
+ }
+
+ return 1;
+ }
+
+# set_permissions(path_glob, permissions)
+# Return 1 if success, 0 if failure
+sub set_permissions
+{
+ my ($path_glob, $permissions) = @_;
+ my (@paths, $errstr, $result, $count);
+
+ $errstr = undef;
+ $count = 0;
+ $result = 1;
+
+ emit(sprintf("set_permissions(%s, %s)\n",
+ $path_glob,
+ defined($permissions) ? sprintf("%o", $permissions) : ""), "debug");
+
+ return 1 if $dry_run;
+
+ @paths = glob($path_glob);
+
+ if (($count = chmod($permissions, @paths)) != @paths) {
+ $errstr = "$!";
+ $result = 0;
+ emit(sprintf("failed to set permission (%o) on \"%s\" => (%s), %d out of %d failed, \"%s\"\n",
+ $permissions, $path_glob, "@paths", @paths - $count, @paths+0, $errstr), 'error');
+ }
+ return $result;
+ }
+
+# set_owner_group(path_glob, owner, group)
+# Return 1 if success, 0 if failure
+sub set_owner_group
+{
+ my ($path_glob, $owner, $group) = @_;
+ my (@paths, $errstr, $result, $count);
+ my ($uid, $gid);
+
+ $errstr = undef;
+ $count = 0;
+ $result = 1;
+
+ emit(sprintf("set_owner_group(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ $uid = getpwnam($owner);
+ $gid = getgrnam($group);
+ @paths = glob($path_glob);
+
+ if (($count = chown($uid, $gid, @paths)) != @paths) {
+ $errstr = "$!";
+ $result = 0;
+ emit(sprintf("failed to set ownership (%s) on \"%s\" => (%s), %d out of %d failed, \"%s\"\n",
+ "${owner}:${group}", $path_glob, "@paths", @paths - $count, @paths+0, $errstr), 'error');
+ }
+ return $result;
+}
+
+# set_file_props(path_glob, permissions, owner, group)
+# Return 1 if success, 0 if failure
+sub set_file_props
+{
+ my ($path_glob, $permissions, $owner, $group) = @_;
+ my (@paths, $tmp_result, $result);
+
+ $result = 1;
+
+ emit(sprintf("set_file_props(%s %s %s %s)\n",
+ $path_glob,
+ defined($permissions) ? sprintf("%o", $permissions) : "",
+ $owner, $group), "debug");
+
+ return 1 if $dry_run;
+
+ $tmp_result = set_permissions($path_glob, $permissions);
+ $result = 0 if !$tmp_result;
+
+ $tmp_result = set_owner_group($path_glob, $owner, $group);
+ $result = 0 if !$tmp_result;
+
+ return $result;
+ }
+
+
+
+##############################################################
+# Generic "directory" Subroutines
+##############################################################
+
+# Callback for walk_dir(), see walk_dir() for documentation
+sub walk_callback {
+ my ($dir, $basename, $is_dir, $prune, $opts) = @_;
+
+ if ($is_dir) {
+ my ($include_dirs, $mark_dir, $add_to_list, $regexp, $regexps);
+
+ # Don't descend into directories unless recursive.
+ $$prune = ! $opts->{'recursive'};
+
+ # If include filter is provided, basename must match
+ # at least one regexp in filter list.
+ if (defined($regexps = $opts->{'dir_includes'})) {
+ $add_to_list = 0;
+ for $regexp (@$regexps) {
+ if ($basename =~ /$regexp/) {
+ $add_to_list = 1;
+ last;
+ }
+ }
+ } else {
+ $add_to_list = 1;
+ }
+
+ if (!$add_to_list) {
+ $$prune = 1;
+ return;
+ }
+
+ # If exclude filter is provided, basename cannot match
+ # any regexp in filter list.
+ if (defined($regexps = $opts->{'dir_excludes'})) {
+ for $regexp (@$regexps) {
+ if ($basename =~ /$regexp/) {
+ $add_to_list = 0;
+ last;
+ }
+ }
+ }
+
+ if (!$add_to_list) {
+ $$prune = 1;
+ return;
+ }
+
+ # Are we collecting directories?
+ $include_dirs = $opts->{'include_dirs'} // 0;
+ return if ! $include_dirs;
+
+ if ($opts->{'mark_dir'}) {
+ push(@{$opts->{'file_list'}}, "${dir}/${basename}/");
+ } else {
+ push(@{$opts->{'file_list'}}, "${dir}/${basename}");
+ }
+ }
+ else {
+ my ($include_files, $add_to_list, $regexp, $regexps);
+
+ # If include filter is provided, basename must match
+ # at least one regexp in filter list.
+ if (defined($regexps = $opts->{'file_includes'})) {
+ $add_to_list = 0;
+ for $regexp (@$regexps) {
+ if ($basename =~ /$regexp/) {
+ $add_to_list = 1;
+ last;
+ }
+ }
+ } else {
+ $add_to_list = 1;
+ }
+
+ return if !$add_to_list;
+
+ # If exclude filter is provided, basename cannot match
+ # any regexp in filter list.
+ if (defined($regexps = $opts->{'file_excludes'})) {
+ for $regexp (@$regexps) {
+ if ($basename =~ /$regexp/) {
+ $add_to_list = 0;
+ last;
+ }
+ }
+ }
+
+ return if !$add_to_list;
+
+ # Are we collecting files?
+ $include_files = $opts->{'include_files'} // 0;
+ return if ! $include_files;
+
+ push(@{$opts->{'file_list'}}, "${dir}/${basename}");
+ }
+}
+
+# Walk directory structure invoking a callback on each
+# item found. Optionally prune traversal.
+#
+# walk_dir($dir, $callback, $prune, $user_data)
+#
+# dir Path of directory to examine.
+# callback Pointer to callback function.
+# prune Pointer to boolean variable.
+# Callback can set to avoid descending into a directory.
+# Ignored for non-directory callback invocations.
+# opts Hash table of key/value pairs which controls execution and
+# can be used to pass user values to the walk callback.
+# See get_directory_files() for definitions.
+#
+# The signature of the callback is:
+#
+# callback($dir, $basename, $is_dir, $prune, $user_data)
+#
+# dir Current directory path.
+# basename Entry in directory.
+# is_dir Boolean, true if basename is a directory
+# prune Pointer to boolean variable.
+# Callback can set to avoid descending into a directory.
+# Ignored for non-directory callback invocations.
+# opts Hash table of key/value pairs which controls execution and
+# can be used to pass user values to the walk callback.
+# See get_directory_files() for definitions.
+#
+sub walk_dir {
+ my ($dir, $callback, $prune, $opts) = @_;
+ my ($basename);
+
+ # Get the list of files in the current directory.
+ opendir(DIR, $dir) || (warn "Can't open $dir: $!\n", return);
+ my (@entries) = sort readdir(DIR);
+ closedir(DIR);
+
+ foreach $basename (@entries) {
+ next if $basename eq '.';
+ next if $basename eq '..';
+ $$prune = 0;
+
+ my $path = "${dir}/${basename}";
+ if ((-d $path) &&
+ ((! $opts->{'preserve_links'}) || (! -l $path))) { # yes it is a directory
+ &$callback($dir, $basename, 1, $prune, $opts);
+ if (!$$prune) {
+ walk_dir($path, $callback, $prune, $opts);
+ }
+ }
+ else { # not a directory
+ &$callback($dir, $basename, 0, $prune, $opts);
+ last if $$prune;
+ }
+ }
+}
+
+# Given a directory path return a sorted array of it's contents.
+# The opts parameter is a hash of key/value pairs which controls
+# execution and can be used to pass user values to the walk callback.
+#
+# The options are:
+#
+# strip_dir (default = false)
+# If true strip the leading $dir from returned paths,
+# otherwise preserve $dir in each returned path.
+# recursive (default = true)
+# If true then recusively descend into each directory,
+# otherwise just examine the starting directory
+# preserve_links (default = true)
+# If true symbolic links are preserved.
+# If false symbolic links are traversed.
+# include_dirs (default = false)
+# If true include directories in the returned array,
+# otherwise directories are omitted.
+# include_files (default = true)
+# If true include files in the returned array,
+# otherwise files are omitted.
+# mark_dir (default = false)
+# If true paths which are directories (include_dirs must be true)
+# are indicated by a trailing slash, otherwise the basename of
+# the directory is left bare.
+#
+# Filtering
+#
+# You may specify a set of include/exclude filters on both directories and
+# files. An entry will be added to the returned list if it's in the include
+# list and not in the exclude list. If either the include or exclude list
+# is undefined it has no effect. Each filter is an array of regular
+# expressions. The basename (directory entry) is tested against the regular
+# expression. For the include filter the basename must match at least one
+# of the regular expressions. For the exclude filter if the basename
+# matches any of the regular expressions it will be excluded.
+#
+# In addition if the traversal is recursive and a directory is excluded via
+# filtering then that directory is not descended into during the recursive
+# traversal.
+#
+# dir_includes (default = undef)
+# Array of regular expressions. If defined a directory must match at
+# least one regular expression in the array to be included.
+# dir_excludes (default = undef)
+# Array of regular expressions. If defined a directory will be excluded
+# if it matches any regular expression in the array.
+# file_includes (default = undef)
+# Array of regular expressions. If defined a file must match at
+# least one regular expression in the array to be included.
+# file_excludes (default = undef)
+# Array of regular expressions. If defined a file will be excluded
+# if it matches any regular expression in the array.
+#
+sub get_directory_files
+{
+ my ($dir, $opts) = @_;
+ my ($strip_dir, $mark_dir, $recursive, $preserve_links, $include_dirs, $include_files);
+ my ($dir_includes, $dir_excludes, $file_includes, $file_excludes);
+ my ($files, $prune, $pat);
+
+ $strip_dir = $opts->{'strip_dir'} // 0;
+ $mark_dir = $opts->{'mark_dir'} // 0;
+ $recursive = $opts->{'recursive'} // 1;
+ $preserve_links = $opts->{'preserve_links'} // 1;
+ $include_dirs = $opts->{'include_dirs'} // 0;
+ $include_files = $opts->{'include_files'} // 1;
+ $dir_includes = $opts->{'dir_includes'} // undef;
+ $dir_excludes = $opts->{'dir_excludes'} // undef;
+ $file_includes = $opts->{'file_includes'} // undef;
+ $file_excludes = $opts->{'file_excludes'} // undef;
+
+ $files = [];
+ $prune = 0;
+
+ walk_dir($dir, \&walk_callback, \$prune,
+ {'file_list' => $files,
+ 'mark_dir' => $mark_dir,
+ 'recursive' => $recursive,
+ 'preserve_links' => $preserve_links,
+ 'include_dirs' => $include_dirs,
+ 'include_files' => $include_files,
+ 'dir_includes' => $dir_includes,
+ 'dir_excludes' => $dir_excludes,
+ 'file_includes' => $file_includes,
+ 'file_excludes' => $file_excludes,
+ });
+
+ if ($strip_dir) {
+ $pat = "^${dir}/";
+ map {s/$pat//; $_} @$files;
+ }
+
+ return $files;
+}
+
+# Normalize paths such that:
+# Multiple slashes are collapsed into one slash
+# Trailing slash is stripped.
+# Strip "." path components.
+# Strip previous path component for ".."
+# Returns normalized path.
+sub normalize_path
+{
+ my ($path) = @_;
+ my (@src_components, @dst_components, $component, $leading_slash, $new_path);
+
+ $leading_slash = $path =~ m!^/! ? "/" : "";
+
+ @src_components = split("/", $path);
+
+ foreach $component (@src_components) {
+ next if !$component;
+ next if $component eq ".";
+ if ($component eq "..") {
+ die "no directory component to pop \"..\" for in \"$path\"" if !@dst_components;
+ pop @dst_components;
+ next;
+ }
+ push @dst_components, $component;
+ }
+
+ $new_path = join("/", @dst_components);
+
+ return $leading_slash . $new_path;
+}
+
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub directory_exists
+{
+ my ($dir) = @_;
+
+ my $result = 0;
+
+ if (-d $dir) {
+ $result = 1;
+ } elsif (-e $dir) {
+ my $type = entity_type($dir);
+ emit("Directory $dir DOES NOT exist because $dir is a $type!\n",
+ "error");
+ $result = 0;
+ }
+
+ return $result;
+}
+
+
+# return 1 - empty, or
+# return 0 - NOT empty
+sub is_directory_empty
+{
+ my ($dir) = @_;
+
+ my $empty = 1;
+ my $entity = "";
+
+ if (!directory_exists($dir)) {
+ return 1;
+ }
+
+ opendir(DIR, $dir);
+ while (defined($entity = readdir(DIR)) && ($empty == 1)) {
+ if ($entity ne "." && $entity ne "..") {
+ # NOTE: This is not necessarily an error!
+ #
+ # my $type = entity_type("$dir/$entity");
+ # emit(" Found $type $entity in directory $dir.\n",
+ # "debug");
+
+ $empty = 0;
+ }
+ }
+ closedir(DIR);
+
+ return $empty;
+}
+
+
+# Return 1 if success, 0 if failure
+sub create_directory
+{
+ my ($dir, $permissions, $owner, $group, $uninstall_action) = @_;
+ my $result = 1;
+ my $errors;
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+
+ emit(sprintf("create_directory(%s, %s, %s, %s, %s)\n",
+ $dir,
+ defined($permissions) ? sprintf("%o", $permissions) : "",
+ $owner, $group, $uninstall_action), "debug");
+
+ add_install_info($dir, 'dir', $uninstall_action);
+
+ return 1 if $dry_run;
+
+ if (!directory_exists($dir)) {
+ make_path($dir, {error => \$errors});
+ if (@$errors) {
+ my ($error, $path, $errstr);
+ $result = 0;
+ for $error (@$errors) {
+ ($path, $errstr) = %$error;
+ if ($path eq '') {
+ emit("create_directory(): dir=\"$dir\" \"$errstr\"\n", "error");
+}
+ else {
+ remove_install_info($path);
+ emit("create_directory(): dir=\"$dir\" path=\"$path\" \"$errstr\"\n", "error");
+ }
+ }
+ }
+ }
+
+ if ($result) {
+ if (defined($permissions)) {
+ return 0 if !set_permissions($dir, $permissions);
+ }
+
+ if (defined($owner) && defined($group)) {
+ return 0 if !set_owner_group($dir, $owner, $group);
+ }
+ }
+
+ return $result;
+}
+
+# Return 1 if success, 0 if failure
+sub copy_directory
+{
+ my ($src_dir_path, $dst_dir_path,
+ $dir_permissions, $file_permissions,
+ $owner, $group, $uninstall_action) = @_;
+ my($result);
+ my ($files, $sub_dirs, $path, $src_path, $dst_path);
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+ $result = 1;
+
+ $src_dir_path = normalize_path($src_dir_path);
+ $dst_dir_path = normalize_path($dst_dir_path);
+
+ emit(sprintf("copy_directory(%s, %s, %s, %s, %s, %s, %s)\n",
+ $src_dir_path, $dst_dir_path,
+ defined($dir_permissions) ? sprintf("%o", $dir_permissions) : "",
+ defined($dir_permissions) ? sprintf("%o", $dir_permissions) : "",
+ $owner, $group, $uninstall_action), "debug");
+
+ if (!is_path_valid($src_dir_path)) {
+ emit("copy_directory(): illegal src path => $src_dir_path.\n",
+ "error");
+ return 0;
+ }
+
+ if (!is_path_valid($dst_dir_path)) {
+ emit("copy_directory(): illegal dst path ($dst_dir_path)\n", "error");
+ return 0;
+ }
+
+ if (!directory_exists($src_dir_path)) {
+ # Take the case where this directory does not exist
+ # Just return true
+ emit("copy_directory(): non-existent src path ($src_dir_path)\n", "error");
+ return 1;
+ }
+
+ # Get list of directories under the src dir
+ $sub_dirs = get_directory_files($src_dir_path,
+ {'strip_dir' => 1, 'include_dirs' => 1, 'include_files' => 0});
+
+ # Get list of files under the src dir
+ $files = get_directory_files($src_dir_path,
+ {'strip_dir' => 1, 'include_dirs' => 0, 'include_files' => 1});
+
+ # Assure each destination directory exists
+ return 0 if !create_directory($dst_dir_path,
+ $dir_permissions, $owner, $group, $uninstall_action);
+ for $path (@$sub_dirs) {
+ $dst_path = "${dst_dir_path}/${path}";
+ return 0 if !create_directory($dst_path, $dir_permissions,
+ $owner, $group, $uninstall_action);
+ }
+
+ # Copy each file
+ for $path (@$files) {
+ $src_path = "${src_dir_path}/${path}";
+ $dst_path = "${dst_dir_path}/${path}";
+
+ # Emulate cp's behavior with respect to symbolic links,
+ # symbolic links are NOT followed when copying recursively.
+ # During recursive copies symbolic links are recreated.
+ if (-l $src_path) { # src is a symbolic link
+ if (!copy_symlink($src_path, $dst_path,
+ $owner, $group, $uninstall_action)) {
+ $result = 0;
+ }
+ } else { # src is not a symbolic link
+ if (!copy_file($src_path, $dst_path,
+ $file_permissions, $owner, $group, $uninstall_action)) {
+ $result = 0;
+ }
+ }
+ }
+
+ if (!$result) {
+ emit("copy_directory(): failed $src_dir_path => $dst_dir_path.\n",
+ "error");
+ }
+
+ return $result;
+}
+
+
+# Removes given directory. By default only the directory is removed and
+# only if it is empty. To remove the directory and all of it's contents
+# you must provide the $remove_contents parameter and set it to true,
+# it defaults to false.
+#
+# Return 1 if success, 0 if failure
+sub remove_directory
+{
+ my($dir, $remove_contents) = @_;
+ my($errors, $result);
+
+ emit(sprintf("remove_directory(%s)\n", join(", ", @_)), "debug");
+
+ $remove_contents = 0 unless defined($remove_contents);
+ $result = 1;
+
+ add_install_info($dir, 'dir', 'remove', 'remove');
+
+ return 1 if $dry_run;
+
+ if (!is_path_valid($dir)) {
+ emit("remove_directory(): specified invalid directory $dir.\n",
+ "error");
+ return 0;
+ }
+
+ if ($dir eq "/") {
+ emit("remove_directory(): don't even think about removing root!.\n",
+ "error");
+ return 0;
+ }
+
+ if (!directory_exists($dir)) {
+ return 1;
+ }
+
+ if ($remove_contents) {
+ remove_tree($dir, {error => \$errors});
+ if (@$errors) {
+ my($error, $path, $errstr);
+ $result = 0;
+ for $error (@$errors) {
+ ($path, $errstr) = %$error;
+ if ($path eq '') {
+ emit("remove_directory(): tree=\"$dir\" ($errstr)\n", "error");
+ }
+ else {
+ emit("remove_directory(): tree=\"$dir\" path=\"$path\" ($errstr)\n", "error");
+ }
+ }
+ }
+ } else {
+ if (!rmdir($dir)) {
+ $result = 0;
+ emit("remove_directory(): dir=\"$dir\" ($!) \n", "error");
+ }
+ }
+
+ return $result;
+}
+
+
+# Return 1 if success, 0 if failure
+sub set_owner_group_on_directory_contents
+{
+ my ($dir, $owner, $group, $recursive) = @_;
+ my ($result, $paths, $path);
+
+ $recursive = $recursive // 1;
+ $result = 1;
+
+ emit(sprintf("set_owner_group_on_directory_contents(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ if (!$dir || !directory_exists($dir)) {
+ emit("set_owner_group_on_directory_contents(): invalid directory specified.\n",
+ "error");
+ return 0;
+ }
+
+ if (!$owner || !$group) {
+ emit("set_owner_group_on_directory_contents(): directory $dir needs a user and group!\n",
+ "error");
+ return 0;
+ }
+
+ $paths = get_directory_files($dir, {'recursive' => $recursive,
+ 'include_dirs' => 1});
+
+ for $path (@$paths) {
+ $result = 0 if !set_owner_group($path, $owner, $group);
+ }
+
+ return $result;
+}
+
+
+##############################################################
+# Generic "symbolic link" Subroutines
+##############################################################
+
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub symlink_exists
+{
+ my ($symlink) = @_;
+
+ my $result = 0;
+
+ if (-l $symlink) {
+ $result = 1;
+ } elsif (-e $symlink) {
+ my $type = entity_type($symlink);
+ emit("Symbolic link $symlink DOES NOT exist because $symlink "
+ . "is a $type!\n",
+ "error");
+ $result = 0;
+ }
+
+
+ return $result;
+}
+
+
+# Return 1 if success, 0 if failure
+sub create_symlink
+{
+ my ($symlink, $dst_path, $owner, $group, $uninstall_action) = @_;
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+
+ emit(sprintf("create_symlink(%s)\n", join(", ", @_)), "debug");
+
+ add_install_info($symlink, 'symlink', $uninstall_action);
+
+ return 1 if $dry_run;
+
+ if (symlink_exists($symlink)) {
+ # delete symbolic link so that we can recreate link for upgrades
+ if (unlink($symlink) != 1) {
+ emit("create_symlink(): could not remove existing link \"$symlink\"\n", 'error');
+ remove_install_info($symlink);
+ return 0;
+ }
+ }
+
+ if (!is_path_valid($symlink)) {
+ emit("create_symlink(): invalid path \"$symlink\"\n", "error");
+ remove_install_info($symlink);
+ return 0;
+ }
+
+ if (!is_path_valid($dst_path) || !entity_exists($dst_path)) {
+ emit("create_symlink(): illegal dst path \"$dst_path\"\n", "error");
+ remove_install_info($symlink);
+ return 0;
+ }
+
+ if (!symlink($dst_path, $symlink)) {
+ emit("create_symlink(): failed \"$symlink\" => \"$dst_path\" ($!)\n", "error");
+ remove_install_info($symlink);
+ return 0;
+ }
+
+ if (defined($owner) && defined($group)) {
+ # The Perl Lchown package implements lchown, but it's not currently available
+ # as an RPM so use a system command instead. :-(
+ return 0 if !set_owner_group_on_symlink($symlink, $owner, $group);
+ }
+ return 1;
+}
+
+# Return 1 if success, 0 if failure
+sub copy_symlink
+{
+ my ($src_path, $dst_path, $owner, $group, $uninstall_action) = @_;
+ my ($target);
+
+ $uninstall_action = 'remove' unless defined($uninstall_action);
+
+ emit(sprintf("copy_symlink(%s)\n", join(", ", @_)), "debug");
+
+ add_install_info($dst_path, 'symlink', $uninstall_action);
+
+ if (!is_path_valid($src_path)) {
+ emit("copy_symlink(): illegal src path => \"$src_path\".\n",
+ "error");
+ remove_install_info($dst_path);
+ return 0;
+ }
+
+ if (!is_path_valid($dst_path)) {
+ emit("copy_symlink(): illegal dst path => \"$dst_path\".\n",
+ "error");
+ remove_install_info($dst_path);
+ return 0;
+ }
+
+ if (! -l $src_path) {
+ emit("copy_symlink(): $src_path is not a symbolic link\n");
+ return 0;
+ }
+
+ return 1 if $dry_run;
+
+ $target = readlink($src_path);
+
+ if (!symlink($target, $dst_path)) {
+ emit("could not symbolically link $target dst_path", "error");
+ remove_install_info($dst_path);
+ return 0;
+ }
+
+ if (defined($owner) && defined($group)) {
+ return 0 if !set_owner_group_on_symlink($dst_path, $owner, $group);
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub remove_symlink
+{
+ my ($symlink) = @_;
+ my $result = 0;
+
+ emit(sprintf("remove_symlink(%s)\n", join(", ", @_)), "debug");
+
+ add_install_info($symlink, 'symlink', 'remove', 'remove');
+
+ return 1 if $dry_run;
+
+ if (!$symlink) {
+ # symlink is NULL
+ return 1;
+ }
+
+ if (!symlink_exists($symlink)) {
+ return 1;
+ }
+
+ if (unlink($symlink) != 1) {
+ emit("remove_symlink(): failed \"$symlink\" ($!)\n", "error");
+ return 0;
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub set_owner_group_on_symlink
+{
+ my ($symlink, $owner, $group) = @_;
+
+ emit(sprintf("set_owner_group_on_symlink(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ if (!$symlink || !symlink_exists($symlink)) {
+ emit("set_owner_group_on_symlink(): invalid symbolic link specified \"$symlink\"\n",
+ "error");
+ return 1;
+ }
+
+ if (!$owner || !$group) {
+ emit("set_owner_group_on_symlink(): symbolic link \"$symlink\" needs a user and group!\n",
+ "error");
+ return 0;
+ }
+
+ # The Perl Lchown package implements lchown, but it's not currently available
+ # as an RPM so use a system command instead. :-(
+ return run_command("chown --no-dereference ${owner}:${group} $symlink");
+}
+
+
+##############################################################
+# Generic "chkconfig" Subroutines (Linux ONLY)
+##############################################################
+
+if ($^O eq "linux") {
+ # Return 1 if success, 0 if failure
+ sub register_pki_instance_with_chkconfig
+ {
+ my ($pki_instance_name) = @_;
+ my ($command, $exit_status, $result);
+
+ $result = 1;
+ $command = "/sbin/chkconfig --add $pki_instance_name";
+ if (run_command($command)) {
+ emit("Registered '$pki_instance_name' with '/sbin/chkconfig'.\n");
+ } else {
+ $result = 0;
+ emit("Failed to register '$pki_instance_name' with '/sbin/chkconfig'.\n", 'error');
+ }
+ return $result;
+ }
+
+ # Return 1 if success, 0 if failure
+ sub deregister_pki_instance_with_chkconfig
+ {
+ my ($pki_instance_name) = @_;
+ my ($command, $exit_status, $result);
+
+ $result = 1;
+ $command = "/sbin/chkconfig --del $pki_instance_name";
+ if (run_command($command)) {
+ emit("Registered '$pki_instance_name' with '/sbin/chkconfig'.\n");
+ } else {
+ $result = 0;
+ emit("Failed to deregister '$pki_instance_name' with '/sbin/chkconfig'.\n", 'error');
+ }
+ return $result;
+ }
+}
+
+##############################################################
+# Generic Subprocess Subroutines
+##############################################################
+
+# Runs the supplied command in a sub-shell. The command is subject
+# to shell interpretation.
+#
+# WARNING: Do not supply shell IO redirection in the command.
+#
+# Return 1 if success, 0 if failure
+#
+# The critical aspect of running a command is determining if the
+# command succeeded or failed. The proper way to determine this is by
+# checking exit status of command. Perl's subprocess mechansims are
+# less than ideal. In simplicity you would want to run the subprocess,
+# indpendently capture stdout & stderr, wait for termination and then
+# get the exit status. However most of the mechanisms discard
+# stderr. The advantages & disadvantages of each approach is nicely
+# documented here:
+#
+# http://blog.0x1fff.com/2009/09/howto-execute-system-commands-in-perl.html
+#
+# Ideally we would like to capture stdout and stderr
+# independently. The best way to do this is with Perl's IPC::Cmd
+# package which is part of the standard Perl distribution (whose
+# installation may be optional on a given system. RPM can detect our
+# use of this package and force it's installation as a
+# dependency). One disadvantage of IPC::Cmd is that it does not return
+# the actual exit status, just an indication if it was non-zero or not
+# (e.g. success). If we chose to use IPC::Cmd at a future date the
+# implementation would look like this:
+#
+# # Note: IPC::Cmd is in the perl-IPC-Cmd RPM
+# use IPC::Cmd qw[run];
+#
+# my ($success, $error_code, $full_buf, $stdout_buf, $stderr_buf) =
+# run(command => $cmd, verbose => 0);
+#
+# if (!$success) {
+# my ($err_msg);
+#
+# $err_msg = join("", @$stderr_buf);
+# chomp($err_msg);
+#
+# emit(sprintf("FAILED run_command(\"%s\"), output=\"%s\"\n",
+# $cmd, $err_msg), "error");
+#
+# return 0;
+# }
+#
+sub run_command
+{
+ my ($cmd) = @_;
+ my ($output, $wait_status, $exit_status);
+
+ emit(sprintf("run_command(%s)\n", join(", ", @_)), "debug");
+
+ return 1 if $dry_run;
+
+ # Perl backtick only captures stdout.
+ # stderr goes to the existing stderr file descriptor, probably the console.
+ # Capture stderr along with stdout via shell redirection (e.g. 2>&1)
+
+ $output = `$cmd 2>&1`;
+ $wait_status = $?;
+
+ # The low order 8 bits of the status is the terminating signal
+ # for the process, the actual exit status is obtained by
+ # shifting the low order 8 bits out.
+ $exit_status = $wait_status >> 8;
+
+ if ($exit_status != 0) {
+ chomp($output);
+ emit(sprintf("FAILED run_command(\"%s\"), exit status=%d output=\"%s\"\n",
+ $cmd, $exit_status, $output), "error");
+ return 0;
+ }
+
+ return 1;
+}
+
+##############################################################
+# Generic Java Subroutines
+##############################################################
+
+# Given a jar's base name locate it in the file system
+# using standard Java jar path for this system.
+# Return the path to the jar if found, undef otherwise.
+sub find_jar
+{
+ my($jar_name) = @_;
+ my($jar_dir, $jar_path);
+
+ for $jar_dir (@default_jar_path) {
+ $jar_path = "$jar_dir/$jar_name";
+ if (-e $jar_path) {
+ return $jar_path;
+ }
+ }
+ return undef;
+}
+
+##############################################################
+# Generic PKI Subroutines
+##############################################################
+
+# Get parameter value(s) from CS.cfg file
+#
+# get_cs_cfg(config_path, search)
+#
+# There are 3 ways the parameters can be returned, as a string, as a
+# set of variables, or as a hash table depending on the search
+# parameter type.
+#
+# If search is string then the parameter value is returned as a string
+# if it was found, otherwise if it wasn't found then undef is
+# returned.
+#
+# If search is a reference to a hash then each key in the hash will be
+# searched for and the key's value will be used as a reference to
+# assign the value of the parameter to. If the key was not found then
+# the reference will be assigned the value of undef.
+#
+# If search is reference to an array then every parameter in the
+# array will be searched for and a hash will be returned with a key
+# for every parameter found, the key's value is the parameter value.
+#
+# Examples:
+#
+# my ($subsystem_type, $uri, $table);
+#
+# # Get a single string: $subsystem_type is assigned the string "CA"
+# $subsystem_type = get_cs_cfg("/etc/pki-ca/CS.cfg", "cs.type");
+#
+# # Assign a set of variables: $subsystem_type and $uri are assigned
+# get_cs_cfg($config_path, {"cs.type" => \$subsystem_type,
+# "ee.interface.uri" => \$uri});
+#
+# # Get a lookup table:
+# $table = get_cs_cfg("/etc/pki-ca/CS.cfg", ["cs.type", "ee.interface.uri"]);
+# # returns the hash:
+# # {"cs.type" => "CA",
+# # "ee.interface.uri" => "ca/ee/ca"}
+#
+sub get_cs_cfg
+{
+ my ($config_path, $search) = @_;
+ my ($text, $key, $value, $num_found);
+
+ $text = read_file($config_path);
+
+ if (ref($search) eq "HASH") {
+ my $num_found = 0;
+ while (my ($key, $ref) = each(%$search)) {
+ if ($text =~ /^\s*\Q$key\E\s*=\s*(.*)/m) {
+ $value = $1;
+ $$ref = $value;
+ $num_found += 1;
+ } else {
+ $$ref = undef;
+ }
+ }
+ return $num_found;
+ } elsif (ref($search) eq "ARRAY") {
+ my $result = {};
+ my $keys = $search;
+
+ foreach $key (@$keys) {
+ if ($text =~ /^\s*\Q$key\E\s*=\s*(.*)/m) {
+ $value = $1;
+ $result->{$key} = $value;
+ }
+ }
+
+ return $result;
+
+ } else {
+ my $result = undef;
+ $key = $search;
+
+ if ($text =~ /^\s*\Q$key\E\s*=\s*(.*)/m) {
+ $value = $1;
+ $result = $value;
+ }
+
+ return $result;
+
+ }
+}
+
+sub get_registry_initscript_name
+{
+ my ($subsystem_type) = @_;
+ my ($pki_initscript);
+
+ if ($subsystem_type eq $CA) {
+ $pki_initscript = $CA_INITSCRIPT;
+ } elsif($subsystem_type eq $KRA) {
+ $pki_initscript = $KRA_INITSCRIPT;
+ } elsif($subsystem_type eq $OCSP) {
+ $pki_initscript = $OCSP_INITSCRIPT;
+ } elsif($subsystem_type eq $RA) {
+ $pki_initscript = $RA_INITSCRIPT;
+ } elsif($subsystem_type eq $TKS) {
+ $pki_initscript = $TKS_INITSCRIPT;
+ } elsif($subsystem_type eq $TPS) {
+ $pki_initscript = $TPS_INITSCRIPT;
+ } else {
+ die "unknown subsystem type \"$subsystem_type\"";
+ }
+
+}
+
+#######################################
+# Generic selinux routines
+#######################################
+
+sub check_selinux_port
+{
+ my ($setype, $seport) = @_;
+
+ return $SELINUX_PORT_UNDEFINED if $dry_run;
+
+ if (defined $selinux_ports{$seport}) {
+ if ($selinux_ports{$seport} eq $setype) {
+ return $SELINUX_PORT_DEFINED;
+ } else {
+ return $SELINUX_PORT_WRONGLY_DEFINED;
+ }
+ } else {
+ return $SELINUX_PORT_UNDEFINED;
+ }
+}
+
+sub parse_selinux_ports
+{
+ open SM, '/usr/sbin/semanage port -l |grep tcp |sed \'s/tcp/___/g\'|sed \'s/\s//g\'|';
+ while (<SM>) {
+ chomp($_);
+ my ($type, $portstr) = split /___/, $_;
+ my @ports = split /,/, $portstr;
+ foreach my $port (@ports) {
+ if ($port =~ /(.*)-(.*)/) {
+ for (my $count = $1; $count <= $2; $count++) {
+ $selinux_ports{$count} = $type;
+ }
+ } else {
+ $selinux_ports{$port} = $type;
+ }
+ }
+ }
+ close(SM);
+}
+
+sub add_selinux_port
+{
+ my ($setype, $seport, $cmds_ref) = @_;
+ my $status = check_selinux_port($setype, $seport);
+
+ if ($status == $SELINUX_PORT_UNDEFINED) {
+ if ($cmds_ref) {
+ $$cmds_ref .= "port -a -t $setype -p tcp $seport\n";
+ } else {
+ my $cmd = "$semanage port -a -t $setype -p tcp $seport\n";
+ if (! run_command($cmd)) {
+ emit("Failed to set selinux context for $seport", "error");
+ }
+ }
+
+ } elsif ($status == $SELINUX_PORT_WRONGLY_DEFINED) {
+ emit("Failed setting selinux context $setype for $seport. " .
+ "Port already defined otherwise.\n", "error");
+ }
+}
+
+sub add_selinux_file_context
+{
+ my ($fcontext, $fname, $ftype, $cmds_ref) = @_;
+ my ($result);
+
+ emit(sprintf("add_selinux_file_context(%s)\n", join(", ", @_)), "debug");
+
+ #check if fcontext has already been set
+ my $tmp = `$semanage fcontext -l -n |grep $fname |grep ":$fcontext:" | wc -l`;
+ chomp $tmp;
+ if ($tmp ne "0") {
+ emit("selinux fcontext for $fname already defined\n", "debug");
+ return;
+ }
+
+ if ($ftype eq "f") {
+ $$cmds_ref .= "fcontext -a -t $fcontext -f -- $fname\n";
+ } else {
+ $$cmds_ref .= "fcontext -a -t $fcontext $fname\n";
+ }
+}
+
+1;
diff --git a/base/setup/pkicreate b/base/setup/pkicreate
new file mode 100755
index 000000000..edde86ecc
--- /dev/null
+++ b/base/setup/pkicreate
@@ -0,0 +1,3479 @@
+#!/usr/bin/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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2007-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+
+use strict;
+use warnings;
+
+use File::Slurp qw(read_file write_file);
+use Getopt::Long qw(GetOptions);
+
+##############################################################
+# This script is used to create a new instance of a
+# subsystem within a PKI installation.
+#
+# Sample Invocation (for CA):
+#
+# ./pkicreate -pki_instance_root=/var/lib
+# -pki_instance_name=pki-ca
+# -subsystem_type=ca
+# -agent_secure_port=9443
+# -ee_secure_port=9444
+# -ee_secure_client_auth_port=9446
+# -admin_secure_port=9445
+# -unsecure_port=9180
+# -tomcat_server_port=9701
+# -user=pkiuser
+# -group=pkiuser
+# -redirect conf=/etc/pki-ca
+# -redirect logs=/var/log/pki-ca
+# -verbose
+#
+##############################################################
+
+
+##############################################################
+# Execution Check
+##############################################################
+
+# Disallow 'others' the ability to 'write' to new files
+umask 00002;
+
+# Check to insure that this script's original
+# invocation directory has not been deleted!
+my $cwd = `/bin/pwd`;
+chomp $cwd;
+if (!$cwd) {
+ emit("Cannot invoke '$0' from non-existent directory!\n", "error");
+ exit 255;
+}
+
+
+##############################################################
+# Environment Variables
+##############################################################
+
+# option to not run this script.
+if (defined($ENV{'DONT_RUN_PKICREATE'})) {
+ if ($ENV{'DONT_RUN_PKICREATE'} == 1) {
+ emit("Env. variable DONT_RUN_PKICREATE is set. Exiting.\n", "error");
+ exit 0;
+ }
+}
+
+# untaint called subroutines
+if (($^O ne 'Windows_NT') && ($^O ne 'MSWin32')) {
+ $> = $<; # set effective user ID to real UID
+ $) = $(; # set effective group ID to real GID
+ $ENV{'PATH'} = '/bin:/usr/bin';
+ $ENV{'ENV'} = '' if !defined($ENV{'ENV'});
+}
+
+
+##############################################################
+# Command-Line Variables
+##############################################################
+
+my $ARGS = ($#ARGV + 1);
+
+
+##############################################################
+# Shared Common Perl Data and Subroutines
+##############################################################
+
+use lib "/usr/share/pki/scripts";
+use pkicommon;
+
+# Establish path to scripts
+my $pki_subsystem_common_area = "/usr/share/$pki_flavor";
+
+# make -w happy by suppressing warnings of Global variables used only once
+my $suppress = "";
+$suppress = $hostname;
+$suppress = $obj_ext;
+$suppress = $tmp_dir;
+$suppress = $default_security_libraries;
+$suppress = $default_system_libraries;
+$suppress = $lib_prefix;
+$suppress = $PKI_USER;
+$suppress = $PKI_GROUP;
+$suppress = $install_info_basename;
+
+##############################################################
+# Local Constants
+##############################################################
+
+# Base subsystem directory names
+my $applets_base_subsystem_dir = "applets"; # TPS
+my $cgibin_base_subsystem_dir = "cgi-bin"; # TPS (Apache)
+my $conf_base_subsystem_dir = "conf"; # CA, KRA, OCSP, TKS, RA, TPS
+my $docroot_base_subsystem_dir = "docroot"; # RA, TPS (Apache)
+my $emails_base_subsystem_dir = "emails"; # CA
+my $lib_base_subsystem_dir = "lib"; # RA, TPS
+my $profiles_base_subsystem_dir = "profiles"; # CA, KRA, OCSP, TKS
+my $samples_base_subsystem_dir = "samples"; # TPS
+my $scripts_base_subsystem_dir = "scripts"; # RA, TPS
+my $webapps_base_subsystem_dir = "webapps"; # CA, KRA, OCSP, TKS
+
+# Base instance directory names
+my $alias_base_instance_dir = "alias"; # CA, KRA, OCSP, TKS, RA, TPS
+my $bin_base_instance_dir = "bin"; # TPS
+my $cgibin_base_instance_dir = "cgi-bin"; # TPS (Apache)
+my $conf_base_instance_dir = "conf"; # CA, KRA, OCSP, TKS, RA, TPS
+my $docroot_base_instance_dir = "docroot"; # RA, TPS (Apache)
+my $emails_base_instance_dir = "emails"; # CA
+my $lib_base_instance_dir = "lib"; # RA, TPS
+my $logs_base_instance_dir = "logs"; # CA, KRA, OCSP, TKS, RA, TPS
+my $profiles_base_instance_dir = "profiles"; # CA, KRA, OCSP, TKS
+my $scripts_base_instance_dir = "scripts"; # RA, TPS
+my $tomcat_instance_common_lib_dir = "common/lib"; # CA, KRA, OCSP, TKS (Tomcat)
+my $shared_base_instance_dir = "shared"; # CA, KRA, OCSP, TKS (Tomcat)
+my $temp_base_instance_dir = "temp"; # CA, KRA, OCSP, TKS (Tomcat)
+my $webapps_base_instance_dir = "webapps"; # CA, KRA, OCSP, TKS
+my $work_base_instance_dir = "work"; # CA, KRA, OCSP, TKS (Tomcat)
+
+# Base instance symbolic link names
+my $common_base_instance_symlink = "common"; # CA, KRA, OCSP, TKS
+my $conf_base_instance_symlink = "conf"; # CA, KRA, OCSP, TKS, RA, TPS
+my $logs_base_instance_symlink = "logs"; # CA, KRA, OCSP, TKS, RA, TPS
+my $run_base_instance_symlink = "run"; # RA, TPS
+
+# Base names
+my $cgi_home_base_name = "home/index.cgi"; # TPS
+my $cgi_demo_base_name = "demo/index.cgi"; # TPS
+my $cgi_so_base_name = "so/index.cgi"; # TPS
+my $cgi_so_enroll_name = "so/enroll.cgi"; # TPS
+my $cgi_sow_dir_name = "sow"; # TPS
+my $cgi_sow_cfg_pl_name = "sow/cfg.pl"; # TPS
+my $addAgents_ldif_base_name = "addAgents.ldif"; # TPS
+my $addIndexes_ldif_base_name = "addIndexes.ldif"; # TPS
+my $addTokens_ldif_base_name = "addTokens.ldif"; # TPS
+my $addVLVIndexes_ldif_base_name = "addVLVIndexes.ldif"; # TPS
+my $nss_pcache_base_name = "nss_pcache"; # RA, TPS
+my $pki_subsystem_jar_base_name = undef; # CA, KRA, OCSP, TKS
+
+my $pki_certsrv_jar_base_name = "pki-certsrv.jar"; # CA, KRA, OCSP, TKS
+my $pki_cms_jar_base_name = "pki-cms.jar"; # CA, KRA, OCSP, TKS
+my $pki_cmsbundle_jar_base_name = "pki-cmsbundle.jar"; # CA, KRA, OCSP, TKS
+my $pki_cmscore_jar_base_name = "pki-cmscore.jar"; # CA, KRA, OCSP, TKS
+my $pki_cmsutil_jar_base_name = "pki-cmsutil.jar"; # CA, KRA, OCSP, TKS
+my $commons_collections_jar_base_name = undef; # CA, KRA, OCSP, TKS
+my $commons_lang_jar_base_name = undef; # CA, KRA, OCSP, TKS
+my $commons_logging_jar_base_name = undef; # CA, KRA, OCSP, TKS
+my $jss_jar_base_name = "jss4.jar"; # CA, KRA, OCSP, TKS
+my $ldapjdk_jar_base_name = "ldapjdk.jar"; # CA, KRA, OCSP, TKS
+my $pki_nsutil_jar_base_name = "pki-nsutil.jar"; # CA, KRA, OCSP, TKS
+my $commons_codec_jar_base_name = "commons-codec.jar"; # CA, KRA, OCSP, TKS
+my $symkey_jar_base_name = "symkey.jar"; # CA, KRA, OCSP, TKS
+my $tomcatjss_jar_base_name = "tomcatjss.jar"; # CA, KRA, OCSP, TKS
+my $velocity_jar_base_name = "velocity.jar"; # CA, KRA, OCSP, TKS
+my $xerces_jar_base_name = "xerces-j2.jar"; # CA, KRA, OCSP, TKS
+
+# resteasy jars
+my $javassist_jar_base_name = "javassist-3.9.0.GA.jar"; # CA, KRA, OCSP, TKS
+my $jaxrs_api_jar_base_name = "jaxrs-api-2.2.1.GA.jar"; # CA, KRA, OCSP, TKS
+my $resteasy_jaxb_provider_jar_base_name = "resteasy-jaxb-provider-2.2.1.GA.jar"; # CA, KRA, OCSP, TKS
+my $resteasy_jaxrs_jar_base_name = "resteasy-jaxrs-2.2.1.GA.jar"; # CA, KRA, OCSP, TKS
+my $scannotation_jar_base_name = "scannotation-1.0.2.jar"; # CA, KRA, OCSP, TKS
+my $jettison_jar_base_name = "jettison.jar"; # CA, KRA, OCSP, TKS
+my $resteasy_jettison_provider_jar_base_name = "resteasy-jettison-provider-2.3-RC1.jar"; # CA, KRA, OCSP, TKS
+
+my $apache_commons_collections_jar_base_name = "apache-commons-collections.jar";
+my $jakarta_commons_collections_jar_base_name = "jakarta-commons-collections.jar";
+my $apache_commons_logging_jar_base_name = "apache-commons-logging.jar";
+my $jakarta_commons_logging_jar_base_name = "jakarta-commons-logging.jar";
+my $apache_commons_lang_jar_base_name = "apache-commons-lang.jar";
+my $jakarta_commons_lang_jar_base_name = "jakarta-commons-lang.jar";
+my $xml_commons_apis_jar_base_name = "xml-commons-apis.jar";
+my $xml_commons_resolver_jar_base_name = "xml-commons-resolver.jar";
+
+my $conf_base_name = "conf"; # CA, KRA, OCSP, TKS,
+my $catalina_properties_base_name = "catalina.properties"; # CA, KRA, OCSP, TKS
+
+my $httpd_conf_base_name = "httpd.conf"; # RA, TPS
+my $index_jsp_base_name = "index.jsp"; # CA, KRA, OCSP, TKS
+ # RA, TPS
+my $magic_base_name = "magic"; # RA, TPS
+my $mime_types_base_name = "mime.types"; # RA, TPS
+my $noise_base_name = "noise"; # CA, KRA, OCSP, TKS,
+ # RA, TPS
+my $nss_conf_base_name = "nss.conf"; # RA, TPS
+my $perl_conf_base_name = "perl.conf"; # RA, TPS
+my $password_conf_base_name = "password.conf"; # CA, KRA, OCSP, TKS,
+ # RA, TPS
+my $pfile_base_name = "pfile"; # CA, KRA, OCSP, TKS,
+ # RA, TPS
+my $pwcache_conf_base_name = "pwcache.conf"; # RA, TPS
+my $pki_cfg_base_name = "CS.cfg"; # CA, KRA, OCSP, TKS,
+ # RA, TPS
+my $schemaMods_ldif_base_name = "schemaMods.ldif"; # RA, TPS
+my $server_xml_base_name = "server.xml"; # CA, KRA, OCSP, TKS
+my $servercertnick_conf_base_name = "serverCertNick.conf"; # CA, KRA, OCSP, TKS
+my $tomcat6_conf_base_name = "tomcat6.conf"; # CA, KRA, OCSP, TKS
+my $velocity_prop_base_name = "velocity.properties"; # CA, KRA, OCSP, TKS
+my $web_xml_base_name = "web.xml"; # CA, KRA, OCSP, TKS
+my $profile_select_base_name = "ProfileSelect.template"; # CA
+my $proxy_conf_base_name = "proxy.conf"; # CA
+
+my $registry_template_base_name = "registry_instance"; # CA, KRA, OCSP, TKS, RA, TPS
+my $pki_apache_initscript_base_name = "pki_apache_initscript"; # RA, TPS
+
+# Subdirectory names
+my $perl_base_instance_symlink = "perl"; # RA, TPS
+my $perl_base_subsystem_dir = "perl"; # RA, TPS
+my $signed_audit_base_instance_dir = "signedAudit"; # CA, KRA, OCSP, TKS, TPS
+my $webapps_root_base_instance_dir = "ROOT"; # CA, KRA, OCSP, TKS
+my $webapps_root_base_subsystem_dir = "ROOT"; # CA, KRA, OCSP, TKS
+my $webinf_base_instance_dir = "WEB-INF"; # CA, KRA, OCSP, TKS
+
+# Defaults
+my $default_apache_pids_path = "/var/run/pki";
+my $default_tomcat_pids_path = "/var/run";
+my $default_tomcat_lib_path = "/usr/share/tomcat6/lib";
+my $default_security_token = "internal";
+my $default_nfast_group = "nfast";
+
+# Default PKI user and group to give to PKI installed files
+my $pki_user = $PKI_USER;
+my $pki_group = $PKI_GROUP;
+
+# PKI creation constants
+my $db_password_low = 100000000000;
+my $db_password_high = 999999999999;
+
+# Template slot constants (RA, TPS)
+my $HTTPD_CONF = "HTTPD_CONF";
+my $LIB_PREFIX = "LIB_PREFIX";
+my $NSS_CONF = "NSS_CONF";
+my $OBJ_EXT = "OBJ_EXT";
+my $PORT = "PORT";
+my $PROCESS_ID = "PROCESS_ID";
+my $SECURE_PORT = "SECURE_PORT";
+my $NON_CLIENTAUTH_SECURE_PORT = "NON_CLIENTAUTH_SECURE_PORT";
+my $SECURITY_LIBRARIES = "SECURITY_LIBRARIES";
+my $SERVER_NAME = "SERVER_NAME";
+my $SERVER_ROOT = "SERVER_ROOT";
+my $SYSTEM_LIBRARIES = "SYSTEM_LIBRARIES";
+my $SYSTEM_USER_LIBRARIES = "SYSTEM_USER_LIBRARIES";
+my $TMP_DIR = "TMP_DIR";
+my $TPS_DIR = "TPS_DIR";
+my $FORTITUDE_APACHE = "FORTITUDE_APACHE";
+my $FORTITUDE_DIR = "FORTITUDE_DIR";
+my $FORTITUDE_MODULE = "FORTITUDE_MODULE";
+my $FORTITUDE_LIB_DIR = "FORTITUDE_LIB_DIR";
+my $FORTITUDE_AUTH_MODULES = "FORTITUDE_AUTH_MODULES";
+my $FORTITUDE_NSS_MODULES = "FORTITUDE_NSS_MODULES";
+my $REQUIRE_CFG_PL = "REQUIRE_CFG_PL";
+my $PKI_PIDDIR = "PKI_PIDDIR";
+my $PKI_LOCKDIR = "PKI_LOCKDIR";
+
+# Template slot constants (CA, KRA, OCSP, TKS, RA, TPS)
+my $PKI_INSTANCE_ID_SLOT = "PKI_INSTANCE_ID";
+my $PKI_REGISTRY_FILE_SLOT = "PKI_REGISTRY_FILE";
+
+# Template slot constants (CA, KRA, OCSP, TKS)
+my $INSTALL_TIME = "INSTALL_TIME";
+my $PKI_AGENT_CLIENTAUTH_SLOT = "PKI_AGENT_CLIENTAUTH";
+my $PKI_CERT_DB_PASSWORD_SLOT = "PKI_CERT_DB_PASSWORD";
+my $PKI_CFG_PATH_NAME_SLOT = "PKI_CFG_PATH_NAME";
+my $PKI_GROUP_SLOT = "PKI_GROUP";
+my $PKI_INSTANCE_PATH_SLOT = "PKI_INSTANCE_PATH";
+my $PKI_INSTANCE_ROOT_SLOT = "PKI_INSTANCE_ROOT";
+my $PKI_MACHINE_NAME_SLOT = "PKI_MACHINE_NAME";
+my $PKI_RANDOM_NUMBER_SLOT = "PKI_RANDOM_NUMBER";
+my $PKI_SECURE_PORT_SLOT = "PKI_SECURE_PORT";
+my $PKI_EE_SECURE_PORT_SLOT = "PKI_EE_SECURE_PORT";
+my $PKI_EE_SECURE_CLIENT_AUTH_PORT_SLOT = "PKI_EE_SECURE_CLIENT_AUTH_PORT";
+my $PKI_EE_SECURE_CLIENT_AUTH_PORT_UI_SLOT = "PKI_EE_SECURE_CLIENT_AUTH_PORT_UI";
+my $PKI_AGENT_SECURE_PORT_SLOT = "PKI_AGENT_SECURE_PORT";
+my $PKI_ADMIN_SECURE_PORT_SLOT = "PKI_ADMIN_SECURE_PORT";
+my $PKI_SERVER_XML_CONF = "PKI_SERVER_XML_CONF";
+my $PKI_SUBSYSTEM_TYPE_SLOT = "PKI_SUBSYSTEM_TYPE";
+my $PKI_UNSECURE_PORT_SLOT = "PKI_UNSECURE_PORT";
+my $PKI_USER_SLOT = "PKI_USER";
+my $TOMCAT_SERVER_PORT_SLOT = "TOMCAT_SERVER_PORT";
+my $TOMCAT_PIDFILE = "TOMCAT_PIDFILE";
+my $TOMCAT_CFG = "TOMCAT_CFG";
+my $TOMCAT_SSL_OPTIONS = "TOMCAT_SSL_OPTIONS";
+my $TOMCAT_SSL2_CIPHERS = "TOMCAT_SSL2_CIPHERS";
+my $TOMCAT_SSL3_CIPHERS = "TOMCAT_SSL3_CIPHERS";
+my $TOMCAT_TLS_CIPHERS = "TOMCAT_TLS_CIPHERS";
+my $TOMCAT_INSTANCE_COMMON_LIB = "TOMCAT_INSTANCE_COMMON_LIB";
+my $TOMCAT_LOG_DIR = "TOMCAT_LOG_DIR";
+my $PKI_INSTANCE_INITSCRIPT = "PKI_INSTANCE_INITSCRIPT";
+my $PKI_FLAVOR_SLOT = "PKI_FLAVOR";
+my $PKI_UNSECURE_PORT_CONNECTOR_NAME_SLOT = "PKI_UNSECURE_PORT_CONNECTOR_NAME";
+my $PKI_SECURE_PORT_CONNECTOR_NAME_SLOT = "PKI_SECURE_PORT_CONNECTOR_NAME";
+my $PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME_SLOT = "PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME";
+my $PKI_EE_SECURE_PORT_CONNECTOR_NAME_SLOT = "PKI_EE_SECURE_PORT_CONNECTOR_NAME";
+my $PKI_EE_SECURE_CLIENT_AUTH_PORT_CONNECTOR_NAME_SLOT = "PKI_EE_SECURE_CLIENT_AUTH_PORT_CONNECTOR_NAME";
+my $PKI_UNSECURE_PORT_COMMENT_SERVER_SLOT = "PKI_UNSECURE_PORT_SERVER_COMMENT";
+my $PKI_SECURE_PORT_COMMENT_SERVER_SLOT = "PKI_SECURE_PORT_SERVER_COMMENT";
+my $PKI_ADMIN_SECURE_PORT_COMMENT_SERVER_SLOT = "PKI_ADMIN_SECURE_PORT_SERVER_COMMENT";
+my $PKI_EE_SECURE_PORT_COMMENT_SERVER_SLOT = "PKI_EE_SECURE_PORT_SERVER_COMMENT";
+my $PKI_EE_SECURE_CLIENT_AUTH_PORT_COMMENT_SERVER_SLOT = "PKI_EE_SECURE_CLIENT_AUTH_PORT_SERVER_COMMENT";
+my $PKI_OPEN_SEPARATE_PORTS_COMMENT_SERVER_SLOT = "PKI_OPEN_SEPARATE_PORTS_SERVER_COMMENT";
+my $PKI_CLOSE_SEPARATE_PORTS_COMMENT_SERVER_SLOT = "PKI_CLOSE_SEPARATE_PORTS_SERVER_COMMENT";
+my $PKI_OPEN_SEPARATE_PORTS_COMMENT_WEB_SLOT = "PKI_OPEN_SEPARATE_PORTS_WEB_COMMENT";
+my $PKI_CLOSE_SEPARATE_PORTS_COMMENT_WEB_SLOT = "PKI_CLOSE_SEPARATE_PORTS_WEB_COMMENT";
+my $PKI_OPEN_AJP_PORT_COMMENT_SLOT = "PKI_OPEN_AJP_PORT_COMMENT";
+my $PKI_CLOSE_AJP_PORT_COMMENT_SLOT = "PKI_CLOSE_AJP_PORT_COMMENT";
+my $PKI_OPEN_ENABLE_PROXY_COMMENT_SLOT = "PKI_OPEN_ENABLE_PROXY_COMMENT";
+my $PKI_CLOSE_ENABLE_PROXY_COMMENT_SLOT = "PKI_CLOSE_ENABLE_PROXY_COMMENT";
+my $PKI_AJP_REDIRECT_PORT_SLOT = "PKI_AJP_REDIRECT_PORT";
+my $PKI_AJP_PORT_SLOT = "PKI_AJP_PORT";
+my $PROXY_SECURE_PORT_SLOT = "PKI_PROXY_SECURE_PORT";
+my $PROXY_UNSECURE_PORT_SLOT = "PKI_PROXY_UNSECURE_PORT";
+my $PKI_SYSTEMD_SERVICENAME_SLOT = "PKI_SYSTEMD_SERVICENAME";
+my $PKI_UNSECURE_PORT_NAME = "Unsecure";
+my $PKI_AGENT_SECURE_PORT_NAME = "Agent";
+my $PKI_ADMIN_SECURE_PORT_NAME = "Admin";
+my $PKI_EE_SECURE_PORT_NAME = "EE";
+my $PKI_EE_SECURE_CLIENT_AUTH_PORT_NAME = "EEClientAuth";
+my $PKI_SECURE_PORT_NAME = "Secure";
+my $PKI_UNUSED_SECURE_PORT_NAME = "Unused";
+my $PKI_UNSECURE_SEPARATE_PORTS_COMMENT = "<!-- Port Separation: Unsecure Port Connector -->";
+my $PKI_AGENT_SECURE_SEPARATE_PORTS_COMMENT = "<!-- Port Separation: Agent Secure Port Connector -->";
+my $PKI_ADMIN_SECURE_SEPARATE_PORTS_COMMENT = "<!-- Port Separation: Admin Secure Port Connector -->";
+my $PKI_EE_SECURE_SEPARATE_PORTS_COMMENT = "<!-- Port Separation: EE Secure Port Connector -->";
+my $PKI_EE_SECURE_CLIENT_AUTH_SEPARATE_PORTS_COMMENT = "<!-- Port Separation: EE Secure Client Auth Port Connector -->";
+my $PKI_UNSECURE_SHARED_PORTS_COMMENT = "<!-- Shared Ports: Unsecure Port Connector -->";
+my $PKI_SECURE_SHARED_PORTS_COMMENT = "<!-- Shared Ports: Agent, EE, and Admin Secure Port Connector -->";
+my $PKI_OPEN_COMMENT = "<!--";
+my $PKI_CLOSE_COMMENT = "-->";
+my $PKI_WEBAPPS_NAME = "PKI_WEBAPPS_NAME";
+
+#proxy defaults
+my $PROXY_SECURE_PORT_DEFAULT = "443";
+my $PROXY_UNSECURE_PORT_DEFAULT = "80";
+my $AJP_PORT_DEFAULT = "9447";
+
+##############################################################
+# Local Data Structures
+##############################################################
+
+# Useful pki references
+my %redirects = ();
+my %supported_sec_modules_hash = ();
+
+##############################################################
+# Local Variables
+##############################################################
+
+# Command-line variables (mandatory)
+my $pki_instance_root = undef;
+my $pki_instance_name = undef;
+my $subsystem_type = undef;
+my $secure_port = -1;
+my $non_clientauth_secure_port = -1;
+my $unsecure_port = -1;
+my $tomcat_server_port = -1;
+
+# Command-line variables (optional)
+my $agent_secure_port = -1;
+my $ee_secure_port = -1;
+my $ee_secure_client_auth_port = -1;
+my $admin_secure_port = -1;
+my $proxy_secure_port = -1;
+my $proxy_unsecure_port = -1;
+my $ajp_port = -1;
+my $enable_proxy = undef;
+my $username = undef;
+my $groupname = undef;
+my $redirected_conf_path = undef;
+my $redirected_logs_path = undef;
+
+# Base subsystem directory paths
+my $pki_subsystem_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $applets_subsystem_path = undef; # TPS
+my $bin_subsystem_path = undef; # TPS
+my $cgibin_subsystem_path = undef; # TPS (Apache)
+my $conf_subsystem_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $docroot_subsystem_path = undef; # RA, TPS (Apache)
+my $emails_subsystem_path = undef; # CA
+my $lib_subsystem_path = undef; # RA, TPS
+my $profiles_subsystem_path = undef; # CA, KRA, OCSP, TKS
+my $samples_subsystem_path = undef; # TPS
+my $scripts_subsystem_path = undef; # RA, TPS
+my $webapps_subsystem_path = undef; # CA, KRA, OCSP, TKS
+my $common_ui_subsystem_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $ui_subsystem_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+
+# Base instance directory paths
+my $pki_instance_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $alias_instance_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $bin_instance_path = undef; # TPS
+my $cgibin_instance_path = undef; # TPS (Apache)
+my $conf_instance_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $docroot_instance_path = undef; # RA, TPS (Apache)
+my $emails_instance_path = undef; # CA
+my $lib_instance_path = undef; # RA, TPS
+my $logs_instance_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $profiles_instance_path = undef; # CA, KRA, OCSP, TKS
+my $scripts_instance_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $tomcat_instance_common_lib_path = undef; # CA, KRA, OCSP, TKS (Tomcat)
+my $shared_instance_path = undef; # CA, KRA, OCSP, TKS (Tomcat)
+my $temp_instance_path = undef; # CA, KRA, OCSP, TKS (Tomcat)
+my $webapps_instance_path = undef; # CA, KRA, OCSP, TKS
+my $webapps_subsystem_instance_path = undef; # CA, KRA, OCSP, TKS
+my $work_instance_path = undef; # CA, KRA, OCSP, TKS (Tomcat)
+my $pki_piddir_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $pki_lockdir_path = undef; # RA, TPS
+
+# Base instance symbolic link paths
+my $conf_instance_symlink_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $logs_instance_symlink_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $run_instance_symlink_path = undef; # RA, TPS
+
+# Subdirectory paths
+my $cgi_home_instance_file_path = undef; # TPS
+my $cgi_home_subsystem_file_path = undef; # TPS
+my $cgi_demo_instance_file_path = undef; # TPS
+my $cgi_demo_subsystem_file_path = undef; # TPS
+my $cgi_so_instance_file_path = undef; # TPS
+my $cgi_so_subsystem_file_path = undef; # TPS
+my $cgi_so_instance_enroll_file_path = undef; # TPS
+my $cgi_so_subsystem_enroll_file_path = undef; # TPS
+my $cgi_sow_instance_file_path = undef; # TPS
+my $cgi_sow_subsystem_file_path = undef; # TPS
+my $cgi_sow_instance_cgi_file_path = undef; # TPS
+my $cgi_sow_subsystem_cgi_file_path = undef; # TPS
+my $cgi_sow_instance_cfg_pl_path = undef; # TPS
+my $addAgents_ldif_instance_file_path = undef; # TPS
+my $addAgents_ldif_subsystem_file_path = undef; # TPS
+my $addIndexes_ldif_instance_file_path = undef; # TPS
+my $addIndexes_ldif_subsystem_file_path = undef; # TPS
+my $addTokens_ldif_instance_file_path = undef; # TPS
+my $addTokens_ldif_subsystem_file_path = undef; # TPS
+my $addVLVIndexes_ldif_instance_file_path = undef; # TPS
+my $addVLVIndexes_ldif_subsystem_file_path = undef; # TPS
+my $pki_certsrv_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_certsrv_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cms_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cms_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cmsbundle_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cmsbundle_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cmscore_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cmscore_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cmsutil_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_cmsutil_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $javassist_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $javassist_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $jaxrs_api_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $jaxrs_api_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $resteasy_jaxb_provider_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $resteasy_jaxb_provider_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $resteasy_jaxrs_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $resteasy_jaxrs_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $scannotation_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $scannotation_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $jettison_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $jettison_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $resteasy_jettison_provider_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $resteasy_jettison_provider_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $commons_collections_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $commons_collections_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $commons_lang_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $commons_lang_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $commons_logging_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $commons_logging_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $jss_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $jss_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $ldapjdk_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $ldapjdk_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $pki_nsutil_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_nsutil_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $commons_codec_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $commons_codec_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $symkey_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $symkey_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $tomcatjss_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $tomcatjss_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $velocity_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $velocity_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $xerces_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $xerces_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $xml_commons_apis_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $xml_commons_apis_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $xml_commons_resolver_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $xml_commons_resolver_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $httpd_conf_instance_file_path = undef; # RA, TPS
+my $httpd_conf_subsystem_file_path = undef; # RA, TPS
+my $index_jsp_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $index_jsp_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $magic_instance_file_path = undef; # RA, TPS
+my $magic_subsystem_file_path = undef; # RA, TPS
+my $mime_types_instance_file_path = undef; # RA, TPS
+my $mime_types_subsystem_file_path = undef; # RA, TPS
+my $noise_instance_file_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $nss_conf_instance_file_path = undef; # RA, TPS
+my $nss_conf_subsystem_file_path = undef; # RA, TPS
+my $nss_pcache_instance_file_path = undef; # RA, TPS
+my $nss_pcache_subsystem_file_path = undef; # RA, TPS
+my $perl_conf_instance_file_path = undef; # RA, TPS
+my $perl_conf_subsystem_file_path = undef; # RA, TPS
+my $password_conf_instance_file_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $perl_instance_symlink_path = undef; # RA, TPS
+my $perl_subsystem_path = undef; # RA, TPS
+my $pfile_instance_file_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $pwcache_conf_instance_file_path = undef; # RA, TPS
+my $pki_cfg_subsystem_file_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $pki_cfg_instance_file_path = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $pki_apache_initscript_file_path = undef; # RA, TPS
+my $schemaMods_ldif_instance_file_path = undef; # RA, TPS
+my $schemaMods_ldif_subsystem_file_path = undef; # RA, TPS
+my $server_xml_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $server_xml_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $servercertnick_conf_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $servercertnick_conf_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_subsystem_jar_file_path = undef; # CA, KRA, OCSP, TKS
+my $pki_subsystem_jar_symlink_path = undef; # CA, KRA, OCSP, TKS
+my $tomcat6_conf_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $tomcat6_conf_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $tomcat6_instance_pid_file_path = undef; # CA, KRA, OCSP, TKS
+my $velocity_prop_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $velocity_prop_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $web_xml_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $web_xml_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $catalina_properties_instance_file_path = undef; # CA, KRA, OCSP, TKS
+my $catalina_properties_subsystem_file_path = undef; # CA, KRA, OCSP, TKS
+my $webapps_root_instance_path = undef; # CA, KRA, OCSP, TKS
+my $webapps_root_subsystem_path = undef; # CA, KRA, OCSP, TKS
+my $webinf_instance_path = undef; # CA, KRA, OCSP, TKS
+my $webinf_lib_instance_path = undef; # CA, KRA, OCSP, TKS
+my $webinf_subsystem_path = undef; # CA, KRA, OCSP, TKS
+my $profile_select_template_subsystem_file_path = undef; #CA
+my $profile_select_template_instance_file_path = undef; #CA
+my $proxy_conf_subsystem_file_path = undef; #CA
+my $proxy_conf_instance_file_path = undef; #CA
+
+# PKI init script variables
+my $pki_registry_initscript = undef; # CA, KRA, OCSP, TKS, RA, TPS
+my $pki_registry_initscript_command = undef; # CA, KRA, OCSP, TKS, RA, TPS
+
+# PKI registry variables
+my $pki_registry_subsystem_path = undef; # CA, KRA, OCSP, TKS RA, TPS
+my $pki_registry_subsystem_file_path = undef; # CA, KRA, OCSP, TKS RA, TPS
+my $pki_registry_instance_file_path = undef; # CA, KRA, OCSP, TKS RA, TPS
+
+# PKI creation variables
+my $host = undef;
+my $db_password = undef;
+my $random = undef;
+
+# Linux specific variables
+my $setup_base_subsystem_dir = "setup";
+my $setup_subsystem_path = undef;
+my $tomcat6_initscript_path = undef;
+my $tomcat6_instance_config_path = undef;
+my $root_user = undef;
+my $root_group = undef;
+my $pki_instance_initscript_path = undef;
+
+#systemd specific variables
+my $use_systemd = 0;
+my $pki_subsystem_systemd_wants_path = undef;
+my $pki_subsystem_systemd_service_path = undef;
+my $pki_instance_systemd_service_name = undef;
+
+
+##############################################################
+# Platform-Dependent Data Initialization
+##############################################################
+
+if ($^O eq "linux") {
+ if (is_Fedora() && (fedora_release() >= 16)) {
+ $use_systemd = 1;
+ }
+
+ # Linux init scripts
+ if ($use_systemd) {
+ $tomcat6_initscript_path = "/usr/sbin/tomcat6-sysd";
+ } else {
+ $tomcat6_initscript_path = "${default_initscripts_path}/tomcat6";
+ }
+
+ # Tomcat instance config directory
+ $tomcat6_instance_config_path = "/etc/sysconfig";
+
+ # Superuser and group to give to PKI installed files
+ $root_user = "root";
+ $root_group = "root";
+} else {
+ emit("Unsupported platform '$^O'!\n", "error");
+ exit 255;
+}
+
+
+##############################################################
+# Local Data Initialization
+##############################################################
+
+# Initialize Java-specific variables
+if ($^O eq "linux") {
+ if ($default_hardware_platform eq "i386") {
+ # 32-bit Linux
+
+ # Supported hardware token PKCS #11 modules
+ %supported_sec_modules_hash = ("lunasa" => "/usr/lunasa/lib/libCryptoki2.so",
+ "nfast" => "/opt/nfast/toolkits/pkcs11/libcknfast.so");
+ } elsif ($default_hardware_platform eq "x86_64") {
+ # 64-bit Linux
+
+ # Supported hardware token PKCS #11 modules
+ %supported_sec_modules_hash = ("lunasa" => "/usr/lunasa/lib/libCryptoki2_64.so",
+ "nfast" => "/opt/nfast/toolkits/pkcs11/libcknfast.so");
+ } else {
+ emit("Unsupported '$^O' hardware platform '$default_hardware_platform'!\n", "error");
+ exit 255;
+ }
+} else {
+ emit("Unsupported platform '$^O'!\n", "error");
+ exit 255;
+}
+
+##############################################################
+# PKI Instance Creation Subroutines
+##############################################################
+
+# no args
+# no return value
+sub usage
+{
+ print STDOUT <<'EOF';
+###############################################################################
+### USAGE: CA, KRA, OCSP, or TKS subsystem instance creation (Tomcat) ###
+###############################################################################
+
+pkicreate -pki_instance_root=<pki_instance_root> # Instance root directory
+ # destination
+
+ -pki_instance_name=<pki_instance_id> # Unique PKI subsystem
+ # instance name
+
+ -subsystem_type=<subsystem_type> # Subsystem type
+ # [ca | kra | ocsp | tks]
+
+ #####################################################################
+ ### SELECT separate secure ports for AGENT, EE, and ADMIN: ###
+ #####################################################################
+
+ -agent_secure_port=<agent_secure_port> # Agent secure port
+
+ -ee_secure_port=<ee_secure_port> # EE secure port
+
+ -admin_secure_port=<admin_secure_port> # Admin secure port
+
+ #####################################################################
+ ### ... and a client auth EE port, required for CAs only ###
+ #####################################################################
+
+ -ee_secure_client_auth_port=<ee_secure_client_auth_port>
+ # EE secure client authentication port
+
+ #####################################################################
+ ### OR SELECT a single secure port shared by AGENT,EE and ADMIN ###
+ ### ###
+ ### WARNING: Use of a single shared secure port has been ###
+ ### DEPRECATED! Use 'port separation' in conjunction ###
+ ### with 'port forwarding' to emulate this behavior. ###
+ #####################################################################
+
+ -secure_port=<secure_port> # Secure port
+ # (shared by Agent,
+ # EE, and Admin)
+
+ #####################################################################
+ ### END secure port SELECTION ###
+ #####################################################################
+
+ -unsecure_port=<unsecure_port> # Unsecure port
+
+ -tomcat_server_port=<tomcat_server_port> # Unique port for each
+ # Tomcat instance
+
+ #####################################################################
+ ### proxy configuration ###
+ ### if -enable_proxy is set, ajp_port, proxy_secure_port, and ###
+ ### proxy_unsecure_port are also set. ###
+ #####################################################################
+
+ [-enable_proxy] #enable proxy configuration
+ [-ajp_port=<ajp_port>] #AJP port, default 9447
+
+ [-proxy_secure_port=<proxy_secure_port>] # Proxy secure port,
+ # default 443
+
+ [-proxy_unsecure_port=<unsecure_port>] # Proxy unsecure port,
+ # default 80
+
+ #####################################################################
+ ### END proxy configuration ###
+ #####################################################################
+
+ [-user=<username>] # User ownership
+ # (must ALSO specify
+ # group ownership)
+ #
+ # [Default=pkiuser]
+
+ [-group=<groupname>] # Group ownership
+ # (must ALSO specify
+ # user ownership)
+ #
+ # [Default=pkiuser]
+
+ [-redirect conf=<real conf dir path>] # Redirection of
+ # 'conf' directory
+
+ [-redirect logs=<real logs dir path>] # Redirection of
+ # 'logs' directory
+
+ [-verbose] # Print out liberal info
+ # during 'pkicreate'.
+ # Specify multiple times
+ # to increase verbosity.
+
+ [-dry_run] # Do not perform any actions.
+ # Just report what would have
+ # been done.
+
+ [-help] # Print out this screen
+
+
+###############################################################################
+### USAGE: RA or TPS subsystem instance creation (Apache) ###
+###############################################################################
+
+pkicreate -pki_instance_root=<pki_instance_root> # Instance root directory
+ # destination
+
+ -pki_instance_name=<pki_instance_id> # Unique PKI subsystem
+ # instance name
+
+ -subsystem_type=<subsystem_type> # Subsystem type
+ # [ra | tps]
+
+ -secure_port=<secure_port> # Secure port
+ # (clientauth)
+ # for each
+ # Apache instance
+
+ -non_clientauth_secure_port=<non_clientauth_secure_port>
+
+ # Secure port
+ # (non-clientauth)
+ # for each
+ # Apache instance
+
+ -unsecure_port=<unsecure_port> # Unsecure port
+
+ [-user=<username>] # User ownership
+ # (must ALSO specify
+ # group ownership)
+ #
+ # [Default=pkiuser]
+
+ [-group=<groupname>] # Group ownership
+ # (must ALSO specify
+ # user ownership)
+ #
+ # [Default=pkiuser]
+
+ [-redirect conf=<real conf dir path>] # Redirection of
+ # 'conf' directory
+
+ [-redirect logs=<real logs dir path>] # Redirection of
+ # 'logs' directory
+
+ [-verbose] # Print out liberal info
+ # during 'pkicreate'.
+ # Specify multiple times
+ # to increase verbosity.
+
+ [-dry_run] # Do not perform any actions.
+ # Just report what would have
+ # been done.
+
+ [-help] # Print out this screen
+
+
+###############################################################################
+### EXAMPLES: ###
+### PKI (Tomcat) subsystem instance creation of a CA ###
+### PKI (Tomcat) subsystem instance creation of a Subordinate CA ###
+### PKI (Tomcat) subsystem instance creation of a KRA ###
+### PKI (Tomcat) subsystem instance creation of an OCSP ###
+### PKI (Tomcat) subsystem instance creation of a TKS ###
+### PKI (Apache) subsystem instance creation of an RA ###
+### PKI (Apache) subsystem instance creation of a TPS ###
+### PKI (Apache) subsystem instance creation of a second TPS ###
+###############################################################################
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-ca \
+ -subsystem_type=ca \
+ -agent_secure_port=9443 \
+ -ee_secure_port=9444 \
+ -ee_secure_client_auth_port=9446 \
+ -admin_secure_port=9445 \
+ -unsecure_port=9180 \
+ -tomcat_server_port=9701 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-ca \
+ -redirect logs=/var/log/pki-ca \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-subca \
+ -subsystem_type=ca \
+ -agent_secure_port=9543 \
+ -ee_secure_port=9544 \
+ -ee_secure_client_auth_port=9546 \
+ -admin_secure_port=9545 \
+ -unsecure_port=9580 \
+ -tomcat_server_port=9801 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-subca \
+ -redirect logs=/var/log/pki-subca \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-kra \
+ -subsystem_type=kra \
+ -agent_secure_port=10443 \
+ -ee_secure_port=10444 \
+ -admin_secure_port=10445 \
+ -unsecure_port=10180 \
+ -tomcat_server_port=10701 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-kra \
+ -redirect logs=/var/log/pki-kra \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-ocsp \
+ -subsystem_type=ocsp \
+ -agent_secure_port=11443 \
+ -ee_secure_port=11444 \
+ -admin_secure_port=11445 \
+ -unsecure_port=11180 \
+ -tomcat_server_port=11701 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-ocsp \
+ -redirect logs=/var/log/pki-ocsp \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-tks \
+ -subsystem_type=tks \
+ -agent_secure_port=13443 \
+ -ee_secure_port=13444 \
+ -admin_secure_port=13445 \
+ -unsecure_port=13180 \
+ -tomcat_server_port=13701 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-tks \
+ -redirect logs=/var/log/pki-tks \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-ra \
+ -subsystem_type=ra \
+ -secure_port=12889 \
+ -non_clientauth_secure_port=12890 \
+ -unsecure_port=12888 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-ra \
+ -redirect logs=/var/log/pki-ra \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-tps \
+ -subsystem_type=tps \
+ -secure_port=7889 \
+ -non_clientauth_secure_port=7890 \
+ -unsecure_port=7888 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-tps \
+ -redirect logs=/var/log/pki-tps \
+ -verbose
+
+pkicreate -pki_instance_root=/var/lib \
+ -pki_instance_name=pki-tps1 \
+ -subsystem_type=tps \
+ -secure_port=7989 \
+ -non_clientauth_secure_port=7990 \
+ -unsecure_port=7988 \
+ -user=pkiuser \
+ -group=pkiuser \
+ -redirect conf=/etc/pki-tps1 \
+ -redirect logs=/var/log/pki-tps1 \
+ -verbose
+
+IMPORTANT: Must be run as root!
+EOF
+
+ return;
+}
+
+
+# arg0 instance name
+# return 1 - exists, or
+# return 0 - DOES NOT exist
+sub pki_instance_already_exists
+{
+ my ($name) = @_;
+ my $result = 0;
+ my $instance = "";
+
+ $instance = $pki_registry_path
+ . "/" . $subsystem_type
+ . "/" . $name;
+
+ if (-e $instance) {
+ $result = 1;
+ }
+
+ return $result;
+}
+
+
+# no args
+# return 1 - success, or
+# return 0 - failure
+sub parse_arguments
+{
+ my $l_secure_port = -1;
+ my $l_non_clientauth_secure_port = -1;
+ my $l_unsecure_port = -1;
+ my $l_tomcat_server_port = -1;
+ my $l_agent_secure_port = -1;
+ my $l_ee_secure_port = -1;
+ my $l_ee_secure_client_auth_port = -1;
+ my $l_admin_secure_port = -1;
+ my $l_proxy_secure_port = -1;
+ my $l_proxy_unsecure_port = -1;
+ my $l_ajp_port = -1;
+ my $show_help = 0;
+
+ my $result = GetOptions("help" => \$show_help,
+ "pki_instance_root=s" => \$pki_instance_root,
+ "pki_instance_name=s" => \$pki_instance_name,
+ "subsystem_type=s" => \$subsystem_type,
+ "secure_port:i" => \$l_secure_port,
+ "non_clientauth_secure_port:i" => \$l_non_clientauth_secure_port,
+ "unsecure_port:i" => \$l_unsecure_port,
+ "agent_secure_port:i" => \$l_agent_secure_port,
+ "ee_secure_port:i" => \$l_ee_secure_port,
+ "ee_secure_client_auth_port:i" => \$l_ee_secure_client_auth_port,
+ "admin_secure_port:i" => \$l_admin_secure_port,
+ "tomcat_server_port:i" => \$l_tomcat_server_port,
+ "proxy_secure_port:i" => \$l_proxy_secure_port,
+ "proxy_unsecure_port:i" => \$l_proxy_unsecure_port,
+ "ajp_port:i" => \$l_ajp_port,
+ "enable_proxy" => \$enable_proxy,
+ "user=s" => \$username,
+ "group=s" => \$groupname,
+ "verbose+" => \$verbose,
+ "dry_run" => \$dry_run,
+ "redirect=s" => \%redirects);
+
+
+ ## Optional "-help" option - no "mandatory" options are required
+ if ($show_help) {
+ usage();
+ return 0;
+ }
+
+
+ ## Mandatory "-pki_instance_root=s" option
+ if (!$pki_instance_root) {
+ usage();
+ emit("Must have value for -pki_instance_root!\n", "error");
+ return 0;
+ }
+
+ if ($pki_instance_root eq "/") {
+ usage();
+ emit("Don't even think about making root the pki_instance_root! "
+ . "Try again.\n", "error");
+ return 0;
+ }
+
+ # Remove all trailing directory separators ('/')
+ $pki_instance_root =~ s/\/+$//;
+
+ if (!is_path_valid($pki_instance_root)) {
+ usage();
+ emit("Target directory $pki_instance_root is not a "
+ . "legal directory try again.\n",
+ "error");
+ return 0;
+ }
+
+ ## Mandatory "-subsystem_type=s" option
+ if ($subsystem_type ne $CA &&
+ $subsystem_type ne $KRA &&
+ $subsystem_type ne $OCSP &&
+ $subsystem_type ne $TKS &&
+ $subsystem_type ne $RA &&
+ $subsystem_type ne $TPS) {
+ usage();
+ emit("Illegal value => $subsystem_type : for -subsystem_type!\n",
+ "error");
+ return 0;
+ }
+
+ $pki_subsystem_path = $pki_subsystem_common_area
+ . "/" . $subsystem_type;
+
+ if (!(-d $pki_subsystem_path)) {
+ usage();
+ emit("$pki_subsystem_path not present. "
+ . "Please install the corresponding subsystem RPM first!\n",
+ "error");
+ return 0;
+ } else {
+ emit(" subsystem_type $subsystem_type\n");
+ }
+
+
+ ## Mandatory "-pki_instance_name=s" option
+ if (!$pki_instance_name) {
+ usage();
+ emit("Must have value for -pki_instance_name!\n", "error");
+ return 0;
+ }
+
+ if (!is_name_valid($pki_instance_name)) {
+ usage();
+ emit("Illegal Value => $pki_instance_name for -pki_instance_name!\n",
+ "error");
+ return 0;
+ }
+
+ if (pki_instance_already_exists($pki_instance_name) && !$dry_run) {
+ usage();
+ emit("An instance named $pki_instance_name "
+ . "already exists; please try again.\n", "error");
+ return 0;
+ }
+
+ $pki_instance_path = "${pki_instance_root}/${pki_instance_name}";
+
+ if (directory_exists($pki_instance_path) && !$dry_run) {
+ usage();
+ emit("Target directory $pki_instance_path "
+ . "already exists; clean up and "
+ . "try again.\n", "error");
+ return 0;
+ }
+
+ # Capture installation information in a log file, always overwrite this file.
+ # When creating an instance it's a fatal error if the logfile
+ # cannot be created.
+ my $logfile = "/var/log/${pki_instance_name}-install.log";
+ if (!open_logfile($logfile, $default_file_permissions)) {
+ emit("can not create logfile ($logfile)", "error");
+ return 0;
+ }
+
+ add_install_info($logfile, 'file', 'preserve');
+
+ printf(STDOUT "Capturing installation information in %s\n", $logfile);
+
+ emit("Parsing PKI creation arguments ...\n");
+
+ if ($verbose) {
+ emit(" verbose mode ENABLED (level=$verbose)\n");
+ }
+
+ if ($dry_run) {
+ emit(" dry run mode ENABLED, system will not be modified\n");
+ print STDOUT "dry run mode ENABLED, system will not be modified\n";
+ }
+
+ emit(" pki_instance_root $pki_instance_root\n");
+ emit(" pki_instance_name $pki_instance_name\n");
+
+ ## Mandatory "-secure_port=<secure_port>" option
+ if ($l_secure_port >= 0) {
+ $secure_port = $l_secure_port;
+
+ emit(" secure_port $secure_port\n");
+ } else {
+ if ($l_agent_secure_port == -1)
+ {
+ usage();
+ emit("Must include value for secure_port!\n", "error");
+ return 0;
+ }
+ }
+
+ ## Mandatory "-non_clientauth_secure_port=<non_clientauth_secure_port>"
+ ## option/exclusion
+ if (($subsystem_type eq $RA || $subsystem_type eq $TPS)) {
+ if ($l_non_clientauth_secure_port >= 0) {
+ $non_clientauth_secure_port = $l_non_clientauth_secure_port;
+
+ emit(" non_clientauth_secure_port "
+ . "$non_clientauth_secure_port\n");
+ } else {
+ if ($l_non_clientauth_secure_port == -1)
+ {
+ usage();
+ emit("Must include value for non_clientauth_secure_port!\n",
+ "error");
+ return 0;
+ }
+ }
+
+ if ($l_agent_secure_port > 0 ||
+ $l_ee_secure_port > 0 ||
+ $l_ee_secure_client_auth_port > 0 ||
+ $l_admin_secure_port > 0) {
+ usage();
+ emit("Must NOT include values for any agent|admin|ee ports!\n",
+ "error");
+ return 0;
+ }
+ } else {
+ ## Mandatory EXCLUSION for CA, KRA, OCSP, and TKS subsystems
+ if ($l_non_clientauth_secure_port != -1) {
+ usage();
+ emit("Must NOT include value for non_clientauth_secure_port!\n",
+ "error");
+ return 0;
+ }
+ }
+
+ ## Mandatory "-unsecure_port=<unsecure_port>" option
+ if ($l_unsecure_port >= 0) {
+ $unsecure_port = $l_unsecure_port;
+
+ emit(" unsecure_port $unsecure_port\n");
+ } else {
+ usage();
+ emit("Must include value for unsecure_port!\n", "error");
+ return 0;
+ }
+
+ ## Mandatory "-tomcat_server_port=<tomcat_server_port>" option/exclusion
+ if (!($subsystem_type eq $RA || $subsystem_type eq $TPS)) {
+ ## Mandatory OPTION for CA, KRA, OCSP, and TKS subsystems
+ if ($l_tomcat_server_port < 0) {
+ usage();
+ emit("Must include value for tomcat_server_port!\n", "error");
+ return 0;
+ }
+
+ $tomcat_server_port = $l_tomcat_server_port;
+
+ emit(" tomcat_server_port $tomcat_server_port\n");
+ } else {
+ ## Mandatory EXCLUSION for RA and TPS subsystems
+ if ($l_tomcat_server_port != -1) {
+ usage();
+ emit("Must NOT include value for tomcat_server_port!\n",
+ "error");
+ return 0;
+ }
+ }
+
+ if ($l_agent_secure_port >= 0) {
+ $agent_secure_port = $l_agent_secure_port;
+
+ emit(" agent_secure_port $agent_secure_port\n");
+
+ }
+
+ ## Mandatory ee_secure_port if "-agent_secure_port" is given
+
+ if ($l_ee_secure_port >= 0) {
+ $ee_secure_port = $l_ee_secure_port;
+
+ emit(" ee_secure_port $ee_secure_port\n");
+
+ } else {
+ if ($agent_secure_port >= 0) {
+ emit("Must include value for ee_secure_port if agent_secure_port is given!\n");
+ }
+ }
+
+ ## Mandatory ee_secure_client_auth_port if "-agent_secure_port" is given, and CA subsystem
+
+ if ($l_ee_secure_client_auth_port >= 0) {
+ $ee_secure_client_auth_port = $l_ee_secure_client_auth_port;
+
+ emit(" ee_secure_client_auth_port $ee_secure_client_auth_port\n");
+
+ } else {
+ if (($agent_secure_port >= 0) && ($subsystem_type eq $CA)) {
+ usage();
+ emit("For CAs, must include value for ee_secure_client_auth_port if agent_secure_port is given!\n");
+ return 0;
+ }
+ }
+
+ ## Mandatory admin_secure_port if "-agent_secure_port" is given
+
+ if ($l_admin_secure_port >= 0) {
+ $admin_secure_port = $l_admin_secure_port;
+
+ emit(" admin_secure_port $admin_secure_port\n");
+
+ } else {
+ if ($agent_secure_port >= 0) {
+ emit("Must include value for admin_secure_port if agent_secure_port is given!\n");
+ }
+ }
+
+ if ($enable_proxy) {
+
+ $proxy_secure_port = ($l_proxy_secure_port >= 0) ? $l_proxy_secure_port :
+ $PROXY_SECURE_PORT_DEFAULT;
+ emit(" proxy_secure_port $proxy_secure_port\n");
+
+ $proxy_unsecure_port = ($l_proxy_unsecure_port >= 0) ? $l_proxy_unsecure_port :
+ $PROXY_UNSECURE_PORT_DEFAULT;
+ emit(" proxy_unsecure_port $proxy_unsecure_port\n");
+
+ $ajp_port = ($l_ajp_port >= 0) ? $l_ajp_port : $AJP_PORT_DEFAULT;
+ emit(" ajp_port $ajp_port\n");
+ }
+
+ if (!AreConnectorPortsValid($secure_port,$unsecure_port,$agent_secure_port,
+ $ee_secure_port,$ee_secure_client_auth_port, $admin_secure_port,
+ $proxy_secure_port, $proxy_unsecure_port))
+ {
+ usage();
+ emit("Invalid port numbers submitted!\n","error");
+ return 0;
+ }
+
+
+ ## Optional "-group=<groupname>" option
+ if ($groupname) {
+ if (!$username) {
+ usage();
+ emit("Must ALSO specify user ownership using -user!\n",
+ "error");
+ return 0;
+ }
+
+ if (!group_exists($groupname)) {
+ if (!create_group($groupname)) {
+ usage();
+ emit("Unable to create group '$groupname' on this machine!\n",
+ "error");
+ return 0;
+ }
+ }
+
+ # Overwrite default value of $pki_group with user-specified $groupname
+ $pki_group = $groupname;
+ }
+
+
+ # At this point in time, ALWAYS check that $pki_group exists!
+ if (!group_exists($pki_group)) {
+ if (!create_group($pki_group)) {
+ usage();
+ emit("Unable to create group '$pki_group' on this machine!\n",
+ "error");
+ return 0;
+ }
+ }
+
+
+ ## Optional "-user=<username>" option
+ if ($username) {
+ if (!$groupname) {
+ usage();
+ emit("Must ALSO specify group ownership using -group!\n",
+ "error");
+ return 0;
+ }
+
+ if (!user_exists($username)) {
+ if (!create_user($username, $groupname)) {
+ usage();
+ emit("Unable to create user '$username' on this machine!\n",
+ "error");
+ return 0;
+ }
+ }
+
+ # Overwrite default value of $pki_user with user-specified $username
+ $pki_user = $username;
+ }
+
+
+ # At this point in time, ALWAYS check that $pki_user exists!
+ if (!user_exists($pki_user)) {
+ if (!create_user($pki_user, $pki_group)) {
+ usage();
+ emit("Unable to create user '$pki_user' on this machine!\n",
+ "error");
+ return 0;
+ }
+ }
+
+
+ # At this point in time, ALWAYS check that shell access for $pki_user is
+ # disallowed; for now, simply notify the user performing the installation
+ # and continue
+ if (!user_disallows_shell($pki_user)) {
+ emit("Please contact your system administrator "
+ . "to disallow shell access for '$pki_user'!\n");
+ }
+
+
+ # At this point in time, ALWAYS check that $pki_user
+ # is a valid member of $pki_group
+ #
+ # NOTE: Uncomment the following code to enforce a strict policy of
+ # requiring $pki_user to be a member of $pki_group . . .
+ #
+ # if (!user_is_a_member_of_group($pki_user, $pki_group)) {
+ # usage();
+ # emit("The user '$pki_user' is NOT a member of group '$pki_group'!\n",
+ # "error");
+ # return 0;
+ # }
+
+
+ # At this point in time, ALWAYS attempt to add $pki_user as a
+ # valid member of $default_nfast_group (presuming one exists)
+ if (group_exists($default_nfast_group)) {
+ # Ignore failures as this should be considered a 'benign' error
+ if (add_user_as_a_member_of_group($pki_user,
+ $default_nfast_group)) {
+ emit("User '$pki_user' is a member of group "
+ . "'$default_nfast_group'.\n");
+ }
+ }
+
+
+ ## Optional "-redirect <dir_name>=<real dir path> ..." option
+ while (my ($key, $value) = each(%redirects)) {
+ if (!is_path_valid($value)) {
+ usage();
+ emit("Illegal redirect directory value: key=$key value="
+ . "$value\n", "error");
+ return 0;
+ }
+
+ if ($key eq "conf") {
+ $redirected_conf_path = $value;
+ emit("setting conf_path $redirected_conf_path\n");
+ } elsif ($key eq "logs") {
+ $redirected_logs_path = $value;
+ emit("setting logs_path $redirected_logs_path\n");
+ } else {
+ usage();
+ emit("Illegal redirect directory key: key=$key value="
+ . "$value\n", "error");
+ return 0;
+ }
+
+ emit("redirect $key => $value\n");
+ }
+
+ ## selinux warning
+ if (($pki_instance_root ne "/var/lib") && ($^O eq "linux")) {
+ print STDOUT <<"EOF";
+WARNING: This utility will attempt to relabel the selinux context of the
+$pki_instance_path directory and the files within it
+as pki_$subsystem_type _var_lib_t
+
+Depending on the location of pki_instance_root and the selinux rules
+currently in place on the system, this may not succeed. In that case, the
+directory may have to be manually relabeled, or selinux will have to be run
+in permissive mode.
+
+It is therefore recommended that the default setting of /var/lib be used
+for pki_instance_root.
+EOF
+
+ASK_CONTINUE_NONSTD_INSTANCE_ROOT:
+
+ my $confirm = prompt("You have chosen the following value for pki_instance_root instead: "
+ . $pki_instance_root
+ . "\nDo you wish to proceed with this value (Y/N)?");
+
+ if ($confirm eq "N" || $confirm eq "n") {
+ return 0;
+ } elsif ($confirm ne "Y" && $confirm ne "y") {
+ goto ASK_CONTINUE_NONSTD_INSTANCE_ROOT;
+ }
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub initialize_subsystem_paths
+{
+ ## Initialize subsystem directory paths (subsystem independent)
+ $conf_subsystem_path = $pki_subsystem_path
+ . "/" . $conf_base_subsystem_dir;
+ $setup_subsystem_path = $pki_subsystem_path
+ . "/" . $setup_base_subsystem_dir;
+
+ $pki_registry_subsystem_path = $pki_registry_path
+ . "/" . $subsystem_type;
+ $pki_registry_subsystem_file_path = $setup_subsystem_path
+ . "/" . $registry_template_base_name;
+
+ $pki_registry_initscript = get_registry_initscript_name($subsystem_type);
+
+ ## systemd subsystem variables
+ $pki_subsystem_systemd_wants_path =
+ "/etc/systemd/system/${pki_registry_initscript}.target.wants";
+ $pki_subsystem_systemd_service_path =
+ "/lib/systemd/system/${pki_registry_initscript}\@.service";
+
+ ## Initialize subsystem directory paths (CA subsystems)
+ if ($subsystem_type eq $CA) {
+ $emails_subsystem_path = $pki_subsystem_path
+ . "/" . $emails_base_subsystem_dir;
+ }
+
+
+ $common_ui_subsystem_path = $pki_subsystem_common_area . "/" .
+ "common-ui";
+ $ui_subsystem_path = $pki_subsystem_path . "-ui";
+
+ ## Initialize subsystem directory paths (RA, TPS subsystems)
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ if ($subsystem_type eq $TPS) {
+ $applets_subsystem_path = $pki_subsystem_path
+ . "/" . $applets_base_subsystem_dir;
+ $bin_subsystem_path = $default_system_user_libraries
+ . "/" . $pki_flavor
+ . "/" . $subsystem_type;
+ $samples_subsystem_path = $pki_subsystem_path
+ . "/" . $samples_base_subsystem_dir;
+ }
+
+ $lib_subsystem_path = $pki_subsystem_path
+ . "/" . $lib_base_subsystem_dir;
+ $scripts_subsystem_path = $pki_subsystem_path
+ . "/" . $scripts_base_subsystem_dir;
+
+ # Apache Specific
+ if ($subsystem_type eq $TPS) {
+ $cgibin_subsystem_path = $pki_subsystem_path
+ . "/" . $cgibin_base_subsystem_dir;
+ }
+
+ # Apache Specific
+ $docroot_subsystem_path = $pki_subsystem_path
+ . "/" . $docroot_base_subsystem_dir;
+ } else {
+
+ ## Initialize subsystem directory paths (CA, KRA, OCSP, TKS subsystems)
+
+ $profiles_subsystem_path = $pki_subsystem_path
+ . "/" . $profiles_base_subsystem_dir;
+ $webapps_subsystem_path = $pki_subsystem_path
+ . "/" . $webapps_base_subsystem_dir;
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub initialize_instance_paths
+{
+ ## Initialize instance directory paths (instance independent)
+ $alias_instance_path = $pki_instance_path
+ . "/" . $alias_base_instance_dir;
+ $conf_instance_path = $pki_instance_path
+ . "/" . $conf_base_instance_dir;
+ $logs_instance_path = $pki_instance_path
+ . "/" . $logs_base_instance_dir;
+
+
+ ## Initialize the pki registry instance
+ $pki_registry_instance_file_path = $pki_registry_subsystem_path
+ . "/" . $pki_instance_name;
+
+ ## Initialize path to per instance init script
+ $pki_instance_initscript_path = $pki_instance_path
+ . "/" . $pki_instance_name;
+
+ ## Initialize tomcat6 instance conf
+ $tomcat6_conf_instance_file_path = $tomcat6_instance_config_path
+ . "/" . $pki_instance_name;
+ ## Initialize tomcat6 pid file
+ $tomcat6_instance_pid_file_path = $default_tomcat_pids_path
+ . "/" . $pki_instance_name
+ . ".pid";
+
+ ## systemd instance service name
+ $pki_instance_systemd_service_name =
+ "${pki_registry_initscript}\@${pki_instance_name}.service";
+
+ ## Initialize instance directory paths (RA, TPS instances)
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ if ($subsystem_type eq $TPS) {
+ $bin_instance_path = $pki_instance_path
+ . "/" . $bin_base_instance_dir;
+ }
+
+ $lib_instance_path = $pki_instance_path
+ . "/" . $lib_base_instance_dir;
+ $scripts_instance_path = $pki_instance_path
+ . "/" . $scripts_base_instance_dir;
+
+ # Apache Specific
+ if ($subsystem_type eq $TPS) {
+ $cgibin_instance_path = $pki_instance_path
+ . "/" . $cgibin_base_instance_dir;
+ }
+
+ # Apache Specific
+ $docroot_instance_path = $pki_instance_path
+ . "/" . $docroot_base_instance_dir;
+ } else {
+ ## Initialize instance directory paths (CA, KRA, OCSP, TKS instances)
+ $emails_instance_path = $pki_instance_path
+ . "/" . $emails_base_instance_dir;
+ $profiles_instance_path = $pki_instance_path
+ . "/" . $profiles_base_instance_dir;
+ $webapps_instance_path = $pki_instance_path
+ . "/" . $webapps_base_instance_dir;
+ $webapps_subsystem_instance_path = $webapps_instance_path . "/"
+ . $subsystem_type;
+
+ # Tomcat Specific
+ $shared_instance_path = $pki_instance_path
+ . "/" . $shared_base_instance_dir;
+ $tomcat_instance_common_lib_path = $pki_instance_path
+ . "/" . $tomcat_instance_common_lib_dir;
+ $temp_instance_path = $pki_instance_path
+ . "/" . $temp_base_instance_dir;
+ $work_instance_path = $pki_instance_path
+ . "/" . $work_base_instance_dir;
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub initialize_instance_symlink_paths
+{
+ ## Initialize instance symlinks (instance independent)
+ $conf_instance_symlink_path = $pki_instance_path
+ . "/" . $conf_base_instance_symlink;
+ $logs_instance_symlink_path = $pki_instance_path
+ . "/" . $logs_base_instance_symlink;
+
+
+ ## Initialize instance symlinks (CA instances)
+ # if ($subsystem_type eq $CA) {
+ # }
+
+
+ ## Initialize instance symlinks (RA, TPS instances)
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ # Apache Specific
+ $run_instance_symlink_path = $pki_instance_path
+ . "/" . $run_base_instance_symlink;
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub initialize_subdirectory_paths
+{
+ ## Initialize subdirectory paths (subsystem independent)
+ $pki_cfg_subsystem_file_path = $conf_subsystem_path
+ . "/" . $pki_cfg_base_name;
+ $pki_piddir_path = $default_apache_pids_path
+ . "/" . $subsystem_type;
+
+ ## Initialize subdirectory paths (CA subsystems)
+ if ($subsystem_type eq $CA) {
+ $profile_select_template_subsystem_file_path = $ui_subsystem_path
+ . "/" . $webapps_base_subsystem_dir
+ . "/" . $subsystem_type
+ . "/ee/" . $subsystem_type
+ . "/" . $profile_select_base_name;
+ $profile_select_template_instance_file_path = $webapps_subsystem_instance_path
+ . "/ee/". $subsystem_type
+ . "/" . $profile_select_base_name;
+
+ $proxy_conf_subsystem_file_path = $conf_subsystem_path
+ . "/" . $proxy_conf_base_name;
+ }
+
+ ## Initialize subdirectory paths (RA, TPS subsystems)
+ if ($subsystem_type eq $TPS) {
+ $cgi_sow_subsystem_file_path = $cgibin_subsystem_path
+ . "/"
+ . $cgi_sow_dir_name;
+ $cgi_sow_instance_cfg_pl_path = $cgibin_instance_path
+ . "/"
+ . $cgi_sow_cfg_pl_name;
+ }
+
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+
+ if ($subsystem_type eq $TPS) {
+
+ $cgi_home_instance_file_path = $cgibin_instance_path
+ . "/"
+ . $cgi_home_base_name;
+ $cgi_home_subsystem_file_path = $cgibin_subsystem_path
+ . "/"
+ . $cgi_home_base_name;
+ $cgi_demo_instance_file_path = $cgibin_instance_path
+ . "/"
+ . $cgi_demo_base_name;
+ $cgi_demo_subsystem_file_path = $cgibin_subsystem_path
+ . "/"
+ . $cgi_demo_base_name;
+ $cgi_so_instance_file_path = $cgibin_instance_path
+ . "/"
+ . $cgi_so_base_name;
+ $cgi_so_subsystem_file_path = $cgibin_subsystem_path
+ . "/"
+ . $cgi_so_base_name;
+ $cgi_so_instance_enroll_file_path = $cgibin_instance_path
+ . "/"
+ . $cgi_so_enroll_name;
+ $cgi_so_subsystem_enroll_file_path = $cgibin_subsystem_path
+ . "/"
+ . $cgi_so_enroll_name;
+ $cgi_sow_instance_file_path = $cgibin_instance_path
+ . "/"
+ . $cgi_sow_dir_name;
+ $addAgents_ldif_instance_file_path = $scripts_instance_path
+ . "/"
+ . $addAgents_ldif_base_name;
+ $addAgents_ldif_subsystem_file_path = $scripts_subsystem_path
+ . "/"
+ . $addAgents_ldif_base_name;
+ $addIndexes_ldif_instance_file_path = $scripts_instance_path
+ . "/"
+ . $addIndexes_ldif_base_name;
+ $addIndexes_ldif_subsystem_file_path = $scripts_subsystem_path
+ . "/"
+ . $addIndexes_ldif_base_name;
+ $addTokens_ldif_instance_file_path = $scripts_instance_path
+ . "/"
+ . $addTokens_ldif_base_name;
+ $addTokens_ldif_subsystem_file_path = $scripts_subsystem_path
+ . "/"
+ . $addTokens_ldif_base_name;
+ $addVLVIndexes_ldif_instance_file_path = $scripts_instance_path
+ . "/"
+ . $addVLVIndexes_ldif_base_name;
+ $addVLVIndexes_ldif_subsystem_file_path = $scripts_subsystem_path
+ . "/"
+ . $addVLVIndexes_ldif_base_name;
+ $schemaMods_ldif_instance_file_path = $scripts_instance_path
+ . "/"
+ . $schemaMods_ldif_base_name;
+ $schemaMods_ldif_subsystem_file_path = $scripts_subsystem_path
+ . "/"
+ . $schemaMods_ldif_base_name;
+ }
+
+ $pki_lockdir_path = $default_lockdir
+ . "/" . $subsystem_type;
+ $pki_apache_initscript_file_path = $pki_subsystem_common_area
+ . "/" . $scripts_base_subsystem_dir
+ . "/" . $pki_apache_initscript_base_name;
+ $nss_pcache_instance_file_path = $scripts_instance_path
+ . "/"
+ . $nss_pcache_base_name;
+ $nss_pcache_subsystem_file_path = $scripts_subsystem_path
+ . "/"
+ . $nss_pcache_base_name;
+ $httpd_conf_subsystem_file_path = $conf_subsystem_path
+ . "/" . $httpd_conf_base_name;
+ $magic_subsystem_file_path = $conf_subsystem_path
+ . "/" . $magic_base_name;
+ $mime_types_subsystem_file_path = $conf_subsystem_path
+ . "/" . $mime_types_base_name;
+ $nss_conf_subsystem_file_path = $conf_subsystem_path
+ . "/" . $nss_conf_base_name;
+ $perl_conf_subsystem_file_path = $conf_subsystem_path
+ . "/" . $perl_conf_base_name;
+ $perl_instance_symlink_path = $lib_instance_path
+ . "/"
+ . $perl_base_instance_symlink;
+ $perl_subsystem_path = $lib_subsystem_path
+ . "/"
+ . $perl_base_subsystem_dir;
+ } else {
+ ## Initialize subdirectory paths (CA, KRA, OCSP, TKS subsystems)
+
+ $pki_subsystem_jar_base_name = "pki-${subsystem_type}.jar";
+
+ if (!defined($pki_certsrv_jar_file_path = find_jar($pki_certsrv_jar_base_name))) {
+ emit("could not find jar: $pki_certsrv_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($pki_cms_jar_file_path = find_jar($pki_cms_jar_base_name))) {
+ emit("could not find jar: $pki_cms_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($pki_cmsbundle_jar_file_path = find_jar($pki_cmsbundle_jar_base_name))) {
+ emit("could not find jar: $pki_cmsbundle_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($pki_cmscore_jar_file_path = find_jar($pki_cmscore_jar_base_name))) {
+ emit("could not find jar: $pki_cmscore_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($pki_cmsutil_jar_file_path = find_jar($pki_cmsutil_jar_base_name))) {
+ emit("could not find jar: $pki_cmsutil_jar_base_name", "error");
+ return 0;
+ }
+
+ # jakarta-commons-* has been renamed to apache-commons-* on some
+ # systems, search which one is available, preferring apache-commons
+ if (defined($commons_collections_jar_file_path = find_jar($apache_commons_collections_jar_base_name))) {
+ $commons_collections_jar_base_name = $apache_commons_collections_jar_base_name;
+ } else {
+ if (defined($commons_collections_jar_file_path = find_jar($jakarta_commons_collections_jar_base_name))) {
+ $commons_collections_jar_base_name = $jakarta_commons_collections_jar_base_name;
+ } else {
+ emit("could not find jar: $apache_commons_collections_jar_base_name or $jakarta_commons_collections_jar_base_name", "error");
+ return 0;
+ }
+ }
+
+ if (defined($commons_lang_jar_file_path = find_jar($apache_commons_lang_jar_base_name))) {
+ $commons_lang_jar_base_name = $apache_commons_lang_jar_base_name;
+ } else {
+ if (defined($commons_lang_jar_file_path = find_jar($jakarta_commons_lang_jar_base_name))) {
+ $commons_lang_jar_base_name = $jakarta_commons_lang_jar_base_name;
+ } else {
+ emit("could not find jar: $apache_commons_lang_jar_base_name or $jakarta_commons_lang_jar_base_name", "error");
+ return 0;
+ }
+ }
+
+ if (defined($commons_logging_jar_file_path = find_jar($apache_commons_logging_jar_base_name))) {
+ $commons_logging_jar_base_name = $apache_commons_logging_jar_base_name;
+ } else {
+ if (defined($commons_logging_jar_file_path = find_jar($jakarta_commons_logging_jar_base_name))) {
+ $commons_logging_jar_base_name = $jakarta_commons_logging_jar_base_name;
+ } else {
+ emit("could not find jar: $apache_commons_logging_jar_base_name or $jakarta_commons_logging_jar_base_name", "error");
+ return 0;
+ }
+ }
+
+ if (!defined($jss_jar_file_path = find_jar($jss_jar_base_name))) {
+ emit("could not find jar: $jss_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($ldapjdk_jar_file_path = find_jar($ldapjdk_jar_base_name))) {
+ emit("could not find jar: $ldapjdk_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($pki_nsutil_jar_file_path = find_jar($pki_nsutil_jar_base_name))) {
+ emit("could not find jar: $pki_nsutil_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($commons_codec_jar_file_path = find_jar($commons_codec_jar_base_name))) {
+ emit("could not find jar: $commons_codec_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($pki_subsystem_jar_file_path = find_jar($pki_subsystem_jar_base_name))) {
+ emit("could not find jar: $pki_subsystem_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($symkey_jar_file_path = find_jar($symkey_jar_base_name))) {
+ emit("could not find jar: $symkey_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($tomcatjss_jar_file_path = find_jar($tomcatjss_jar_base_name))) {
+ emit("could not find jar: $tomcatjss_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($velocity_jar_file_path = find_jar($velocity_jar_base_name))) {
+ emit("could not find jar: $velocity_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($xerces_jar_file_path = find_jar($xerces_jar_base_name))) {
+ emit("could not find jar: $xerces_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($xml_commons_apis_jar_file_path = find_jar($xml_commons_apis_jar_base_name))) {
+ emit("could not find jar: $xml_commons_apis_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($xml_commons_resolver_jar_file_path = find_jar($xml_commons_resolver_jar_base_name))) {
+ emit("could not find jar: $xml_commons_resolver_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($javassist_jar_file_path = find_jar($javassist_jar_base_name))) {
+ emit("could not find jar: $javassist_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($jaxrs_api_jar_file_path = find_jar($jaxrs_api_jar_base_name))) {
+ emit("could not find jar: $jaxrs_api_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($resteasy_jaxb_provider_jar_file_path = find_jar($resteasy_jaxb_provider_jar_base_name))) {
+ emit("could not find jar: $resteasy_jaxb_provider_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($resteasy_jaxrs_jar_file_path = find_jar($resteasy_jaxrs_jar_base_name))) {
+ emit("could not find jar: $resteasy_jaxrs_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($scannotation_jar_file_path = find_jar($scannotation_jar_base_name))) {
+ emit("could not find jar: $scannotation_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($resteasy_jettison_provider_jar_file_path = find_jar($resteasy_jettison_provider_jar_base_name))) {
+ emit("could not find jar: $resteasy_jettison_provider_jar_base_name", "error");
+ return 0;
+ }
+
+ if (!defined($jettison_jar_file_path = find_jar($jettison_jar_base_name))) {
+ emit("could not find jar: $jettison_jar_base_name", "error");
+ return 0;
+ }
+
+ $webinf_instance_path = $webapps_instance_path
+ . "/" . $subsystem_type
+ . "/" . $webinf_base_instance_dir;
+ $webinf_subsystem_path = $webapps_subsystem_path
+ . "/" . $subsystem_type
+ . "/" . $webinf_base_instance_dir;
+ $webinf_lib_instance_path = $webinf_instance_path
+ . "/" . $lib_base_instance_dir;
+ $webapps_root_subsystem_path = $webapps_subsystem_path
+ . "/"
+ . $webapps_root_base_subsystem_dir;
+ $webapps_subsystem_instance_path = $webapps_instance_path
+ . "/" . $subsystem_type;
+
+ $pki_certsrv_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_certsrv_jar_base_name;
+ $pki_cms_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_cms_jar_base_name;
+ $pki_cmsbundle_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_cmsbundle_jar_base_name;
+ $pki_cmscore_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_cmscore_jar_base_name;
+ $pki_cmsutil_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_cmsutil_jar_base_name;
+ $commons_collections_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $commons_collections_jar_base_name;
+ $commons_lang_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $commons_lang_jar_base_name;
+ $commons_logging_jar_symlink_path = $tomcat_instance_common_lib_path
+ . "/" . $commons_logging_jar_base_name;
+ $jss_jar_symlink_path = $tomcat_instance_common_lib_path
+ . "/" . $jss_jar_base_name;
+ $ldapjdk_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $ldapjdk_jar_base_name;
+ $pki_nsutil_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_nsutil_jar_base_name;
+ $commons_codec_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $commons_codec_jar_base_name;
+ $symkey_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $symkey_jar_base_name;
+ $pki_subsystem_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $pki_subsystem_jar_base_name;
+ $tomcatjss_jar_symlink_path = $tomcat_instance_common_lib_path
+ . "/" . $tomcatjss_jar_base_name;
+ $velocity_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $velocity_jar_base_name;
+ $xerces_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $xerces_jar_base_name;
+ $xml_commons_apis_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $xml_commons_apis_jar_base_name;
+ $xml_commons_resolver_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $xml_commons_resolver_jar_base_name;
+
+ #resteasy
+ $javassist_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $javassist_jar_base_name;
+ $jaxrs_api_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $jaxrs_api_jar_base_name;
+ $resteasy_jaxb_provider_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $resteasy_jaxb_provider_jar_base_name;
+ $resteasy_jaxrs_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $resteasy_jaxrs_jar_base_name;
+ $scannotation_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $scannotation_jar_base_name;
+ $resteasy_jettison_provider_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $resteasy_jettison_provider_jar_base_name;
+ $jettison_jar_symlink_path = $webinf_lib_instance_path
+ . "/" . $jettison_jar_base_name;
+
+
+ $webapps_root_instance_path = $webapps_instance_path
+ . "/"
+ . $webapps_root_base_instance_dir;
+ $index_jsp_instance_file_path = $webapps_root_instance_path
+ . "/" . $index_jsp_base_name;
+ $index_jsp_subsystem_file_path = $webapps_root_subsystem_path
+ . "/" . $index_jsp_base_name;
+ $server_xml_subsystem_file_path = $conf_subsystem_path
+ . "/" . $server_xml_base_name;
+ $servercertnick_conf_subsystem_file_path = $conf_subsystem_path
+ . "/" . $servercertnick_conf_base_name;
+ $tomcat6_conf_subsystem_file_path = $conf_subsystem_path
+ . "/" . $tomcat6_conf_base_name;
+ $velocity_prop_instance_file_path = $webinf_instance_path
+ . "/" . $velocity_prop_base_name;
+ $velocity_prop_subsystem_file_path = $webinf_subsystem_path
+ . "/" . $velocity_prop_base_name;
+ $web_xml_instance_file_path = $webinf_instance_path
+ . "/" . $web_xml_base_name;
+ $web_xml_subsystem_file_path = $webinf_subsystem_path
+ . "/" . $web_xml_base_name;
+ $catalina_properties_subsystem_file_path = $conf_subsystem_path
+ . "/" . $catalina_properties_base_name;
+ }
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub initialize_paths
+{
+ return 0 if !initialize_subsystem_paths();
+ return 0 if !initialize_instance_paths();
+ return 0 if !initialize_instance_symlink_paths();
+ return 0 if !initialize_subdirectory_paths();
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub initialize_pki_creation_values
+{
+ # obtain the fully-qualified domain name of this host
+ $host = get_FQDN($hostname);
+
+ # we need the certdb password generated now ...
+ $db_password = generate_random($db_password_low, $db_password_high);
+
+ # generate a random value for a pin ...
+ $random = generate_random_string(20);
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub process_pki_directories
+{
+ my $remove_dir="";
+
+ emit("Processing PKI directories for '$pki_instance_path' ...\n");
+
+ ## Populate instance directory paths (instance independent)
+ return 0 if !create_directory($alias_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ # Check for an optionally redirected "conf" directory path ...
+ if (!$redirected_conf_path) {
+ $noise_instance_file_path = $conf_instance_path
+ . "/" . $noise_base_name;
+ $password_conf_instance_file_path = $conf_instance_path
+ . "/" . $password_conf_base_name;
+ $pfile_instance_file_path = $conf_instance_path
+ . "/" . $pfile_base_name;
+ $pki_cfg_instance_file_path = $conf_instance_path
+ . "/" . $pki_cfg_base_name;
+ $proxy_conf_instance_file_path = $conf_instance_path
+ . "/" . $proxy_conf_base_name;
+ $catalina_properties_instance_file_path = $conf_instance_path
+ . "/" . $catalina_properties_base_name;
+
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ $httpd_conf_instance_file_path = $conf_instance_path
+ . "/" . $httpd_conf_base_name;
+ $magic_instance_file_path = $conf_instance_path
+ . "/" . $magic_base_name;
+ $mime_types_instance_file_path = $conf_instance_path
+ . "/" . $mime_types_base_name;
+ $nss_conf_instance_file_path = $conf_instance_path
+ . "/" . $nss_conf_base_name;
+ $perl_conf_instance_file_path = $conf_instance_path
+ . "/" . $perl_conf_base_name;
+ $pwcache_conf_instance_file_path = $conf_instance_path
+ . "/" . $pwcache_conf_base_name;
+
+ # create instance directory
+ return 0 if !create_directory($conf_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ # only copy selected files
+ return 0 if !copy_file($magic_subsystem_file_path, $magic_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ return 0 if !copy_file($mime_types_subsystem_file_path, $mime_types_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ } else {
+ $server_xml_instance_file_path = $conf_instance_path
+ . "/" . $server_xml_base_name;
+ $servercertnick_conf_instance_file_path = $conf_instance_path
+ . "/" . $servercertnick_conf_base_name;
+
+ return 0 if !copy_directory($conf_subsystem_path, $conf_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+ }
+ } else {
+ $noise_instance_file_path = $redirected_conf_path
+ . "/" . $noise_base_name;
+ $password_conf_instance_file_path = $redirected_conf_path
+ . "/" . $password_conf_base_name;
+ $pfile_instance_file_path = $redirected_conf_path
+ . "/" . $pfile_base_name;
+ $pki_cfg_instance_file_path = $redirected_conf_path
+ . "/" . $pki_cfg_base_name;
+ $proxy_conf_instance_file_path = $redirected_conf_path
+ . "/" . $proxy_conf_base_name;
+ $catalina_properties_instance_file_path = $redirected_conf_path
+ . "/" . $catalina_properties_base_name;
+
+ # Populate optionally redirected instance directory path
+ # and setup a symlink in the standard area
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ $httpd_conf_instance_file_path = $redirected_conf_path
+ . "/" . $httpd_conf_base_name;
+ $magic_instance_file_path = $redirected_conf_path
+ . "/" . $magic_base_name;
+ $mime_types_instance_file_path = $redirected_conf_path
+ . "/" . $mime_types_base_name;
+ $nss_conf_instance_file_path = $redirected_conf_path
+ . "/" . $nss_conf_base_name;
+ $perl_conf_instance_file_path = $redirected_conf_path
+ . "/" . $perl_conf_base_name;
+ $pwcache_conf_instance_file_path = $redirected_conf_path
+ . "/" . $pwcache_conf_base_name;
+
+ # create redirected instance directory
+ return 0 if !create_directory($redirected_conf_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ # only copy selected files
+ return 0 if !copy_file($magic_subsystem_file_path, $magic_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ return 0 if !copy_file($mime_types_subsystem_file_path, $mime_types_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ } else {
+ $server_xml_instance_file_path = $redirected_conf_path
+ . "/" . $server_xml_base_name;
+ $servercertnick_conf_instance_file_path = $redirected_conf_path
+ . "/" . $servercertnick_conf_base_name;
+
+ return 0 if !copy_directory($conf_subsystem_path, $redirected_conf_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+ }
+
+ return 0 if !create_symlink($conf_instance_symlink_path, $redirected_conf_path,
+ $pki_user, $pki_group);
+
+ }
+
+
+ # Check for an optionally redirected "logs" directory path ...
+ if (!$redirected_logs_path) {
+ # create instance directory
+ return 0 if !create_directory(${logs_instance_path},
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ ## (CA, KRA, OCSP, TKS, TPS instances)
+ if ($subsystem_type ne $RA) {
+ ## Create a "signedAudit" directory
+ return 0 if !create_directory("${logs_instance_path}/${signed_audit_base_instance_dir}",
+ $default_dir_permissions, $pki_user, $pki_group);
+ }
+ } else {
+ # create redirected instance directory
+ # and setup a symlink in the standard area
+ return 0 if !create_directory($redirected_logs_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ ## (CA, KRA, OCSP, TKS, TPS instances)
+ if ($subsystem_type ne $RA) {
+ ## Create a "signedAudit" directory
+ return 0 if !create_directory("${redirected_logs_path}/${signed_audit_base_instance_dir}",
+ $default_dir_permissions, $pki_user, $pki_group);
+ }
+
+ return 0 if !create_symlink($logs_instance_symlink_path, $redirected_logs_path,
+ $pki_user, $pki_group);
+
+ return 0 if !set_owner_group_on_directory_contents($redirected_logs_path, $pki_user, $pki_group);
+ }
+
+
+ ## Populate pki instance registry
+ # create pki registry for this subsystem
+ return 0 if !create_directory($pki_registry_subsystem_path,
+ $default_dir_permissions, $pki_user, $pki_group, 'preserve');
+
+
+ ## Populate instance directory paths (CA instances)
+ if ($subsystem_type eq $CA) {
+ return 0 if !copy_directory($emails_subsystem_path, $emails_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+
+ return 0 if !copy_directory($profiles_subsystem_path, $profiles_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+ }
+
+
+ ## Populate instance directory paths (RA, TPS instances)
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+
+ if ($subsystem_type eq $TPS) {
+ return 0 if !create_directory($bin_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+ }
+
+ return 0 if !create_directory($lib_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !create_directory($scripts_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ # Apache Specific
+ if ($subsystem_type eq $TPS) {
+ return 0 if !copy_directory($cgibin_subsystem_path, $cgibin_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+ }
+
+ # Apache Specific
+ return 0 if !copy_directory($docroot_subsystem_path, $docroot_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+
+
+ return 0 if !copy_directory($ui_subsystem_path, $pki_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+
+ # fix permissions
+ if (!is_Windows()) {
+ # Apache Specific
+ if ($subsystem_type eq $TPS) {
+ set_permissions("${cgibin_instance_path}/demo", $default_dir_permissions);
+ set_permissions("${cgibin_instance_path}/demo/*.cgi", $default_exe_permissions);
+ set_permissions("${cgibin_instance_path}/demo/*.html", $default_file_permissions);
+ set_permissions("${cgibin_instance_path}/home", $default_dir_permissions);
+ set_permissions("${cgibin_instance_path}/home/*.cgi", $default_exe_permissions);
+ set_permissions("${cgibin_instance_path}/home/*.html", $default_file_permissions);
+ set_permissions("${cgibin_instance_path}/so", $default_dir_permissions);
+ set_permissions("${cgibin_instance_path}/so/*.cgi", $default_exe_permissions);
+ set_permissions("${cgibin_instance_path}/so/*.html", $default_file_permissions);
+ set_permissions("${cgibin_instance_path}/sow", $default_dir_permissions);
+ set_permissions("${cgibin_instance_path}/sow/*.cgi", $default_exe_permissions);
+ set_permissions("${cgibin_instance_path}/sow/*.html", $default_file_permissions);
+ set_permissions("${cgibin_instance_path}/sow/*.pl", $default_exe_permissions);
+ set_permissions("${docroot_instance_path}/", $default_dir_permissions);
+ set_permissions("${docroot_instance_path}/*.cgi", $default_exe_permissions);
+ }
+ }
+ } else {
+ ## Populate instance directory paths (CA, KRA, OCSP, TKS instances)
+ return 0 if !copy_directory($webapps_subsystem_path, $webapps_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+
+ return 0 if !copy_directory($common_ui_subsystem_path, $webapps_subsystem_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+
+ return 0 if !copy_directory($ui_subsystem_path, $pki_instance_path,
+ $default_dir_permissions, $default_file_permissions,
+ $pki_user, $pki_group);
+
+ ## Tomcat Specific
+ return 0 if !create_directory($shared_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !create_directory("$shared_instance_path/classes",
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !create_directory("$shared_instance_path/lib",
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !create_directory($tomcat_instance_common_lib_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !create_directory($temp_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !create_directory($work_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+ }
+
+ ## Set appropriate permissions
+ return 0 if !set_owner_group_on_directory_contents($pki_instance_path, $pki_user, $pki_group);
+
+ return 1;
+}
+
+
+# process_file_template
+#
+# template_name
+# Used to identify the template.
+# src_path
+# The file pathname of the template.
+# dst_path
+# The file pathname the processed template will be written to.
+# substitutions
+# Pointer to a hash. Each key is a substitution name, the key's
+# value is the string to substitute.
+#
+# Given a template file, read it's contents in. Then perform text
+# replacements on any string of the form "[name]". name will be used
+# as a key in the substitutions hash, if the key exists in the hash then
+# it's value will replace the string "[name]".
+#
+# Example, if the src template contained this line:
+#
+# Open port [PORT] on your firewall.
+#
+# And the substitutions hash was this {'PORT' => '1234'}
+#
+# Then the dst file contents will look like this:
+#
+# Open port 1234 on your firewall.
+#
+# Return 1 if success, 0 if failure
+
+sub process_file_template
+{
+ my ($template_name, $src_path, $dst_path, $substitutions) = @_;
+
+ my $buf = "";
+ my $num_subs = 0;
+ my $total_subs = 0;
+ my @keys;
+ my $key;
+ my $value;
+ emit(" Template ($template_name) \"${src_path}\" ==> \"${dst_path}\" ...\n");
+
+ # Check for a valid source file
+ if (!is_path_valid($src_path)) {
+ emit("process_file_template(): invalid source path ${src_path}!\n", "error");
+ return 0;
+ }
+
+ # Check for a valid destination file
+ if (!is_path_valid($dst_path)) {
+ emit("process_file_template(): invalid destination path ${dst_path}!\n", "error");
+ return 0;
+ }
+
+ # Read in contents of source file
+ $buf = read_file($src_path);
+
+ # Process each line substituting each [KEY]
+ # with its corresponding slot hash value
+ @keys = sort(keys %$substitutions);
+ foreach $key (@keys) {
+ $value = $substitutions->{$key};
+ # Perform global substitution on buffer and
+ # get count of how many substitutions were actually performed.
+ $num_subs = $buf =~ s/\[$key\]/$value/g;
+ $total_subs += $num_subs;
+
+ # If any substitutions were performed then log what was done.
+ if ($num_subs > 0) {
+ # Hide sensitive information by emitting the word "(sensitive)"
+ # rather rather than the substituted value.
+ if ($key eq $PKI_CERT_DB_PASSWORD_SLOT) {
+ emit(sprintf(" %3d substitutions: %s ==> (sensitive)\n", $num_subs, $key));
+ } else {
+ emit(sprintf(" %3d substitutions: %s ==> \"%s\"\n", $num_subs, $key, $value));
+ }
+ }
+ }
+
+ emit(" $total_subs substitutions were made in '$dst_path'\n");
+
+ # Sanity check, are there any strings left in the buffer which look
+ # like a substitution.
+ foreach my $match ($buf =~ /\[[A-Z_]+\]/g) {
+ emit("WARNING: Possible missed substitution \"$match\" in $src_path");
+ }
+
+ # Record that we've installed this file.
+ add_install_info($dst_path, 'file');
+
+ if ($verbose >= 2) {
+ # For debugging, emit the contents after substitution.
+ emit(sprintf(">> $dst_path\n%s<< $dst_path\n", $buf));
+ }
+
+ if (!$dry_run) {
+ # Write out these modified contents to the destination file.
+ write_file($dst_path, \$buf);
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub process_pki_templates
+{
+ my $use_port_separation = 0;
+ if ($agent_secure_port >= 0 &&
+ ($subsystem_type ne $RA) &&
+ ($subsystem_type ne $TPS)) {
+ $use_port_separation = 1;
+ }
+
+ my %slot_hash = ();
+
+ emit("Processing PKI templates for '$pki_instance_path' ...\n");
+
+ $slot_hash{$PKI_SUBSYSTEM_TYPE_SLOT} = $subsystem_type;
+ $slot_hash{$PKI_INSTANCE_ID_SLOT} = $pki_instance_name;
+ $slot_hash{$PKI_INSTANCE_ROOT_SLOT} = $pki_instance_root;
+ $slot_hash{$PKI_INSTANCE_INITSCRIPT} = $pki_instance_initscript_path;
+ $slot_hash{$PKI_REGISTRY_FILE_SLOT} = $pki_registry_instance_file_path;
+ $slot_hash{$PKI_USER_SLOT} = $pki_user;
+ $slot_hash{$PKI_GROUP_SLOT} = $pki_group;
+ $slot_hash{$PKI_PIDDIR} = $pki_piddir_path;
+
+ if ($subsystem_type eq $TPS) {
+ $slot_hash{$REQUIRE_CFG_PL} = "require \"${cgi_sow_instance_cfg_pl_path}\";";
+ }
+
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ # Setup templates (RA, TPS)
+ $slot_hash{$HTTPD_CONF} = $httpd_conf_instance_file_path;
+ $slot_hash{$LIB_PREFIX} = $lib_prefix;
+ $slot_hash{$NSS_CONF} = $nss_conf_instance_file_path;
+ $slot_hash{$OBJ_EXT} = $obj_ext;
+ $slot_hash{$PORT} = $unsecure_port;
+ $slot_hash{$PROCESS_ID} = $$;
+ $slot_hash{$SECURE_PORT} = $secure_port;
+ $slot_hash{$NON_CLIENTAUTH_SECURE_PORT} = $non_clientauth_secure_port;
+ $slot_hash{$SECURITY_LIBRARIES} = $default_security_libraries;
+ $slot_hash{$SERVER_NAME} = $host;
+ $slot_hash{$SERVER_ROOT} = $pki_instance_path;
+ $slot_hash{$SYSTEM_LIBRARIES} = $default_system_libraries;
+ $slot_hash{$SYSTEM_USER_LIBRARIES} = $default_system_user_libraries;
+ $slot_hash{$TMP_DIR} = $tmp_dir;
+ $slot_hash{$TPS_DIR} = $pki_subsystem_path;
+ $slot_hash{$PKI_FLAVOR_SLOT} = $pki_flavor;
+ $slot_hash{$PKI_RANDOM_NUMBER_SLOT} = $random;
+ $slot_hash{$PKI_LOCKDIR} = $pki_lockdir_path;
+ if (is_Fedora() || (is_RHEL() && (! is_RHEL4()))) {
+ $slot_hash{$FORTITUDE_APACHE} = "Apache2";
+ $slot_hash{$FORTITUDE_DIR} = "/usr";
+ $slot_hash{$FORTITUDE_LIB_DIR} = "/etc/httpd";
+ $slot_hash{$FORTITUDE_MODULE} = "/etc/httpd/modules";
+ $slot_hash{$FORTITUDE_AUTH_MODULES} =
+"
+LoadModule auth_basic_module /etc/httpd/modules/mod_auth_basic.so
+LoadModule authn_file_module /etc/httpd/modules/mod_authn_file.so
+LoadModule authz_user_module /etc/httpd/modules/mod_authz_user.so
+LoadModule authz_groupfile_module /etc/httpd/modules/mod_authz_groupfile.so
+LoadModule authz_host_module /etc/httpd/modules/mod_authz_host.so
+";
+ $slot_hash{$FORTITUDE_NSS_MODULES} =
+"
+LoadModule nss_module /etc/httpd/modules/libmodnss.so
+";
+ }
+ else {
+ $slot_hash{$FORTITUDE_APACHE} = "Apache";
+ $slot_hash{$FORTITUDE_DIR} = "/opt/fortitude";
+ $slot_hash{$FORTITUDE_LIB_DIR} = "/opt/fortitude";
+ $slot_hash{$FORTITUDE_MODULE} = "/opt/fortitude/modules.local";
+ $slot_hash{$FORTITUDE_AUTH_MODULES} =
+"
+LoadModule auth_module /opt/fortitude/modules/mod_auth.so
+LoadModule access_module /opt/fortitude/modules/mod_access.so
+";
+ $slot_hash{$FORTITUDE_NSS_MODULES} =
+"
+LoadModule nss_module /opt/fortitude/modules.local/libmodnss.so
+";
+ }
+ } else {
+ # Setup templates (CA, KRA, OCSP, TKS)
+ $slot_hash{$INSTALL_TIME} = localtime;
+ $slot_hash{$PKI_CERT_DB_PASSWORD_SLOT} = $db_password;
+ $slot_hash{$PKI_CFG_PATH_NAME_SLOT} = $pki_cfg_instance_file_path;
+ $slot_hash{$PKI_INSTANCE_PATH_SLOT} = $pki_instance_path;
+ $slot_hash{$PKI_MACHINE_NAME_SLOT} = $host;
+ $slot_hash{$PKI_RANDOM_NUMBER_SLOT} = $random;
+ $slot_hash{$PKI_SERVER_XML_CONF} = $server_xml_instance_file_path;
+ $slot_hash{$PKI_UNSECURE_PORT_SLOT} = $unsecure_port;
+
+ if ($use_systemd) {
+ $slot_hash{$PKI_SYSTEMD_SERVICENAME_SLOT} = $pki_instance_systemd_service_name;
+ } else {
+ $slot_hash{$PKI_SYSTEMD_SERVICENAME_SLOT} = "";
+ }
+
+ # Define "Port Separation" (default) versus "Shared Ports" (legacy)
+ if ($use_port_separation) {
+ # Establish "Port Separation" Connector Names
+ $slot_hash{$PKI_UNSECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_UNSECURE_PORT_NAME;
+ $slot_hash{$PKI_SECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_AGENT_SECURE_PORT_NAME;
+ $slot_hash{$PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_ADMIN_SECURE_PORT_NAME;
+ $slot_hash{$PKI_EE_SECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_EE_SECURE_PORT_NAME;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_CONNECTOR_NAME_SLOT} = $PKI_EE_SECURE_CLIENT_AUTH_PORT_NAME;
+
+ # Establish "Port Separation" Connector Ports
+ $slot_hash{$PKI_SECURE_PORT_SLOT} = $agent_secure_port;
+ $slot_hash{$PKI_AGENT_SECURE_PORT_SLOT} = $agent_secure_port;
+ $slot_hash{$PKI_EE_SECURE_PORT_SLOT} = $ee_secure_port;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_SLOT} = $ee_secure_client_auth_port;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_UI_SLOT} = $ee_secure_client_auth_port;
+ $slot_hash{$PKI_ADMIN_SECURE_PORT_SLOT} = $admin_secure_port;
+
+ # Comment "Port Separation" appropriately
+ $slot_hash{$PKI_UNSECURE_PORT_COMMENT_SERVER_SLOT} = $PKI_UNSECURE_SEPARATE_PORTS_COMMENT;
+ $slot_hash{$PKI_SECURE_PORT_COMMENT_SERVER_SLOT} = $PKI_AGENT_SECURE_SEPARATE_PORTS_COMMENT;
+ $slot_hash{$PKI_ADMIN_SECURE_PORT_COMMENT_SERVER_SLOT} = $PKI_ADMIN_SECURE_SEPARATE_PORTS_COMMENT;
+ $slot_hash{$PKI_EE_SECURE_PORT_COMMENT_SERVER_SLOT} = $PKI_EE_SECURE_SEPARATE_PORTS_COMMENT;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_COMMENT_SERVER_SLOT} = $PKI_EE_SECURE_CLIENT_AUTH_SEPARATE_PORTS_COMMENT;
+
+ # Set appropriate "clientAuth" parameter for "Port Separation"
+ $slot_hash{$PKI_AGENT_CLIENTAUTH_SLOT} = "true";
+
+ # Do NOT comment out the "Admin/EE" Ports
+ $slot_hash{$PKI_OPEN_SEPARATE_PORTS_COMMENT_SERVER_SLOT} = "";
+ $slot_hash{$PKI_CLOSE_SEPARATE_PORTS_COMMENT_SERVER_SLOT} = "";
+
+ # Do NOT comment out the "Admin/Agent/EE" Filters
+ # used by Port Separation
+ $slot_hash{$PKI_OPEN_SEPARATE_PORTS_COMMENT_WEB_SLOT} = "";
+ $slot_hash{$PKI_CLOSE_SEPARATE_PORTS_COMMENT_WEB_SLOT} = "";
+ } else {
+ # Establish "Shared Ports" Connector Names
+ $slot_hash{$PKI_UNSECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_UNSECURE_PORT_NAME;
+ $slot_hash{$PKI_SECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_SECURE_PORT_NAME;
+ $slot_hash{$PKI_ADMIN_SECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_UNUSED_SECURE_PORT_NAME;
+ $slot_hash{$PKI_EE_SECURE_PORT_CONNECTOR_NAME_SLOT} = $PKI_UNUSED_SECURE_PORT_NAME;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_CONNECTOR_NAME_SLOT} = $PKI_UNUSED_SECURE_PORT_NAME;
+
+ # Establish "Shared Ports" Connector Ports
+ $slot_hash{$PKI_SECURE_PORT_SLOT} = $secure_port;
+ $slot_hash{$PKI_AGENT_SECURE_PORT_SLOT} = $secure_port;
+ $slot_hash{$PKI_EE_SECURE_PORT_SLOT} = $secure_port;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_SLOT} = $secure_port;
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_UI_SLOT} = $secure_port;
+ $slot_hash{$PKI_ADMIN_SECURE_PORT_SLOT} = $secure_port;
+
+ # Comment "Shared Ports" appropriately
+ $slot_hash{$PKI_UNSECURE_PORT_COMMENT_SERVER_SLOT} = $PKI_UNSECURE_SHARED_PORTS_COMMENT;
+ $slot_hash{$PKI_SECURE_PORT_COMMENT_SERVER_SLOT} = $PKI_SECURE_SHARED_PORTS_COMMENT;
+ $slot_hash{$PKI_ADMIN_SECURE_PORT_COMMENT_SERVER_SLOT} = "";
+ $slot_hash{$PKI_EE_SECURE_PORT_COMMENT_SERVER_SLOT} = "";
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_COMMENT_SERVER_SLOT} = "";
+
+ # Set appropriate "clientAuth" parameter for "Shared Ports"
+ $slot_hash{$PKI_AGENT_CLIENTAUTH_SLOT} = "agent";
+
+ # Comment out the "Admin/EE" Ports
+ $slot_hash{$PKI_OPEN_SEPARATE_PORTS_COMMENT_SERVER_SLOT} = $PKI_OPEN_COMMENT;
+ $slot_hash{$PKI_CLOSE_SEPARATE_PORTS_COMMENT_SERVER_SLOT} = $PKI_CLOSE_COMMENT;;
+
+ # Comment out the "Admin/Agent/EE" Filters
+ $slot_hash{$PKI_OPEN_SEPARATE_PORTS_COMMENT_WEB_SLOT} = $PKI_OPEN_COMMENT;
+ $slot_hash{$PKI_CLOSE_SEPARATE_PORTS_COMMENT_WEB_SLOT} = $PKI_CLOSE_COMMENT;
+ }
+
+ if ($enable_proxy) {
+ if ($use_port_separation) {
+ $slot_hash{$PKI_AJP_REDIRECT_PORT_SLOT} = $ee_secure_port;
+ } else {
+ $slot_hash{$PKI_AJP_REDIRECT_PORT_SLOT} = $secure_port;
+ }
+ $slot_hash{$PKI_EE_SECURE_CLIENT_AUTH_PORT_UI_SLOT} = $proxy_secure_port;
+ $slot_hash{$PKI_AJP_PORT_SLOT} = $ajp_port;
+ $slot_hash{$PKI_OPEN_AJP_PORT_COMMENT_SLOT} = "";
+ $slot_hash{$PKI_CLOSE_AJP_PORT_COMMENT_SLOT} = "";
+ $slot_hash{$PKI_OPEN_ENABLE_PROXY_COMMENT_SLOT} = "";
+ $slot_hash{$PKI_CLOSE_ENABLE_PROXY_COMMENT_SLOT} = "";
+ } else {
+ $slot_hash{$PKI_OPEN_AJP_PORT_COMMENT_SLOT} = $PKI_OPEN_COMMENT;
+ $slot_hash{$PKI_CLOSE_AJP_PORT_COMMENT_SLOT} = $PKI_CLOSE_COMMENT;
+ $slot_hash{$PKI_OPEN_ENABLE_PROXY_COMMENT_SLOT} = $PKI_OPEN_COMMENT;
+ $slot_hash{$PKI_CLOSE_ENABLE_PROXY_COMMENT_SLOT} = $PKI_CLOSE_COMMENT;
+ }
+
+ $slot_hash{$PROXY_SECURE_PORT_SLOT} = ($proxy_secure_port >=0) ?
+ $proxy_secure_port : "";
+ $slot_hash{$PROXY_UNSECURE_PORT_SLOT} = ($proxy_unsecure_port>=0) ?
+ $proxy_unsecure_port : "";
+
+ $slot_hash{$PKI_WEBAPPS_NAME} = $webapps_base_subsystem_dir;
+ $slot_hash{$PKI_FLAVOR_SLOT} = $pki_flavor;
+ $slot_hash{$TOMCAT_SERVER_PORT_SLOT} = $tomcat_server_port;
+ $slot_hash{$TOMCAT_PIDFILE} = $tomcat6_instance_pid_file_path;
+ $slot_hash{$TOMCAT_CFG} = $tomcat6_conf_instance_file_path;
+ $slot_hash{$TOMCAT_SSL_OPTIONS} = "ssl2=true,ssl3=true,tls=true";
+ $slot_hash{$TOMCAT_SSL2_CIPHERS} = "-SSL2_RC4_128_WITH_MD5,-SSL2_RC4_128_EXPORT40_WITH_MD5,"
+ . "-SSL2_RC2_128_CBC_WITH_MD5,-SSL2_RC2_128_CBC_EXPORT40_WITH_MD5,"
+ . "-SSL2_DES_64_CBC_WITH_MD5,-SSL2_DES_192_EDE3_CBC_WITH_MD5";
+ $slot_hash{$TOMCAT_SSL3_CIPHERS} = "-SSL3_FORTEZZA_DMS_WITH_NULL_SHA,-SSL3_FORTEZZA_DMS_WITH_RC4_128_SHA,"
+ . "+SSL3_RSA_WITH_RC4_128_SHA,-SSL3_RSA_EXPORT_WITH_RC4_40_MD5,"
+ . "+SSL3_RSA_WITH_3DES_EDE_CBC_SHA,+SSL3_RSA_WITH_DES_CBC_SHA,"
+ . "-SSL3_RSA_EXPORT_WITH_RC2_CBC_40_MD5,-SSL3_FORTEZZA_DMS_WITH_FORTEZZA_CBC_SHA,"
+ . "-SSL_RSA_FIPS_WITH_DES_CBC_SHA,+SSL_RSA_FIPS_WITH_3DES_EDE_CBC_SHA,"
+ . "-SSL3_RSA_WITH_NULL_MD5,-TLS_RSA_EXPORT1024_WITH_RC4_56_SHA,"
+ . "-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA";
+ $slot_hash{$TOMCAT_TLS_CIPHERS} = "-TLS_ECDH_ECDSA_WITH_AES_128_CBC_SHA,-TLS_ECDH_ECDSA_WITH_3DES_EDE_CBC_SHA,"
+ . "+TLS_ECDH_RSA_WITH_3DES_EDE_CBC_SHA,+TLS_ECDH_RSA_WITH_AES_128_CBC_SHA,"
+ . "+TLS_ECDH_RSA_WITH_AES_256_CBC_SHA,-TLS_ECDH_ECDSA_WITH_AES_256_CBC_SHA,"
+ . "+TLS_ECDHE_ECDSA_WITH_AES_256_CBC_SHA,+TLS_RSA_WITH_3DES_EDE_CBC_SHA,"
+ . "+TLS_RSA_WITH_AES_128_CBC_SHA,+TLS_RSA_WITH_AES_256_CBC_SHA,"
+ . "+TLS_ECDHE_ECDSA_WITH_3DES_EDE_CBC_SHA,+TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA,"
+ . "-TLS_ECDHE_RSA_WITH_3DES_EDE_CBC_SHA,-TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA,"
+ . "-TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA,+TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA,"
+ . "+TLS_DHE_DSS_WITH_AES_128_CBC_SHA,+TLS_DHE_DSS_WITH_AES_256_CBC_SHA,"
+ . "+TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA,+TLS_DHE_RSA_WITH_AES_128_CBC_SHA,"
+ . "+TLS_DHE_RSA_WITH_AES_256_CBC_SHA";
+ $slot_hash{$TOMCAT_INSTANCE_COMMON_LIB} = "$tomcat_instance_common_lib_path/*.jar";
+ if (!$redirected_logs_path) {
+ $slot_hash{$TOMCAT_LOG_DIR} = $logs_instance_path;
+ }
+ else {
+ $slot_hash{$TOMCAT_LOG_DIR} = $redirected_logs_path;
+ }
+
+ }
+
+ ## Process templates (instance independent)
+ #
+ # NOTE: The values substituted may differ across subsystems.
+ #
+
+ # process "CS.cfg" template
+ return 0 if !process_file_template("pki_cfg",
+ $pki_cfg_subsystem_file_path,
+ $pki_cfg_instance_file_path,
+ \%slot_hash);
+ return 0 if !set_file_props($pki_cfg_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ ## Process registry instance template
+ return 0 if !process_file_template("pki_registry_template",
+ $pki_registry_subsystem_file_path,
+ $pki_registry_instance_file_path,
+ \%slot_hash);
+ return 0 if !set_file_props($pki_registry_instance_file_path,
+ $default_file_permissions, $root_user, $root_group);
+
+ ## Process templates (CA instances)
+ if ($subsystem_type eq $CA) {
+ # process ProfileSelect.template
+ return 0 if !process_file_template("profile_select_template",
+ $profile_select_template_subsystem_file_path,
+ $profile_select_template_instance_file_path,
+ \%slot_hash);
+ # process proxy.conf file
+ return 0 if !process_file_template("proxy_conf",
+ $proxy_conf_subsystem_file_path,
+ $proxy_conf_instance_file_path,
+ \%slot_hash);
+ }
+
+
+ ## Process templates (RA, TPS instances)
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+
+ if ($subsystem_type eq $TPS) {
+
+ # process "cgi" template
+ return 0 if !process_file_template("cgi_home",
+ $cgi_home_subsystem_file_path,
+ $cgi_home_instance_file_path,
+ \%slot_hash);
+
+ return 0 if !process_file_template("cgi_demo",
+ $cgi_demo_subsystem_file_path,
+ $cgi_demo_instance_file_path,
+ \%slot_hash);
+
+ return 0 if !process_file_template("cgi_so",
+ $cgi_so_subsystem_file_path,
+ $cgi_so_instance_file_path,
+ \%slot_hash);
+
+ return 0 if !process_file_template("cgi_so_enroll",
+ $cgi_so_subsystem_enroll_file_path,
+ $cgi_so_instance_enroll_file_path,
+ \%slot_hash);
+
+ # process each "*.cgi" file in subsystem "sow" directory
+ opendir(SUBSYSTEM_DIR, $cgi_sow_subsystem_file_path);
+ while (defined(my $entity = readdir(SUBSYSTEM_DIR))) {
+ if ($entity =~ m/.cgi$/) {
+ # build complete "sow" subystem ".cgi" file name
+ $cgi_sow_subsystem_cgi_file_path = "${cgi_sow_subsystem_file_path}/${entity}";
+ # build complete "sow" instance ".cgi" file name
+ $cgi_sow_instance_cgi_file_path = "${cgi_sow_instance_file_path}/${entity}";
+ # process complete "sow" instance ".cgi" file name
+ return 0 if !process_file_template("cgi_sow",
+ $cgi_sow_subsystem_cgi_file_path,
+ $cgi_sow_instance_cgi_file_path,
+ \%slot_hash);
+ }
+ }
+ closedir(SUBSYSTEM_DIR);
+
+ # process "addAgents.ldif" template
+ return 0 if !process_file_template("addAgents_ldif",
+ $addAgents_ldif_subsystem_file_path,
+ $addAgents_ldif_instance_file_path,
+ \%slot_hash);
+
+ # process "addIndexes.ldif" template
+ return 0 if !process_file_template("addIndexes_ldif",
+ $addIndexes_ldif_subsystem_file_path,
+ $addIndexes_ldif_instance_file_path,
+ \%slot_hash);
+
+ # process "addTokens.ldif" template
+ return 0 if !process_file_template("addTokens_ldif",
+ $addTokens_ldif_subsystem_file_path,
+ $addTokens_ldif_instance_file_path,
+ \%slot_hash);
+
+ # process "addVLVIndexes.ldif" template
+ return 0 if !process_file_template("addVLVIndexes_ldif",
+ $addVLVIndexes_ldif_subsystem_file_path,
+ $addVLVIndexes_ldif_instance_file_path,
+ \%slot_hash);
+
+ # process "schemaMods.ldif" template
+ return 0 if !process_file_template("schemaMods_ldif",
+ $schemaMods_ldif_subsystem_file_path,
+ $schemaMods_ldif_instance_file_path,
+ \%slot_hash);
+ }
+
+
+ # process "httpd.conf" template
+ return 0 if !process_file_template("httpd_conf",
+ $httpd_conf_subsystem_file_path,
+ $httpd_conf_instance_file_path,
+ \%slot_hash);
+ return 0 if !set_file_props($httpd_conf_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+
+ # process "nss.conf" template
+ return 0 if !process_file_template("nss_conf",
+ $nss_conf_subsystem_file_path,
+ $nss_conf_instance_file_path,
+ \%slot_hash);
+ return 0 if !set_file_props($nss_conf_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ # process "perl.conf" template
+ return 0 if !process_file_template("perl_conf",
+ $perl_conf_subsystem_file_path,
+ $perl_conf_instance_file_path,
+ \%slot_hash);
+
+ return 0 if !set_file_props($perl_conf_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+
+ # process "nss_pcache" template
+ return 0 if !process_file_template("nss_pcache",
+ $nss_pcache_subsystem_file_path,
+ $nss_pcache_instance_file_path,
+ \%slot_hash);
+
+ return 0 if !set_permissions($nss_pcache_instance_file_path,
+ $default_exe_permissions);
+
+ # process "pki_apache_initscript" template
+ return 0 if !process_file_template("pki_apache_initscript",
+ $pki_apache_initscript_file_path,
+ $pki_instance_initscript_path,
+ \%slot_hash);
+
+ return 0 if !set_permissions($pki_instance_initscript_path,
+ $default_exe_permissions);
+
+
+ } else {
+ ## Process templates (CA, KRA, OCSP, TKS instances)
+ # process "index.jsp" template
+ return 0 if !process_file_template("index_jsp",
+ $index_jsp_subsystem_file_path,
+ $index_jsp_instance_file_path,
+ \%slot_hash);
+
+ # process "server.xml" template
+ return 0 if !process_file_template("server_xml",
+ $server_xml_subsystem_file_path,
+ $server_xml_instance_file_path,
+ \%slot_hash);
+
+ # process "serverCertNick.conf" template
+ return 0 if !process_file_template("servercertnick_conf",
+ $servercertnick_conf_subsystem_file_path,
+ $servercertnick_conf_instance_file_path,
+ \%slot_hash);
+
+ # process "tomcat6.conf" template
+ return 0 if !process_file_template("tomcat6_conf",
+ $tomcat6_conf_subsystem_file_path,
+ $tomcat6_conf_instance_file_path,
+ \%slot_hash);
+
+ # process "velocity.properties" template
+ return 0 if !process_file_template("velocity_prop",
+ $velocity_prop_subsystem_file_path,
+ $velocity_prop_instance_file_path,
+ \%slot_hash);
+
+ # process "web.xml" template
+ return 0 if !process_file_template("web_xml",
+ $web_xml_subsystem_file_path,
+ $web_xml_instance_file_path,
+ \%slot_hash);
+
+ # process "catalina.properties" template
+ return 0 if !process_file_template("catalina_properties",
+ $catalina_properties_subsystem_file_path,
+ $catalina_properties_instance_file_path,
+ \%slot_hash);
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub process_pki_files_and_symlinks
+{
+ emit("Processing PKI files and symbolic links for '$pki_instance_path' ...\n");
+
+ ## Populate instances (instance independent)
+
+ # create a filled in temporary "noise"
+ # file for this instance
+ my $noise = generate_random_string(1024);
+
+ return 0 if !create_file($noise_instance_file_path,
+ $noise,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ # create a filled in empty "password.conf"
+ # password file for this instance
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ return 0 if !create_file($password_conf_instance_file_path,
+ "${default_security_token}:${db_password}\n",
+ $default_file_permissions, $pki_user, $pki_group);
+ } else {
+ return 0 if !create_file($password_conf_instance_file_path,
+ "${default_security_token}=${db_password}\n",
+ $default_file_permissions, $pki_user, $pki_group);
+ }
+
+ # create a filled in empty temporary "pfile"
+ # password file for this instance
+ return 0 if !create_file($pfile_instance_file_path,
+ "${db_password}\n",
+ $default_file_permissions, $pki_user, $pki_group);
+
+ ## Populate instances (RA, TPS instances)
+ if ($subsystem_type eq $RA || $subsystem_type eq $TPS) {
+ # create an empty file called "pwcache.conf" for this
+ return 0 if !create_empty_file($pwcache_conf_instance_file_path,
+ $default_file_permissions, $pki_user, $pki_group);
+
+ # create instance symlink to subsystem "perl" subdirectory
+ return 0 if !create_symlink($perl_instance_symlink_path, $perl_subsystem_path,
+ $pki_user, $pki_group);
+
+ return 0 if !create_symlink($run_instance_symlink_path,
+ "${default_apache_pids_path}/${subsystem_type}",
+ $pki_user, $pki_group);
+
+ } else {
+ ## Populate instances (CA, KRA, OCSP, TKS instances)
+ # create instance "webapps/$subsystem_type/WEB-INF/lib" subdirectory
+
+ # Create symlink of pki_instance_name pointing to tomcat6 init script.
+ # This is our per instance init script, tomcat6 will use the basename
+ # to find our tomcat6 configuration file in /etc/sysconfig
+ return 0 if !create_symlink($pki_instance_initscript_path, $tomcat6_initscript_path,
+ $root_user, $root_group);
+ if ($use_systemd) {
+ return 0 if !create_symlink(
+ "${pki_subsystem_systemd_wants_path}/${pki_instance_systemd_service_name}",
+ "$pki_subsystem_systemd_service_path",
+ $root_user, $root_group);
+
+ # reload systemd configuration
+ run_command("/bin/systemctl --system daemon-reload");
+
+ }
+
+ return 0 if !create_directory($webinf_lib_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ # create instance symlink to "pki-certsrv.jar"
+ return 0 if !create_symlink($pki_certsrv_jar_symlink_path, $pki_certsrv_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-cms.jar"
+ return 0 if !create_symlink($pki_cms_jar_symlink_path, $pki_cms_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-cmsbundle.jar"
+ return 0 if !create_symlink($pki_cmsbundle_jar_symlink_path, $pki_cmsbundle_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-cmscore.jar"
+ return 0 if !create_symlink($pki_cmscore_jar_symlink_path, $pki_cmscore_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-cmsutil.jar"
+ return 0 if !create_symlink($pki_cmsutil_jar_symlink_path, $pki_cmsutil_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create symlink to either "apache-commons-collections.jar" or "jakarta-commons-collections.jar"
+ # needed by velocity
+ return 0 if !create_symlink($commons_collections_jar_symlink_path,
+ $commons_collections_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create symlink to either "apache-commons-lang.jar" or "jakarta-commons-lang.jar"
+ # needed by velocity
+ return 0 if !create_symlink($commons_lang_jar_symlink_path,
+ $commons_lang_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create symlink to "apache-commons-logging.jar or jakarta-commons-logging.jar"
+ # this is needed by tomcatjss
+ return 0 if !create_symlink($commons_logging_jar_symlink_path,
+ $commons_logging_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create symlink to "jss.jar"
+ return 0 if !create_symlink($jss_jar_symlink_path, $jss_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create symlink to "ldapjdk.jar"
+ return 0 if !create_symlink($ldapjdk_jar_symlink_path, $ldapjdk_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-nsutil.jar"
+ return 0 if !create_symlink($pki_nsutil_jar_symlink_path, $pki_nsutil_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "commons_codec.jar"
+ return 0 if !create_symlink($commons_codec_jar_symlink_path, $commons_codec_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "${subsystem_type}.jar"
+ return 0 if !create_symlink($pki_subsystem_jar_symlink_path, $pki_subsystem_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "symkey.jar"
+ return 0 if !create_symlink($symkey_jar_symlink_path, $symkey_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create symlink to "tomcatjss.jar"
+ return 0 if !create_symlink($tomcatjss_jar_symlink_path, $tomcatjss_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "velocity.jar"
+ return 0 if !create_symlink($velocity_jar_symlink_path, $velocity_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "xerces.jar"
+ return 0 if !create_symlink($xerces_jar_symlink_path, $xerces_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "xml_commons_apis.jar"
+ return 0 if !create_symlink($xml_commons_apis_jar_symlink_path, $xml_commons_apis_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "xml_commons_resolver.jar"
+ return 0 if !create_symlink($xml_commons_resolver_jar_symlink_path, $xml_commons_resolver_jar_file_path,
+ $pki_user, $pki_group);
+
+ #resteasy
+ # create instance symlink to "javassist.jar"
+ return 0 if !create_symlink($javassist_jar_symlink_path, $javassist_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "jaxrs-api.jar"
+ return 0 if !create_symlink($jaxrs_api_jar_symlink_path, $jaxrs_api_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-resteasy_jaxb_provider.jar"
+ return 0 if !create_symlink($resteasy_jaxb_provider_jar_symlink_path, $resteasy_jaxb_provider_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "resteasy_jaxrs.jar"
+ return 0 if !create_symlink($resteasy_jaxrs_jar_symlink_path, $resteasy_jaxrs_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "scannotation.jar"
+ return 0 if !create_symlink($scannotation_jar_symlink_path, $scannotation_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "pki-resteasy_jettison_provider.jar"
+ return 0 if !create_symlink($resteasy_jettison_provider_jar_symlink_path, $resteasy_jettison_provider_jar_file_path,
+ $pki_user, $pki_group);
+
+ # create instance symlink to "jettison.jar"
+ return 0 if !create_symlink($jettison_jar_symlink_path, $jettison_jar_file_path,
+ $pki_user, $pki_group);
+
+
+ }
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub process_pki_security_databases
+{
+ my $result = 0;
+ my $serial_number = 0;
+ my $validity_period = 12;
+ my $time_stamp = get_time_stamp();
+ my $subject = "CN=$host,O=$time_stamp";
+ my $issuer_name = "CN=$host,O=$time_stamp";
+ my $nickname = "Server-Cert cert-$pki_instance_name";
+ my $trustargs = "CTu,CTu,CTu";
+
+ emit("Processing PKI security databases for '$pki_instance_path' ...\n");
+
+ # now create and configure pki security databases,
+ # cert3.db, key3.db, secmod.db ...
+ if (!file_exists($default_certutil_command) && !$dry_run) {
+ emit("process_pki_security_databases(): $default_certutil_command does not exist!\n", "error");
+ return $result;
+
+ }
+
+ if (!file_exists($noise_instance_file_path) && !$dry_run) {
+ emit("process_pki_security_databases(): Can't find temp noise file!\n", "error");
+ return $result;
+ }
+
+ if (!file_exists($pfile_instance_file_path) && !$dry_run) {
+ emit("process_pki_security_databases(): Can't find temp file with password!\n", "error");
+ return $result;
+ }
+
+ certutil_create_databases($alias_instance_path,
+ $pfile_instance_file_path);
+
+ certutil_generate_self_signed_cert($alias_instance_path,
+ $default_security_token,
+ $serial_number,
+ $validity_period,
+ $subject,
+ $issuer_name,
+ $nickname,
+ $trustargs,
+ $noise_instance_file_path,
+ $pfile_instance_file_path);
+
+ remove_file($noise_instance_file_path);
+
+ remove_file($pfile_instance_file_path);
+
+ set_owner_group_on_directory_contents($alias_instance_path,
+ $pki_user, $pki_group);
+
+ return 1;
+}
+
+
+# Return 1 if success, 0 if failure
+sub process_pki_security_modules
+{
+ my $result = 0;
+
+ emit("Processing PKI security modules for '$pki_instance_path' ...\n");
+
+ if (!file_exists($default_modutil_command) && !$dry_run) {
+ emit("process_pki_security_modules(): $default_modutil_command must be installed on system!\n", "error");
+ return $result;
+ }
+
+ emit(" Attempting to add hardware security modules to system if applicable ...\n");
+
+ while (my ($key, $value) = each(%supported_sec_modules_hash)) {
+ if (!file_exists($value)) {
+ emit(" module name: $key lib: $value DOES NOT EXIST!\n");
+ next;
+ } else {
+ modutil_add_token($alias_instance_path, $key, $value);
+ emit(" Added module name: $key lib: $value\n");
+ }
+ }
+
+ return 1;
+}
+
+sub process_pki_selinux_setup
+{
+ my $setype = "pki_" . $subsystem_type;
+ my $setype_p = $setype . "_port_t";
+ my $default_instance_name = "pki-" . $subsystem_type;
+ my $default_instance_root = "/var/lib";
+ my $default_log_path = "/var/log/" . $default_instance_name;
+ my $default_conf_path = "/etc/" . $default_instance_name;
+ my $status = 0;
+
+ my $conf_path;
+ my $log_path;
+ my $ftype;
+ my $java_component = 0;
+ my $semanage_cmds = "";
+ my @restorecon_cmds;
+
+ emit("configuring SELinux ...\n");
+
+ if (!$redirected_logs_path) {
+ $log_path = $logs_instance_path;
+ }
+ else {
+ $log_path =$redirected_logs_path;
+ }
+
+ if (!$redirected_conf_path) {
+ $conf_path = $conf_instance_path;
+ }
+ else {
+ $conf_path =$redirected_conf_path;
+ }
+
+ if ($subsystem_type eq $CA ||
+ $subsystem_type eq $KRA ||
+ $subsystem_type eq $OCSP ||
+ $subsystem_type eq $TKS) {
+ $java_component =1;
+ }
+
+ # set file contexts
+ if ($java_component) {
+ push (@restorecon_cmds, "$restorecon -F -R /usr/share/java/pki");
+ }
+ push (@restorecon_cmds, "$restorecon -F -R /usr/share/pki");
+
+ # set file context for $pki_instance_root/$pki_instance_name
+ if (($pki_instance_name ne $default_instance_name) || ($pki_instance_root ne $default_instance_root)) {
+ add_selinux_file_context($setype . "_var_lib_t",
+ "\"${pki_instance_root}/${pki_instance_name}(/.*)?\"",
+ "a", \$semanage_cmds);
+ }
+ push(@restorecon_cmds, "$restorecon -F -R $pki_instance_root/$pki_instance_name");
+
+
+ if ($java_component) {
+ # set file context for instance pid file
+ my $pidfile = $tomcat6_instance_pid_file_path;
+ if ($pki_instance_name ne $default_instance_name) {
+ add_selinux_file_context($setype . "_var_run_t",
+ $pidfile, "f", \$semanage_cmds);
+ }
+ if (-e $pidfile) {
+ push(@restorecon_cmds, "$restorecon -F $pidfile");
+ }
+
+ my $pidpath = $default_apache_pids_path;
+ if (-e $pidpath) {
+ push(@restorecon_cmds, "$restorecon -F -R $pidpath");
+ }
+ }
+
+ # set file context for $log_path
+ $log_path =~ s/\/+$//;
+ if (!$log_path) {
+ emit("Error: Cannot set selinux context $setype" . "_log_t for directory /");
+ } else {
+ if ($log_path ne $default_log_path) {
+ add_selinux_file_context($setype . "_log_t",
+ "\"$log_path(/.*)?\"", "a", \$semanage_cmds);
+ }
+ push(@restorecon_cmds, "$restorecon -F -R $log_path");
+ }
+
+ # set file context for $conf_path
+ $conf_path =~ s/\/+$//;
+ if (!$conf_path) {
+ emit("Error: Cannot set selinux context $setype" . "_etc_rw_t for directory /");
+ } else {
+ if ($conf_path ne $default_conf_path) {
+ add_selinux_file_context($setype . "_etc_rw_t",
+ "\"$conf_path(/.*)?\"", "a", \$semanage_cmds);
+ }
+ push(@restorecon_cmds, "$restorecon -F -R $conf_path");
+ }
+
+ if (! $java_component) {
+ push(@restorecon_cmds, "$restorecon -F -R /usr/sbin/httpd.worker");
+ }
+
+ # add ports
+ parse_selinux_ports();
+ if ($secure_port != -1) {
+ add_selinux_port($setype_p, $secure_port, \$semanage_cmds);
+ }
+ if ($non_clientauth_secure_port != -1) {
+ add_selinux_port($setype_p, $non_clientauth_secure_port, \$semanage_cmds);
+ }
+ if ($unsecure_port != -1) {
+ add_selinux_port($setype_p, $unsecure_port, \$semanage_cmds);
+ }
+ if ($tomcat_server_port != -1) {
+ add_selinux_port($setype_p, $tomcat_server_port, \$semanage_cmds);
+ }
+ if ($agent_secure_port != -1) {
+ add_selinux_port($setype_p, $agent_secure_port, \$semanage_cmds);
+ }
+ if ($ee_secure_port != -1) {
+ add_selinux_port($setype_p, $ee_secure_port, \$semanage_cmds);
+ }
+ if ($ee_secure_client_auth_port != -1) {
+ add_selinux_port($setype_p, $ee_secure_client_auth_port, \$semanage_cmds);
+ }
+ if ($admin_secure_port != -1) {
+ add_selinux_port($setype_p, $admin_secure_port, \$semanage_cmds);
+ }
+ if ($ajp_port != -1) {
+ add_selinux_port($setype_p, $ajp_port, \$semanage_cmds);
+ }
+
+ # now run the selinux commands in batch mode
+ if ($semanage_cmds ne "") {
+ emit("Running the semanage commands in batch mode\n", "debug");
+ if (! $dry_run) {
+ if(! run_command("$semanage -S targeted -i - " . ' << _EOF' . "\n$semanage_cmds\n" . '_EOF' . "\n")) {
+ emit("Failed executing semanage batch command \n", "error");
+ }
+ }
+ } else {
+ emit("Selinux contexts already set. No need to run semanage.\n", "debug");
+ }
+
+ #now run the restorecons
+ emit("Running restorecon commands\n", "debug");
+ foreach my $cmd (@restorecon_cmds) {
+ emit("$cmd\n", "debug");
+ if (! $dry_run) {
+ if (!run_command($cmd)) {
+ emit("Failed executing restorecon command; $cmd\n", "error");
+ }
+ }
+ }
+
+ return 1;
+}
+
+# no args
+# return 1 - success, or
+# return 0 - failure
+sub install_pki_instance
+{
+ emit("Installing PKI instance ...\n");
+
+ return 0 if !create_directory($pki_instance_path,
+ $default_dir_permissions, $pki_user, $pki_group);
+
+ return 0 if !process_pki_directories();
+ return 0 if !process_pki_templates();
+ return 0 if !process_pki_files_and_symlinks();
+ return 0 if !process_pki_security_databases();
+ return 0 if !process_pki_security_modules();
+
+ if (($^O eq "linux") && (is_Fedora() || (is_RHEL() && (! is_RHEL4())))){
+ return 0 if !process_pki_selinux_setup();
+ }
+
+ return 1;
+}
+
+
+##############################################################
+# PKI Instance Removal Subroutines
+##############################################################
+
+
+# Return 1 if success, 0 if failure
+sub cleanup
+{
+ my $result = 0;
+
+ emit(sprintf("cleanup(%s)\n", join(", ", @_)), "debug");
+
+ emit("PKI instance creation Cleanup Utility cleaning up on error ...", "info");
+
+ $result = uninstall(\%installation_info);
+
+ return $result;
+}
+
+# Return 1 if success, 0 if failure
+sub write_install_info
+{
+ if ($dry_run) {
+ return 1;
+ } else {
+ if (!defined($pki_instance_path)) {
+ return 0;
+ }
+ my $install_info_file_path = write_install_info_to_dir($pki_instance_path,
+ \%installation_info);
+ if (defined($install_info_file_path)) {
+ emit(sprintf("Installation manifest: %s", $install_info_file_path));
+ return 1;
+ } else {
+ return 0;
+ }
+ }
+}
+
+##############################################################
+# Signal Handlers
+##############################################################
+
+sub die_handler
+{
+ my ($msg) = @_;
+
+ # If we abort write the installation manifest
+ # so cleanup can still be performed later.
+ write_install_info();
+}
+
+$SIG{'__DIE__'} = \&die_handler;
+
+##############################################################
+# Main Program
+##############################################################
+
+# no args
+# no return value
+sub main
+{
+ my $result = 0;
+ my $parse_result = 0;
+ my $command = "";
+
+ chdir("/tmp");
+
+ print(STDOUT "PKI instance creation Utility ...\n\n");
+
+ # On Linux/UNIX, insure that this script is being run as "root".
+ $result = check_for_root_UID();
+ if (!$result) {
+ usage();
+ exit 255;
+ }
+
+ # Setup platform-dependent parameters
+ setup_platform_dependent_parameters();
+
+ $parse_result = parse_arguments();
+ if (!$parse_result || $parse_result == -1) {
+ close_logfile();
+ exit 255;
+ }
+
+ exit 255 if !initialize_paths();
+
+ exit 255 if !initialize_pki_creation_values();
+
+ $result = install_pki_instance();
+ if (!$result) {
+ print(STDOUT "\n");
+
+ my $install_description = get_install_description();
+ emit(sprintf("The following was performed\n%s\n\n", $install_description));
+
+ASK_AGAIN:
+ my $confirm = prompt("Error detected would you like to clean up ${pki_instance_path} (Y/N)? ");
+
+ if ($confirm eq "Y" || $confirm eq "y") {
+ cleanup();
+ } elsif ($confirm ne "N" && $confirm ne "n") {
+ goto ASK_AGAIN;
+ }
+
+ close_logfile();
+
+ exit 255;
+ }
+
+ print(STDOUT "\n");
+ print(STDOUT "PKI instance creation completed ...\n\n");
+
+ # Write the installation manifest.
+ write_install_info();
+
+ my $install_description = get_install_description();
+ emit(sprintf("The following was performed:\n%s\n", $install_description));
+
+ printf(STDOUT "Installation information recorded in %s.\n", get_logfile_path());
+
+ if ($use_systemd) {
+ $pki_registry_initscript_command =
+ "/bin/systemctl restart $pki_instance_systemd_service_name";
+ } else {
+ $pki_registry_initscript_command =
+ "/sbin/service $pki_registry_initscript restart $pki_instance_name";
+ }
+
+ $command = "${pki_registry_initscript_command}";
+ run_command($command);
+
+ if ($dry_run) {
+ print STDOUT "dry run mode ENABLED, system was not modified\n";
+ } else {
+
+ # Notify user to check firewall settings . . .
+ print(STDOUT
+ "Before proceeding with the configuration, make sure \n"
+ . "the firewall settings of this machine permit proper \n"
+ . "access to this subsystem. \n\n");
+
+ # EXCEPTION: To enable a user to easily configure their PKI subsystem,
+ # this is the ONLY instance in which we print out the actual
+ # value of the the one-time random PIN, as well as store this
+ # message at the end of the initialization log.
+ if ($subsystem_type eq $CA ||
+ $subsystem_type eq $KRA ||
+ $subsystem_type eq $OCSP ||
+ $subsystem_type eq $TKS) {
+ if ($admin_secure_port > 0) {
+ # Port Separation: CA, KRA, OCSP, TKS
+ print(STDOUT
+ "Please start the configuration by accessing:\n\n"
+ . "https://$host:$admin_secure_port/$subsystem_type/admin/"
+ . "console/config/login?pin=$random\n\n");
+ emit("Configuration Wizard listening on\n"
+ . "https://$host:$admin_secure_port/$subsystem_type/admin/"
+ . "console/config/login?pin=$random\n",
+ "log");
+ } else {
+ # Shared Ports: CA, KRA, OCSP, TKS
+ print(STDOUT
+ "Please start the configuration by accessing:\n\n"
+ . "https://$host:$secure_port/$subsystem_type/admin/"
+ . "console/config/login?pin=$random\n\n");
+ emit("Configuration Wizard listening on\n"
+ . "https://$host:$secure_port/$subsystem_type/admin/"
+ . "console/config/login?pin=$random\n",
+ "log");
+ }
+ } else {
+ # Port Separation: RA, TPS
+ print(STDOUT
+ "Please start the configuration by accessing:\n\n"
+ . "https://$host:$non_clientauth_secure_port/$subsystem_type/"
+ . "admin/console/config/login?pin=$random\n\n");
+ emit("Configuration Wizard listening on\n"
+ . "https://$host:$non_clientauth_secure_port/$subsystem_type/"
+ . "admin/console/config/login?pin=$random\n",
+ "log");
+ }
+
+ print(STDOUT
+ "After configuration, the server can be operated by the command:\n\n"
+ . " $pki_registry_initscript_command\n\n");
+ emit("After configuration, the server can be operated by the command:\n"
+ . "${pki_registry_initscript_command}\n",
+ "log");
+ }
+
+ close_logfile();
+
+ return;
+}
+
+
+##############################################################
+# PKI Instance Creation
+##############################################################
+
+main();
+
+exit 0;
+
diff --git a/base/setup/pkiremove b/base/setup/pkiremove
new file mode 100755
index 000000000..dd9fbc7f9
--- /dev/null
+++ b/base/setup/pkiremove
@@ -0,0 +1,680 @@
+#!/usr/bin/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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2007-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+
+use strict;
+use warnings;
+
+use Getopt::Long qw(GetOptions);
+
+##############################################################
+# This script is used to remove an existing PKI instance.
+#
+# To execute:
+#
+# ./pkiremove -pki_instance_root=<pki_instance_root> # Instance root
+# # directory destination
+#
+# -pki_instance_name=<pki_instance_id> # Unique PKI subsystem
+# # instance name
+# # (e. g. - pki-pki1)
+#
+# [-token_pwd=<token pw>] # Password of token containing
+# # subsystem certificate
+#
+# [-force] # Don't ask any
+# # questions
+#
+##############################################################
+
+
+##############################################################
+# Execution Check
+##############################################################
+
+# Check to insure that this script's original
+# invocation directory has not been deleted!
+my $cwd = `/bin/pwd`;
+chomp $cwd;
+if (!$cwd) {
+ emit("Cannot invoke '$0' from non-existent directory!\n", "error");
+ exit 255;
+}
+
+##############################################################
+# Environment Variables
+##############################################################
+
+# untaint called subroutines
+if (($^O ne 'Windows_NT') && ($^O ne 'MSWin32')) {
+ $> = $<; # set effective user ID to real UID
+ $) = $(; # set effective group ID to real GID
+ $ENV{'PATH'} = '/bin:/usr/bin';
+ $ENV{'ENV'} = '' if !defined($ENV{'ENV'});
+}
+
+
+##############################################################
+# Command-Line Variables
+##############################################################
+
+my $ARGS = ($#ARGV + 1);
+
+
+##############################################################
+# Shared Common Perl Data and Subroutines
+##############################################################
+
+use lib "/usr/share/pki/scripts";
+use pkicommon;
+
+# make -w happy by suppressing warnings of Global variables used only once
+my $suppress = "";
+$suppress = $default_file_permissions;
+
+##############################################################
+# Local Constants
+##############################################################
+
+my $semanage = "/usr/sbin/semanage";
+
+##############################################################
+# Local Data Structures
+##############################################################
+
+
+##############################################################
+# Local Variables
+##############################################################
+
+my $pki_instance_root = undef;
+my $pki_instance_name = undef;
+my $force = 0;
+my $token_pwd = "";
+
+my $conf_file = undef;
+my $pki_instance_path = undef;
+my $subsystem_type = undef;
+
+# PKI init script variables
+my $pki_registry_initscript = undef;
+my $pki_registry_initscript_command = undef;
+
+# PKI registry variables
+my $pki_registry_subsystem_path = undef;
+
+#systemd specific variables
+my $use_systemd = 0;
+my $pki_instance_systemd_service_name = undef;
+
+##############################################################
+# Platform-Dependent Data Initialization
+##############################################################
+
+if ($^O eq "linux") {
+ if (is_Fedora() && (fedora_release() >= 16)) {
+ $use_systemd = 1;
+ }
+} else {
+ emit("Unsupported platform '$^O'!\n", "error");
+ exit 255;
+}
+
+##############################################################
+# Local Data Initialization
+##############################################################
+
+##############################################################
+# PKI Instance Removal Subroutines
+##############################################################
+
+# no args
+# no return value
+sub usage
+{
+ print STDOUT <<'EOF';
+Usage: pkiremove -pki_instance_root=<pki_instance_root> # Instance root
+ # directory
+ # destination
+ -pki_instance_name=<pki_instance_id> # Unique PKI
+ # subsystem
+ # instance name
+ # (e. g. - pki-pki1)
+ #
+[-token_pwd=<token password>] # Password for token containing subsystem cert.
+
+[-force] # Don't ask any questions
+
+[-verbose] # Display detailed information. May be specified multiple times,
+ # each time increasing the verbosity level.
+
+[-dry_run] # Do not perform any actions.
+ # Just report what would have been done.
+
+Example: pkiremove -pki_instance_root=/var/lib -pki_instance_name=pki-ca
+
+IMPORTANT: Must be run as root!
+EOF
+ return;
+}
+
+sub update_domain
+{
+ my $sport;
+ my $ncsport;
+ my $sechost;
+ my $httpport;
+ my $seceeport;
+ my $secagentport;
+ my $secadminport;
+ my $adminsport;
+ my $agentsport;
+ my $secselect;
+ my $subsystemnick;
+ my $machinename;
+ my $typeval;
+ my $url;
+
+ get_cs_cfg($conf_file, {"service.machineName" => \$machinename,
+ "service.securityDomainPort" => \$sport,
+ "service.non_clientauth_securePort" => \$ncsport,
+ "securitydomain.host" => \$sechost,
+ "securitydomain.httpport" => \$httpport,
+ "securitydomain.httpseeport" => \$seceeport,
+ "securitydomain.httpsagentport" => \$secagentport,
+ "securitydomain.httpsadminport" => \$secadminport,
+ "securitydomain.select" => \$secselect,
+ "pkicreate.admin_secure_port" => \$adminsport,
+ "cs.type" => \$typeval,
+ "pkicreate.agent_secure_port" => \$agentsport});
+
+ my $subsystemnick_param = lc($typeval) . ".cert.subsystem.nickname";
+ get_cs_cfg($conf_file, {$subsystemnick_param => \$subsystemnick});
+
+ # NOTE: Don't check for the existence of $httpport, as this will
+ # be undefined for a Security Domain that has been migrated!
+ if ((!defined($sechost)) ||
+ (!defined($seceeport)) ||
+ (!defined($secagentport)) ||
+ (!defined($secadminport))) {
+ print(STDOUT "No security domain defined.\nIf this is an unconfigured instance, then that is OK.\n" .
+ "Otherwise, manually delete the entry from the security domain master.\n");
+ return;
+ }
+
+ die "Subsystem nickname not defined" if (!defined($subsystemnick));
+ if (!defined($adminsport)) {
+ $adminsport = "";
+ }
+
+ if (!defined($agentsport)) {
+ $agentsport = "";
+ }
+
+ if (!defined($ncsport)) {
+ $ncsport = "";
+ }
+
+ (my $token_name, my $nick) = split(/:/, $subsystemnick, 2);
+ if ((!defined($nick)) || ($nick eq "")) {
+ $token_name = "internal";
+ }
+
+ if ($secselect ne "new") {
+ # This is not a domain master, so we need to update the master
+ print(STDOUT "Contacting the security domain master to update the security domain\n");
+ my $listval = $subsystem_type . "List";
+ my $urlheader = "https://" . $sechost . ":" . $seceeport;
+ my $urlagentheader = "https://" . $sechost . ":" . $secagentport;
+ my $urladminheader = "https://" . $sechost . ":" . $secadminport;
+ my $updateURL = "/ca/agent/ca/updateDomainXML";
+
+ if ($token_pwd eq "") {
+ my $pwfile = $pki_instance_path . "/conf/password.conf";
+ if (-r $pwfile) {
+ open(DAT, $pwfile) or die "Could not open password.conf file to read token password.";
+ my @pw_data=<DAT>;
+ foreach my $line (@pw_data) {
+ chomp($line);
+ if (($typeval eq "CA") ||
+ ($typeval eq "KRA") ||
+ ($typeval eq "OCSP") ||
+ ($typeval eq "TKS")) {
+ (my $varname, my $valname) = split(/=/, $line);
+ if ($varname eq "hardware-$token_name") { $token_pwd = $valname; }
+ if ($varname eq "$token_name") { $token_pwd = $valname; }
+ } else { # TPS, RA
+ (my $varname, my $valname) = split(/:/, $line);
+ if ($varname eq $token_name) { $token_pwd = $valname; }
+ if ($varname eq "hardware-$token_name") { $token_pwd = $valname; }
+ }
+ }
+ close($pwfile);
+ }
+ }
+
+ while ($token_pwd eq "") {
+ $token_pwd = prompt( "No password found for $token_name. What is the password for this token?");
+ }
+
+ my $params = "name=$pki_instance_name" .
+ "&type=$typeval" .
+ "&list=$listval" .
+ "&host=$machinename" .
+ "&sport=$sport" .
+ "&ncsport=$ncsport" .
+ "&adminsport=$adminsport" .
+ "&agentsport=$agentsport" .
+ "&operation=remove";
+
+ #update domainXML
+ my $cmd = `/usr/bin/sslget -d \"$pki_instance_path/alias\" -p \"$token_pwd\" -v -n \"$subsystemnick\" -r \"$updateURL\" -e \"$params\" $sechost:$secagentport 2>&1`;
+ $cmd =~ /\<Status\>(.*?)\<\/Status\>/;
+ $cmd = $1;
+
+ die ("Security Domain returns non-zero status for updateDomainXML.") if ($cmd ne "0");
+ }
+}
+
+sub remove_fcontext
+{
+ my ($fcontext, $fname, $ftype, $cmd_ref) = @_;
+ emit(sprintf("remove_fcontext(%s)\n", join(", ", @_)), "debug");
+
+ my $tmp = `$semanage fcontext -l -C |grep $fcontext |grep $fname |wc -l`;
+ chomp $tmp;
+ if ($tmp eq "0" ) {
+ emit("File context $fcontext for $fname defined in policy, not deleted", "debug");
+ return 0;
+ }
+
+ if ($ftype eq "f") {
+ $$cmd_ref .= "fcontext -d -t $fcontext -f -- $fname\n";
+ } else {
+ $$cmd_ref .= "fcontext -d -t $fcontext $fname\n";
+ }
+}
+
+sub get_selinux_fcontexts
+{
+ my ($cmd_ref) = @_;
+ my $setype = "pki_" . $subsystem_type;
+ my $default_instance_name = "pki-" . $subsystem_type;
+ my $default_instance_root = "/var/lib";
+ my $default_log_path = "/var/log/" . $default_instance_name;
+ my $default_conf_path = "/etc/" . $default_instance_name;
+
+ my $log_path = "$pki_instance_path/logs";
+ my $conf_path = "$pki_instance_path/conf";
+ my $ftype;
+ my $java_component = 0;
+
+ if (($subsystem_type eq $CA) ||
+ ($subsystem_type eq $KRA) ||
+ ($subsystem_type eq $OCSP) ||
+ ($subsystem_type eq $TKS)) {
+ $java_component=1;
+ }
+
+ if (-l $log_path) {
+ $log_path = readlink $log_path;
+ };
+
+ if (-l $conf_path) {
+ $conf_path = readlink $conf_path;
+ };
+
+ # For backwards compatibility, support removal of instances
+ # which use the legacy start/stop implementation
+ if (entity_exists("$default_initscripts_path/$pki_instance_name")) {
+ # remove context for "$default_initscripts_path/$pki_instance_name"
+ if ($pki_instance_name ne $default_instance_name) {
+ remove_fcontext($setype . "_script_exec_t",
+ "/etc/rc\\.d/init\\.d/$pki_instance_name", "f", $cmd_ref);
+ }
+ }
+
+ # remove context for $pki_instance_root/$pki_instance_name
+ if (($pki_instance_name ne $default_instance_name) || ($pki_instance_root ne $default_instance_root)) {
+ remove_fcontext($setype . "_var_lib_t",
+ "\"$pki_instance_root/$pki_instance_name(/.*)?\"", "a", $cmd_ref);
+ }
+
+ # remove context for /var/run/$pki_instance_name.pid
+ if (($java_component) && ($pki_instance_name ne $default_instance_name)) {
+ remove_fcontext($setype . "_var_run_t",
+ "/var/run/$pki_instance_name" . '.pid', "f", $cmd_ref);
+ }
+
+ # remove context for $log_path
+ if ($log_path ne $default_log_path) {
+ remove_fcontext($setype . "_log_t",
+ "\"$log_path(/.*)?\"", "a", $cmd_ref);
+ }
+
+ # remove context for $conf_path
+ if ($conf_path ne $default_conf_path) {
+ remove_fcontext($setype . "_etc_rw_t",
+ "\"$conf_path(/.*)?\"", "a", $cmd_ref);
+ }
+
+}
+
+
+sub get_selinux_ports
+{
+ my ($cmd_ref) = @_;
+ my $status;
+ my $semanage = "/usr/sbin/semanage";
+ my $secure_port;
+ my $non_clientauth_secure_port;
+ my $unsecure_port;
+ my @ports = ();
+
+ get_cs_cfg($conf_file, {"service.securePort" => \$secure_port,
+ "service.non_clientauth_securePort" => \$non_clientauth_secure_port,
+ "service.unsecurePort" => \$unsecure_port});
+
+ if (($subsystem_type eq $CA) ||
+ ($subsystem_type eq $KRA) ||
+ ($subsystem_type eq $OCSP) ||
+ ($subsystem_type eq $TKS)) {
+ use XML::LibXML;
+ my $parser = XML::LibXML->new();
+ my $config = $parser->parse_file($pki_instance_path . "/conf/server.xml")
+ or die "Could not read XML from server.xml to determine ports.";
+
+ my $root = $config->getDocumentElement;
+
+ my $i = 0;
+ foreach my $port ($root->findnodes('//@port')) {
+ $ports[$i] = $port->getValue();
+ $i++;
+ }
+ } else { # TPS, RA
+ my $i =0;
+ if (defined $secure_port) {
+ $ports[$i] = $secure_port;
+ $i++;
+ }
+ if (defined $non_clientauth_secure_port) {
+ $ports[$i] = $non_clientauth_secure_port;
+ $i++;
+ }
+ if (defined $unsecure_port) {
+ $ports[$i] = $unsecure_port;
+ $i++;
+ }
+ }
+
+ print(STDOUT "\n");
+ foreach my $port (@ports) {
+ my $setype = "pki_" . $subsystem_type . "_port_t";
+ my $tmp = `$semanage port -l -C |grep $setype |grep $port | wc -l`;
+ chomp $tmp;
+ if ($tmp eq "0") {
+ emit("Port context $setype for $port defined in policy, not deleting", "debug");
+ } else {
+ $$cmd_ref .= "port -d -t $setype -ptcp $port\n";
+ }
+ }
+}
+
+
+# Return 1 if success, 0 if failure
+sub remove_instance
+{
+ my ($result, $confirm, $install_info);
+ $confirm = "Y";
+ $result = 1;
+
+ print(STDOUT "PKI instance Deletion Utility cleaning up instance ...\n\n");
+
+ASK_AGAIN:
+ if (!$force) {
+ $confirm = prompt("You have elected to remove the instance "
+ . "installed in $pki_instance_path.\n"
+ . "Are you sure (Y/N)? ");
+ }
+
+ if ($confirm eq "N" || $confirm eq "n") {
+ return 1;
+ } elsif ($confirm ne "Y" && $confirm ne "y") {
+ goto ASK_AGAIN;
+ }
+
+ $install_info = read_install_info_from_dir($pki_instance_path);
+ if (!defined($install_info)) {
+ emit("Can't remove instance, installation manifest does not exist!", "error");
+ return $result;
+ }
+
+ eval { update_domain(); } if !$dry_run; # FIXME so update_domain shows what it would do
+ warn "Error updating security domain: " . $@ if $@;
+
+ if (($^O eq "linux") && (is_Fedora() || (is_RHEL() && (! is_RHEL4())))) {
+ my $semanage_cmds = "";
+
+ eval { get_selinux_ports(\$semanage_cmds); };
+ warn "Error getting selinux ports: " . $@ if $@;
+
+ eval { get_selinux_fcontexts(\$semanage_cmds); };
+ warn "Error getting selinux file contexts: " . $@ if $@;
+
+ print STDOUT "Removing selinux contexts\n";
+ if ($semanage_cmds ne "") {
+ emit("Executing selinux commands in batch mode.\n", "debug");
+ if (! $dry_run) {
+ if (! run_command("$semanage -S targeted -i - " . '<< _EOF' . "\n$semanage_cmds\n" . '_EOF' . "\n")) {
+ emit("Error executing selinux batch commands\n", "error");
+ }
+ }
+ } else {
+ emit("No selinux contexts need to be removed. No need to run semanage. \n");
+ }
+ }
+
+ $pki_registry_initscript = get_registry_initscript_name($subsystem_type);
+
+ # Shutdown this instance
+ if ($^O eq "linux") {
+ if ($use_systemd) {
+ $pki_instance_systemd_service_name =
+ "${pki_registry_initscript}\@${pki_instance_name}.service";
+ $pki_registry_initscript_command =
+ "/bin/systemctl stop $pki_instance_systemd_service_name";
+ } else {
+ if (entity_exists("$default_initscripts_path/$pki_instance_name")) {
+ $pki_registry_initscript_command = "/sbin/service $pki_instance_name stop";
+ } else {
+ $pki_registry_initscript_command =
+ "/sbin/service $pki_registry_initscript stop $pki_instance_name";
+ }
+ }
+ } else {
+ emit("Unsupported platform '$^O'!\n", "error");
+ exit 255;
+ }
+ run_command($pki_registry_initscript_command);
+
+ if (!$use_systemd) {
+ # De-register this instance with "chkconfig"
+ if ($^O eq "linux") {
+ if (entity_exists("$default_initscripts_path/$pki_instance_name")) {
+ # De-register this instance with '/sbin/chkconfig'
+ print(STDOUT "Removing '$pki_instance_name' from chkconfig.\n");
+ deregister_pki_instance_with_chkconfig($pki_instance_name);
+ }
+ }
+ }
+
+ print(STDOUT "\n");
+
+ # Remove all installed files and directories.
+ $result = 0 if !uninstall($install_info);
+
+ if ($use_systemd) {
+ run_command("/bin/systemctl --system daemon-reload");
+ }
+
+ print(STDOUT "\n");
+
+ return $result;
+}
+
+
+##############################################################
+# Main Program
+##############################################################
+
+# no args
+# return 1 - success, or
+# return 0 - failure
+sub main
+{
+ chdir("/tmp");
+
+ my $result = 0;
+
+ print(STDOUT "PKI instance Deletion Utility ...\n\n");
+
+ # On Linux/UNIX, insure that this script is being run as "root".
+ $result = check_for_root_UID();
+ if (!$result) {
+ usage();
+ exit 255;
+ }
+
+ # Check for a valid number of command-line arguments.
+ if ($ARGS < 2) {
+ emit("$0: Insufficient arguments!", "error");
+ usage();
+ exit 255;
+ }
+
+ # Parse command-line arguments.
+ $result = GetOptions("pki_instance_root=s" => \$pki_instance_root,
+ "pki_instance_name=s" => \$pki_instance_name,
+ "token_pwd=s" => \$token_pwd,
+ "verbose+" => \$verbose,
+ "dry_run" => \$dry_run,
+ "force" => \$force);
+
+ # Always disallow root to be the pki_instance_root.
+ if ($pki_instance_root eq "/") {
+ emit("$0: Don't even think about making root "
+ . "the pki_instance_root!", "error");
+ usage();
+ exit 255;
+ }
+
+ $pki_instance_root = normalize_path($pki_instance_root);
+
+ # Check for valid content of command-line arguments.
+ if (!$pki_instance_root) {
+ emit("$0: Must have value for -pki_instance_root!", "error");
+ usage();
+ exit 255;
+ }
+
+ if (!$pki_instance_name) {
+ emit("$0: The instance ID of the PKI instance "
+ . "to be removed is required!", "error");
+ usage();
+ exit 255;
+ }
+
+ $pki_instance_path = "${pki_instance_root}/${pki_instance_name}";
+
+ if (!directory_exists($pki_instance_path)) {
+ emit("$0: Target directory $pki_instance_path "
+ . "is not a legal directory.", "error");
+ usage();
+ exit 255;
+ }
+
+ # Capture uninstall information in a log file, always overwrite this file.
+ # When removing an instance it's never a fatal error if the logfile
+ # cannot be created.
+ my $logfile = "/var/log/${pki_instance_name}-uninstall.log";
+ open_logfile($logfile, $default_file_permissions);
+
+ emit("Capturing installation information in $logfile.\n");
+
+ if ($verbose) {
+ emit(" verbose mode ENABLED (level=$verbose)\n");
+ }
+
+ if ($dry_run) {
+ emit(" dry run mode ENABLED, system will not be modified, log to $logfile\n");
+ print STDOUT "dry run mode ENABLED, system will not be modified\n";
+ }
+
+ emit(" pki_instance_root $pki_instance_root\n");
+ emit(" pki_instance_name $pki_instance_name\n");
+ emit(" pki_instance_path $pki_instance_path\n");
+
+ $conf_file = $pki_instance_path . "/conf/CS.cfg";
+ $subsystem_type = get_cs_cfg($conf_file, "cs.type");
+ if (!defined($subsystem_type)) {
+ emit("Could not determine the subsystem type from the file \"$conf_file\"\n", "error");
+ exit 1;
+ }
+ $subsystem_type = lc($subsystem_type);
+
+ # Remove the specified instance
+ $result = remove_instance();
+ if ($result != 1) {
+ exit 255;
+ }
+
+ # Establish PKI subsystem-level registry
+ $pki_registry_subsystem_path = "$pki_registry_path/$subsystem_type";
+
+ # If empty, remove the PKI subsystem-level registry
+ if (directory_exists($pki_registry_subsystem_path)) {
+ if (is_directory_empty($pki_registry_subsystem_path)) {
+ remove_directory($pki_registry_subsystem_path);
+ }
+ }
+
+ # If empty, remove the PKI-level registry
+ if (directory_exists($pki_registry_path)) {
+ if (is_directory_empty($pki_registry_path)) {
+ remove_directory($pki_registry_path);
+ }
+ }
+
+ if ($dry_run) {
+ print STDOUT "dry run mode ENABLED, system was not modified\n";
+ }
+
+ return $result;
+}
+
+
+##############################################################
+# PKI Instance Removal
+##############################################################
+
+main();
+
+exit 0;
+
diff --git a/base/setup/scripts/functions b/base/setup/scripts/functions
new file mode 100644
index 000000000..516bf32e2
--- /dev/null
+++ b/base/setup/scripts/functions
@@ -0,0 +1,1121 @@
+#!/bin/bash
+
+# From "http://fedoraproject.org/wiki/FCNewInit/Initscripts":
+#
+# Status Exit Codes
+#
+# 0 program is running or service is OK
+# 1 program is dead and /var/run pid file exists
+# 2 program is dead and /var/lock lock file exists
+# 3 program is not running
+# 4 program or service status is unknown
+# 5-99 reserved for future LSB use
+# 100-149 reserved for distribution use
+# 150-199 reserved for application use
+# 200-254 reserved
+#
+# Non-Status Exit Codes
+#
+# 0 action was successful
+# 1 generic or unspecified error (current practice)
+# 2 invalid or excess argument(s)
+# 3 unimplemented feature (for example, "reload")
+# 4 user had insufficient privilege
+# 5 program is not installed
+# 6 program is not configured
+# 7 program is not running
+# 8-99 reserved for future LSB use
+# 100-149 reserved for distribution use
+# 150-199 reserved for application use
+# 200-254 reserved
+#
+
+# PKI subsystem-level directory and file values for locks
+lockfile="/var/lock/subsys/${SERVICE_NAME}"
+
+default_error=0
+
+case $command in
+ start|stop|restart|condrestart|force-restart|try-restart)
+ # 1 generic or unspecified error (current practice)
+ default_error=1
+ ;;
+ reload)
+ default_error=3
+ ;;
+ status)
+ # 4 program or service status is unknown
+ default_error=4
+ ;;
+ *)
+ # 2 invalid argument(s)
+ default_error=2
+ ;;
+esac
+
+# Enable nullglob, if set then shell pattern globs which do not match any
+# file returns the empty string rather than the unmodified glob pattern.
+shopt -s nullglob
+
+OS=`uname -s`
+ARCHITECTURE=`uname -i`
+
+# Check to insure that this script's original invocation directory
+# has not been deleted!
+CWD=`/bin/pwd > /dev/null 2>&1`
+if [ $? -ne 0 ] ; then
+ echo "Cannot invoke '$PROG_NAME' from non-existent directory!"
+ exit ${default_error}
+fi
+
+# Check to insure that this script's associated PKI
+# subsystem currently resides on this system.
+if [ ! -d ${PKI_PATH} ] ; then
+ echo "This machine is missing the '${PKI_TYPE}' subsystem!"
+ if [ "${command}" != "status" ]; then
+ # 5 program is not installed
+ exit 5
+ else
+ exit ${default_error}
+ fi
+fi
+
+# Check to insure that this script's associated PKI
+# subsystem instance registry currently resides on this system.
+if [ ! -d ${PKI_REGISTRY} ] ; then
+ echo "This machine contains no registered '${PKI_TYPE}' subsystem instances!"
+ if [ "${command}" != "status" ]; then
+ # 5 program is not installed
+ exit 5
+ else
+ exit ${default_error}
+ fi
+fi
+
+# This script must be run as root!
+RV=0
+if [ `id -u` -ne 0 ] ; then
+ echo "Must be 'root' to execute '$PROG_NAME'!"
+ if [ "${command}" != "status" ]; then
+ # 4 user had insufficient privilege
+ exit 4
+ else
+ # 4 program or service status is unknown
+ exit 4
+ fi
+fi
+
+PKI_REGISTRY_ENTRIES=""
+TOTAL_PKI_REGISTRY_ENTRIES=0
+TOTAL_UNCONFIGURED_PKI_ENTRIES=0
+
+# Gather ALL registered instances of this PKI subsystem type
+for FILE in ${PKI_REGISTRY}/*; do
+ if [ -f "$FILE" ] ; then
+ PKI_REGISTRY_ENTRIES="${PKI_REGISTRY_ENTRIES} $FILE"
+ TOTAL_PKI_REGISTRY_ENTRIES=`expr ${TOTAL_PKI_REGISTRY_ENTRIES} + 1`
+ fi
+done
+
+if [ -n "${pki_instance}" ]; then
+ for I in ${PKI_REGISTRY_ENTRIES}; do
+ if [ "${PKI_REGISTRY}/${pki_instance}" = "$I" ]; then
+ PKI_REGISTRY_ENTRIES="${PKI_REGISTRY}/${pki_instance}"
+ TOTAL_PKI_REGISTRY_ENTRIES=1
+ break
+ fi
+ done
+fi
+
+usage()
+{
+ echo -n "Usage: ${SERVICE_PROG} ${SERVICE_NAME}"
+ echo -n "{start"
+ echo -n "|stop"
+ echo -n "|restart"
+ echo -n "|condrestart"
+ echo -n "|force-restart"
+ echo -n "|try-restart"
+ echo -n "|reload"
+ echo -n "|status} "
+ echo -n "[instance-name]"
+ echo
+ echo
+}
+
+usage_systemd()
+{
+ echo -n "Usage: /usr/bin/pkicontrol "
+ echo -n "{start"
+ echo -n "|stop"
+ echo -n "|restart"
+ echo -n "|condrestart"
+ echo -n "|force-restart"
+ echo -n "|try-restart"
+ echo -n "|reload"
+ echo -n "|status} "
+ echo -n "subsytem-type "
+ echo -n "[instance-name]"
+ echo
+ echo
+}
+
+
+list_instances()
+{
+ echo
+ for PKI_REGISTRY_ENTRY in $PKI_REGISTRY_ENTRIES; do
+ instance_name=`basename $PKI_REGISTRY_ENTRY`
+ echo " $instance_name"
+ done
+ echo
+}
+
+# Check arguments
+if [ $SYSTEMD ]; then
+ if [ $# -lt 2 ] ; then
+ # [insufficient arguments]
+ echo "$PROG_NAME: Insufficient arguments!"
+ echo
+ usage_systemd
+ echo "where valid instance names include:"
+ list_instances
+ exit 3
+ elif [ ${default_error} -eq 2 ] ; then
+ # 2 invalid argument
+ echo "$PROG_NAME: Invalid arguments!"
+ echo
+ usage_systemd
+ echo "where valid instance names include:"
+ list_instances
+ exit 2
+ elif [ $# -gt 3 ] ; then
+ echo "$PROG_NAME: Excess arguments!"
+ echo
+ usage_systemd
+ echo "where valid instance names include:"
+ list_instances
+ if [ "${command}" != "status" ]; then
+ # 2 excess arguments
+ exit 2
+ else
+ # 4 program or service status is unknown
+ exit 4
+ fi
+ fi
+else
+ if [ $# -lt 1 ] ; then
+ # 3 unimplemented feature (for example, "reload")
+ # [insufficient arguments]
+ echo "$PROG_NAME: Insufficient arguments!"
+ echo
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ exit 3
+ elif [ ${default_error} -eq 2 ] ; then
+ # 2 invalid argument
+ echo "$PROG_NAME: Invalid arguments!"
+ echo
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ exit 2
+ elif [ $# -gt 2 ] ; then
+ echo "$PROG_NAME: Excess arguments!"
+ echo
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ if [ "${command}" != "status" ]; then
+ # 2 excess arguments
+ exit 2
+ else
+ # 4 program or service status is unknown
+ exit 4
+ fi
+ fi
+fi
+
+# If an "instance" was supplied, check that it is a "valid" instance
+if [ -n "${pki_instance}" ]; then
+ valid=0
+ for PKI_REGISTRY_ENTRY in $PKI_REGISTRY_ENTRIES; do
+ instance_name=`basename $PKI_REGISTRY_ENTRY`
+ if [ $pki_instance == $instance_name ]; then
+ valid=1
+ break
+ fi
+ done
+ if [ $valid -eq 0 ]; then
+ echo -n "${pki_instance} is an invalid '${PKI_TYPE}' instance"
+ if [ ! $SYSTEMD ]; then
+ echo_failure
+ fi
+ echo
+
+ if [ "${command}" != "status" ]; then
+ # 5 program is not installed
+ exit 5
+ else
+ # 4 program or service status is unknown
+ exit 4
+ fi
+ fi
+fi
+
+check_pki_configuration_status()
+{
+ rv=0
+
+ rv=`grep -c ^preop ${pki_instance_configuration_file}`
+
+ rv=`expr ${rv} + 0`
+
+ if [ $rv -ne 0 ] ; then
+ echo " '${PKI_INSTANCE_ID}' must still be CONFIGURED!"
+ echo " (see /var/log/${PKI_INSTANCE_ID}-install.log)"
+ if [ "${command}" != "status" ]; then
+ # 6 program is not configured
+ rv=6
+ else
+ # 4 program or service status is unknown
+ rv=4
+ fi
+ TOTAL_UNCONFIGURED_PKI_ENTRIES=`expr ${TOTAL_UNCONFIGURED_PKI_ENTRIES} + 1`
+ elif [ -f ${RESTART_SERVER} ] ; then
+ echo -n " Although '${PKI_INSTANCE_ID}' has been CONFIGURED, "
+ echo -n "it must still be RESTARTED!"
+ echo
+ if [ "${command}" != "status" ]; then
+ # 1 generic or unspecified error (current practice)
+ rv=1
+ else
+ # 4 program or service status is unknown
+ rv=4
+ fi
+ fi
+
+ return $rv
+}
+
+get_pki_status_definitions()
+{
+ case $PKI_SUBSYSTEM_TYPE in
+ ca|kra|ocsp|tks)
+ get_pki_status_definitions_tomcat
+ return $?
+ ;;
+ ra)
+ get_pki_status_definitions_ra
+ return $?
+ ;;
+ tps)
+ get_pki_status_definitions_tps
+ return $?
+ ;;
+ *)
+ echo "Unknown subsystem type ($PKI_SUBSYSTEM_TYPE)"
+ exit ${default_error}
+ ;;
+ esac
+}
+
+get_pki_status_definitions_ra()
+{
+ # establish well-known strings
+ total_ports=0
+ UNSECURE_PORT=""
+ CLIENTAUTH_PORT=""
+ NON_CLIENTAUTH_PORT=""
+
+ # check to see that an instance-specific "httpd.conf" file exists
+ if [ ! -f ${PKI_HTTPD_CONF} ] ; then
+ echo "File '${PKI_HTTPD_CONF}' does not exist!"
+ exit ${default_error}
+ fi
+
+ # check to see that an instance-specific "nss.conf" file exists
+ if [ ! -f ${PKI_NSS_CONF} ] ; then
+ echo "File '${PKI_NSS_CONF}' does not exist!"
+ exit ${default_error}
+ fi
+
+ # Iterate over Listen statements
+ for port in `sed -n 's/^[ \t]*Listen[ \t][ \t]*\([^ \t][^ \t]*\)/\1/p' ${PKI_HTTPD_CONF}`; do
+ UNSECURE_PORT=$port
+ if [ $total_ports -eq 0 ]; then
+ echo " Unsecure Port = http://${PKI_SERVER_NAME}:${UNSECURE_PORT}"
+ else
+ echo "ERROR: extra Unsecure Port = http://${PKI_SERVER_NAME}:${UNSECURE_PORT}"
+ fi
+ total_ports=`expr ${total_ports} + 1`
+
+ done
+
+ # Iterate over Listen statements
+ for port in `sed -n 's/^[ \t]*Listen[ \t][ \t]*\([^ \t][^ \t]*\)/\1/p' ${PKI_NSS_CONF}`; do
+ UNSECURE_PORT=$port
+ if [ $total_ports -eq 1 ]; then
+ CLIENTAUTH_PORT=$port
+ echo " Secure Clientauth Port = https://${PKI_SERVER_NAME}:${CLIENTAUTH_PORT}"
+ fi
+ if [ $total_ports -eq 2 ]; then
+ NON_CLIENTAUTH_PORT=$port
+ echo " Secure Non-Clientauth Port = https://${PKI_SERVER_NAME}:${NON_CLIENTAUTH_PORT}"
+ fi
+ total_ports=`expr ${total_ports} + 1`
+
+ done
+
+ return 0;
+}
+
+get_pki_status_definitions_tps()
+{
+ # establish well-known strings
+ total_ports=0
+ UNSECURE_PORT=""
+ CLIENTAUTH_PORT=""
+ NON_CLIENTAUTH_PORT=""
+
+ # check to see that an instance-specific "httpd.conf" file exists
+ if [ ! -f ${PKI_HTTPD_CONF} ] ; then
+ echo "File '${PKI_HTTPD_CONF}' does not exist!"
+ exit ${default_error}
+ fi
+
+ # check to see that an instance-specific "nss.conf" file exists
+ if [ ! -f ${PKI_NSS_CONF} ] ; then
+ echo "File '${PKI_NSS_CONF}' does not exist!"
+ exit ${default_error}
+ fi
+
+ # Iterate over Listen statements
+ for port in `sed -n 's/^[ \t]*Listen[ \t][ \t]*\([^ \t][^ \t]*\)/\1/p' ${PKI_HTTPD_CONF}`; do
+ UNSECURE_PORT=$port
+ if [ $total_ports -eq 0 ]; then
+ echo " Unsecure Port = http://${PKI_SERVER_NAME}:${UNSECURE_PORT}/cgi-bin/so/enroll.cgi"
+ echo " (ESC Security Officer Enrollment)"
+ echo " Unsecure Port = http://${PKI_SERVER_NAME}:${UNSECURE_PORT}/cgi-bin/home/index.cgi"
+ echo " (ESC Phone Home)"
+ else
+ echo "ERROR: extra Unsecure Port = http://${PKI_SERVER_NAME}:${UNSECURE_PORT}"
+ fi
+ total_ports=`expr ${total_ports} + 1`
+
+ done
+
+ # Iterate over Listen statements
+ for port in `sed -n 's/^[ \t]*Listen[ \t][ \t]*\([^ \t][^ \t]*\)/\1/p' ${PKI_NSS_CONF}`; do
+ UNSECURE_PORT=$port
+ if [ $total_ports -eq 1 ]; then
+ CLIENTAUTH_PORT=$port
+ echo " Secure Clientauth Port = https://${PKI_SERVER_NAME}:${CLIENTAUTH_PORT}/cgi-bin/sow/welcome.cgi"
+ echo " (ESC Security Officer Workstation)"
+ echo " Secure Clientauth Port = https://${PKI_SERVER_NAME}:${CLIENTAUTH_PORT}/tus"
+ echo " (TPS Roles - Operator/Administrator/Agent)"
+ fi
+ if [ $total_ports -eq 2 ]; then
+ NON_CLIENTAUTH_PORT=$port
+ echo " Secure Non-Clientauth Port = https://${PKI_SERVER_NAME}:${NON_CLIENTAUTH_PORT}/cgi-bin/so/enroll.cgi"
+ echo " (ESC Security Officer Enrollment)"
+ echo " Secure Non-Clientauth Port = https://${PKI_SERVER_NAME}:${NON_CLIENTAUTH_PORT}/cgi-bin/home/index.cgi"
+ echo " (ESC Phone Home)"
+ fi
+ total_ports=`expr ${total_ports} + 1`
+
+ done
+
+ return 0;
+}
+
+get_pki_status_definitions_tomcat()
+{
+ # establish well-known strings
+ begin_pki_status_comment="<!-- DO NOT REMOVE - Begin PKI Status Definitions -->"
+ end_pki_status_comment="<!-- DO NOT REMOVE - End PKI Status Definitions -->"
+ total_ports=0
+ unsecure_port_statement="Unsecure Port"
+ secure_agent_port_statement="Secure Agent Port"
+ secure_ee_port_statement="Secure EE Port"
+ secure_ee_client_auth_port_statement="EE Client Auth Port"
+ secure_admin_port_statement="Secure Admin Port"
+ pki_console_port_statement="PKI Console Port"
+ tomcat_port_statement="Tomcat Port"
+
+ # initialize looping variables
+ pki_status_comment_found=0
+
+ # first check to see that an instance-specific "server.xml" file exists
+ if [ ! -f ${PKI_SERVER_XML_CONF} ] ; then
+ echo "File '${PKI_SERVER_XML_CONF}' does not exist!"
+ exit ${default_error}
+ fi
+
+ # read this instance-specific "server.xml" file line-by-line
+ # to obtain the current PKI Status Definitions
+ exec < ${PKI_SERVER_XML_CONF}
+ while read line; do
+ # first look for the well-known end PKI Status comment
+ # (to turn off processing)
+ if [ "$line" == "$end_pki_status_comment" ] ; then
+ pki_status_comment_found=0
+ break;
+ fi
+
+ # then look for the well-known begin PKI Status comment
+ # (to turn on processing)
+ if [ "$line" == "$begin_pki_status_comment" ] ; then
+ pki_status_comment_found=1
+ fi
+
+ # once the well-known begin PKI Status comment has been found,
+ # begin processing to obtain all of the PKI Status Definitions
+ if [ $pki_status_comment_found -eq 1 ] ; then
+ # look for a PKI Status Definition and print it
+ head=`echo "$line" | sed -e 's/^\([^=]*\)[ \t]*= .*$/\1/' -e 's/[ \t]*$//'`
+ if [ "$head" == "$unsecure_port_statement" ] ||
+ [ "$head" == "$secure_agent_port_statement" ] ||
+ [ "$head" == "$secure_ee_port_statement" ] ||
+ [ "$head" == "$secure_ee_client_auth_port_statement" ] ||
+ [ "$head" == "$secure_admin_port_statement" ] ||
+ [ "$head" == "$pki_console_port_statement" ] ||
+ [ "$head" == "$tomcat_port_statement" ] ; then
+ echo " $line"
+ total_ports=`expr ${total_ports} + 1`
+ fi
+ fi
+ done
+
+ return 0;
+}
+
+get_pki_configuration_definitions()
+{
+ # Obtain the PKI Subsystem Type
+ line=`grep -e '^[ \t]*cs.type[ \t]*=' ${pki_instance_configuration_file}`
+ pki_subsystem=`echo "${line}" | sed -e 's/^[^=]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ if [ "${line}" != "" ] ; then
+ if [ "${pki_subsystem}" != "CA" ] &&
+ [ "${pki_subsystem}" != "KRA" ] &&
+ [ "${pki_subsystem}" != "OCSP" ] &&
+ [ "${pki_subsystem}" != "TKS" ] &&
+ [ "${pki_subsystem}" != "RA" ] &&
+ [ "${pki_subsystem}" != "TPS" ]
+ then
+ return ${default_error}
+ fi
+ if [ "${pki_subsystem}" == "KRA" ] ; then
+ # Rename "KRA" to "DRM"
+ pki_subsystem="DRM"
+ fi
+ else
+ return ${default_error}
+ fi
+
+ # If "${pki_subsystem}" is a CA, DRM, OCSP, or TKS,
+ # check to see if "${pki_subsystem}" is a "Clone"
+ pki_clone=""
+ if [ "${pki_subsystem}" == "CA" ] ||
+ [ "${pki_subsystem}" == "DRM" ] ||
+ [ "${pki_subsystem}" == "OCSP" ] ||
+ [ "${pki_subsystem}" == "TKS" ]
+ then
+ line=`grep -e '^[ \t]*subsystem.select[ \t]*=' ${pki_instance_configuration_file}`
+ if [ "${line}" != "" ] ; then
+ pki_clone=`echo "${line}" | sed -e 's/^[^=]*[ \t]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ if [ "${pki_clone}" != "Clone" ] ; then
+ # Reset "${pki_clone}" to be empty
+ pki_clone=""
+ fi
+ else
+ return ${default_error}
+ fi
+ fi
+
+ # If "${pki_subsystem}" is a CA, and is NOT a "Clone", check to
+ # see "${pki_subsystem}" is a "Root" or a "Subordinate" CA
+ pki_hierarchy=""
+ if [ "${pki_subsystem}" == "CA" ] &&
+ [ "${pki_clone}" != "Clone" ]
+ then
+ line=`grep -e '^[ \t]*hierarchy.select[ \t]*=' ${pki_instance_configuration_file}`
+ if [ "${line}" != "" ] ; then
+ pki_hierarchy=`echo "${line}" | sed -e 's/^[^=]*[ \t]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ else
+ return ${default_error}
+ fi
+ fi
+
+ # If ${pki_subsystem} is a CA, check to
+ # see if it is also a Security Domain
+ pki_security_domain=""
+ if [ "${pki_subsystem}" == "CA" ] ; then
+ line=`grep -e '^[ \t]*securitydomain.select[ \t]*=' ${pki_instance_configuration_file}`
+ if [ "${line}" != "" ] ; then
+ pki_security_domain=`echo "${line}" | sed -e 's/^[^=]*[ \t]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ if [ "${pki_security_domain}" == "new" ] ; then
+ # Set a fixed value for "${pki_security_domain}"
+ pki_security_domain="(Security Domain)"
+ else
+ # Reset "${pki_security_domain}" to be empty
+ pki_security_domain=""
+ fi
+ else
+ return ${default_error}
+ fi
+ fi
+
+ # Always obtain this PKI instance's "registered"
+ # security domain information
+ pki_security_domain_name=""
+ pki_security_domain_hostname=""
+ pki_security_domain_https_admin_port=""
+
+ line=`grep -e '^[ \t]*securitydomain.name[ \t]*=' ${pki_instance_configuration_file}`
+ if [ "${line}" != "" ] ; then
+ pki_security_domain_name=`echo "${line}" | sed -e 's/^[^=]*[ \t]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ else
+ return ${default_error}
+ fi
+
+ line=`grep -e '^[ \t]*securitydomain.host[ \t]*=' ${pki_instance_configuration_file}`
+ if [ "${line}" != "" ] ; then
+ pki_security_domain_hostname=`echo "${line}" | sed -e 's/^[^=]*[ \t]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ else
+ return ${default_error}
+ fi
+
+ line=`grep -e '^[ \t]*securitydomain.httpsadminport[ \t]*=' ${pki_instance_configuration_file}`
+ if [ "${line}" != "" ] ; then
+ pki_security_domain_https_admin_port=`echo "${line}" | sed -e 's/^[^=]*[ \t]*=[ \t]*\(.*\)/\1/' -e 's/[ \t]*$//'`
+ else
+ return ${default_error}
+ fi
+
+ # Compose the "PKI Instance Name" Status Line
+ pki_instance_name="PKI Instance Name: ${PKI_INSTANCE_ID}"
+
+ # Compose the "PKI Subsystem Type" Status Line
+ header="PKI Subsystem Type: "
+ if [ "${pki_clone}" != "" ] ; then
+ if [ "${pki_security_domain}" != "" ]; then
+ # Possible Values:
+ #
+ # "CA Clone (Security Domain)"
+ #
+ data="${pki_subsystem} ${pki_clone} ${pki_security_domain}"
+ else
+ # Possible Values:
+ #
+ # "CA Clone"
+ # "DRM Clone"
+ # "OCSP Clone"
+ # "TKS Clone"
+ #
+ data="${pki_subsystem} ${pki_clone}"
+ fi
+ elif [ "${pki_hierarchy}" != "" ] ; then
+ if [ "${pki_security_domain}" != "" ]; then
+ # Possible Values:
+ #
+ # "Root CA (Security Domain)"
+ # "Subordinate CA (Security Domain)"
+ #
+ data="${pki_hierarchy} ${pki_subsystem} ${pki_security_domain}"
+ else
+ # Possible Values:
+ #
+ # "Root CA"
+ # "Subordinate CA"
+ #
+ data="${pki_hierarchy} ${pki_subsystem}"
+ fi
+ else
+ # Possible Values:
+ #
+ # "DRM"
+ # "OCSP"
+ # "RA"
+ # "TKS"
+ # "TPS"
+ #
+ data="${pki_subsystem}"
+ fi
+ pki_subsystem_type="${header} ${data}"
+
+ # Compose the "Registered PKI Security Domain Information" Status Line
+ header="Name: "
+ registered_pki_security_domain_name="${header} ${pki_security_domain_name}"
+
+ header="URL: "
+ if [ "${pki_security_domain_hostname}" != "" ] &&
+ [ "${pki_security_domain_https_admin_port}" != "" ]
+ then
+ data="https://${pki_security_domain_hostname}:${pki_security_domain_https_admin_port}"
+ else
+ return ${default_error}
+ fi
+ registered_pki_security_domain_url="${header} ${data}"
+
+ # Print the "PKI Subsystem Type" Status Line
+ echo
+ echo " ${pki_instance_name}"
+
+ # Print the "PKI Subsystem Type" Status Line
+ echo
+ echo " ${pki_subsystem_type}"
+
+ # Print the "Registered PKI Security Domain Information" Status Line
+ echo
+ echo " Registered PKI Security Domain Information:"
+ echo " =========================================================================="
+ echo " ${registered_pki_security_domain_name}"
+ echo " ${registered_pki_security_domain_url}"
+ echo " =========================================================================="
+
+ return 0
+}
+
+display_configuration_information()
+{
+ result=0
+ check_pki_configuration_status
+ rv=$?
+ if [ $rv -eq 0 ] ; then
+ get_pki_status_definitions
+ rv=$?
+ if [ $rv -ne 0 ] ; then
+ result=$rv
+ echo
+ echo "${PKI_INSTANCE_ID} Status Definitions not found"
+ else
+ get_pki_configuration_definitions
+ rv=$?
+ if [ $rv -ne 0 ] ; then
+ result=$rv
+ echo
+ echo "${PKI_INSTANCE_ID} Configuration Definitions not found"
+ fi
+ fi
+ fi
+ return $result
+}
+
+display_instance_status_systemd()
+{
+ echo -n "Status for ${PKI_INSTANCE_ID}: "
+ systemctl status "$PKI_SYSTEMD_TARGET@$PKI_INSTANCE_ID.service" > /dev/null 2>&1
+ rv=$?
+
+ if [ $rv -eq 0 ] ; then
+ echo "$PKI_INSTANCE_ID is running .."
+ display_configuration_information
+ else
+ echo "$PKI_INSTANCE_ID is stopped"
+ fi
+
+ return $rv
+}
+
+display_instance_status()
+{
+ # Verify there is an initscript for this instance
+ if [ ! -f $PKI_INSTANCE_INITSCRIPT ]; then
+ # 4 program or service status is unknown
+ return 4
+ fi
+
+ # Invoke the initscript for this instance
+ $PKI_INSTANCE_INITSCRIPT status
+ rv=$?
+
+ if [ $rv -eq 0 ] ; then
+ display_configuration_information
+ fi
+
+ return $rv
+}
+
+start_instance()
+{
+ rv=0
+
+ if [ -f ${RESTART_SERVER} ] ; then
+ rm -f ${RESTART_SERVER}
+ fi
+
+ # Invoke the initscript for this instance
+ case $PKI_SUBSYSTEM_TYPE in
+ ca|kra|ocsp|tks)
+
+ # We must export the service name so that the systemd version
+ # of the tomcat6 init script knows which instance specific
+ # configuration file to source.
+ export SERVICE_NAME=$PKI_INSTANCE_ID
+
+ if [ -x /usr/sbin/selinuxenabled ] && /usr/sbin/selinuxenabled; then
+ /usr/bin/runcon -t pki_${PKI_SUBSYSTEM_TYPE}_script_t \
+ $PKI_INSTANCE_INITSCRIPT start
+ rv=$?
+ else
+ $PKI_INSTANCE_INITSCRIPT start
+ rv=$?
+ fi
+ ;;
+ ra|tps)
+ $PKI_INSTANCE_INITSCRIPT start
+ rv=$?
+ ;;
+ esac
+
+ if [ $rv -ne 0 ] ; then
+ return $rv
+ fi
+
+ # On Tomcat subsystems, make certain that the service has started
+ case $PKI_SUBSYSTEM_TYPE in
+ ca|kra|ocsp|tks)
+ count=0
+ tries=30
+ port=`grep '^pkicreate.unsecure_port=' ${pki_instance_configuration_file} | cut -b25- -`
+ while [ $count -lt $tries ]
+ do
+ netstat -antl | grep ${port} > /dev/null
+ netrv=$?
+ if [ $netrv -eq 0 ] ; then
+ break;
+ fi
+ sleep 1
+ let count=$count+1;
+ done
+ if [ $netrv -ne 0 ] ; then
+ return 1
+ fi
+ ;;
+ esac
+
+ if [ $rv -eq 0 ] ; then
+ # From the PKI point of view a returned error code of 6 implies
+ # that the program is not "configured". An error code of 1 implies
+ # that the program was "configured" but must still be restarted.
+ #
+ # If the return code is 6 return this value unchanged to the
+ # calling routine so that the total number of configuration errors
+ # may be counted. Other return codes are ignored.
+ #
+ check_pki_configuration_status
+ rv=$?
+ if [ $rv -eq 6 ]; then
+ # 6 program is not configured
+ return 6
+ else
+ # 0 success
+
+ # Tomcat instances automatically place pid files under
+ # '/var/run' and lock files under '/var/lock/subsys'.
+ #
+ # However, since PKI subsystem instances can have any name,
+ # in order to identify the PKI subsystem type of a particular
+ # PKI instance, we create a separate "pki subsystem identity"
+ # symlink to the PKI instance pid file and place it under
+ # '/var/run/pki/<pki subsystem>', and a separate
+ # "pki subsystem identity" symlink to the PKI instance
+ # lock file and place it under '/var/lock/pki/<pki subsystem>'.
+ #
+ case $PKI_SUBSYSTEM_TYPE in
+ ca|kra|ocsp|tks)
+ if [ -h ${PKI_PIDFILE} ]; then
+ rm -f ${PKI_PIDFILE}
+ fi
+ if [ -f ${TOMCAT_PIDFILE} ]; then
+ ln -s ${TOMCAT_PIDFILE} ${PKI_PIDFILE}
+ chown -h ${TOMCAT_USER}:${TOMCAT_GROUP} ${PKI_PIDFILE}
+ fi
+ if [ -h ${PKI_LOCKFILE} ]; then
+ rm -f ${PKI_LOCKFILE}
+ fi
+ if [ -f ${TOMCAT_LOCKFILE} ]; then
+ ln -s ${TOMCAT_LOCKFILE} ${PKI_LOCKFILE}
+ fi
+ ;;
+ esac
+
+ return 0
+ fi
+ fi
+ return $rv
+}
+
+stop_instance()
+{
+ rv=0
+
+ export SERVICE_NAME=$PKI_INSTANCE_ID
+ # Invoke the initscript for this instance
+ $PKI_INSTANCE_INITSCRIPT stop
+ rv=$?
+
+ # On Tomcat subsystems, always remove the "pki subsystem identity" symlinks
+ # that were previously associated with the Tomcat 'pid' and 'lock' files.
+ case $PKI_SUBSYSTEM_TYPE in
+ ca|kra|ocsp|tks)
+ if [ -h ${PKI_PIDFILE} ]; then
+ rm -f ${PKI_PIDFILE}
+ fi
+ if [ -h ${PKI_LOCKFILE} ]; then
+ rm -f ${PKI_LOCKFILE}
+ fi
+ ;;
+ esac
+
+ return $rv
+}
+
+start()
+{
+ error_rv=0
+ rv=0
+ config_errors=0
+ errors=0
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -eq 0 ]; then
+ echo
+ echo "ERROR: No '${PKI_TYPE}' instances installed!"
+ # 5 program is not installed
+ return 5
+ fi
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ]; then
+ echo "BEGIN STARTING '${PKI_TYPE}' INSTANCES:"
+ fi
+
+ # Start every PKI instance of this type that isn't already running
+ for PKI_REGISTRY_ENTRY in ${PKI_REGISTRY_ENTRIES}; do
+ # Source values associated with this particular PKI instance
+ [ -f ${PKI_REGISTRY_ENTRY} ] &&
+ . ${PKI_REGISTRY_ENTRY}
+
+ [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] && echo
+
+ start_instance
+ rv=$?
+ if [ $rv = 6 ] ; then
+ # Since at least ONE configuration error exists, then there
+ # is at least ONE unconfigured instance from the PKI point
+ # of view.
+ #
+ # However, it must still be considered that the
+ # instance is "running" from the point of view of other
+ # OS programs such as 'chkconfig'.
+ #
+ # Therefore, ignore non-zero return codes resulting
+ # from configuration errors.
+ #
+
+ config_errors=`expr $config_errors + 1`
+ rv=0
+ elif [ $rv != 0 ] ; then
+ errors=`expr $errors + 1`
+ error_rv=$rv
+ fi
+ done
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt ${errors} ] ; then
+ touch ${lockfile}
+ chmod 00600 ${lockfile}
+ fi
+
+ # ONLY print a "WARNING" message if multiple
+ # instances are being examined
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] ; then
+ # NOTE: "bad" return code(s) OVERRIDE configuration errors!
+ if [ ${errors} -eq 1 ]; then
+ # Since only ONE error exists, return that "bad" error code.
+ rv=${error_rv}
+ elif [ ${errors} -gt 1 ]; then
+ # Since MORE than ONE error exists, return an OVERALL status
+ # of "1 generic or unspecified error (current practice)"
+ rv=1
+ fi
+
+ if [ ${errors} -ge 1 ]; then
+ echo
+ echo -n "WARNING: "
+ echo -n "${errors} of ${TOTAL_PKI_REGISTRY_ENTRIES} "
+ echo -n "'${PKI_TYPE}' instances failed to start!"
+ echo
+ fi
+
+ if [ ${TOTAL_UNCONFIGURED_PKI_ENTRIES} -ge 1 ]; then
+ echo
+ echo -n "WARNING: "
+ echo -n "${TOTAL_UNCONFIGURED_PKI_ENTRIES} "
+ echo -n "of ${TOTAL_PKI_REGISTRY_ENTRIES} "
+ echo -n "'${PKI_TYPE}' instances MUST be configured!"
+ echo
+ fi
+
+ echo
+ echo "FINISHED STARTING '${PKI_TYPE}' INSTANCE(S)."
+ fi
+
+ return $rv
+}
+
+stop()
+{
+ error_rv=0
+ rv=0
+ errors=0
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -eq 0 ]; then
+ echo
+ echo "ERROR: No '${PKI_TYPE}' instances installed!"
+ # 5 program is not installed
+ return 5
+ fi
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] ; then
+ echo "BEGIN SHUTTING DOWN '${PKI_TYPE}' INSTANCE(S):"
+ fi
+
+ # Shutdown every PKI instance of this type that is running
+ for PKI_REGISTRY_ENTRY in ${PKI_REGISTRY_ENTRIES}; do
+ # Source values associated with this particular PKI instance
+ [ -f ${PKI_REGISTRY_ENTRY} ] &&
+ . ${PKI_REGISTRY_ENTRY}
+
+ [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] && echo
+
+ stop_instance
+ rv=$?
+ if [ $rv != 0 ] ; then
+ errors=`expr $errors + 1`
+ error_rv=$rv
+ fi
+ done
+
+ if [ ${errors} -eq 0 ] ; then
+ rm -f ${lockfile}
+ fi
+
+ # ONLY print a "WARNING" message if multiple
+ # instances are being examined
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] ; then
+ if [ ${errors} -eq 1 ]; then
+ # Since only ONE error exists, return that "bad" error code.
+ rv=${error_rv}
+ elif [ ${errors} -gt 1 ]; then
+ # Since MORE than ONE error exists, return an OVERALL status
+ # of "1 generic or unspecified error (current practice)"
+ rv=1
+ fi
+
+ if [ ${errors} -ge 1 ]; then
+ echo
+ echo -n "WARNING: "
+ echo -n "${errors} of ${TOTAL_PKI_REGISTRY_ENTRIES} "
+ echo -n "'${PKI_TYPE}' instances were "
+ echo -n "unsuccessfully stopped!"
+ echo
+ fi
+
+ echo
+ echo "FINISHED SHUTTING DOWN '${PKI_TYPE}' INSTANCE(S)."
+ fi
+
+ return $rv
+}
+
+restart()
+{
+ stop
+ sleep 2
+ start
+
+ return $?
+}
+
+registry_status()
+{
+ error_rv=0
+ rv=0
+ errors=0
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -eq 0 ]; then
+ echo
+ echo "ERROR: No '${PKI_TYPE}' instances installed!"
+ # 4 program or service status is unknown
+ return 4
+ fi
+
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] ; then
+ echo "REPORT STATUS OF '${PKI_TYPE}' INSTANCE(S):"
+ fi
+
+ # Obtain status of every PKI instance of this type
+ for PKI_REGISTRY_ENTRY in ${PKI_REGISTRY_ENTRIES}; do
+ # Source values associated with this particular PKI instance
+ [ -f ${PKI_REGISTRY_ENTRY} ] &&
+ . ${PKI_REGISTRY_ENTRY}
+
+ [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] && echo
+
+ case $PKI_SUBSYSTEM_TYPE in
+ ca|kra|ocsp|tks)
+ if [ $SYSTEMD ]; then
+ display_instance_status_systemd
+ else
+ display_instance_status
+ fi
+ rv=$?
+ ;;
+ tps|ra)
+ display_instance_status
+ rv=$?
+ ;;
+ esac
+ if [ $rv -ne 0 ] ; then
+ errors=`expr $errors + 1`
+ error_rv=$rv
+ fi
+ done
+
+ # ONLY print a "WARNING" message if multiple
+ # instances are being examined
+ if [ ${TOTAL_PKI_REGISTRY_ENTRIES} -gt 1 ] ; then
+ if [ ${errors} -eq 1 ]; then
+ # Since only ONE error exists, return that "bad" error code.
+ rv=${error_rv}
+ elif [ ${errors} -gt 1 ]; then
+ # Since MORE than ONE error exists, return an OVERALL status
+ # of "4 - program or service status is unknown"
+ rv=4
+ fi
+
+ if [ ${errors} -ge 1 ]; then
+ echo
+ echo -n "WARNING: "
+ echo -n "${errors} of ${TOTAL_PKI_REGISTRY_ENTRIES} "
+ echo -n "'${PKI_TYPE}' instances reported status failures!"
+ echo
+ fi
+
+ if [ ${TOTAL_UNCONFIGURED_PKI_ENTRIES} -ge 1 ]; then
+ echo
+ echo -n "WARNING: "
+ echo -n "${TOTAL_UNCONFIGURED_PKI_ENTRIES} "
+ echo -n "of ${TOTAL_PKI_REGISTRY_ENTRIES} "
+ echo -n "'${PKI_TYPE}' instances MUST be configured!"
+ echo
+ fi
+
+ echo
+ echo "FINISHED REPORTING STATUS OF '${PKI_TYPE}' INSTANCE(S)."
+ fi
+
+ return $rv
+}
+
diff --git a/base/setup/scripts/pki_apache_initscript b/base/setup/scripts/pki_apache_initscript
new file mode 100755
index 000000000..e51231065
--- /dev/null
+++ b/base/setup/scripts/pki_apache_initscript
@@ -0,0 +1,246 @@
+#!/bin/bash
+
+command="$1"
+
+# Source function library.
+. /etc/init.d/functions
+
+PKI_REGISTRY_FILE=[PKI_REGISTRY_FILE]
+
+# Enable nullglob, if set then shell pattern globs which do not match any
+# file returns the empty string rather than the unmodified glob pattern.
+shopt -s nullglob
+
+OS=`uname -s`
+ARCHITECTURE=`uname -i`
+
+# Source values associated with this particular PKI instance
+if [ -f $PKI_REGISTRY_FILE ]; then
+ . ${PKI_REGISTRY_FILE}
+else
+ echo "No PKI registry file ($PKI_REGISTRY_FILE)"
+ case $command in
+ status)
+ exit 4
+ ;;
+ *)
+ exit 1
+ ;;
+ esac
+fi
+
+prog=$PKI_INSTANCE_ID
+lockfile=$PKI_LOCK_FILE
+pidfile=$PKI_PID_FILE
+
+
+STARTUP_WAIT=30
+SHUTDOWN_WAIT=30
+
+start()
+{
+ rv=0
+
+ echo -n $"Starting ${prog}: "
+
+ if [ -f ${lockfile} ] ; then
+ if [ -f ${pidfile} ]; then
+ read kpid < ${pidfile}
+ if checkpid $kpid 2>&1; then
+ echo
+ echo "${PKI_INSTANCE_ID} (pid ${kpid}) is already running ..."
+ echo
+ return 0
+ else
+ echo
+ echo -n "lock file found but no process "
+ echo -n "running for pid $kpid, continuing"
+ echo
+ echo
+ rm -f ${lockfile}
+ fi
+ fi
+ fi
+
+ touch ${pidfile}
+ chown ${PKI_USER}:${PKI_GROUP} ${pidfile}
+ chmod 00600 ${pidfile}
+ [ -x /sbin/restorecon ] && /sbin/restorecon ${pidfile}
+
+ # restore context for ncipher hsm
+ [ -x /sbin/restorecon ] && [ -d /dev/nfast ] && /sbin/restorecon -R /dev/nfast
+
+ /usr/sbin/selinuxenabled
+ rv=$?
+ if [ ${rv} = 0 ] ; then
+ if [ ${ARCHITECTURE} = "i386" ] ; then
+ LANG=${PKI_HTTPD_LANG} daemon runcon -t ${PKI_SELINUX_TYPE} -- ${httpd} ${PKI_OPTIONS}
+ rv=$?
+ # overwrite output from "daemon"
+ echo -n $"Starting ${prog}: "
+ elif [ ${ARCHITECTURE} = "x86_64" ] ; then
+ # NOTE: "daemon" is incompatible with "httpd" on 64-bit architectures
+ LANG=${PKI_HTTPD_LANG} runcon -t ${PKI_SELINUX_TYPE} -- ${httpd} ${PKI_OPTIONS}
+ rv=$?
+ fi
+ else
+ LANG=${PKI_HTTPD_LANG} daemon ${httpd} ${PKI_OPTIONS}
+ rv=$?
+ # overwrite output from "daemon"
+ echo -n $"Starting ${prog}: "
+ fi
+
+ if [ ${rv} = 0 ] ; then
+ touch ${lockfile}
+ chown ${PKI_USER}:${PKI_GROUP} ${lockfile}
+ chmod 00600 ${lockfile}
+
+ count=0;
+
+ let swait=$STARTUP_WAIT
+ until [ -s ${pidfile} ] ||
+ [ $count -gt $swait ]
+ do
+ echo -n "."
+ sleep 1
+ let count=$count+1;
+ done
+
+ echo_success
+ echo
+
+ # Set permissions of log files
+ for file in ${pki_logs_directory}/*; do
+ if [ `basename $file` != "signedAudit" ]; then
+ chown ${PKI_USER}:${PKI_GROUP} ${file}
+ chmod 00640 ${file}
+ fi
+ done
+
+ if [ -d ${pki_logs_directory}/signedAudit ]; then
+ for file in ${pki_logs_directory}/signedAudit/*; do
+ chown ${PKI_USER} ${file}
+ chmod 00640 ${file}
+ done
+ fi
+
+ else
+ echo_failure
+ echo
+ fi
+
+
+ return ${rv}
+}
+
+stop()
+{
+ rv=0
+
+ echo -n "Stopping ${prog}: "
+
+ if [ -f ${lockfile} ] ; then
+ ${httpd} ${PKI_OPTIONS} -k stop
+ rv=$?
+
+ if [ ${rv} = 0 ]; then
+ count=0;
+
+ if [ -f ${pidfile} ]; then
+ read kpid < ${pidfile}
+ let kwait=$SHUTDOWN_WAIT
+
+ until [ `ps -p $kpid | grep -c $kpid` = '0' ] ||
+ [ $count -gt $kwait ]
+ do
+ echo -n "."
+ sleep 1
+ let count=$count+1;
+ done
+
+ if [ $count -gt $kwait ]; then
+ kill -9 $kpid
+ fi
+ fi
+
+ rm -f ${lockfile}
+ rm -f ${pidfile}
+
+ echo_success
+ echo
+ else
+ echo_failure
+ echo
+ rv=${default_error}
+ fi
+ else
+ echo
+ echo "process already stopped"
+ rv=0
+ fi
+
+ return ${rv}
+}
+
+reload()
+{
+ rv=0
+
+ echo -n $"Reloading ${prog}: "
+
+ if ! LANG=${PKI_HTTPD_LANG} ${httpd} ${PKI_OPTIONS} -t >&/dev/null; then
+ rv=$?
+ echo $"not reloading due to configuration syntax error"
+ failure $"not reloading ${httpd} due to configuration syntax error"
+ else
+ killproc -p ${pidfile} ${httpd} -HUP
+ rv=$?
+ fi
+ echo
+
+ return ${rv}
+}
+
+instance_status()
+{
+ status -p ${pidfile} ${prog}
+ rv=$?
+ return $rv
+}
+
+# See how we were called.
+case $command in
+ status)
+ instance_status
+ exit $?
+ ;;
+ start)
+ start
+ exit $?
+ ;;
+ restart)
+ restart
+ exit $?
+ ;;
+ stop)
+ stop
+ exit $?
+ ;;
+ condrestart|force-restart|try-restart)
+ [ ! -f ${lockfile} ] || restart
+ exit $?
+ ;;
+ reload)
+ echo "The 'reload' action is an unimplemented feature."
+ exit 3
+ ;;
+ condrestart|force-restart|try-restart)
+ [ ! -f ${lockfile} ] || restart
+ exit $?
+ ;;
+ *)
+ echo "unknown action ($command)"
+ exit 2
+ ;;
+esac
+
diff --git a/base/setup/scripts/pkicontrol b/base/setup/scripts/pkicontrol
new file mode 100755
index 000000000..f9a279b07
--- /dev/null
+++ b/base/setup/scripts/pkicontrol
@@ -0,0 +1,73 @@
+#!/bin/bash
+#
+# --- 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.,
+# 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
+#
+# Copyright (C) 2007-2010 Red Hat, Inc.
+# All rights reserved.
+# --- END COPYRIGHT BLOCK ---
+#
+
+PROG_NAME=`basename $0`
+SERVICE_NAME="pkicontrol"
+SERVICE_PROG="/bin/systemctl"
+
+command="$1"
+pki_subsystem_type="$2"
+pki_instance="$3"
+
+PKI_PATH="/usr/share/pki/${pki_subsystem_type}"
+PKI_REGISTRY="/etc/sysconfig/pki/${pki_subsystem_type}"
+PKI_TYPE="pki-${pki_subsystem_type}"
+PKI_SYSTEMD_TARGET="pki-${pki_subsystem_type}d"
+SYSTEMD=1
+
+# Source the PKI function library
+. /usr/share/pki/scripts/functions
+
+# See how we were called.
+case $command in
+ status)
+ registry_status
+ exit $?
+ ;;
+ start)
+ start
+ exit $?
+ ;;
+ restart)
+ restart
+ exit $?
+ ;;
+ stop)
+ stop
+ exit $?
+ ;;
+ condrestart|force-restart|try-restart)
+ [ ! -f ${lockfile} ] || restart
+ exit $?
+ ;;
+ reload)
+ echo "The 'reload' action is an unimplemented feature."
+ exit ${default_error}
+ ;;
+ *)
+ echo "unknown action ($command)"
+ usage
+ echo "where valid instance names include:"
+ list_instances
+ exit ${default_error}
+ ;;
+esac
+