#!/usr/bin/suidperl -U
#
#  Program:       custom
#
#  Copyright:     COPYRIGHT Compaq Computer Corporation 2001.  All rights reserved.
#
#  Description:   This program performs actual changes to the operating system.
#                 It serves as the ONLY point where critical changes to the
#                 system are allowed.  It is hoped that this limits the number
#                 of suidperl programs and provides a more concise locale for
#                 security analysis.
#
#                 In the future, this central point should also provide a 
#                 method for logging and additional security checks.
#
#  History:
#
use strict;
use lib qw (
	/var/cpqcfg/cgi-bin/CompaqConfigurator/system
);

use config;
use general;
use custom::custom;

# First we retrieve the passed parameters
my $command = shift(@ARGV) || "";
my $parameters = \@ARGV || "";
my @parameters = @{$parameters};

#$ENV{PATH} = "";
#$ENV{BASH_ENV} = "";

my %system = config::system();

$| = 1;

# Determine which command to use
#print STDERR "Custom received command = \"$command\"\n";

# Shutdown the server
if ($command eq "shutdown") {
  custom::shutdown(@parameters);
}
# Update the root password
elsif ($command eq "update_root") {
  custom::updateRoot(@parameters);
}
# Update the date and time on the system
elsif ($command eq "update_datetime") {
  custom::updateDateTime(@parameters);
}
# Update general network options
elsif ($command eq "update_network") {
  custom::updateNetwork(@parameters);
}
# Update routing
elsif ($command eq "update_routing") {
  custom::updateRouting(@parameters);
}
elsif ($command eq "update_nameresolution") {
  custom::updateNameResolution(@parameters);
}
# Update a network interface
elsif ($command eq "update_interface") {
  custom::updateInterface(@parameters);
}
elsif ($command eq "add_nfsmount") {
  custom::addNFSMount(@parameters);
}
elsif ($command eq "del_nfsmount") {
  custom::delNFSMount(@parameters);
}
elsif ($command eq "update_nfs_mounts") {
  custom::updateNFSMounts();
}
# Add a user to the system
elsif ($command eq "add_user") {
  print custom::addUser(@parameters);
}
# Update a particular user
elsif ($command eq "update_user") {
  custom::updateUser(@parameters);
}
# Delete a user from the system
elsif ($command eq "del_user") {
  custom::delUser(@parameters);
}
# Delete a user from the perspective of a virtual site admin
elsif ($command eq "del_user_virtualsite") {

    my %userInfo = datastore::userInfo($parameters[0]);
    my %groupInfo = datastore::groupInfo($parameters[1]);
    my $group = $groupInfo{'shortname'};

    print STDERR "Group number = $parameters[1]\n";

    my $command = "/bin/cat $system{'datastore'}/groups.xml | /bin/grep \\\<UserID\\\>$userInfo{'uid'}\\\<\\\/UserID\\\> | /usr/bin/wc -l";
    my $result = `$command`;
    $command = "/bin/cat $system{'datastore'}/virtualsites.xml | /bin/grep \\\<ServerAdmin\\\>$userInfo{'uid'}\\\<\\\/ServerAdmin\\\>";
    my $serveradmin = `$command`;
    $result =~ s/\W//g;

    print STDERR "User $userInfo{'uid'} used in \"$result\" places.  scalar = ". scalar($result) . "\n";

    # First check to make sure that they are not involved elsewhere
    if (scalar($result) <= 2 && $serveradmin eq "") {

	print STDERR "Calling cust user delete\n";
      custom::delUser(@parameters);
	
    }
    else {

	print STDERR "Deleting user from virtual site group $group only\n";

	# Update the group.xml file

	eval {
	    
	    # Set error handling
	    local $SIG{ALRM} = sub { 
		close(LOCK_FILE);
		print "<H3><FONT color='red'>ERROR:  Add group timed out.</FONT></H3>";
		warn("Add group timed out");
		die("alarm\n");
	    };
	    
	    # Set timeout
	    alarm($system{'locktimeout'});

	    # Set an exclusive lock
	    open(LOCK_FILE, ">$system{'datastore'}/groups.lck");

	    my $parser = new XML::DOM::Parser;
	    my $doc = $parser->parsefile("$system{'datastore'}/groups.xml");

	    # Search for this group
	    my $foundNode = "";
	    foreach my $groupNode ($doc->getElementsByTagName("Group")) {

		my $thisName = eval { $groupNode->getElementsByTagName("ShortName")->item(0)->getFirstChild->getData(); } || "";

		if ($thisName eq $group) {
		    $foundNode = $groupNode;
		    last;
		}
	    }

	    if ($foundNode ne "") {

		print STDERR "Found the write group....deleting child\n";

		foreach my $memberNode ($foundNode->getElementsByTagName("UserID")) {

		    my $userid = eval { $memberNode->getFirstChild->getData(); } || "";

		    if ($userid eq $userInfo{'uid'}) {

			my $parentNode = $memberNode->getParentNode;
		    
			eval { $parentNode->removeChild($memberNode); };

		    }
		}

		$doc->printToFile("$system{'datastore'}/groups.xml");

	    }

	    close(LOCK_FILE);

	};
    }

}
# Add the sym link for a particular user to a particular site
elsif ($command eq "vs_sym_link") {
    my $command = "/bin/ln -s /home/VirtualSites/$parameters[1] /home/$parameters[0]/$parameters[1]";
    my $result = `$command`;
}
# Add a group to the system
elsif ($command eq "add_group") {

  my $groupID = custom::addGroup(@parameters);

  if ($groupID ne "") {
      print "$groupID";
      print STDERR "Add group with ID $groupID\n";
  }

}
elsif ($command eq "update_group") {
  custom::updateGroup(@parameters);
}
# Delete a group from the system
elsif ($command eq "del_group") {
  custom::delGroup(@parameters);
}
# Update email aliases on the system
elsif ($command eq "update_emailaliases") {
  custom::updateEmailAliases(@parameters);
}
# Delete an email alias
elsif ($command eq "del_emailalias") {
  custom::delEmailAlias(@parameters);
}
# Add a virtual host to the system
elsif ($command eq "add_virtualsite") {
  custom::addVirtualSite(@parameters);
}
# Delete a virtual host from the system
elsif ($command eq "del_virtualsite") {
  custom::delVirtualSite(@parameters);
}
# Update the virtual hosts
elsif ($command eq "update_virtualsite") {
  custom::updateVirtualSite(@parameters);
  custom::updateSendmail();
  custom::stopApache();
  custom::restartApache();
}
# Update httpd.conf and restart server
elsif ($command eq "update_apache") {
  custom::updateApache(@parameters);
  custom::stopApache();
  custom::restartApache();
  custom::stopApache();
  custom::restartApache();
}
# A command to cycle Apache
elsif ($command eq "restart_apache") {
  custom::stopApache();
  custom::restartApache();
}
# Apply a performance profile to the system
elsif ($command eq "apply_profile") {
  custom::applyApacheProfile(@parameters);
  custom::stopApache();
  custom::restartApache();
}
# Update sendmail and restart the server
elsif ($command eq "update_sendmail") {
  custom::updateSendmail(@parameters);
}
# System backup
elsif ($command eq "backup") {
  custom::systemBackup(@parameters);
}
# Log rotation configuration
elsif ($command eq "update_logconfig") {
  custom::updateLogConfig(@parameters);
}
# SNMP configuration
elsif ($command eq "update_snmpconfig") {
  custom::updateSNMPConfig(@parameters);
}
# Update network services
elsif ($command eq "update_services") {
  custom::updateServices(@parameters);
}
# Grab the current SSL Key value
elsif ($command eq "get_apache_sslkey") {
    print custom::getApacheSSLKey(@parameters);
}
# Grab the current SSL CSR
elsif ($command eq "get_apache_sslcsr") {
  print custom::getApacheSSLCSR(@parameters);
}
# Grab the current SSL CRT
elsif ($command eq "get_apache_sslcrt") {
  print custom::getApacheSSLCRT(@parameters);
}
# Regenerate the apache SSL key automatically
elsif ($command eq "apache_key_regen") {
  custom::apacheSSLKeyRegen(@parameters);
  custom::updateApache();
  custom::stopApache();
  custom::restartApache();
}
# Grab the date/time of the current Apache SSL key files
elsif ($command eq "apache_key_dates") {
  print custom::getApacheSSLdates(@parameters);
}
# Update the existing keys with a given value
elsif ($command eq "apache_key_update") {
  custom::updateApacheSSLKeys(@parameters);
  custom::updateApache();
  custom::stopApache();
  custom::restartApache();
}
# Update SSH Settings
elsif ($command eq "update_ssh") {
  custom::updateSSH(@parameters);
}
# Get SSH Public Key
elsif ($command eq "get_ssh_public") {
    print custom::getPublicSSHSSLKey();
}
# Get SSH Private Key
elsif ($command eq "get_ssh_private") {
    print custom::getPrivateSSHSSLKey();
}
# Enable Floppy for boot
elsif ($command eq "enable_cd_floppy") {
    `/usr/compaq/bin/floppy -u`;
}
elsif ($command eq "disable_cd_floppy") {
    `/usr/compaq/bin/floppy -l`;
}
# Check disk quota
elsif ($command eq "check_quota") {

    my $uid = shift(@parameters) || exit(0);
    my $isgrp = shift(@parameters) || "0";

    my $dev = Quota::getqcarg("/home");

    my ($bc, $bs, $bh, $bt, $ic, $is, $ih, $it) = ();

    if ($isgrp == 0) {
	($bc, $bs, $bh, $bt, $ic, $is, $ih, $it) = Quota::query($dev, $uid);
    }
    else {
	($bc, $bs, $bh, $bt, $ic, $is, $ih, $it) = Quota::query($dev, $uid, 1);
    }

    print "$bc $bs $bh $bt $ic $is $ih $it";
}
elsif ($command eq "eject_cd") {
    `/usr/bin/eject`;
}
elsif ($command eq "upgrade_system") {
  custom::upgradeSystem(@parameters);
}
elsif ($command eq "set_config_status") {
  custom::setConfigStatus();
}
elsif ($command eq "netport_alert") {
  custom::updateNetPortAlert();
}
elsif ($command eq "fix_shadow_permissions") {
  print STDERR `$system{'root'}/system/bin/chgrp cpqcfg /etc/passwd* /etc/shadow*`;
  print STDERR `$system{'root'}/system/bin/chmod g+r /etc/passwd* /etc/shadow*`;
}

exit(0);
