#!/usr/bin/perl
#
# $Revision: 1.18 $
# Script which creates various "custom inventory" scripts for
# RTI Altiris agent.
#
# Note that this script has been written in a way that it is usasble under Daisy as well, thus
# making changes in one POS easier to 'port to' the other.
#
# This file should be located under:
# /opt/altiris/notification/nsagent/var/packages/{*
# This file is automagically downloaded by the Altiris client as a package. The package also 
# manages how often the script is run.
#
use strict;
use warnings;
use File::Basename;
use File::stat;
use Getopt::Long;
use POSIX;


my $ALTIRIS_SERVER = "https://altiris.teleflora.com";
my $ALTIRIS_DIR = "/opt/altiris";
my $CUSTOMINV_DIR= "$ALTIRIS_DIR/notification/nsagent/var/packages/{B89D89CA-DF94-4FC6-8DE4-D2EB4BB50984}";
my $VERSION = 0;
my $CHECKIN = 0;
my $INSTALL = 0;
my $UNINSTALL = 0;
my $RTI = 0;
my $DAISY = 0;
my $UPDATES = 0;
my $RESTART = 0;
my $SHOWLOG = 0;
my $GUID = 0;
my $HELP = 0;
my $returnval = 0;
my $OS = "";



GetOptions(
	"help" => \$HELP,
	"version" => \$VERSION,
	"checkin" => \$CHECKIN,
	"rti" => \$RTI,
	"daisy" => \$DAISY,
	"restart" => \$RESTART,
	"showlog!" => \$SHOWLOG,
	"log!" => \$SHOWLOG,
	"guid!" => \$GUID,
	"updates" => \$UPDATES,
	"install" => \$INSTALL,
	"uninstall" => \$UNINSTALL,
);



#--help
if($HELP != 0) {
	usage();
	exit(0);
}


#--version
if($VERSION != 0) {
	print("OSTools Version: 1.12.3\n");
	print "$0 " . '$Revision: 1.18 $' . "\n";
	if(-f "$ALTIRIS_DIR/notification/nsagent/etc/host.GUID") {
		print("Altiris \"computer GUID\": " . get_guid() . "\n");
	}
	exit(0);
}



#--install
if($INSTALL != 0) {
	$returnval = install_altiris();
	exit($returnval);
}

#--uninstall
if($UNINSTALL != 0) {
	$returnval = uninstall_altiris();
	exit($returnval);
}

#--guid 
if($GUID != 0) {
	$returnval = get_guid();
	if("$returnval" eq "") {
		print("No \"Computer GUID\" Found.\n");
	} else {
		print("Altirs \"Computer GUID\": $returnval\n");
	}
	exit(0);
}



#--checkin 
if($CHECKIN != 0) {
	$returnval = checkin();
	exit($returnval);
}


# --updates
if($UPDATES != 0) {
	$returnval = get_updates();
	exit($returnval);
}


# --restart
if ($RESTART != 0) {
	exec "/sbin/service altiris restart";
	exit($?);
}


# --showlog
if ($SHOWLOG != 0) {
	exec "less $ALTIRIS_DIR/notification/nsagent/var/aex-client.log";
	exit($?);
}




usage();

exit(0);
############################################################################################
############################################################################################
############################################################################################

sub usage
{
	print ("\n");
	print ("Usage:\n");
	print ("$0 " . '$Revision: 1.18 $' . "\n");
	print ("$0 --help\n");
	print ("$0 --version\n");
	print ("$0 --guid\n");
	print ("\n");
	print ("$0 --checkin\tSee if Altiris is alive, sign into server.\n");
	print ("$0 --updates\tInteractively fetch updates.\n");
	print ("\n");
	print ("$0 --install\tInstall Altiris Software.\n");
	print ("$0 --uninstall\tRemove (uninstall) Altiris Software.\n");
	print ("\n");
	print ("$0 --restart\tRestart the Altiris Daemon.\n");
	print ("$0 --showlog\tShow Altiris client logfile.\n");
	print ("\n");
	print ("\n");
}


sub determine_os
{
	$OS = "";

	# We could also use /usr/bin/lsb-release
	open(FILE, "< /etc/redhat-release");
	while(<FILE>) {

		# Fedora Core 3
		if(/(Fedora)(\s+)(Core)(\s+)(release)(\s+)(3)/) {
			$OS = "FC3";
			last;
		}

		# Fedora Core 4
		if(/(Fedora)(\s+)(Core)(\s+)(release)(\s+)(4)/) {
			$OS = "FC4";
			last;
		}

		# Fedora Core 5
		if(/(Fedora)(\s+)(Core)(\s+)(release)(\s+)(5)/) {
			$OS = "FC5";
			last;
		}

		# Redhat Enterprise Linux Client Workstation 5
		if( /(Client release)(\s+)(5)/ ) {
			$OS = "RHWS5";
			last;
		}

		# ES 6
		# Redhat Enterprise Linux Server 6
		if( /(release)(\s+)(6)/ ) {
			$OS = "RHEL6";
			last;
		}

		# ES 5
		# Redhat Enterprise Linux Server 5
		if( (/(release)(\s+)(5)/)
		||  (/(CentOS)([[:print:]]+)(\s)(5)/) ) {
			$OS = "RHEL5";
			last;
		}

		# EL 4
		# Redhat Enterprise Linux Server 4
		if( (/(release)(\s+)(4)/) 
		||  (/(CentOS)([[:print:]]+)(\s)(4)/) ) {
			$OS = "RHEL4";
			last;
		}

		# Redhat 7.2
		if(/(release)(\s+)(7\.2)/) {
			$OS = "RH72";
			last;
		}
	}
	close(FILE);

	return($OS);
}


#
# Send custom inventory, receive packages.
#
sub checkin
{
	my $returnval = 0;


	system "$ALTIRIS_DIR/notification/nsagent/bin/aex-helper agent --send-basic-inventory";
	$returnval += $?;
	system "$ALTIRIS_DIR/notification/nsagent/bin/aex-helper agent --refresh-policies";
	$returnval += $?;

	return($returnval);
}


#
# Invoke user interface for running packages.
#
sub get_updates
{
	system "$ALTIRIS_DIR/notification/nsagent/bin/aex-swdapm";
	return($?);
}



#
# Remove ALtiris Software from the system.
# Altiris is installed as an RPM.
#
sub uninstall_altiris
{
	my $pkg = "";
	my $returnval = 0;






	open(PIPE, "rpm -qa | grep aex-nsclt |");
	while(<PIPE>) {
		chomp;
		$pkg = $_;
		last;
	} 
	close(PIPE);


	if($pkg ne "") {
		print("Removing Altiris RPM Package \"$pkg\"\n");
		system("rpm -e $pkg");
		$returnval += $?;
	} else {
		print("Error: Could not find an Altiris RPM package 'aex-nsclt'\n");
		return(2);
	}

	return($returnval);
}



#
# Install the Altiris Client software.
#
sub install_altiris
{
	my $string= "";
	my $datestamp = strftime("%Y%m%d%H%M%S", localtime());
	my $returnval = 0;
	my $should_install = 1;



	# If the shop is already running altiris, but, we are not using "unique" GUIDs
	# then, re-install altiris.
	# Otherwise, don't re-install, as, that would results in us constantly 
	# assigning a new GUID in the altiris portal with each upgrade.
	if(-f "/opt/altiris/notification/nsagent/etc/host.GUID") {
		open(GUID, "< /opt/altiris/notification/nsagent/etc/host.GUID");
		while(<GUID>) {
			chomp;
			if (substr($_, (1+14), 1) eq "D") {
				$should_install = 0;
				last;
			}
		}
		close(GUID);

		# We have a guid, but not with the magic 'D' byte.
		# We should *re-install*.
		# Here, we'll uninstall s.t. our next check later down, doesn't fail.
		#
		# Note that, the "magic 'D' byte" is here to help differentiate, within the altiris portal
		# hosts which all have the same hostname. If we use the default altiris guid generator,
		# Two hosts with the same IP and the same hostname, will get the same  host.guid, which, in the
		# altiris portal, would make the two (or more) hosts step on one another.
		# This "magic 'd' byte", coupled with generating our own GUID, should ensure that we are unique.
		#
		if($should_install != 0) {
			print("Altiris is installed without a Unique GUID.\n");
			print("Will re-install altiris with a new, unique GUID.\n");
			uninstall_altiris();
		}

	}
	if($should_install == 0) {
		print("A valid Altiris GUID file was already found. Please uninstall first.\n");
		return(0);
	}



	# Have we already installed altiris?
	open(PIPE, "rpm -qa |");
	while(<PIPE>) {
		chomp;
		if(/aex-nsclt/) {
			$should_install = 0;
			last;
		}
	} 
	close(PIPE);
	if($should_install == 0) {
		print("Altiris RPM package \"aex-nsclt\" already installed.\n");
		print("Please uninstall first.\n");
		return(0);
	}



	#
	# First choice is curl.  BUT, the curl on RH72 does not accept
	# the "--insecure" option.
	#
	my $urlgetcmd = "/usr/bin/curl";
	my $urlcmdopts = "--insecure";

	$OS = determine_os();

	if ($OS eq "RH72") {
		$urlcmdopts = "";
	}

	my $url = "$ALTIRIS_SERVER/Altiris/NS/NSCap/Bin/Unix/Agent/Linux/x86/aex-bootstrap.gz";

	#
	# If first choice for a get url command is not available, try another.
	#
	unless (-x $urlgetcmd) {
		$urlgetcmd = '/usr/bin/wget';
		$urlcmdopts = '-q -O -';
	}

	#
	# Can't continue if there is no tool to get the url.
	#
	unless (-x $urlgetcmd) {
		print "Error: Could not find tool to download Altiris Install program.\n";
		return (3);
	}

	# Install the agent.
	system "$urlgetcmd $urlcmdopts $url | gzip -dc > /tmp/aex-bootstrap";
	if(-z "/tmp/aex-bootstrap") {
		print "Error: Could not download Altiris Install program.\n";
		return (3);
	}

	system "chown root /tmp/aex-bootstrap";
	system "chmod 544 /tmp/aex-bootstrap";
	system "rm -f .aex-agent-install-config.xml /tmp/.aex-agent-install-config.xml"; # Stale config files



	# It is somewhat possible that a tech may have "rm -rf'ed" the altiris
	# directory. Yet, the altiris install script only looks to see if an RPM has
	# been installed.
	# Thus, we really need to uninstall the RPM, prior to running the install process 
	# again.
	uninstall_altiris();


	# Actually run the 'aex-bootstrap' program here.
	system "/tmp/aex-bootstrap $ALTIRIS_SERVER";
	if($? != 0) {
		print "Error: Though aex-bootstrap could be downloaded, an error\n";
		print "\toccurred while installing the Altiris client.\n";
		system "killall aex-bootstrap";
		return (4);
	}

	# Create a unique GUID for this customer.
	# Altiris, by default, uses a UUID based on the hostname
	# Hostnames, at least under Daisy, are almost always the same, thus,
	# we have had issues in daisy with individual servers now "showing up" on the windos portal.
	if(-f "/usr/bin/uuidgen") {
		my $uuid = qx(/usr/bin/uuidgen);
		chomp($uuid);
		if ($uuid eq "") {
			print "Error: uuidgen returned null uuid.\n";
		} else {
			# Mark it as a Teleflora customized UUID
			substr($uuid, 14, 1, "D");
			# Add the syntactic sugar that apparently Altiris wants
			$uuid = "{" . uc($uuid) . "}";
			# Write it to the Altiris guid file
			unless (open(GF, "> /opt/altiris/notification/nsagent/etc/host.GUID")) {
				print "Error: Can not open Altiris host.GUID file";
			} else {
				print GF "$uuid\n";
				close(GF);
			}
		}
	} else {
		print("/usr/bin/uuidgen program not found. Could not generate a new, unique GUID.\n");
	}




	# Send Basic Inventory.
	# Note that this may take some time on a "first load", as, we are fetching a new Guid from the server.
	sleep(10);
	if(-f "$ALTIRIS_DIR/notification/nsagent/bin/aex-helper") {
		system "$ALTIRIS_DIR/notification/nsagent/bin/aex-helper agent --send-basic-inventory";
		system "$ALTIRIS_DIR/notification/nsagent/bin/aex-helper agent --refresh-policies";
	}



	# Enable SSL in our config file.
	if(-f "$ALTIRIS_DIR/notification/nsagent/etc/client.conf") {
		system("cp $ALTIRIS_DIR/notification/nsagent/etc/client.conf $ALTIRIS_DIR/notification/nsagent/etc/client.conf.$$");
		if (-f "$ALTIRIS_DIR/notification/nsagent/etc/client.conf.$$") {
			print("Updating Altiris \"client.conf\" with ssl_verify_host\"...\n");
			open(OLD, "< $ALTIRIS_DIR/notification/nsagent/etc/client.conf.$$");
			open(NEW, "> $ALTIRIS_DIR/notification/nsagent/etc/client.conf");
			while(<OLD>) {
				if(/(ssl_verify_host)(\s*)(=)(\s*)/) {
					print(NEW "ssl_verify_host=1\n");
					next;
				}
				print(NEW  $_);
			}
			close(OLD);
			close(NEW);
		}
	}

	if(! -f "$ALTIRIS_DIR/notification/nsagent/etc/host.GUID") {
		print "Error: Could not find host.GUID file. We have no client GUID.\n";
	} else {
		print "Altiris \"computer GUID\": ";
		system "cat $ALTIRIS_DIR/notification/nsagent/etc/host.GUID";
	}
	return(0);
}

# Find and return the altiris guid.
sub get_guid
{
	my $guid = "";

	if(! -f "/opt/altiris/notification/nsagent/etc/host.GUID") {
		return("");
	}

	open(GUID, "< /opt/altiris/notification/nsagent/etc/host.GUID");
	while(<GUID>) {
		chomp;
		$guid = $_;
		last;
	}
	close(GUID);
	return($guid);
}
