diff options
Diffstat (limited to 'recipes-security/bastille/files/ServiceAdmin.pm')
-rw-r--r-- | recipes-security/bastille/files/ServiceAdmin.pm | 690 |
1 files changed, 0 insertions, 690 deletions
diff --git a/recipes-security/bastille/files/ServiceAdmin.pm b/recipes-security/bastille/files/ServiceAdmin.pm deleted file mode 100644 index 879223a..0000000 --- a/recipes-security/bastille/files/ServiceAdmin.pm +++ /dev/null @@ -1,690 +0,0 @@ -package Bastille::API::ServiceAdmin; -use strict; - -use Bastille::API; - -use Bastille::API::HPSpecific; -use Bastille::API::FileContent; - -require Exporter; -our @ISA = qw(Exporter); -our @EXPORT_OK = qw( -B_chkconfig_on -B_chkconfig_off -B_service_start -B_service_stop -B_service_restart -B_is_service_off -checkServiceOnLinux -remoteServiceCheck -remoteNISPlusServiceCheck -B_create_nsswitch_file -); -our @EXPORT = @EXPORT_OK; - - -####### -# &B_chkconfig_on and &B_chkconfig_off() are great for systems that didn't use -# a more modern init system. This is a bit of a problem on Fedora, though, -# which used upstart from Fedora 9 to Fedora 14, then switched to a new -# Red Hat-created system called systemd for Fedora 15 and 16 (so far). -# OpenSUSE also moved to systemd, starting with 12.1. Version 11.4 did not -# use systemd. -# It is also a problem on Ubuntu, starting at version 6.10, where they also -# used upstart. -##### - - - - -########################################################################### -# &B_chkconfig_on ($daemon_name) creates the symbolic links that are -# named in the "# chkconfig: ___ _ _ " portion of the init.d files. We -# need this utility, in place of the distro's chkconfig, because of both -# our need to add revert functionality and our need to harden distros that -# are not mounted on /. -# -# It uses the following global variables to find the links and the init -# scripts, respectively: -# -# &getGlobal('DIR', "rcd") -- directory where the rc_.d subdirs can be found -# &getGlobal('DIR', "initd") -- directory the rc_.d directories link to -# -# Here an example of where you might use this: -# -# You'd like to tell the system to run the firewall at boot: -# B_chkconfig_on("bastille-firewall") -# -########################################################################### - -# PW: Blech. Copied B_chkconfig_off() and changed a few things, -# then changed a few more things.... - -sub B_chkconfig_on { - - my $startup_script=$_[0]; - my $retval=1; - - my $chkconfig_line; - my ($runlevelinfo,@runlevels); - my ($start_order,$stop_order,$filetolink); - - &B_log("ACTION","# chkconfig_on enabling $startup_script\n"); - - # In Debian system there is no chkconfig script, run levels are checked - # one by one (jfs) - if (&GetDistro =~/^DB.*/) { - $filetolink = &getGlobal('DIR', "initd") . "/$startup_script"; - if (-x $filetolink) - { - foreach my $level ("0","1","2","3","4","5","6" ) { - my $link = ''; - $link = &getGlobal('DIR', "rcd") . "/rc" . "$level" . ".d/K50" . "$startup_script"; - $retval=symlink($filetolink,$link); - } - } - return $retval; - } - # - # On SUSE, chkconfig-based rc scripts have been replaced with a whole different - # system. chkconfig on SUSE is actually a shell script that does some stuff and then - # calls insserv, their replacement. - # - - if (&GetDistro =~ /^SE/) { - # only try to chkconfig on if init script is found - if ( -e (&getGlobal('DIR', "initd") . "/$startup_script") ) { - $chkconfig_line=&getGlobal('BIN','chkconfig'); - &B_System("$chkconfig_line $startup_script on", "$chkconfig_line $startup_script off"); - # chkconfig doesn't take affect until reboot, need to restart service also - B_service_restart("$startup_script"); - return 1; #success - } - return 0; #failure - } - - # - # Run through the init script looking for the chkconfig line... - # - $retval = open CHKCONFIG,&getGlobal('DIR', "initd") . "/$startup_script"; - unless ($retval) { - &B_log("ACTION","# Didn't chkconfig_on $startup_script because we couldn't open " . &getGlobal('DIR', "initd") . "/$startup_script\n"); - } - else { - - READ_LOOP: - while (my $line=<CHKCONFIG>) { - - # We're looking for lines like this one: - # # chkconfig: 2345 10 90 - # OR this - # # chkconfig: - 10 90 - - if ($line =~ /^#\s*chkconfig:\s*([-\d]+)\s*(\d+)\s*(\d+)/ ) { - $runlevelinfo = $1; - $start_order = $2; - $stop_order = $3; - # handle a run levels arg of '-' - if ( $runlevelinfo eq '-' ) { - &B_log("ACTION","chkconfig_on saw '-' for run levels for \"$startup_script\", is defaulting to levels 3,4,5\n"); - $runlevelinfo = '345'; - } - @runlevels = split(//,$runlevelinfo); - # make sure the orders have 2 digits - $start_order =~ s/^(\d)$/0$1/; - $stop_order =~ s/^(\d)$/0$1/; - last READ_LOOP; - } - } - close CHKCONFIG; - - # Do we have what we need? - if ( (scalar(@runlevels) < 1) || (! $start_order =~ /^\d{2}$/) || (! $stop_order =~ /^\d{2}$/) ) { - # problem - &B_log("ERROR","# B_chkconfig_on $startup_script failed -- no valid run level/start/stop info found\n"); - return(-1); - } - - # Now, run through creating symlinks... - &B_log("ACTION","# chkconfig_on will use run levels ".join(",",@runlevels)." for \"$startup_script\" with S order $start_order and K order $stop_order\n"); - - $retval=0; - # BUG: we really ought to readdir() on &getGlobal('DIR', "rcd") to get all levels - foreach my $level ( "0","1","2","3","4","5","6" ) { - my $link = ''; - # we make K links in run levels not specified in the chkconfig line - $link = &getGlobal('DIR', "rcd") . "/rc" . $level . ".d/K$stop_order" . $startup_script; - my $klink = $link; - # now we see if this is a specified run level; if so, make an S link - foreach my $markedlevel ( @runlevels ) { - if ( $level == $markedlevel) { - $link = &getGlobal('DIR', "rcd") . "/rc" . $level . ".d/S$start_order" . $startup_script; - } - } - my $target = &getGlobal('DIR', "initd") ."/" . $startup_script; - my $local_return; - - if ( (-e "$klink") && ($klink ne $link) ) { - # there's a K link, but this level needs an S link - unless ($GLOBAL_LOGONLY) { - $local_return = unlink("$klink"); - if ( ! $local_return ) { - # unlinking old, bad $klink failed - &B_log("ERROR","Unlinking $klink failed\n"); - } else { - &B_log("ACTION","Removed link $klink\n"); - # If we removed the link, add a link command to the revert file - &B_revert_log (&getGlobal('BIN','ln') . " -s $target $klink\n"); - } # close what to do if unlink works - } # if not GLOBAL_LOGONLY - } # if $klink exists and ne $link - - # OK, we've disposed of any old K links, make what we need - if ( (! ( -e "$link" )) && ($link ne '') ) { - # link doesn't exist and the start/stop number is OK; make it - unless ($GLOBAL_LOGONLY) { - # create the link - $local_return = &B_symlink($target,$link); - if ($local_return) { - $retval++; - &B_log("ACTION","Created link $link\n"); - } else { - &B_log("ERROR","Couldn't create $link when trying to chkconfig on $startup_script\n"); - } - } - - } # link doesn't exist - } # foreach level - - } - - if ($retval < @runlevels) { - $retval=0; - } - - $retval; - -} - - -########################################################################### -# &B_chkconfig_off ($daemon_name) deletes the symbolic links that are -# named in the "# chkconfig: ___ _ _ " portion of the init.d files. We -# need this utility, in place of the distro's chkconfig, because of both -# our need to add revert functionality and our need to harden distros that -# are not mounted on /. -# -# chkconfig allows for a REVERT of its work by writing to an executable -# file &getGlobal('BFILE', "removed-symlinks"). -# -# It uses the following global variables to find the links and the init -# scripts, respectively: -# -# &getGlobal('DIR', "rcd") -- directory where the rc_.d subdirs can be found -# &getGlobal('DIR', "initd") -- directory the rc_.d directories link to -# -# Here an example of where you might use this: -# -# You'd like to tell stop running sendmail in daemon mode on boot: -# B_chkconfig_off("sendmail") -# -########################################################################### - - - -sub B_chkconfig_off { - - my $startup_script=$_[0]; - my $retval=1; - - my $chkconfig_line; - my @runlevels; - my ($start_order,$stop_order,$filetolink); - - if (&GetDistro =~/^DB.*/) { - $filetolink = &getGlobal('DIR', "initd") . "/$startup_script"; - if (-x $filetolink) - { - # Three ways to do this in Debian: - # 1.- have the initd script set to 600 mode - # 2.- Remove the links in rcd (re-installing the package - # will break it) - # 3.- Use update-rc.d --remove (same as 2.) - # (jfs) - &B_chmod(0600,$filetolink); - $retval=6; - - # The second option - #foreach my $level ("0","1","2","3","4","5","6" ) { - #my $link = ''; - #$link = &getGlobal('DIR', "rcd") . "/rc" . "$level" . ".d/K50" . "$startup_script"; - #unlink($link); - #} - } - } - - # - # On SUSE, chkconfig-based rc scripts have been replaced with a whole different - # system. chkconfig on SUSE is actually a shell script that does some stuff and then - # calls insserv, their replacement. - # - elsif (&GetDistro =~ /^SE/) { - # only try to chkconfig off if init script is found - if ( -e (&getGlobal('DIR', "initd") . "/$startup_script") ) { - $chkconfig_line=&getGlobal('BIN','chkconfig'); - &B_System("$chkconfig_line $startup_script on", "$chkconfig_line $startup_script off"); - # chkconfig doesn't take affect until reboot, need to stop service - # since expectation is that the daemons are disabled even without a reboot - B_service_stop("$startup_script"); - return 1; #success - } - return 0; #failure - } - else { - - # Run through the init script looking for the chkconfig line... - - - $retval = open CHKCONFIG,&getGlobal('DIR', "initd") . "/$startup_script"; - unless ($retval) { - &B_log("ACTION","Didn't chkconfig_off $startup_script because we couldn't open " . &getGlobal('DIR', "initd") . "/$startup_script\n"); - } - else { - - READ_LOOP: - while (my $line=<CHKCONFIG>) { - - # We're looking for lines like this one: - # # chkconfig: 2345 10 90 - - if ($line =~ /^#\s*chkconfig:\s*([-\d]+)\s*(\d+)\s*(\d+)/ ) { - @runlevels=split //,$1; - $start_order=$2; - $stop_order=$3; - - - # Change single digit run levels to double digit -- otherwise, - # the alphabetic ordering chkconfig depends on fails. - if ($start_order =~ /^\d$/ ) { - $start_order = "0" . $start_order; - &B_log("ACTION","chkconfig_off converted start order to $start_order\n"); - } - if ($stop_order =~ /^\d$/ ) { - $stop_order = "0" . $stop_order; - &B_log("ACTION","chkconfig_off converted stop order to $stop_order\n"); - } - - last READ_LOOP; - } - } - close CHKCONFIG; - - # If we never found a chkconfig line, can we just run through all 5 - # rcX.d dirs from 1 to 5...? - - # unless ( $start_order and $stop_order ) { - # @runlevels=("1","2","3","4","5"); - # $start_order = "*"; $stop_order="*"; - # } - - # Now, run through removing symlinks... - - - - $retval=0; - - # Handle the special case that the run level specified is solely "-" - if ($runlevels[0] =~ /-/) { - @runlevels = ( "0","1","2","3","4","5","6" ); - } - - foreach my $level ( @runlevels ) { - my $link = &getGlobal('DIR', "rcd") . "/rc" . $level . ".d/S$start_order" . $startup_script; - my $new_link = &getGlobal('DIR', "rcd") . "/rc" . $level . ".d/K$stop_order" . $startup_script; - my $target = &getGlobal('DIR', "initd") ."/" . $startup_script; - my $local_return; - - - # Replace the S__ link in this level with a K__ link. - if ( -e $link ) { - unless ($GLOBAL_LOGONLY) { - $local_return=unlink $link; - if ($local_return) { - $local_return=symlink $target,$new_link; - unless ($local_return) { - &B_log("ERROR","Linking $target to $new_link failed.\n"); - } - } - else { # unlinking failed - &B_log("ERROR","Unlinking $link failed\n"); - } - - } - if ($local_return) { - $retval++; - &B_log("ACTION","Removed link $link\n"); - - # - # If we removed the link, add a link command to the revert file - # Write out the revert information for recreating the S__ - # symlink and deleting the K__ symlink. - &B_revert_log(&getGlobal('BIN',"ln") . " -s $target $link\n"); - &B_revert_log(&getGlobal('BIN',"rm") . " -f $new_link\n"); - } - else { - &B_log("ERROR","B_chkconfig_off $startup_script failed\n"); - } - - } - } # foreach - - } # else-unless - - } # else-DB - if ($retval < @runlevels) { - $retval=0; - } - - $retval; - -} - - -########################################################################### -# &B_service_start ($daemon_name) -# Starts service on RedHat/SUSE-based Linux distributions which have the -# service command: -# -# service $daemon_name start -# -# Other Linux distros that also support this method of starting -# services can be added to use this function. -# -# Here an example of where you might use this: -# -# You'd like to tell the system to start the vsftpd daemon: -# &B_service_start("vsftpd") -# -# Uses &B_System in HP_API.pm -# To match how the &B_System command works this method: -# returns 1 on success -# returns 0 on failure -########################################################################### - -sub B_service_start { - - my $daemon=$_[0]; - - if ( (&GetDistro !~ /^SE/) and (&GetDistro !~ /^RH/) and - (&GetDistro !~ /^RHFC/) and (&GetDistro !~ /^MN/) ) { - &B_log("ERROR","Tried to call service_start on a system lacking a service command! Internal Bastille error."); - return undef; - } - - # only start service if init script is found - if ( -e (&getGlobal('DIR', 'initd') . "/$daemon") ) { - &B_log("ACTION","# service_start enabling $daemon\n"); - - my $service_cmd=&getGlobal('BIN', 'service'); - if ($service_cmd) { - # Start the service, - # Also provide &B_System revert command - - return (&B_System("$service_cmd $daemon start", - "$service_cmd $daemon stop")); - } - } - - # init script not found, do not try to start, return failure - return 0; -} - -########################################################################### -# &B_service_stop ($daemon_name) -# Stops service on RedHat/SUSE-based Linux distributions which have the -# service command: -# -# service $daemon_name stop -# -# Other Linux distros that also support this method of starting -# services can be added to use this function. -# Stops service. -# -# -# Here an example of where you might use this: -# -# You'd like to tell the system to stop the vsftpd daemon: -# &B_service_stop("vsftpd") -# -# Uses &B_System in HP_API.pm -# To match how the &B_System command works this method: -# returns 1 on success -# returns 0 on failure -########################################################################### - -sub B_service_stop { - - my $daemon=$_[0]; - - if ( (&GetDistro !~ /^SE/) and (&GetDistro !~ /^RH/) and - (&GetDistro !~ /^RHFC/) and (&GetDistro !~ /^MN/) ) { - &B_log("ERROR","Tried to call service_stop on a system lacking a service command! Internal Bastille error."); - return undef; - } - - # only stop service if init script is found - if ( -e (&getGlobal('DIR', 'initd') . "/$daemon") ) { - &B_log("ACTION","# service_stop disabling $daemon\n"); - - my $service_cmd=&getGlobal('BIN', 'service'); - if ($service_cmd) { - - # Stop the service, - # Also provide &B_System revert command - - return (&B_System("$service_cmd $daemon stop", - "$service_cmd $daemon start")); - } - } - - # init script not found, do not try to stop, return failure - return 0; -} - - -########################################################################### -# &B_service_restart ($daemon_name) -# Restarts service on RedHat/SUSE-based Linux distributions which have the -# service command: -# -# service $daemon_name restart -# -# Other Linux distros that also support this method of starting -# services can be added to use this function. -# -# Here an example of where you might use this: -# -# You'd like to tell the system to restart the vsftpd daemon: -# &B_service_restart("vsftpd") -# -# Uses &B_System in HP_API.pm -# To match how the &B_System command works this method: -# returns 1 on success -# returns 0 on failure -########################################################################### - -sub B_service_restart { - - my $daemon=$_[0]; - - if ( (&GetDistro !~ /^SE/) and (&GetDistro !~ /^RH/) and - (&GetDistro !~ /^RHFC/) and (&GetDistro !~ /^MN/) ) { - &B_log("ERROR","Tried to call service_restart on a system lacking a service command! Internal Bastille error."); - return undef; - } - - # only restart service if init script is found - if ( -e (&getGlobal('DIR', 'initd') . "/$daemon") ) { - &B_log("ACTION","# service_restart re-enabling $daemon\n"); - - my $service_cmd=&getGlobal('BIN', 'service'); - if ($service_cmd) { - - # Restart the service - return (&B_System("$service_cmd $daemon restart", - "$service_cmd $daemon restart")); - } - } - - # init script not found, do not try to restart, return failure - return 0; -} - -########################################################################### -# &B_is_service_off($;$) -# -# Runs the specified test to determine whether or not the question should -# be answered. -# -# return values: -# NOTSECURE_CAN_CHANGE()/0: service is on -# SECURE_CANT_CHANGE()/1: service is off -# undef: test is not defined -########################################################################### - -sub B_is_service_off ($){ - my $service=$_[0]; - - if(&GetDistro =~ "^HP-UX"){ - #die "Why do I think I'm on HPUX?!\n"; - return &checkServiceOnHPUX($service); - } - elsif ( (&GetDistro =~ "^RH") || (&GetDistro =~ "^SE") ) { - return &checkServiceOnLinux($service); - } - else { - &B_log("DEBUG","B_is_service off called for unsupported OS"); - # not yet implemented for other distributions of Linux - # when GLOBAL_SERVICE, GLOBAL_SERVTYPE and GLOBAL_PROCESS are filled - # in for Linux, then - # at least inetd and inittab services should be similar to the above, - # whereas chkconfig would be used on some Linux distros to determine - # if non-inetd/inittab services are running at boot time. Looking at - # processes should be similar. - return undef; - } -} - -########################################################################### -# &checkServiceOnLinux($service); -# -# Checks if the given service is running on a Linux system. This is -# called by B_is_Service_Off(), which is the function that Bastille -# modules should call. -# -# Return values: -# NOTSECURE_CAN_CHANGE() if the service is on -# SECURE_CANT_CHANGE() if the service is off -# undef if the state of the service cannot be determined -# -########################################################################### -sub checkServiceOnLinux($) { - my $service=$_[0]; - - # get the list of parameters which could be used to initiate the service - # (could be in /etc/rc.d/rc?.d, /etc/inetd.conf, or /etc/inittab, so we - # check all of them) - - my @params = @{ &getGlobal('SERVICE', $service) }; - my $chkconfig = &getGlobal('BIN', 'chkconfig'); - my $grep = &getGlobal('BIN', 'grep'); - my $inittab = &getGlobal('FILE', 'inittab'); - my $serviceType = &getGlobal('SERVTYPE', $service);; - - # A kludge to get things running because &getGlobal('SERVICE' doesn't - # return the expected values. - @params = (); - push (@params, $service); - - foreach my $param (@params) { - &B_log("DEBUG","Checking to see if service $service is off.\n"); - - if ($serviceType =~ /rc/) { - my $on = &B_Backtick("$chkconfig --list $param 2>&1"); - if ($on =~ /^$param:\s+unknown/) { - # This service isn't installed on the system - return NOT_INSTALLED(); - } - if ($on =~ /^error reading information on service $param: No such file or directory/) { - # This service isn't installed on the system - return NOT_INSTALLED(); - } - if ($on =~ /^error/) { - # This probably - &B_log("DEBUG","chkconfig returned: $param=$on\n"); - return undef; - } - $on =~ s/^$param\s+//; # remove the service name and spaces - $on =~ s/[0-6]:off\s*//g; # remove any runlevel:off entries - $on =~ s/:on\s*//g; # remove the :on from the runlevels - # what remains is a list of runlevels in which the service is on, - # or a null string if it is never turned on - chomp $on; # newline should be gone already (\s) - &B_log("DEBUG","chkconfig returned: $param=$on\n"); - - if ($on =~ /^\d+$/) { - # service is not off - ########################### BREAK out, don't skip question - return NOTSECURE_CAN_CHANGE(); - } - } - elsif ($serviceType =~ /inet/) { - my $on = &B_Backtick("$chkconfig --list $param 2>&1"); - if ($on =~ /^$param:\s+unknown/) { - # This service isn't installed on the system - return NOT_INSTALLED(); - } - if ($on =~ /^error reading information on service $param: No such file or directory/) { - # This service isn't installed on the system - return NOT_INSTALLED(); - } - if ($on =~ /^error/ ) { - # Something else is wrong? - # return undef - return undef; - } - if ($on =~ tr/\n// > 1) { - $on =~ s/^xinetd.+\n//; - } - $on =~ s/^\s*$param:?\s+//; # remove the service name and spaces - chomp $on; # newline should be gone already (\s) - &B_log("DEBUG","chkconfig returned: $param=$on\n"); - - if ($on =~ /^on$/) { - # service is not off - ########################### BREAK out, don't skip question - return NOTSECURE_CAN_CHANGE(); - } - } - else { - # perhaps the service is started by inittab - my $inittabline = &B_Backtick("$grep -E '^[^#].{0,3}:.*:.+:.*$param' $inittab"); - if ($inittabline =~ /.+/) { # . matches anything except newlines - # service is not off - &B_log("DEBUG","Checking inittab; found $inittabline\n"); - ########################### BREAK out, don't skip question - return NOTSECURE_CAN_CHANGE(); - } - } - } # foreach my $param - - - # boot-time parameters are not set; check processes - # Note the checkProcsforService returns INCONSISTENT() if a process is found - # assuming the checks above - return &checkProcsForService($service); -} - -1; - - |