package INSTALL::admin; use INSTALL::common; use INSTALL::os; use strict; no strict 'subs'; my $CONST_ComponentName = "Administration Console"; my $CONST_StartPriority = 86; my $CONST_StopPriority = 14; my $pOS = \%INSTALL::os::Details; my $debug = 0; my $debug_output = ($debug ? "" : " > /dev/null 2>&1"); use INSTALL::parameter; use INSTALL::global; use INSTALL::component; my $pGlobals = \%INSTALL::global::variables; my $pParameters = \%INSTALL::parameter::variables; #------------------------------------------------------------------------------ # If this flag is set to 1, then the installation of the administration console # is configurable. Otherwise, it will be installed regardless of what the # user wants. #------------------------------------------------------------------------------ my $CONST_InstallConfigurable = 0; sub verify_username { my ($username, $password) = (@_); if ($#_ == 0) { system("stty -echo"); print STDERR "New Password: "; my $password = ; print STDERR "\nConfirm Password (reenter password): "; my $confirm_password = ; system("stty echo"); print STDERR "\n"; chomp($username,$password,$confirm_password); if ($password eq $confirm_password) { return(not system_log("$pGlobals->{asphome}/admtool -a $username:$password")); } else { print STDERR "Passwords do not match.\n"; return(undef); } } else { return(not system_log("$pGlobals->{asphome}/admtool -a $username:$password")); } } use INSTALL::query; use INSTALL::services; use INSTALL::reboot; use INSTALL::substitute; #------------------------------------------------------------------------------ # The admin::configure method is responsible for querying / identifying the # wants of the user and incorporating those wants into the generated console. #============================================================================== #------------------------------------------------------------------------------ sub configure { my $tarball; ########## User query. if (not exists $pParameters->{install_admin}) { # Default to yes. $pParameters->{install_admin} = "true"; } if ((not exists $pParameters->{admin_port}) || (not $pParameters->{admin_port} =~ /^[0-9]+$/)) { # Default to 5100. $pParameters->{admin_port} = 5100; } if (not exists $pParameters->{admin_startonboot}) { # Automatic start enabled by default. $pParameters->{admin_startonboot} = "true"; } if (not exists $pParameters->{admin_username}) { # Default username = admin $pParameters->{admin_username} = "admin"; } if (not exists $pParameters->{admin_password}) { # Default password = root $pParameters->{admin_password} = "root"; } if ($CONST_InstallConfigurable) { if (not interactive) { if (not boolean_value($pParameters->{install_admin})) { goto CONFIGURE_CANCEL; } } else { INSTALL::query::user_menu ("Sun Chili!Soft ASP - Administration Console Installation", "You now have the opportunity to install the Sun Chili!Soft ASP Administration Console. ". "This utility makes managing ASP simpler by providing a web-based ". "interface to the most commonly needed configuration options."); my $answer = INSTALL::query::user ("Would you like to install the administration console", "terminal_mark=?","default=y","n"); if ($answer eq "n") { goto CONFIGURE_CANCEL; } } } if (interactive) { my $install_defaults = INSTALL::query::user_menu ("Chili!Soft ASP - Administration Console Installation", "Setup will now install the Sun Chili!Soft ASP Adminstation Console. Unless ". "you are an experienced Sun Chili!Soft ASP user, it is strongly recommened ". "that you choose the default configuration (option 1, below). If you choose ". "the custom configuration option, you will be asked to specify a number of ". "settings. For detailed information about configuring the Sun Chili!Soft ASP ". "Adminstration Console, see 'Chapter 3' in the product documentation.\n". " \n". "Note: If you choose the 'Default configuration' option, the username and\n". " password will be set to default values. To protect the security\n". " of your server, you should change these settings immediately after\n". " installation. For more infromation, see the product documentation.", "Select a configuration option for the Administration Console", "terminal_mark=.", "default=Default configuration", "Custom configuration"); if ($install_defaults == 2) { $pParameters->{custom_install} = "true"; } } my $custom_install = boolean_value($pParameters->{custom_install}); if (interactive && $custom_install) { sub is_port_valid { my ($check_port) = @_; if ($check_port <= 1024) { return 0; } return(INSTALL::services::validate_free_ports($check_port,1)); } my $recommended = INSTALL::services::locate_free_ports(5100,1); INSTALL::query::user_menu ("Sun Chili!Soft ASP - Administration Console Options", "To configure the Administration Console, respond to the following prompts."); $pParameters->{admin_port} = INSTALL::query::user_function ("Type the Administration Console port number, or \npress Enter to accept the default",*is_port_valid,"default=$recommended", "terminal_mark=.", "invalid_choice=Port already in use or invalid"); print "\n"; } elsif (interactive) { INSTALL::query::user_menu ("Sun Chili!Soft ASP - Configuring the Administration Console", "Setup will now perform the default option selection for you.\n". "Please wait."); } if (interactive && $custom_install) { $pParameters->{admin_startonboot} = (INSTALL::query::user ("Automatically start the Administration Console on system boot", "default=y","n", "terminal_mark=?") eq "y") ? "true" : "false"; } my $extract_child_pid = fork; if (not $extract_child_pid) { ########## Install initial tarball into the asphome directory. my $admin_base = "admin.$pOS->{ostag}_$pGlobals->{CSTARGET}"; local *COMPDIR; if (opendir(COMPDIR,$pGlobals->{admin_component_dir})) { foreach my $file (readdir(COMPDIR)) { if ($file =~ /^$admin_base\.tar/) { $tarball = "$pGlobals->{admin_component_dir}/$file"; } } closedir(COMPDIR); unless(defined $tarball) { error("Unable to find the $CONST_ComponentName tarball."); goto EXIT_ERROR; } } else { error("Unable to locate $CONST_ComponentName component dir:", " $pGlobals->{admin_component_dir}"); goto EXIT_ERROR; } # Blow away any unregistered administration console ... god forbid. if (-d $pGlobals->{admin_dir}) { recursive_rmdir($pGlobals->{admin_dir}); } my $admtool = "$pGlobals->{asphome}/admtool"; if (-f $admtool) { unlink($admtool); } unless (decompress($tarball,$pGlobals->{asphome})) { error("Unable to untar / uncompress $tarball."); goto EXIT_ERROR; } $main::ENV{COM_LAYER} = "$pGlobals->{com_layer}"; $main::ENV{CSREGISTRY} = "$pGlobals->{admin_conf_dir}"; if (-x "$pGlobals->{admin_bin_dir}/admd") { my $module; my $version_string = `$pGlobals->{admin_bin_dir}/admd -v`; if ($version_string =~ m@Server version:.*/(\d+)\.(\d+)\.(\d+)@s) { $pGlobals->{admd_version} = "$1.$2.$3" ; } else { error("Invalid / broken ChiliSoft Administration server.", "Unable to obtain version values for the server with config file:", " $pGlobals->{admd_conf_dir}/admd.conf"); goto EXIT_ERROR; } my $define_string = `$pGlobals->{admin_bin_dir}/admd -V`; if ($define_string =~ /EAPI/) { $pGlobals->{admd_api_type} = "eapi"; } else { $pGlobals->{admd_api_type} = "standard"; } my $module_string = `$pGlobals->{admin_bin_dir}/admd -l`; # Check, whether the webserver module is built-in. if ($module_string =~ /mod_casp2/) { $pGlobals->{admd_dso_support} = "no"; } elsif ($module_string =~ /mod_so/) { $pGlobals->{admd_dso_support} = "yes"; } else { error("Invalid / broken ChiliSoft Administration server.", "Administration Server MUST support either DSO or have a built-in module.", " $pGlobals->{admd_conf_dir}/admd.conf"); goto EXIT_ERROR; } # We need to do a shallow copy, only if the Administration Server # is a DSO Supported module. if (boolean_value($pGlobals->{admd_dso_support})) { my $mod_dir = $pGlobals->{module_dir}; my $apache_version = "apache_$pGlobals->{admd_version}"; my $mod_api = $pGlobals->{admd_api_type}; my $mod_so = "mod_casp2.$pGlobals->{lib_ext}"; $module = "$mod_dir/$apache_version/$mod_api/$mod_so"; unless (-f $module) { error("Unable to find appropriate admd module."); goto EXIT_ERROR; } unless (shallow_copy($module, $pGlobals->{admin_module_dir})) { error("Unable to make a backup copy of the admd module."); goto EXIT_ERROR; } } } else { error("Unable to locate admd executable."); goto EXIT_ERROR; } mkpath($pGlobals->{admin_logs_dir},0644); exit(0); } ########## Perform file substitutions # On HP-UX machines, the nobody has an invalid group id. so things # might not work out. so in this case , we might use daemon or www as # the user name. # So we need to be more tolerant towards user name and group. my @password_info ; my ($username,$password,$uid,$gid); my @user_lists = ("nobody","daemon","www","sys") ; foreach (@user_lists) { @password_info = getpwnam($_); if ($#password_info > 0) { ($username,$password,$uid,$gid) = @password_info; } #$uid = getpwnam($_) ; $gid = getgrnam($_) ; last if (($uid > 0) && ($gid > 0)) ; } # Legacy code let me not change it for now. if ($#password_info < 0) { ($username,$password,$uid,$gid) = getpwnam("chiliasp"); } my ($groupname) = getgrgid($gid); if (not $groupname) { # If the groups file does not contain an entry for the gid, # merely use the gid as is. $groupname = $gid; } if (not $username) { $username = $uid; } my %subst = ("admin::admd_port" => INSTALL::services::allocate_free_ports($pParameters->{admin_port},1,"Sun Chili!Soft ASP $CONST_ComponentName"), "admin::admin_port" => INSTALL::services::allocate_free_ports($pParameters->{admin_port},2,"Sun Chili!Soft ASP $CONST_ComponentName Engines"), "admin::webserver_user" => $username, "admin::webserver_group" => $groupname, "admin::supports_multiprocess" => "false", "admin::supports_multiserver" => "false", "admin::servername" => $pGlobals->{full_hostname} ); foreach($pGlobals->{casp_version}) { /3.6.0/ && do { # All but linux supports multiprocess. foreach($pOS->{os}) { (not /Linux/i) && do { $subst{admin::supports_multiprocess} = "true"; }; } last; }; # Else, use defaults. } if (interactive) { print STDERR "Installing Administration Console ... "; INSTALL::common::spinner_wait($extract_child_pid); print STDERR "\n"; if ($?) { goto CONFIGURE_ERROR; } } else { waitpid $extract_child_pid,0; } INSTALL::substitute::template("admtool",$pGlobals->{asphome},%subst); INSTALL::substitute::template("casp.cnfg","$pGlobals->{admin_bin_dir}",%subst); INSTALL::substitute::template("caspctrl","$pGlobals->{admin_bin_dir}",%subst); INSTALL::substitute::template("apachectl","$pGlobals->{admin_bin_dir}",%subst); INSTALL::substitute::template("admd.conf","$pGlobals->{admin_conf_dir}",%subst); INSTALL::substitute::template("odbc.ini","$pGlobals->{admin_conf_dir}",%subst); INSTALL::substitute::optional_template("Global.asa","$pGlobals->{asphome}/caspsamp","$pGlobals->{asphome}/caspsamp",%subst); INSTALL::substitute::optional_template("default.asp","$pGlobals->{asphome}/caspsamp","$pGlobals->{asphome}/caspsamp",%subst); INSTALL::substitute::optional_template("setup.asp","$pGlobals->{admin_dir}/web","$pGlobals->{admin_dir}/web",%subst); # odbc.ini assumes permission 0600 for security sake. chmod(0600,"$pGlobals->{admin_conf_dir}/odbc.ini"); ########## Duplicate needed executables. shallow_copy("$pGlobals->{bin_dir}/caspd","$pGlobals->{admin_bin_dir}/admdog"); shallow_copy("$pGlobals->{bin_dir}/caspctrlb","$pGlobals->{admin_bin_dir}"); shallow_copy("$pGlobals->{bin_dir}/caspeng","$pGlobals->{admin_bin_dir}/admeng"); ########## Register the needed libraries. my $ENVIRON="COM_LAYER='$pGlobals->{com_layer}' CSREGISTRY='$pGlobals->{admin_conf_dir}'"; my $regsvr = "$ENVIRON $pGlobals->{asphome}/chregsvr"; my $regedit = "$ENVIRON $pGlobals->{asphome}/chregedit"; my $register_child_pid = fork; if (not $register_child_pid) { my @register_log; push @register_log, "Entering default registry settings (admin-console): Success."; system_log("$regedit $pGlobals->{settings_reg} >> $pGlobals->{installer_output}"); if (-r "$pGlobals->{lib_dir}/hashobj") { # we need to register the hashobj as well here. my $setup = "$pGlobals->{asphome}/chsetup.sh"; if (not system_log(" . $setup ; $pGlobals->{lib_dir}/hashobj -regserver >> $pGlobals->{installer_output} 2>&1")) { push @register_log, "Registering hashobj: Success."; } else { push @register_log, "Registering hashobj: Failed."; } } my @register_libs; @register_libs = ( ( map { "$pGlobals->{com_lib_dir}/lib$_.$pGlobals->{lib_ext}" } ( "atl", "vbscript", "jscript" ) ), ( map { "$pGlobals->{lib_dir}/lib$_.$pGlobals->{lib_ext}" } ( "chiliado", "chiliscrrun", "calc", "chilicap", "chiliasp" ) ), ( map { "$pGlobals->{admin_bin_dir}/lib$_.$pGlobals->{lib_ext}" } ( "chilifile", "csadmin" ) ) ); push @register_log, "Registering intrinsic objects (admin-console):"; foreach my $libpath (@register_libs) { my $libname = basename($libpath); if (not system_log("$regsvr $libpath")) { push @register_log, " $libname: Success."; } else { push @register_log, " $libname: Failed."; } $pGlobals->{register_log} .= "\n"; } # Log the registration summary information to the register log. register_log(@register_log); exit(0); } ########## Confirm file modes. my @binaries = ("$pGlobals->{admin_bin_dir}/admd", "$pGlobals->{admin_bin_dir}/admdog", "$pGlobals->{admin_bin_dir}/apachectl", "$pGlobals->{admin_bin_dir}/caspctrl", "$pGlobals->{admin_bin_dir}/caspctrlb", "$pGlobals->{admin_bin_dir}/admeng", "$pGlobals->{admin_conf_dir}/htpasswd", "$pGlobals->{asphome}/admtool"); chmod(0755,@binaries); ########## Install a user to the administration console. if (interactive && $custom_install) { print "\n"; $pParameters->{admin_username} = INSTALL::query::user_function ("Type the username for the administrator, or \npress Enter to accept the default.",*verify_username, "default=admin","invalid_choice=Invalid username / password"); } else { verify_username($pParameters->{admin_username},$pParameters->{admin_password}); } $subst{admin::username} = $pParameters->{admin_username}; ########## Proceed with configuration. if (not INSTALL::component::register($CONST_ComponentName,$pGlobals->{asphome})) { note("Failed to register administration console."); } if (boolean_value($pParameters->{admin_startonboot}) && INSTALL::reboot::supported) { my $script_name = "asp-admin-$subst{admin::admd_port}"; INSTALL::reboot::install_script($script_name, "$pGlobals->{asphome}/admtool -s", "$pGlobals->{asphome}/admtool -e", "$pGlobals->{asphome}/admtool -q", $CONST_StartPriority,$CONST_StopPriority); } ########## Start the console. # We must make certain not to start the console, until everything has been registered # (ie. by waiting for the child to exit). if (interactive) { print STDERR "Finalizing Administration Console configuration ... "; INSTALL::common::spinner_wait($register_child_pid); } else { waitpid $register_child_pid,0; } if (not fork) { system_log("$pGlobals->{asphome}/admtool -s"); exit(0); } my @summary_log = ("Administration console installed:", " URL: http://$subst{admin::servername}:$subst{admin::admd_port}", " Port: $subst{admin::admd_port}", " Admin Engine / Daemon ports: $subst{admin::admin_port}", " Administration (Root) Username: $subst{admin::username}" ); # Place the details of the installation in both the summary and component logs. summary_log(@summary_log); component_log(@summary_log); if (interactive) { INSTALL::query::user_menu ("Sun Chili!Soft ASP - Administration Console Information", "Setup has finished installing the Administration Console. To configure ". "Sun Chili!Soft ASP, you can connect to the Administration Console from a URL ". "or from the command line, as shown below. For more information about configuring ". "Sun Chili!Soft ASP, see 'Chapter 3' in the product documentation. \n". "It is a good idea to print this page for future reference."); print "To connect from a browser, use this URL: http://$subst{admin::servername}:$subst{admin::admd_port}\n"; print "To start, stop and add users, use this script: $pGlobals->{asphome}/admtool\n"; print "The console's username is: $subst{admin::username}\n"; print "The console's password is: $pParameters->{admin_password}\n" if (not $custom_install); print "\n"; print "To continue, press Enter."; ; } my %component_details; foreach(keys %subst) { my $key = $_; s/admin:://; $component_details{$_} = $subst{$key}; } $component_details{uninstaller} = ("$pGlobals->{perl} -I$pGlobals->{asphome} -I$pGlobals->{admin_component_dir} ". "$pGlobals->{admin_component_dir}/install.pl $pGlobals->{execute_params} \"uninstall=true\""); ########## Make the service.pwd file readable / writable only by nobody user and ########## associated group. chown($uid,$gid,"$pGlobals->{admin_conf_dir}/service.pwd"); chmod(0600,"$pGlobals->{admin_conf_dir}/service.pwd"); return(INSTALL::component::merge($CONST_ComponentName, $pGlobals->{asphome}, %component_details)); CONFIGURE_CANCEL: my $summary_log = "Administration console installation: Canceled."; summary_log($summary_log); component_log($summary_log); return(undef); CONFIGURE_ERROR: my $summary_log = "Administration console installation: Failed."; summary_log($summary_log); component_log($summary_log); return(undef); EXIT_ERROR: INSTALL::services::deallocate_ports($subst{"admin::admd_port"},1); INSTALL::services::deallocate_ports($subst{"admin::admin_port"},2); exit(1); } #------------------------------------------------------------------------------ # The admin::configure method is responsible for querying / identifying the # wants of the user and incorporating those wants into the generated console. #============================================================================== #------------------------------------------------------------------------------ sub uninstall { my $pComponent = INSTALL::component::open($CONST_ComponentName, $pGlobals->{asphome}); if (not $pComponent) { return(error("Unable to open $CONST_ComponentName component.")); } ########## Stop service system_log("$pGlobals->{asphome}/admtool -e"); ########## Remove reboot scripts, if they exist ... if (INSTALL::reboot::supported) { my $script_name = "asp-admin-$pComponent->{admd_port}"; INSTALL::reboot::uninstall_script($script_name, $CONST_StartPriority, $CONST_StopPriority); } ########## Deallocate used ports. INSTALL::services::deallocate_ports($pComponent->{admd_port},1); INSTALL::services::deallocate_ports($pComponent->{admin_port},2); ########## Remove binaries. if (-d $pGlobals->{admin_dir}) { recursive_rmdir($pGlobals->{admin_dir}); } my $admtool = "$pGlobals->{asphome}/admtool"; if (-f $admtool) { unlink($admtool); } ########## Put the Global.asa of the samples back to pre-admin-console state. INSTALL::substitute::file("$pGlobals->{asphome}/caspsamp/default.asp", "$pGlobals->{asphome}/caspsamp/default.asp", { "\"$pComponent->{admd_port}\"" => '"<>"' }); INSTALL::substitute::file("$pGlobals->{asphome}/caspsamp/Global.asa", "$pGlobals->{asphome}/caspsamp/Global.asa", { "\"$pComponent->{admd_port}\"" => '"<>"' }); ########## Unregister component. INSTALL::component::unregister($CONST_ComponentName,$pGlobals->{asphome}); my @summary_log = ("Administration console uninstalled:", " Port: $pComponent->{admd_port}"); summary_log(@summary_log); component_log(@summary_log); return(1); } 1;