#! /usr/bin/perl 
#
# $Revision: 1.18 $
# Copyright 2010 Teleflora
#
# Do something that causes a change in configuration.
#

use strict;
use warnings;
use POSIX;
use Getopt::Long;
use English;
use File::Basename;

my $CVS_REVISION = '$Revision: 1.18 $';
my $TIMESTAMP = strftime("%Y%m%d%H%M%S", localtime());
my $PROGNAME = basename($0);

#=====================================#
# +---------------------------------+ #
# | Global variables                | #
# +---------------------------------+ #
#=====================================#
my $VERSION = 0;
my $HELP = 0;
my $CONFPATH = "";
my $BLM_PRIORITY = 0;
my $RTIBACKUP_CRON = 0;
my $SAMBA_BROWSING = 0;
my $SAMBA_SECURITY = 0;
my $SET_ROOT_PASSWORD = "";
my $ADD_DAISY_ALIAS = 0;
my $ADD_DAISY_PATH = 0;
my $DISABLE_LOGWATCH = 0;
my $REMOVE_LOGWATCH = 0;
my $KASEYA_INI = 0;
my $NSSWITCH_SUDO = 0;
my $UPDATE_HOSTS_ALLOW = 0;

#=====================================#
# +---------------------------------+ #
# | Exit status values              | #
# +---------------------------------+ #
#=====================================#
my $EXIT_OK = 0;
my $EXIT_COMMAND_LINE = 1;
my $EXIT_MUST_BE_ROOT = 2;
my $EXIT_BLM_PRIORITY = 3;
my $EXIT_RTIBACKUP_CRON = 4;
my $EXIT_SAMBA_CONF = 5;
my $EXIT_ROOT_PASSWD = 6;
my $EXIT_DAISY_ALIAS = 7;
my $EXIT_DAISY_PATH = 8;
my $EXIT_DISABLE_LOGWATCH = 9;
my $EXIT_KASEYA_INI = 10;
my $EXIT_NSSWITCH_SUDO = 11;
my $EXIT_REMOVE_LOGWATCH = 12;
my $EXIT_UPDATE_HOSTS_ALLOW = 13;

#
# What platform is the script running on.
#
my $OS;
#
# Alternate os and root for testing.
#
my $ALTROOT = "";
my $ALTOS = "";

my $LOGFILE = 'OS-Patches.log';

my $COMMAND_LINE = "";


#
# The command line must be recorded before the GetOptions modules
# is called or any options will be removed.
#
$COMMAND_LINE = get_command_line();

GetOptions (
	"version" => \$VERSION,
	"help" => \$HELP,
	"confpath=s" => \$CONFPATH,
	"altroot=s" => \$ALTROOT,
	"blm-priority" => \$BLM_PRIORITY,
	"rtibackup-cron" => \$RTIBACKUP_CRON,
	"samba-browsing" => \$SAMBA_BROWSING,
	"samba-security" => \$SAMBA_SECURITY,
	"set-root-password=s" => \$SET_ROOT_PASSWORD,
	"add-daisy-alias" => \$ADD_DAISY_ALIAS,
	"add-daisy-path" => \$ADD_DAISY_PATH,
	"disable-logwatch" => \$DISABLE_LOGWATCH,
	"remove-logwatch" => \$REMOVE_LOGWATCH,
	"kaseya-ini" => \$KASEYA_INI,
	"nsswitch-sudo" => \$NSSWITCH_SUDO,
	"update-hosts-allow" => \$UPDATE_HOSTS_ALLOW,
) || die "command line options error... exiting";


# --version
if ($VERSION != 0) {
	print "$CVS_REVISION\n";
	exit($EXIT_OK);
}


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


my $RTIDIR = "$ALTROOT/usr2/bbx";
my $DAISYDIR = "$ALTROOT/d/daisy";


#=====================================#
# +---------------------------------+ #
# | Main                            | #
# +---------------------------------+ #
#=====================================#
sub main
{
    # If there is a command line argument, it's an error.
    if (@ARGV) {
	    usage();
	    return($EXIT_COMMAND_LINE);
    }

    log_set_filename();

    loginfo("===========================================");
    loginfo("Log Entry for $PROGNAME $CVS_REVISION");
    loginfo("===========================================");
    loginfo("Invoked with command line:");
    loginfo("$COMMAND_LINE");

    my $exit_status = $EXIT_OK;

    if ($BLM_PRIORITY) {
	if (edit_blm_init_script() != 0) {
	    $exit_status = $EXIT_BLM_PRIORITY;
	}
    }

    if ($RTIBACKUP_CRON) {
	if (edit_rtibackup_cron_file() != 0) {
	    $exit_status = $EXIT_RTIBACKUP_CRON;
	}
    }

    if ($SAMBA_BROWSING) {
	if (edit_samba_conf() != 0) {
	    $exit_status = $EXIT_SAMBA_CONF;
	}
    }

    if ($SAMBA_SECURITY) {
	if (edit_samba_conf_security() != 0) {
	    $exit_status = $EXIT_SAMBA_CONF;
	}
    }

    if ($SET_ROOT_PASSWORD) {
	if (set_root_password($SET_ROOT_PASSWORD) != 0) {
	    $exit_status = $EXIT_ROOT_PASSWD;
	}
    }

    if ($ADD_DAISY_ALIAS) {
	if (add_daisy_alias() != 0) {
	    $exit_status = $EXIT_DAISY_ALIAS;
	}
    }

    if ($ADD_DAISY_PATH) {
	if (add_daisy_path() != 0) {
	    $exit_status = $EXIT_DAISY_PATH;
	}
    }

    if ($DISABLE_LOGWATCH) {
	if (disable_logwatch() != 0) {
	    $exit_status = $EXIT_DISABLE_LOGWATCH;
	}
    }

    if ($REMOVE_LOGWATCH) {
	if (remove_logwatch() != 0) {
	    $exit_status = $EXIT_REMOVE_LOGWATCH;
	}
    }

    if ($KASEYA_INI) {
	if (edit_kaseya_ini() != 0) {
	    $exit_status = $EXIT_KASEYA_INI;
	}
    }

    if ($NSSWITCH_SUDO) {
	if (edit_nsswitch_sudo() != 0) {
	    $exit_status = $EXIT_NSSWITCH_SUDO;
	}
    }

    if ($UPDATE_HOSTS_ALLOW) {
	if (update_hosts_allow() != 0) {
	    $exit_status = $EXIT_UPDATE_HOSTS_ALLOW;
	}
    }

    log_set_perms();

    return($exit_status);
}

#=====================================#
# +---------------------------------+ #
# | Utility Functions               | #
# +---------------------------------+ #
#=====================================#
sub usage
{
	print "Telelfora Config File Editor\n\n";
	print "Usage:\n";
	print "$PROGNAME $CVS_REVISION\n";
	print "$PROGNAME --help                 # output this help message and exit\n";
	print "$PROGNAME --version              # output version number and exit\n";
	print "$PROGNAME --confpath=/some/path  # edit a conf file located at specified path\n";
	print "$PROGNAME --add-daisy-alias	# add alias (l=ls -l) to /etc/profile.d/daisy.sh\n";
	print "$PROGNAME --add-daisy-path	# add /d/daisy/bin to PATH in /etc/profile.d/daisy.sh\n";
	print "$PROGNAME --blm-priority         # edit priority in blm init.d file\n";
	print "$PROGNAME --disable-logwatch     # disable the logwatch cron job\n";
	print "$PROGNAME --remove-logwatch      # remove the logwatch rpm package\n";
	print "$PROGNAME --kaseya-ini           # edit Kaseya ini file\n";
	print "$PROGNAME --nsswitch-sudo        # edit /etc/nsswitch.conf file\n";
	print "$PROGNAME --rtibackup-cron       # edit rtibackup.pl cron job file\n";
	print "$PROGNAME --samba-browsing       # edit browsing parameters in smb.conf\n";
	print "$PROGNAME --samba-security       # edit security parameters in smb.conf\n";
	print "$PROGNAME --set-root-password	# set the root password\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);

	#
	# Allow a last minute switcheroo.
	#
	if ($ALTOS) {
	    $OS = $ALTOS;
	}

	return($OS);
}


sub get_hostname
{
    my $hostname = qx(hostname --short);
    chomp($hostname);

    return($hostname);
}


sub get_command_line
{
	my $cmd_line = "";

	$cmd_line = $0;
	foreach my $i (@ARGV) {
		$cmd_line .= " ";
		if ($i =~/\s/) {
			$cmd_line .= "\"$i\"";
		} else {
			$cmd_line .= "$i";
		}
	}

	return($cmd_line);
}


#
# search file for regular expression
#
# Returns
#   0 found regular expression
#   1 did not find regular expression
#
sub fgrep
{
    my ($fpath, $re) = @_;

    my $rc = 1;
    if (open(my $fp, '<', $fpath)) {
	while (<$fp>) {
	    chomp;
	    if (/$re/) {
		$rc = 0;
		last;
	    }
        }
	close($fp);
    }

    return($rc);
}


# Print to screen, and log to logfile.
sub showinfo
{
	my $message = $_[0];

	print("$message\n");
	return(loginfo("<I>  $message"));
}


# Print to screen, and log to logfile.
sub showerror
{
	my $message = $_[0];

	print("Error: $message\n");
	return(loginfo("<E>  $message"));
}


sub log_set_filename
{
    my $logfiledir = "";

    if (-d "$RTIDIR/log") {
	$logfiledir= "$RTIDIR/log";
    }
    elsif (-d "$DAISYDIR/log") {
	$logfiledir = "$DAISYDIR/log";
    }
    else {
	$logfiledir = "$ALTROOT/tmp";
    }

    if ($LOGFILE eq "") {
	$LOGFILE = 'OS-Patches.log';
    }

    $LOGFILE = "$logfiledir/$LOGFILE";
}


# insurance that the log file can be accessed by non-root users
sub log_set_perms
{
    if ($ALTROOT eq "") {
	system "chown tfsupport $LOGFILE";
    }
    system "chmod 664 $LOGFILE";
}


sub logerror
{
    my $message = $_[0];

    return(loginfo("<E> $message"));
}

sub logdebug
{
    my $message = $_[0];

    return(loginfo("<D> $message"));
}


#
# Write message to logfile.
#
sub loginfo
{
    my $message = $_[0];

    # form line to write
    my $timestamp = strftime("%Y-%m-%d %H:%M:%S", localtime(time()));
    my $msg_type = "";
    if ( ($message !~ /<E>/) &&  ($message !~ /<D>/) &&  ($message !~ /<I>/) ) {
	    $msg_type = "<I>";
    }
    my $line_out = "$timestamp $msg_type $message\n";

    # write logfile
    open(LOG, ">> $LOGFILE");
    print(LOG " $line_out");
    close(LOG);

    return(0);
}

#=====================================#
# +---------------------------------+ #
# | Application Specific Functions  | #
# +---------------------------------+ #
#=====================================#

#
# function: edit_blm_init_script
#
# Change the chkconfig line of the systerm service file /etc/init.d/blm.
# The chkconfig file is expected to look like this:
#
# 	# chkconfig: 2345 80 20
#
# to this:
#
# 	# chkconfig: 2345 79 20
#

sub edit_blm_init_script
{
        my $conf_file = '/etc/init.d/blm';
        my $timestamp = strftime("%Y-%m-%d:%H%M%S", localtime());
        my $new_conf_file = "$conf_file-$timestamp";
	my $gpattern = "# chkconfig: ";
	my $pattern = '# chkconfig: (\d+) (\d{2}) (\d{2})';
	my $exit_status = 0;

        # grep returns zero if search pattern found otherwise non-zero
        system("grep \"$gpattern\" $conf_file > /dev/null 2> /dev/null");
        if ( (WIFEXITED($?) != 0) && (WEXITSTATUS($?) != 0) ) {
                return(2);
        }

        unless (-s "$conf_file") {
                logerror("$conf_file does not exist...  Will skip edits.");
                return(2);
        }

        unless (open(OLD, "< $conf_file")) {
                logerror("Could not open $conf_file for read... Will skip edits.");
                return(2);
        }

        unless (open(NEW, "> $new_conf_file")) {
                logerror("Could not open $new_conf_file for write... Will skip edits.");
                close(OLD);
                return(2);
        }
        while (<OLD>) {
                chomp;

		next if ( /^#$PROGNAME#/ );

                if ( /^$pattern/ ) {
			print(NEW "#$PROGNAME# --- $CVS_REVISION $timestamp ---\n");
			print(NEW "#$PROGNAME# --- following line changed ---\n");
                        print(NEW "# chkconfig: $1 79 $3\n");
			next;
                }

                # By default, just copy what we read.
                print(NEW "$_\n");

        }

	close(OLD);
	close(NEW);

	# If we created a new conf file that is zero sized, that is bad.
	if (-z $new_conf_file) {
		logerror("Copy of $conf_file is a zero size file. Will skip edits.");
		system("rm $new_conf_file");
		return(2);
	}

	# Assume conf file was successfully transformed... so replace the old one with the new.
	system("chmod --reference=$conf_file $new_conf_file");
	system("chown --reference=$conf_file $new_conf_file");
	system("mv $new_conf_file $conf_file");
	if ($? != 0) {
		logerror("Replacement of old $conf_file with new $new_conf_file failed.");
		return(2);
	}

	my $service_name = basename($conf_file);
	system("/sbin/chkconfig $service_name on");
	$exit_status = $?;
	if ($exit_status == 0) {
	    loginfo("$service_name successfully changed");
	} else {
	    logerror("The chkconfig of $service_name returned exit status: $exit_status");
	    $exit_status = 2;
	}

	return($exit_status);
}


sub edit_rtibackup_cron_file
{
    my $old_daisy_cronjob = "$ALTROOT/etc/cron.d/daisy-backup";
    my $new_cronjob = "$ALTROOT/etc/cron.d/nightly-backup";
    my $conf_file = "";
    my $new_conf_file = "";
    my $conf_file_changed = 0;
    my $DAISY_BINDIR = "$DAISYDIR/bin";

    my $OS = determine_os();
    if ($OS eq 'RH72') {
	logerror("Unsupported platform: $OS");
	return($EXIT_RTIBACKUP_CRON);
    }

    unless (-d $DAISYDIR) {
	logerror("Daisy database directory missing: $DAISYDIR");
	return($EXIT_RTIBACKUP_CRON);
    }

    # if both new and old cron job file exist, remove old one and
    # select the new one.
    if (-e $new_cronjob) {
	if (-e $old_daisy_cronjob) {
	    loginfo("Removing old Daisy cronjob: $old_daisy_cronjob");
	    system "rm -f $old_daisy_cronjob";
	    if (-e $old_daisy_cronjob) {
		logerror("Can't remove old Daisy cronjob");
		return($EXIT_RTIBACKUP_CRON);
	    }
	}

	$conf_file = $new_cronjob;
    }

    # if only old cron job file exists, select that one.
    elsif (-e $old_daisy_cronjob) {
	$conf_file = $old_daisy_cronjob;
    }

    # if there are no cron job files, that's an error.
    elsif (-e "$DAISY_BINDIR/rtibackup.pl") {
	logerror("rtibackup.pl installed but cron job file missing: $new_cronjob");
	return($EXIT_RTIBACKUP_CRON);
    }

    # if there is no backup script file, that's an error.
    else {
	logerror("rtibackup.pl not installed: $DAISY_BINDIR/rtibackup.pl");
	return($EXIT_RTIBACKUP_CRON);
    }

    $new_conf_file = "$conf_file.$$";

    open(OLDFILE, "< $conf_file");
    open(NEWFILE, "> $new_conf_file");
    while (<OLDFILE>) {
	if ( /rtibackup.pl --daisy --saveall/ ) {
	    if (! /^(\s*)#/ ) {
		print(NEWFILE "# Following line commented out by $PROGNAME $TIMESTAMP\n");
		print(NEWFILE "# $_");
		$conf_file_changed = 1;
	    }
	}
	else {
	    print(NEWFILE $_);
	}
    }
    close(OLDFILE);
    close(NEWFILE);

    if (-z $new_conf_file) {
	logerror("New cron job file empty");
	loginfo("Previous cron job file $conf_file unchanged");
	system("rm $new_conf_file");
	return($EXIT_RTIBACKUP_CRON);
    }

    system("mv $new_conf_file $conf_file");
    if ($? != 0) {
	logerror("The mv of $new_conf_file to $conf_file returned exit status: $?");
	loginfo("Previous cron job file $conf_file unchanged");
	system("rm $new_conf_file");
	return($EXIT_RTIBACKUP_CRON);
    }

    my $conf_file_status = ($conf_file_changed) ? "changed" : "unchanged";
    loginfo("Config file $conf_file_status: $conf_file");

    return(0);
}


#
# If the line is a comment or blank line, return TRUE else FALSE.
#
sub is_samba_conf_comment
{
    my $line = $_[0];

    if ( /^(\s*)([;#])/ ) {
	return(1);
    }
    elsif ( /^(\s*)$/ ) {
	return(1);
    }
    else {
	return(0);
    }
}


#
# conf file = /etc/samba/smb.conf
# if conf file does not exist, do nothing
# if conf file contains "local master = xyz" or it's not present
#   replace with "local master = no"
# if conf file contains "preferred master = xyz" or it's not present
#   replace with "preferred master = no"
# if conf file contains "os level = xyz" or it's not present
#   replace with "os level = no"
#

sub edit_samba_conf
{
    my $conf_file = "$ALTROOT/etc/samba/smb.conf";
    my $new_conf_file = "$conf_file.$$";
    my $in_global_section = 0;
    my $section_name = "";
    my $old_section_name = "";
    my @commentq = ();
    my $q_size = 0;

    unless (-e $conf_file) {
	loginfo("Samba config file $conf_file: no such file");
	return($EXIT_SAMBA_CONF);
    }

    unless (open(OLDFILE, "< $conf_file")) {
	logerror("Could not open current Samba config file $conf_file for read.");
	return($EXIT_SAMBA_CONF);
    }
    unless (open(NEWFILE, "> $new_conf_file")) {
	logerror("Could not open new Samba config file $new_conf_file for write.");
	close(OLDFILE);
	return($EXIT_SAMBA_CONF);
    }

    while (<OLDFILE>) {

	my $current_line = $_;

	# if a section name statement, isloate the section name and 
	# update the value of "in global section" flag appropriately and
	# write lines that belong at end of global section.

	if ($current_line =~ /^(\s*)(\[)(.+)(\])/) {

	    # first, deal with a change of section
	    $old_section_name = $section_name;
	    $section_name = $3;
	    $in_global_section = ($section_name eq 'global') ? 1 : 0;

	    # write any queued comment lines first
	    $q_size = @commentq;
	    for (my $i=0; $i < $q_size; $i++) {
		my $comment_line = pop(@commentq);
		print(NEWFILE $comment_line);
	    }

	    # now write out the new directives if leaving "global"
	    if ($old_section_name eq 'global') {

		print(NEWFILE "\n");
		print(NEWFILE "# Begin lines added by $PROGNAME $TIMESTAMP\n");
		print(NEWFILE "local master = no\n");
		print(NEWFILE "preferred master = no\n");
		print(NEWFILE "os level = 0\n");
		print(NEWFILE "# End lines added by $PROGNAME $TIMESTAMP\n");
		print(NEWFILE "\n");
	    }
	}

	if ($in_global_section) {
	    my $comment_out_line = 0;

	    # look for lines to be commented out
	    if ($current_line =~ /^(\s*)(local master)(.+)=/) {
		$comment_out_line = 1;
	    } elsif ($current_line =~ /^(\s*)(preferred master)(.+)=/) {
		$comment_out_line = 1;
	    } elsif ($current_line =~ /^(\s*)(os level)(.+)=/) {
		$comment_out_line = 1;
	    }

	    if ($comment_out_line) {
		# first write any saved comment lines
		$q_size = @commentq;
		for (my $i=0; $i < $q_size; $i++) {
		    my $comment_line = pop(@commentq);
		    print(NEWFILE $comment_line);
		}
		print(NEWFILE "# Following line commented out by $PROGNAME $TIMESTAMP\n");
		print(NEWFILE "# $current_line");

		next;
	    }
	}

	# if a comment line, put it on the queue else output it
	if (is_samba_conf_comment($current_line)) {
	    unshift(@commentq, $current_line);
	}
	else {
	    # first output any saved comment lines
	    $q_size = @commentq;
	    for (my $i=0; $i < $q_size; $i++) {
		my $comment_line = pop(@commentq);
		print(NEWFILE $comment_line);
	    }
	    print(NEWFILE $current_line);
	}
    }
    close(OLDFILE);

    # output any saved comment lines
    $q_size = @commentq;
    for (my $i=0; $i < $q_size; $i++) {
	my $comment_line = pop(@commentq);
	print(NEWFILE $comment_line);
    }

    # At this point, we have read the entire file, and if the "in global
    # section" flag is set, it means that we need to handle the case where
    # the only section is a global section
    if ($in_global_section) {
	print(NEWFILE "\n");
	print(NEWFILE "# Begin lines added by $PROGNAME $TIMESTAMP\n");
	print(NEWFILE "local master = no\n");
	print(NEWFILE "preferred master = no\n");
	print(NEWFILE "os level = 0\n");
	print(NEWFILE "# End lines added by $PROGNAME $TIMESTAMP\n");
	print(NEWFILE "\n");
    }

    close(NEWFILE);

    unless (-z "$new_conf_file") {
	system("mv $new_conf_file $conf_file");
	if ($? != 0) {
	    logerror("The mv of $new_conf_file to $conf_file returned exit status: $?");
	    loginfo("Previous Samba config file $conf_file unchanged");
	    system("rm $new_conf_file");
	    return($EXIT_SAMBA_CONF);
	}
    }

    return(0);
}

#
# conf file = /etc/samba/smb.conf
# if conf file does not exist, do nothing
# if global section of conf file contains "security = user", no change
# if global section of conf file contains "security = xyz" and
# "xyz" is not equal to "user", replace with "security = user"
# if global section of conf file contains "server signing = auto", no change
# if global section of conf file contains "server signing = xyz",
# replace with "server signing = auto"
# if global section of conf file does not contain "server signing = auto",
# add it
#

sub edit_samba_conf_security
{
    my $conf_file = "$ALTROOT/etc/samba/smb.conf";
    my $new_conf_file = "$conf_file.$$";
    my $in_global_section = 0;
    my $section_name = "";
    my $old_section_name = "";
    my @commentq = ();
    my $q_size = 0;

    unless (-e $conf_file) {
	loginfo("Samba config file $conf_file: no such file");
	return($EXIT_SAMBA_CONF);
    }

    unless (open(OLDFILE, "< $conf_file")) {
	logerror("Could not open current Samba config file $conf_file for read.");
	return($EXIT_SAMBA_CONF);
    }
    unless (open(NEWFILE, "> $new_conf_file")) {
	logerror("Could not open new Samba config file $new_conf_file for write.");
	close(OLDFILE);
	return($EXIT_SAMBA_CONF);
    }

    while (<OLDFILE>) {

	my $current_line = $_;

	# if a section name statement, isloate the section name and 
	# update the value of "in global section" flag appropriately and
	# write lines that belong at end of global section.

	if ($current_line =~ /^\s*\[(.+)\]/) {

	    # first, deal with a change of section
	    $old_section_name = $section_name;
	    $section_name = $1;
	    $in_global_section = ($section_name eq 'global') ? 1 : 0;

	    # write any queued comment lines first
	    $q_size = @commentq;
	    for (my $i=0; $i < $q_size; $i++) {
		my $comment_line = pop(@commentq);
		print(NEWFILE $comment_line);
	    }

	    # now write out the new directives if leaving "global"
	    if ($old_section_name eq 'global') {

		print(NEWFILE "\n");
		print(NEWFILE "# Begin lines added by $PROGNAME $TIMESTAMP\n");
		print(NEWFILE "security = user\n");
                print(NEWFILE "server signing = auto\n");
		print(NEWFILE "# End lines added by $PROGNAME $TIMESTAMP\n");
		print(NEWFILE "\n");
	    }
	}

	if ($in_global_section) {
	    my $comment_out_line = 0;

	    # look for lines to be commented out
	    if ($current_line =~ /^(\s*)(security)(.+)=/) {
		$comment_out_line = 1;
	    }
	    elsif ($current_line =~ /^(\s*)(server signing)(.+)=/) {
		$comment_out_line = 1;
	    }

	    if ($comment_out_line) {
		# first write any saved comment lines
		$q_size = @commentq;
		for (my $i=0; $i < $q_size; $i++) {
		    my $comment_line = pop(@commentq);
		    print(NEWFILE $comment_line);
		}
		print(NEWFILE "# Following line commented out by $PROGNAME $TIMESTAMP\n");
		print(NEWFILE "# $current_line");

		next;
	    }
	}

	# if a comment line, put it on the queue else output it
	if (is_samba_conf_comment($current_line)) {
	    unshift(@commentq, $current_line);
	}
	else {
	    # first output any saved comment lines
	    $q_size = @commentq;
	    for (my $i=0; $i < $q_size; $i++) {
		my $comment_line = pop(@commentq);
		print(NEWFILE $comment_line);
	    }
	    print(NEWFILE $current_line);
	}
    }
    close(OLDFILE);

    # output any saved comment lines
    $q_size = @commentq;
    for (my $i=0; $i < $q_size; $i++) {
	my $comment_line = pop(@commentq);
	print(NEWFILE $comment_line);
    }

    # At this point, we have read the entire file, and if the "in global
    # section" flag is set, it means that we need to handle the case where
    # the only section is a global section
    if ($in_global_section) {
	print(NEWFILE "\n");
	print(NEWFILE "# Begin lines added by $PROGNAME $TIMESTAMP\n");
	print(NEWFILE "security = user\n");
	print(NEWFILE "server signing = auto\n");
	print(NEWFILE "# End lines added by $PROGNAME $TIMESTAMP\n");
	print(NEWFILE "\n");
    }

    close(NEWFILE);

    unless (-z "$new_conf_file") {
	system("mv $new_conf_file $conf_file");
	if ($? != 0) {
	    logerror("The mv of $new_conf_file to $conf_file returned exit status: $?");
	    loginfo("Previous Samba config file $conf_file unchanged");
	    system("rm $new_conf_file");
	    return($EXIT_SAMBA_CONF);
	}
    }

    return(0);
}

#
# Input:
#	new root password
#
# Returns:
#	0 if root password was expired and changed successfully
#	1 if root password was expired and change failed
#	2 if root password was not expired
#	3 for some other error
#
sub set_root_password
{
    my $new_root_password = $_[0];

    if ($new_root_password eq "") {
	logerror("The new root password is empty");
	return(3);
    }

    my $cmd = "chage -l root";
    unless (open(PIPE, "$cmd |")) {
	logerror("Could not open pipe: $cmd");
	return(3);
    }

    my $OS = determine_os();
    if ($OS eq "") {
	logerror("Unknown OS: $OS");
	return(3);
    }

    my $root_password_expired = 0;
    my $unsupported_os = 0;
    while(<PIPE>) {
	chomp;
	if ($OS eq "FC5" || $OS eq "RHEL5" || $OS eq "RHWS5") {
	    if (/(Last password change)(.*)(password must be changed)/) {
		$root_password_expired = 1;
	    }
	}
	elsif ($OS eq "FC3") {
	    if (/(Last Change:)(.*)(Never)/) {
		$root_password_expired = 1;
	    }
	}
	else {
	    $unsupported_os = 1;
	}
    }
    close(PIPE);

    if ($unsupported_os) {
	logerror("Unsupported OS: $OS");
	return(3);
    }

    my $rc = 0;
    if ($root_password_expired) {
	loginfo("root password is expired");
	system("echo $new_root_password | passwd --stdin root > /dev/null 2>&1");
	if ($? == 0) {
	    loginfo("successful change of root password");
	}
	else {
	    logerror("change of root password failed");
	    $rc = 1;
	}
    }
    else {
	loginfo("root password is not expired");
	$rc = 2;
    }

    return($rc);
}


#
# Input:
#	none
#
# Returns:
#   0 success
#   1 if conf file does not exist
#   2 alias already exists
#   3 addition failed
#
sub add_daisy_alias
{
    my $conf_file = '/etc/profile.d/daisy.sh';

    unless (-e $conf_file) {
	logerror("Daisy global definitions file does not exist: $conf_file");
	return(1);
    }

    system("grep '^alias l=' $conf_file > /dev/null 2> /dev/null");
    if ($? == 0) {
	loginfo("Alias already exists in: $conf_file");
	return(2);
    }

    system("echo \"alias l='ls -l'\" >> $conf_file ");
    unless ($? == 0) {
	logerror("Can't add alias to: $conf_file");
	return(3);
    }

    return(0);
}

#
# Input:
#	none
#
# Returns:
#   0 success
#   1 if conf file does not exist
#   2 PATH already set
#   3 addition failed
#
sub add_daisy_path
{
    my $conf_file = '/etc/profile.d/daisy.sh';

    unless (-e $conf_file) {
	logerror("Daisy global definitions file does not exist: $conf_file");
	return(1);
    }

    system("grep '^PATH=\/d\/daisy\/bin/:\$PATH' $conf_file > /dev/null 2> /dev/null");
    if ($? == 0) {
	loginfo("PATH already set in: $conf_file");
	return(2);
    }

    system("echo \'PATH=/d/daisy/bin/:\$PATH\' >> $conf_file ");
    unless ($? == 0) {
	logerror("Can't set PATH in: $conf_file");
	return(3);
    }
    return(0);
}


#
# Disable the logwatch cron job by removing the logwatch
# cron job file so the script linked to never runs.
#
# Returns:
#   0 success
#   1 can't disable logwatch cron job
#
sub disable_logwatch
{
    my $cron_dir = "$ALTROOT/etc/cron.daily";

    my $OS = determine_os();
    my $cron_file = ($OS eq "RHEL4") ? "00-logwatch" : "0logwatch";

    my $cron_file_path = "$cron_dir/$cron_file";

    unless (-e "$cron_file_path") {
	loginfo("Logwatch cron job already disabled, cron file does not exist: $cron_file_path");
	return(0);
    }

    system("rm $cron_file_path");
    if ($? == 0) {
	loginfo("Logwatch cron job disabled, cron file removed: $cron_file_path");
    }
    else {
	logerror("Logwatch cron job NOT disabled, error removing cron file: $cron_file_path");
	return(1);
    }

    return(0);
}

#
# Remove the logwatch RPM package.
#
# At the point in time this comment written, only three
# OS platforms are supported: "RHEL4", "RHEL5", "RHEL6".
#
# Returns:
#   0 success
#   1 can't remove logwatch package
#   2 unsupported OS
#
sub remove_logwatch
{
    my $logwatch_pkg_name = "";

    my $OS = determine_os();

    if (($OS eq "RHEL4") || ($OS eq "RHEL5") || ($OS eq "RHEL6")) {
	$logwatch_pkg_name = "logwatch";
    }
    else {
	logerror("unsupported OS: $OS");
	logerror("package NOT removed: $logwatch_pkg_name");
	return(2);
    }

    system("rpm -qa | grep  $logwatch_pkg_name > /dev/null 2> /dev/null");
    if ($? == 0) {
	system("rpm -e --test $logwatch_pkg_name");
	if ($? == 0) {
	    system("rpm -e $logwatch_pkg_name");
	    if ($? == 0) {
		loginfo("package removed: $logwatch_pkg_name");
	    }
	    else {
		logerror("cmd rpm -e $logwatch_pkg_name returns non-zero: $?");
		logerror("package NOT removed: $logwatch_pkg_name");
		return(1);
	    }
	}
	else {
	    logerror("cmd rpm -e --test $logwatch_pkg_name returns non-zero: $?");
	    logerror("package NOT removed: $logwatch_pkg_name");
	    return(1);
	}
    }

    else {
	loginfo("logwatch package not installed: $logwatch_pkg_name");
	return(0);
    }

    return(0);
}

#
# function: edit_kaseya_ini
#
# Input:
#	none
#
# Returns:
#   0 success
#   1 ini file does not exist
#   2 more than one ini file
#   3 can't get hostname
#   4 can't open old conf file for read
#   5 can't open new conf file for write
#   6 new conf file zero length 
#   7 replacement of old conf with new file failed
#

sub edit_kaseya_ini
{
    my $ini_file_path_re = "/opt/Kaseya/*/etc/KaseyaD.ini";

    my @ini_file_path = glob($ini_file_path_re);

    my $nr_of_ini_files = scalar(@ini_file_path);

    if ($nr_of_ini_files == 0) {
	logerror("Kaseya ini file does not exist: $ini_file_path_re");
	return(1);
    }

    # we only handle one ini file
    if ($nr_of_ini_files != 1) {
	logerror("More than one ini file not supported: $nr_of_ini_files");
	return(2);
    }

    my $hostname = get_hostname();
    if ($hostname eq "") {
	logerror("Can't get hostname");
	return(3);
    }

    my $conf_file = $ini_file_path[0];
    my $new_conf_file = "$conf_file.$$";

    unless (open(OLD, '<', $conf_file)) {
	logerror("Could not open $conf_file for read... Will skip edits.");
	return(4);
    }

    unless (open(NEW, '>', $new_conf_file)) {
	logerror("Could not open $new_conf_file for write... Will skip edits.");
	close(OLD);
	return(5);
    }

    while (<OLD>) {
	if (/^(User_Name\s+)/) {
	    print NEW $1 . $hostname . ".unknown.linux_services\n";
	}

	elsif (/^(Server_Name\s+)(localhost)/) {
	    print NEW $1 . "65.198.163.25\n";
	}

	elsif (/^(Backup_Server_Name\s+)(localhost)/) {
	    print NEW $1 . "65.198.163.25\n";
	}

	elsif (/^(User_Web_Name\s+)(localhost)/) {
	    print NEW $1 . "65.198.163.25\n";
	}

	elsif (/^(Web_Server_Name\s+)(localhost)/) {
	    print NEW $1 . "65.198.163.25\n";
	}

	else {
	    print NEW $_;
	}
    }

    close(OLD);
    close(NEW);

    # If we created a new conf file that is zero sized, that's a fatal error.
    if (-z $new_conf_file) {
	logerror("Copy of $conf_file is a zero size file. Will skip edits.");
	system("rm $new_conf_file");
	return(6);
    }

    # Assume conf file was successfully transformed...
    # so replace the old one with the new.
    system("echo chmod --reference=$conf_file $new_conf_file");
    system("echo chown --reference=$conf_file $new_conf_file");
    system("mv $new_conf_file $conf_file");
    if ($? != 0) {
	logerror("Replacement of old $conf_file with new $new_conf_file failed.");
	system("rm $new_conf_file");
	return(7);
    }

    return(0);
}


#
# function: edit_nsswitch_sudo
#
# if the nsswitch conf file contains '^sudoers: files ldap$', then
# 1. make a temp file
# 2. copy old conf to new conf removing the line with "sudoers"
# 3. set the owner, group, and perms
#
# If the nsswitch conf file does not contain an "sudoers" line, then
# 1. concatenate the line "sudoers:  file ldap" to the conf file
# 2. set the owner, group, and perms
#
# Input:
#	none
#
# Returns:
#   0 success
#   1 conf file does not exist
#   4 can't open old conf file for read
#   5 can't open new conf file for write
#   6 new conf file zero length 
#   7 replacement of old file with new file failed
#   8 addition of new line to conf file failed
#

sub edit_nsswitch_sudo
{
    my $conf_file = "$ALTROOT/etc/nsswitch.conf";
    my $new_conf_file = "$conf_file.$$";

    unless (-e $conf_file) {
	logerror("Conf file $conf_file does not exist... Will skip edits.");
	return(1);
    }

    #
    # if very specific "sudoers" line is present, remove from conf file
    #
    system("grep -q '^sudoers: files ldap\$' $conf_file");
    if ($? == 0) {
	unless (open(OLD, '<', $conf_file)) {
	    logerror("Could not open $conf_file for read... Will skip edits.");
	    return(4);
	}

	unless (open(NEW, '>', $new_conf_file)) {
	    logerror("Could not open $new_conf_file for write... Will skip edits.");
	    close(OLD);
	    return(5);
	}

	while (<OLD>) {
	    chomp;
	    if (/^sudoers: files ldap$/) {
		next;
	    }

	    print NEW "$_\n";
	}

	close(OLD);
	close(NEW);

	# If we created a new conf file that is zero sized, that's a fatal error.
	if (-z $new_conf_file) {
	    logerror("Copy of $conf_file is a zero size file. Will skip edits.");
	    system("rm $new_conf_file");
	    return(6);
	}

	# Assume conf file was successfully transformed...
	# so replace the old one with the new.
	system("mv $new_conf_file $conf_file");
	if ($? != 0) {
	    logerror("Replacement of old $conf_file with new $new_conf_file failed.");
	    system("rm $new_conf_file");
	    return(7);
	}

	system("chown root:root $conf_file");
	system("chmod 644 $conf_file");

	loginfo("The line 'sudoers: files ldap' successfully removed from: $conf_file");
    }

    #
    # If there isn't any "sudoers" line, add very specific one.
    #
    system("grep -q '^[[:space:]]*sudoers:' $conf_file");
    if ($? != 0) {
       system("echo 'sudoers:  files ldap' >> $conf_file");
	if ($? != 0) {
	    logerror("Could not add 'sudoers' line to $conf_file.");
	    system("rm $new_conf_file");
	    return(8);
	}

	system("chown root:root $conf_file");
	system("chmod 644 $conf_file");

	loginfo("The line 'sudoers:  files ldap' successfully added to: $conf_file");
    }
    else {
	loginfo("The $conf_file already contains sudoers line");
    }


    return(0);
}

#
# function: update_hosts_allow
#
# if the "/etc/hosts.allow" file contains either of the
# following lines:
#	sshd: 70.128.30.254
#	tfremote: 70.128.30.254
#
# then make a new "/etc/hosts.allow" file which changes
# the ip addr to "209.141.208.118".
#
# if the "/etc/hosts.allow" does not exist or does not
# contain either of these lines , then make no changes.
#
# Input:
#	none
#
# Returns:
#   0 success
#   1 conf file does not exist
#   4 can't open old conf file for read
#   5 can't open new conf file for write
#   6 new conf file zero length 
#   7 replacement of old file with new file failed
#   8 addition of new line to conf file failed
#

sub update_hosts_allow
{
    my $conf_file = "$ALTROOT/etc/hosts.allow";
    my $new_conf_file = "$conf_file.$$";

    # if the file does not exist, make no changes, report success.
    unless (-e $conf_file) {
	loginfo("config file $conf_file does not exist - no changes made");
	return(0);
    }

    my $old_sshd_line = "sshd: 70.128.30.254";
    my $old_tfremote_line = "tfremote: 70.128.30.254";

    # if neither lines appears, make no changes, report success.
    if (fgrep($conf_file, $old_sshd_line)) {
	if (fgrep($conf_file, $old_tfremote_line)) {
	    loginfo("config file $conf_file does not contain old ip address - no changes made");
	    return(0);
	}
    }

    # at this point, the file exists and there is a change to make.

    my $old_ip_addr = "70.128.30.254";
    my $new_ip_addr = "209.141.208.118";

    if (open(my $ocf, '<', $conf_file)) {
	if (open(my $ncf, '>', $new_conf_file)) {
	    while (my $line = <$ocf>) {
		chomp($line);
		if ($line =~ /^sshd:\s*($old_ip_addr)/) {
		    $line =~ s/$old_ip_addr/$new_ip_addr/;
		}
		if ($line =~ /^tfremote:\s*($old_ip_addr)/) {
		    $line =~ s/$old_ip_addr/$new_ip_addr/;
		}

		print $ncf "$line\n";
	    }

	    close($ocf);
	    close($ncf);

	    # If we created a new conf file that is zero sized, that's a fatal error.
	    if (-z $new_conf_file) {
		logerror("new config file is a zero size: $new_conf_file");
		unlink($new_conf_file);
		return(6);
	    }

	    # Assume conf file was successfully transformed...
	    # so replace the old one with the new.
	    system("mv $new_conf_file $conf_file");
	    if ($? != 0) {
		logerror("error moving new config file to old config file: $conf_file");
		unlink($new_conf_file);
		return(7);
	    }

	    system("chown root:root $conf_file");
	    system("chmod 644 $conf_file");

	    loginfo("config file converted: $conf_file");
	}
	else {
	    logerror("error opening new conf file for write: $new_conf_file");
	    close($ocf);
	    return(5);
	}
    }
    else {
	logerror("error opening old conf file for read: $conf_file");
	return(4);
    }

    return(0);
}

#
# Here is where the interesting code starts and finishes.
#
exit(main());


__END__

=pod

=head1 NAME

B<tfconfed.pl> - Teleflora Configuration File Editor


=head1 VERSION

This documenation refers to version: $Revision: 1.18 $


=head1 USAGE

tfconfed.pl

tfconfed.pl B<--version>

tfconfed.pl B<--help>

tfconfed.pl B<--blm-priority>

tfconfed.pl B<--add-daisy-alias>

tfconfed.pl B<--add-daisy-path>

tfconfed.pl B<--kaseya-ini>

tfconfed.pl B<--nsswitch-sudo>

tfconfed.pl B<--rtibackup-cron>

tfconfed.pl B<--samba-browsing>

tfconfed.pl B<--samba-security>

tfconfed.pl B<--set-root-password=password>

tfconfed.pl B<--disable-logwatch>

tfconfed.pl B<--remove-logwatch>

tfconfed.pl B<--update-hosts-allow>

=head1 OPTIONS

=over 4

=item B<--version>

Output the version number of the script and exit.

=item B<--help>

Output a short help message and exit.

=item B<--blm-priority>

# edit startup priority in C</etc/init.d/blm> script

=item B<--add-daisy-alias>

# add an alias for "l=ls -l" to C</etc/profile.d/daisy.sh>

=item B<--add-daisy-path>

# add setting the PATH to C</etc/profile.d/daisy.sh>

=item B<--kaseya-ini>

# edit the Kaseya C<ini> file

=item B<--nsswitch-sudo>

# edit the C</etc/nsswitch.conf> file

=item B<--rtibackup-cron>

# edit B<rtibackup.pl> cron job file

=item B<--samba-browsing>

# edit browsing parameters in Samba config file

=item B<--samba-security>

# edit security parameters in C<[global]> section of Samba config file

=item B<--set-root-password>

# set the root password to value specified

=item B<--disable-logwatch>

# disable logwatch by removing cron job

=item B<--remove-logwatch>

# remove the logwatch RPM package

=item B<--update-hosts-allow>

# update the /etc/hosts file with new Paragould IP addr

=back


=head1 DESCRIPTION

This B<tfconfed.pl> script provides a convenient method for applying changes
to system config files for RTI and Daisy POS systems via the Altiris facility.


=head2 Set BLM System Service Priority

The B<--blm-priority> command line option changes the start priority of
C<blm> by editing the file C</etc/init.d/blm> and changing the C<chkconfig>
comment line in the file; the start priority is changed to C<79>.


=head2 Add BASH Alias

The B<--add-daisy-alias> command line option adds a BASH shell alias
to the file C</etc/profile.d/daisy.sh>.  The alias is C<l=ls -l>.
The file is sourced by C<~/.bash_profile> for all normal daisy accounts and
for all Daisy admin accounts including the B<tfsupport> account.


=head2 Edit PATH

The B<--add-daisy-path> command line option adds an assignment to the
PATH environment variable.  The path C</d/daisy/bin> is added to the PATH.
The file is sourced by C<~/.bash_profile> for all normal daisy accounts and
for all Daisy admin accounts including the B<tfsupport> account.


=head2 Edit Kaseya INI file

The B<--kaseya-ini> command line option modifies the Kaseya "ini" file by
setting the C<User_Name> line to:

    hostname + "unknown.linux_services"

and "Server_Name", "Backup_Server_Name", "User_Web_Name", and
"Web_Server_Name" lines to "65.198.163.25" which is the IP addr of
the Kaseya server at Teleflora.

The code first looks for the exact path to the Kaseya "ini" file by
globing the path C</opt/Kaseya/*/etc/KaseyaD.ini>.
Since only one "ini" file is supported by this script,
if more than one "ini" file or no "init" file is found,
than an error is logged and the script exits without
changing the "ini" file.

Then the hostname of the system is looked up - if not found,
an error is logged and the script exits and the script exits without
changing the "ini" file.

Finally, the "ini" file is edited to make the changes to the lines
as described above.

If the edit fails, an error is logged and the script exits without
changing the "ini" file.


=head2 Edit C</etc/nsswitch.conf> file

The B<--nsswitch-sudo> command line option modifies the
C</etc/nsswitch.conf> config file under certain conditions.

If the config file contains the string C<^sudoers: files ldap$>,
it is removed.
Then, if the config file does not contain the string C<^\s*sudoers:>,
the line C<sudoers:  files ldap> is added to the end of the file.
If any changes are made by B<tfconfed.pl>,
the owner and group are set to C<root:root> and
the file perms are set to C<644>.


=head2 Remove Old Cron Job File

The B<--rtibackup-cron> command line option removes the previous
B<rtibackup.pl> cron job file
C</etc/cron.d/daisy-backup> if it exists and edits the current
cron job file C</etc/cron.d/nightly-backup> to comment out the line
where B<rtibackup.pl> is invoked with the B<--saveall> command line option.


=head2 Edit Samba Conf File

The B<--samba-browsing> command line option either edits or augments
the browsing parameters in the Samba config file C</etc/samba/smb.conf>.
If the parameters C<local master>, C<preferred master> or C<os level>
appear in the file, and no matter whether they have the value C<yes> or
C<no>, the lines are commented out.  Then the following
lines are added to the end of the C<[global]> section:

    # Begin lines added by tfconfed.pl 20110419131809
    local master = no
    preferred master = no
    os level = 0
    # End lines added by tfconfed.pl 20110419131809


=head2 Edit Security Statements in Samba Conf File

The B<--samba-security> command line option either edits or augments
the security statements in the global section of the Samba config file
C</etc/samba/smb.conf>.
If the security statments C<security => or C<server signing = >
appear in the file, the lines are commented out.
Then the following lines are added to the end of the C<[global]> section:

    # Begin lines added by tfconfed.pl 20110419131809
    security = user
    server signing = auto
    # End lines added by tfconfed.pl 20110419131809


=head2 Set Password for C<root> account

The B<--set-root-password> command line option sets the root password
to the value specified on the command line if the state of the
root account has an expired password.
If the password is not expired, then no change is made.
Only RHEL5, RHWS5, Fedora Core 5, and Fedora Core 3 platforms
are supported.


=head2 Disable the C<logwatch> cron job

The B<--disable-logwatch> command line option disables 
any output from C<logwatch> by removing it's cron job file.


=head2 Remove the C<logwatch> RPM package

The B<--remove-logwatch> command line option removes
the C<logwatch> RPM package.


=head2 Update IP addr in C</etc/hosts.allow>

The B<--update-hosts-allow> command line option updated
the IP address in the C</etc/hosts.allow> file with the
new one for Paragould.


=head1 FILES

=over 4

=item C</etc/init.d/blm>

The C<init.d> script for the Basis license manager using on RTI systems.

=item C</etc/samba/smb.conf>

The configuration file for Samba.

=item C</etc/cron.d/daisy-backup>

The name previously used for B<rtibackup.pl> cron job file on Daisy systems.

=item C</etc/cron.d/nightly-backup>

The current name of the RTI and Daisy rtibackup.pl cron job file.

=item C</etc/profile.d/daisy.sh>

This file contains global shell definitions for all daisy accounts.

=item C<OS-Patches.log>

The B<tfconfed.pl> script writes log entries to this file;
the standard location for the logfile is in
the directory C</usr2/bbx/log> for RTI systems and
the directory C</d/daisy/log> for Daisy systems.

=item C</d/daisy/bin>

This directory contains many of the programs in the default Daisy database.

=item C</opt/Kaseya/*/etc/KaseyaD.ini>

Kaseya "ini" file.

=item C</etc/nsswitch.conf>

The name service switch config file.

=item C</etc/cron.daily/0logwatch>

The cron job file for RHEL5 and RHEL6 C<logwatch>.

=item C</etc/cron.daily/00-logwatch>

The cron job file for RHEL4 C<logwatch>.

=item C</etc/hosts.allow>

This file contains IP addrs specific to Oklahoma and
Paragould.

=back


=head1 DIAGNOSTICS

=over 4

=item Exit status 0

Successful completion.

=item Exit status 1

In general, there was an issue with the syntax of the command line.

=item Exit status 3

There was an error with editing the C</etc/init.d/blm> file.

=item Exit status 4

There was an error with editing the B<rtibackup.pl> cron job file.

=item Exit status 5

There was an error with editing the B<samba> config file.

=item Exit status 6

There was an error setting the password for the "root" account.

=item Exit status 7

There was an error adding an alias for Daisy.

=item Exit status 8

There was an error modifying the Daisy default PATH.

=item Exit status 9

There was an error removing the C<logwatch> cron job file.

=item Exit status 10

There was an error editing the Kaseya "ini" file.

=item Exit status 11

There was an error editing the C</etc/nsswitch.conf> config file.

=item Exit status 12

There was an error removing the C<logwatch> RPM package.

=item Exit status 13

There was an error updating the C</etc/hosts.allow> file.

=back


=head1 SEE ALSO

B<rtibackup.pl>, B<updateos.pl>

=cut
