#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2000,2007 
# All Rights Reserved 
#  
# US Government Users Restricted Rights - Use, duplication or 
# disclosure restricted by GSA ADP Schedule Contract with IBM Corp. 
#  
# IBM_PROLOG_END_TAG 
# @(#)13   1.14.4.3   src/csm/dms/cmds/csmconfig.perl, dms, csm_rfish, rfishs001b 1/2/07 13:53:29

use strict;
use locale;

BEGIN
{

	# this enables us to redirect where it looks for other CSM files during development
	$::csmroot = $ENV{'CSM_ROOT'} ? $ENV{'CSM_ROOT'} : '/opt/csm';
	$::csmpm   = "$::csmroot/pm";
	$::csmbin  = "$::csmroot/bin";
}
use lib $::csmpm;
use Getopt::Std;
require NodeUtils;
require CSMDefs;
require InstallKRB5Utils;
require ServerUtils;
require ArchiveUtils;

$::OK = 0;
$::NOK = 1;
@::READONLY_ATTR = ( 'CSMLogDir', 'CSMAdminID', 'CFMRootDir');
@::HMC_READONLY_ATTR = ( 'CFMRootDir', 'SetupKRB5', 'RemoteShell', 'RemoteCopyCmd', 'SyncCmd');

my $PROPNAME = $ENV{'CSM_CONFIG_PROP_ATTR'} || 'Properties';

# get the definitions we need for this command
# in this case get_OSDefs uses the attrs of the management
# server to identify the correct definitions
%::myOSDefs = ServerUtils->get_OSDefs();
my $CSMKEYTAB = "/var/ct/IW/sec/krb5/csm/k5keytabs/ctsrcmdp";

#set LD_ASSUME_KERNEL if running on a RH EL 3 machine
my $rh_relfile = "/etc/redhat-release";
my $rh_vers    = '^Red Hat Enterprise Linux .* release 3 (.*)$';
if (-f $rh_relfile)
{
	`/bin/grep \"$rh_vers\" $rh_relfile > /dev/null 2>&1`;
	my $exit = $? >> 8;
	if ($exit == 0)
	{
		$ENV{'LD_ASSUME_KERNEL'} = "2.4.19";
	}
}

# For the usage, see nodecmds.msg
sub usage
{
	MessageUtils->message('I', 'IMsgCsmconfigUsage');
	exit(scalar(@_) ? $_[0] : 1);
}

$::MSGCAT     = 'nodecmds.cat';
$::MSGMAPPATH = "$::csmroot/msgmaps";
# setting this explicitly so it will work with the old dmsctrl link
$::MSGSET     = 'csmconfig';    

# check if the command is running on management server
if (!NodeUtils->isMgmtSvr())
{
	MessageUtils->messageFromCat('csmInstall.cat', $::MSGMAPPATH, 'csminstall',
								 'E2', 'EMsgNOManagementServer');

}

# Parse the cmd line args and check them
if (!getopts('hvVp:u:m:s:r:t:R:K:Ld:Z:cP')) { &usage; }
if ($::opt_h) { &usage(0); }
#On HMC following options are not supported
if ( NodeUtils->isHMC())
{
    MessageUtils->message('E1', 'EMsgNotSupportedOnHMC', '-c') if defined($::opt_c); 
    MessageUtils->message('E1', 'EMsgNotSupportedOnHMC', '-Z') if defined($::opt_Z); 
    MessageUtils->message('E1', 'EMsgNotSupportedOnHMC', '-u') if defined($::opt_u); 
    MessageUtils->message('E1', 'EMsgNotSupportedOnHMC', '-t') if defined($::opt_t); 
    MessageUtils->message('E1', 'EMsgNotSupportedOnHMC', '-L') if defined($::opt_L); 
    MessageUtils->message('E1', 'EMsgNotSupportedOnHMC', '-K') if defined($::opt_K); 
    MessageUtils->message('E1', 'EMsgNotSupportedOnHMC', '-r') if defined($::opt_r); 
}
        
my $setflags =
  defined($::opt_u) + defined($::opt_m) + defined($::opt_s) + defined($::opt_r)
  + defined($::opt_R) + defined($::opt_t) + defined($::opt_K) +
  defined($::opt_p);
if (
	(
	 defined($::opt_V) + defined($::opt_L) + defined($::opt_d) +
	 defined($::opt_Z) + (
						       $setflags > 0
							|| (scalar(@ARGV) > 0 && !defined($::opt_L))
							|| (defined($::opt_P) && !defined($::opt_d))
						 )
	) > 1
   )
{
	&usage;
}
if ($setflags > 0 && defined($::opt_P)) { &usage; }

$::VERBOSE = $::opt_v;
# set local scope because we only want the local DmsCtrl class
$ENV{'CT_MANAGEMENT_SCOPE'} = 1;

#--------------------------------------------------------------------------
if ($::opt_V)    # display CSM version
{
	my $server_pkg;
    if ( NodeUtils->isHMC()) {
	   $server_pkg = "csm_hmc.server";
    } else {  
	   $server_pkg = "csm.server";

    }
	my $version = NodeUtils->get_CSMVersion($server_pkg, 1);
	if (!defined($version))
	{
		exit 2;
	}            # the above function already displayed an error msg

    if (!( NodeUtils->isHMC()))  # not on the HMC
	{
	  $version .= " ";
	  my $cmd = "$::CSMCSMBIN/csmversion";
	  my @output= NodeUtils->runcmd("$cmd");   # get build info
	  $version .= $output[0];
	}            # the above function already displayed an error msg
	$version .= "\n";

	print "$version";
}

# Install A License Key File

#--------------------------------------------------------------------------
elsif (defined($::opt_L))
{
	installLicenseKey();

	# add cron jobs after accepting the license
	ServerUtils->addCronJob("cfmupdatenode");
	ServerUtils->addCronJob("cleanup.logs.csp");
}

#--------------------------------------------------------------------------
elsif (defined($::opt_Z))    # display license agreement
{
	&displayLicenseAgreement($::opt_Z);
}

#--------------------------------------------------------------------------
elsif (defined($::opt_d))    # display just one attr
{
	my $select;
	if (defined($::opt_P)) { $select = $PROPNAME; }
	else
	{
		$select = $::opt_d;
		if ($select =~ /Sensitivity/ || $select =~ /Frequency/)
		{
			$select =~ s/Heartbeat//;
		}
	}
	my $outref =
	  NodeUtils->runrmccmd('lsrsrc-api', '', "-s IBM.DmsCtrl::::$select");

	if (defined($::opt_P))
	{
		my ($delim, $propstr) = $$outref[0] =~ /^(\W*)(.*?)$/;
		my $delimpat;
		if (length($delim))
		{
			$delimpat = $delim;
			$delimpat =~ s/([\\\|\(\)\[\{\^\$\*\+\?\.])/\\$1/g;
		}
		else { $delim = '|:|'; $delimpat = '\|:\|'; }

		my %props = split(/$delimpat/, $propstr);
		print "$props{$::opt_d}\n";
	}
	else    # displaying a attribute, not a property
	{
		print "$$outref[0]\n";
	}
}

#--------------------------------------------------------------------------
elsif ($setflags || scalar(@ARGV) > 0)    # set 1 or more of the values
{
	my %attrs;

	# 1st process the attr=val pairs
	foreach my $a (@ARGV)
	{

		# Note: we allow a null value
		my ($at, $val) = $a =~ /^\s*(\S+?)\s*=\s*(\S*.*)$/;
		if (!defined($at))
		{
			MessageUtils->messageFromCat($::MSGCAT, $::MSGMAPPATH, 'createnode',
										 'E1', 'EMsgBAD_ATTR_VAL_FORM');
		}
		if ($at =~ /Sensitivity/ || $at =~ /Frequency/)
		{
			$at =~ s/Heartbeat//;
		}

        if ( grep /$at/, @::READONLY_ATTR)
        {
            MessageUtils->message('E1', 'EMsgReadOnlyAttr', $at);
        }
        if ( NodeUtils->isHMC() && ( grep /$at/, @::HMC_READONLY_ATTR))
        {
            MessageUtils->message('E1', 'EMsgReadOnlyAttrOnHMC', $at);
        }
		$attrs{$at} = $val;
	}

	# Now process specific flags
	if (defined($::opt_u)) { $attrs{'AddUnrecognizedNodes'} = $::opt_u; }
	if (defined($::opt_R)) { $attrs{'SetupRemoteShell'}     = $::opt_R; }
	if (defined($::opt_K)) { $attrs{'SetupKRB5'}            = $::opt_K; }
	if (defined($::opt_r)) { $attrs{'RemoteShell'}          = $::opt_r; }
	if (defined($::opt_t)) { $attrs{'TFTPpackage'}          = $::opt_t; }
	if (defined($::opt_m)) { $attrs{'ClusterTM'}            = $::opt_m; }
	if (defined($::opt_s)) { $attrs{'ClusterSNum'}          = $::opt_s; }
	if (defined($::opt_p)) { $attrs{'PowerStatusMode'}      = $::opt_p; }

	# Now check the values
	if (!defined($::opt_P))
	{
		my $r;    # this reduces the # of hash lookups
		if (defined($r = $attrs{'AddUnrecognizedNodes'}))
		{
			if    ($r =~ /yes|1/i) { $attrs{'AddUnrecognizedNodes'} = 1; }
			elsif ($r =~ /no|0/i)  { $attrs{'AddUnrecognizedNodes'} = 0; }
			else
			{
				MessageUtils->message(
									  'E1',
									  'EMsgBAD_U_VALUE',
									  'AddUnrecognizedNodes'
									 );
			}
		}
		if (defined($r = $attrs{'SetupRemoteShell'}))
		{
			if    ($r =~ /yes|1/i) { $attrs{'SetupRemoteShell'} = 1; }
			elsif ($r =~ /no|0/i)  { $attrs{'SetupRemoteShell'} = 0; }
			else
			{
				MessageUtils->message('E1', 'EMsgBAD_U_VALUE',
									  'SetupRemoteShell');
			}
		}
		if (defined($r = $attrs{'SetupKRB5'}))
		{
			setupKRB5($r, \%attrs);
		}    # end SetupKRB5
		if (defined($r = $attrs{'RemoteShell'}))
		{
			if (!(-x $r)) { MessageUtils->message('E1', 'EMsgBAD_SHELL', $r); }
		}
		if (defined($r = $attrs{'ClusterTM'}))
		{
			if (!($r =~ /^\s*\d{4}-\d{3}\s*$/))
			{
				MessageUtils->message('E1', 'EMsgBAD_MODEL', $r);
			}
		}
		if (defined($r = $attrs{'PowerStatusMode'}))
		{
			if    ($r =~ /Mixed|0/i)   { $attrs{'PowerStatusMode'} = 0; }
			elsif ($r =~ /Events|1/i)  { $attrs{'PowerStatusMode'} = 1; }
			elsif ($r =~ /Polling|2/i) { $attrs{'PowerStatusMode'} = 2; }
			elsif ($r =~ /None|3/i)    { $attrs{'PowerStatusMode'} = 3; }
			else
			{
				MessageUtils->message('E1', 'EMsgBAD_P_VALUE',
									  'PowerStatusMode');
			}
		}
		if (defined($r = $attrs{'HAMode'}) && !$ENV{'CSM_HAMS_CONTROL'})
		{
			MessageUtils->message('E1', 'EMsgCannotSetHAMode');
		}
		if (defined($r = $attrs{'TFTPpackage'}))
		{
			if (!grep(/^$r$/, @::valid_TFTP))
			{
				MessageUtils->message(            'E', 'EMsgBAD_T_VALUE',
									  $r, join(',', @::valid_TFTP));
			}
		}
		if (defined($r = $attrs{'NetworkInstallProtocol'}))
		{
			if    ($r =~ /^NFS$/i)   { $attrs{'NetworkInstallProtocol'} = "nfs"; }
			elsif ($r =~ /^HTTP$/i)   { $attrs{'NetworkInstallProtocol'} = "http"; }
			else
			{
				MessageUtils->message('E1', 
				    'EMsgInvalid_NetworkInstallProtocol', $r);
			}
		}
		if (defined($r = $attrs{'SetupNetworkInstallProtocol'}))
		{
			if    ($r =~ /^yes$|^1$/i) { $attrs{'SetupNetworkInstallProtocol'} = 1; }
			elsif ($r =~ /^no$|^0$/i)  { $attrs{'SetupNetworkInstallProtocol'} = 0; }
			else
			{
				MessageUtils->message('E1', 
				    'EMsgInvalid_SetupNetworkInstallProtocol', $r);
			}
		}
		if (defined($r = $attrs{'SyncCmd'}))
		{
			if (grep /rdist/, $attrs{'SyncCmd'}) {  # rdist
			   if (NodeUtils->isAIX) {
					if ($attrs{'SyncCmd'} ne '/usr/sbin/rdist') {
			        	MessageUtils->message('E', 
			    	    'EMsgInvalid_SyncCmd', $attrs{'SyncCmd'}, 'AIX', '/usr/sbin/rdist');
						$attrs{'SyncCmd'} = '/usr/sbin/rdist';
					}
			    } else {  # Linux
					if ($attrs{'SyncCmd'} ne '/usr/bin/rdist') {
			        	MessageUtils->message('E', 
			    	    'EMsgInvalid_SyncCmd', $attrs{'SyncCmd'}, 'Linux', '/usr/bin/rdist');
						$attrs{'SyncCmd'} = '/usr/bin/rdist';
					}
			    }
			}
		}
	}

	# Build the cmd string
	my $chstr = buildChangeStr(\%attrs);
	my $outref = NodeUtils->runrmccmd('chrsrc-api', '-i', $chstr);
}

#--------------------------------------------------------------------------
elsif (
	 !defined($::opt_c)) # display all values if not copying binaries, "-c" flag
{
	my $select = defined($::opt_P) ? $PROPNAME : "'*p0x0020'";
	my $outref =
	  NodeUtils->runrmccmd(
						   'lsrsrc-api',
						   "-D ':|:' -n",
						   "-s IBM.DmsCtrl::::$select"
						  );

	# takes the alternating attrs and values and puts them in the hash correctly
	my %attrs = split(/:\|:/, $$outref[0]);

	if (defined($::opt_P))
	{
		my ($delim, $propstr) = $attrs{$PROPNAME} =~ /^(\W*)(.*?)$/;
		my $delimpat;
		if (length($delim))
		{
			$delimpat = $delim;
			$delimpat =~ s/([\\\|\(\)\[\{\^\$\*\+\?\.])/\\$1/g;
		}
		else { $delim = '|:|'; $delimpat = '\|:\|'; }

		%attrs = split(/$delimpat/, $propstr);
	}
	else
	{    # displaying regular attributes, not properties
		delete $attrs{'NodeNameList'};        # do not want to display this one
		delete $attrs{'ActivePeerDomain'};    # do not want to display this one

		# Current BMC implementation does not support SOL encryption
		#
		delete $attrs{'BMCConsoleEncryptSOL'};

		if ($attrs{'Sensitivity'})
		{
			$attrs{'HeartbeatSensitivity'} = $attrs{'Sensitivity'};
			delete $attrs{'Sensitivity'};
		}
		if ($attrs{'Frequency'})
		{
			$attrs{'HeartbeatFrequency'} = $attrs{'Frequency'};
			delete $attrs{'Frequency'};
		}

		# Give explanations for some of the attributes
		&getMeanings();

		my $r;    # this reduces the # of hash lookups
		if (defined($r = $attrs{'MaxNumNodesInDomain'}))
		{
			if ($r == -1) { $attrs{'MaxNumNodesInDomain'} .= " $::UNLIMITED"; }
		}
		if (defined($r = $attrs{'AddUnrecognizedNodes'}))
		{
			$attrs{'AddUnrecognizedNodes'} .= $r ? " $::YES" : " $::NO";
		}
		if (defined($r = $attrs{'SetupRemoteShell'}))
		{
			$attrs{'SetupRemoteShell'} .= $r ? " $::YES" : " $::NO";
		}
		if (defined($r = $attrs{'SetupNetworkInstallProtocol'}))
		{
			$attrs{'SetupNetworkInstallProtocol'} .= $r ? " $::YES" : " $::NO";
		}
		if (defined($r = $attrs{'PowerStatusMode'}))
		{
			if ($r =~ /Mixed|0/i)
			{
				$attrs{'PowerStatusMode'} .= " $::MIXED";
			}
			elsif ($r =~ /Events|1/i)
			{
				$attrs{'PowerStatusMode'} .= " $::EVENTS";
			}
			elsif ($r =~ /Polling|2/i)
			{
				$attrs{'PowerStatusMode'} .= " $::POLLING";
			}
			elsif ($r =~ /None|3/i)
			{
				$attrs{'PowerStatusMode'} .= " $::NONE";
			}
		}
		if (defined($r = $attrs{'BMCConsolePerMsgAuth'}))
		{
			$attrs{'BMCConsolePerMsgAuth'} .= $r ? " $::YES" : " $::NO";
		}
		if (defined($r = $attrs{'BMCConsoleEncryptAuth'}))
		{
			$attrs{'BMCConsoleEncryptAuth'} .= $r ? " $::YES" : " $::NO";
		}

		# Current BMC implementation does not support SOL encryption
		#
		if (defined($r = $attrs{'BMCConsoleKeepAlive'}))
		{
			$attrs{'BMCConsoleKeepAlive'} .= $r ? " $::YES" : " $::NO";
		}
	}

	# Now display the attributes, sorted
	foreach my $k (sort keys %attrs)
	{

		#my $name = defined($names{$k}) ? $names{$k} : $k;
		print " $k = $attrs{$k}\n";
	}
}

#
#--------------------------------------------------------------------------
# Create the /csminstall directory and subdirectories; copy the
# binary files into /csminstall/csm
#
if ($::opt_c)
{
	MessageUtils->messageFromCat('csmInstall.cat', $::MSGMAPPATH, 'csminstall',
								 'I', 'IMsgCOPYING_CSMBINARIES');
	ServerUtils->copyBinaries;

	# convert InstallServer attributes if migrating from pre CSM 1.4.1
	ServerUtils->migrate_install_servers;
}
elsif (scalar(@ARGV) > 0)
{

	# This handles the case where a customer specifies "csmconfig -L <file> -c"
	foreach my $a (@ARGV)
	{
		if ($a =~ /-c/)
		{
			MessageUtils->messageFromCat('csmInstall.cat', $::MSGMAPPATH,
								  'csminstall', 'I', 'IMsgCOPYING_CSMBINARIES');
			ServerUtils->copyBinaries;
			# copy customization scripts if need
			ServerUtils->copy_csm_scripts(1);    

			# convert InstallServer attributes if migrating from pre CSM 1.4.1
			ServerUtils->migrate_install_servers;
		}
	}
}
exit;

# Gets a list of the words: (yes) (no) (on) (off) (unknown)
# and puts them in global vars
sub getMeanings
{

	# Check if we already got them so we do not do it every time.
	if (!defined($::YES))
	{
		($::YES, $::NO, $::UNLIMITED) =
		  split(/\|/,
				MessageUtils->getMessage('IMsgCsmconfigATTRIBUTE_MEANINGS'));
		($::MIXED, $::EVENTS, $::POLLING, $::NONE) =
		  split(
				/\|/,
				MessageUtils->getMessage(
										 'IMsgCsmconfigPowerATTRIBUTE_MEANINGS')
			   );
	}
}

# Build the chrsrc-api cmd option string
sub buildChangeStr
{
	my $attrs = shift @_;    # this is a reference to the attrs hash
	my $chstr;
	if (defined($::opt_P))    # changing user defined properties
	{

		# Get original Properties string for each node
		my $outref =
		  NodeUtils->runrmccmd(
							   'lsrsrc-api',
							   "-i -D ':|:'",
							   "-s IBM.DmsCtrl::::${PROPNAME}"
							  );

		# Substitute the new property values into the string
		my ($delim, $propstr) = $$outref[0] =~ /^(\W*)(.*?)$/;
		my $delimpat;
		if (length($delim))
		{
			$delimpat = $delim;
			$delimpat =~ s/([\\\|\(\)\[\{\^\$\*\+\?\.])/\\$1/g;
		}
		else { $delim = '|:|'; $delimpat = '\|:\|'; }

		my %props = split(/$delimpat/, $propstr);
		foreach my $k (keys %$attrs)    # each attribute
		{
			if (!length($$attrs{$k}) || $$attrs{$k} eq "''")
			{
				delete($props{$k});
			}    # they gave this prop a null value, so remove it
			else { $props{$k} = $$attrs{$k}; }
		}
		my $specialdelim = ($delim eq '|:|' ? '' : $delim);
		$chstr =
		  qq(-s IBM.DmsCtrl::::${PROPNAME}::)
		  . NodeUtils->quote($specialdelim . join($delim, %props));
	}
	else         # doing regular attributes, not properties
	{
		$chstr = '-s IBM.DmsCtrl::';
		foreach my $k (keys %$attrs)
		{
			my $val = $$attrs{$k};
			if (!length($val))
			{
				$val = "''";
			}    # chrsrc-api needs something for the value
			# Put quotes around the value to protect spaces or weird chars
			$val = NodeUtils->quote($val) ;   
			$chstr .= "::${k}::$val";
		}
	}
	return $chstr;
}

sub displayLicenseAgreement
{
	my $tab = shift;
	my $rc = ArchiveUtils->invokeLAP($tab ? 'tab' : 'full');
	if ($rc == 9)
	{
		# Tell the user the license was accepted.
		# a return code of 9 from invokeLAP means
		# that the user accepted it.
		MessageUtils->message('I', 'IMsgACCEPTED');
	}
	else
	{
		# Tell the user the license was not accepted.
		MessageUtils->message('W3', 'EMsgNOT_ACCEPTED');
	}

	# return true or false if the license was accepted or not.
	return ($rc == 9);
}

sub installLicenseKey
{

	# Possible Flows
	#
	# Was a key provided?
	#   Yes:
	#     Was it a tab key?
	#       Yes:
	#         Was a key provided previously?
	#           Yes:
	#             Was it a tab key?
	#               Yes: *CASE 1* can not install tab key over tab key
	#               No:  *CASE 2* can not install tab key over full key
	#           No: *CASE 3* process tab key
	#       No:
	#         Was a key provided previously?
	#           Yes:
	#             Was it a tab key?
	#               Yes: *CASE 4* process full key - back up previous tab key
	#               No:
	#                 Is key provided same as previous accepted key?
	#                   Yes: *CASE 5* process full key
	#                   No:  *CASE 6* process full key - back up previous full key
	#           No: *CASE 7* process full key
	#   No:
	#     Was a key provided previously?
	#       Yes:
	#         Was it a tab key?
	#           Yes: *CASE 8* will not  process tab key over tab key
	#           No:  *CASE 9* reprocess old full key
	#       No: *CASE 10* process default tab key

	# Variables Used

	my $name_key_given;
	my $key_given;
	my $temp;
	my $tab_key_given;
	my $key_accepted_before;
	my $tab_key_accepted_before;
	my $key;
	my $tab_key;
	my $key_version;
	my $process_license_agreement;
	my $process_license_key;
	my $install_itlm_inventory_signature = 0;

	# Information gathering about key provided and previously existing keys

	# Was a key given on the command line?
	# command syntax is csmconfig -L <key>
	# check if key file name given and readable
	if (scalar(@ARGV))
	{

		# A key was given on the command line.
		$name_key_given = $ARGV[0];

		# Is it readable?
		if (!(-r $name_key_given))
		{

			# File not readable
			MessageUtils->message('E1', 'EMsgBAD_KEYFILE', $name_key_given);
			$key_given = 0;
		}
		else
		{
			# It is readable!
			$key_given = 1;
		}
	}
	else
	{
		# A key was not given on the command line.
		$key_given = 0;
	}

	# If a key was provided, what kind of key is it?
	# we can see if it is a try and buy by grepping for it in the file
	if ($key_given)
	{
		$temp = NodeUtils->runcmd("/bin/grep TryAndBuy $name_key_given");
		if ($temp =~ /TryAndBuy\s*=\s*Yes/)
		{
			$tab_key_given = 1;
		}
		else
		{
			$tab_key_given = 0;
		}
	}
	else
	{
		$tab_key_given = 0;
	}

	# Restore existing key.
	if ((-d "/var/opt/csm/.lic") && (-d "/var/opt/csm/lic")) 
	{
		if (-f "/var/opt/csm/.lic/csmlum.lic") 
		{
			NodeUtils->runcmd("/bin/mv /var/opt/csm/.lic/csmlum.lic /var/opt/csm/lic");
		} 
		elsif (-f "/var/opt/csm/.lic/csmlum.tab") 
		{
			NodeUtils->runcmd("/bin/mv /var/opt/csm/.lic/csmlum.tab /var/opt/csm/lic");
		}

		if (-f "/var/opt/csm/.lic/nodelock")
		{
			NodeUtils->runcmd("/bin/mv /var/opt/csm/.lic/nodelock /var/opt/csm/lic");
		}

		NodeUtils->runcmd("/bin/rm -rf /var/opt/csm/.lic");
	}

	# Was a key ever accepted in the past?
	# if a full key was previously accepted, it would be located at
	# /var/opt/csm/lic/csmlum.lic
	# if a tab key was previously accepted, it would be located at
	# /var/opt/csm/lic/csmlum.tab
	if (   (-f "/var/opt/csm/lic/csmlum.lic")
		|| (-f "/var/opt/csm/lic/csmlum.tab"))
	{
		$key_accepted_before = 1;
	}
	else
	{
		$key_accepted_before = 0;
	}

	# If a key was accepted, what kind of key was it?
	# we can tell based on what files exist in the lic directory
	# a csmlim.lic and csmlum.tab should never exist at the same time
	if ($key_accepted_before)
	{
		if (-f "/var/opt/csm/lic/csmlum.tab")
		{
			$tab_key_accepted_before = 1;
		}
		else
		{
			$tab_key_accepted_before = 0;
		}
	}
	else
	{
		$tab_key_accepted_before = 0;
	}

	# Figure out how to process keys

	if ($key_given)
	{
		if ($tab_key_given)
		{
			if ($key_accepted_before)
			{
				if ($tab_key_accepted_before)
				{
					# CASE 1
					# tab key was given, but tab key was previously accepted
					# cannot install tab key over another tab key
					MessageUtils->message('W2', 'EMsgALREADY_TAB');
				}
				else
				{
					# CASE 2
					# tab key was given, but full key was previously accepted
					# cannot install tab key over a full key
					MessageUtils->message('W2', 'EMsgALREADY_FULL');
					#$install_itlm_inventory_signature = 1;
				}
			}
			else
			{
				# CASE 3
				# tab key given, no keys accepted before
				$key                       = $name_key_given;
				$tab_key                   = $tab_key_given;
				$process_license_agreement = 1;
				$process_license_key       = 1;
			}
		}
		else
		{
			# CASES 4, 5, 6, 7
			# full key was given
			# alway process full key regardless of what was accepted before
			$key                       = $name_key_given;
			$tab_key                   = $tab_key_given;
			$process_license_agreement = 1;
			$process_license_key       = 1;
			$install_itlm_inventory_signature = 1;
		}
	}
	else
	{
		if ($key_accepted_before)
		{
			if ($tab_key_accepted_before)
			{
				# CASE 8
				# a key was not given, but a tab key was accepted previously
				# we will continue to use that one and will display license 
				# agreement.
				$key                       = "/var/opt/csm/lic/csmlum.tab";
				$tab_key                   = 1;
				$process_license_agreement = 1;
				$process_license_key       = 1;
			}
			else
			{
				# CASE 9
				# a key was not given, but a full key was accepted previously
				# we will continue to use that one
				$key                       = "/var/opt/csm/lic/csmlum.lic";
				$tab_key                   = 0;
				$process_license_agreement = 1;
				$process_license_key       = 1;
				$install_itlm_inventory_signature = 1;
			}
		}
		else
		{
			# CASE 10
			# a key was not given, and none have been accepted previously
			# we will use the default try and buy license
			$key                       = "/var/opt/csm/lic/default";
			$tab_key                   = 1;
			$process_license_agreement = 1;
			$process_license_key       = 1;
		}
	}

	# Process license agreement
	if ($process_license_agreement)
	{
		# Display license agreement
		# display full or try and buy agreement based on the key we are using
		&displayLicenseAgreement($tab_key);
	}

	# Process license key
	if ($process_license_key)
	{
		# if the license directory does not exist, create it
		if (!(-d "/var/opt/csm/lic"))
		{
			NodeUtils->runcmd("/bin/mkdir -p /var/opt/csm/lic");
		}

		# Backup previous license files

		if (!$tab_key)
		{
			# backup previous nodelock file, if necessary
			# regenerate the nodelock file every time 
			# (the refresh of dmsrm regenerates the file).
			# in case of tab key, this file is preserved.
			if (-f "/var/opt/csm/lic/nodelock")
			{
				rename("/var/opt/csm/lic/nodelock",
					   "/var/opt/csm/lic/nodelock.backup")
				  or MessageUtils->messageFromCat(
					$::MSGCAT,
					$::MSGMAPPATH,
					'NodeUtils',
					'E' . $! / 1,
					'EMsgCMD_FAILED',
					$! / 1,
					"rename(/var/opt/csm/lic/nodelock, /var/opt/csm/lic/nodelock.backup)",
					$!
				  );
			}
		}

		# backup previous tab file, if necessary
		if (-f "/var/opt/csm/lic/csmlum.tab")
		{
			rename("/var/opt/csm/lic/csmlum.tab",
				   "/var/opt/csm/lic/csmlum.tab.backup")
			  or MessageUtils->messageFromCat(
				$::MSGCAT,
				$::MSGMAPPATH,
				'NodeUtils',
				'E' . $! / 1,
				'EMsgCMD_FAILED',
				$! / 1,
				"rename(/var/opt/csm/lic/csmlum.tab, /var/opt/csm/lic/csmlum.tab.backup)",
				$!
			  );
		}

		# backup previous lic file, if necessary
		if (-f "/var/opt/csm/lic/csmlum.lic")
		{
			rename("/var/opt/csm/lic/csmlum.lic",
				   "/var/opt/csm/lic/csmlum.lic.backup")
			  or MessageUtils->messageFromCat(
				$::MSGCAT,
				$::MSGMAPPATH,
				'NodeUtils',
				'E' . $! / 1,
				'EMsgCMD_FAILED',
				$! / 1,
				"rename(/var/opt/csm/lic/csmlum.lic, /var/opt/csm/lic/csmlum.lic.backup)",
				$!
			  );
		}

		# if key we are using was previously accepted, rename it to now point to the backup
		if ($key =~ /\/var\/opt\/csm\/lic\/csmlum.tab/)
		{
			$key = "/var/opt/csm/lic/csmlum.tab.backup";
		}
		if ($key =~ /\/var\/opt\/csm\/lic\/csmlum.lic/)
		{
			$key = "/var/opt/csm/lic/csmlum.lic.backup";
		}

		# copy the tab or lic file to the location DMSRM needs it in
		if ($tab_key)
		{
			NodeUtils->runcmd("/bin/cp $key /var/opt/csm/lic/csmlum.tab");
		}
		else
		{
			NodeUtils->runcmd("/bin/cp $key /var/opt/csm/lic/csmlum.lic");
		}

		# Send DMSRM the product version in the LUM file.
		# DMSRM will accept 1.3 or 1.4 in CSM 1.4*
		$key_version = NodeUtils->runcmd("/bin/grep ProductVersion $key");
		$key_version =~ s/ProductVersion=//;
		NodeUtils->runrmccmd('chrsrc-api', '-i',
					 qq(-s IBM.DmsCtrl::::LicenseProductVersion::$key_version));

		# Refresh DmsCtrl so that it picks up the ECF file and creates the
		# nodelock file
		NodeUtils->runrmccmd('refrsrc-api', '-c IBM.DmsCtrl');
	}

	# install CSM inventory signature for ITLM enablement
	if ($install_itlm_inventory_signature) {
		NodeUtils->runcmd("/opt/csm/itlm/tools/itlmgen -i -f /opt/csm/itlm/info/CSM.info");
	}
}

sub setupKRB5
{
	my $r     = shift @_;
	my $attrs = shift @_;    # this is a reference to the attrs hash

	if (   ($r ne "0")
		&& ($r ne "1")
		&& ($r ne "2")
		&& ($r ne "3")
		&& ($r ne "4")
		&& ($r ne "5")
		&& ($r ne "6")
		&& ($r ne "7")
		&& ($r ne "8")
		&& ($r ne "9")
		&& ($r ne "10")
		&& ($r ne "11")
		&& ($r ne "12")
		&& ($r ne "13")
		&& ($r ne "14")
		&& ($r ne "15"))
	{
		MessageUtils->message('E1', 'EMsgBAD_K_VALUE', 'SetupKRB5');
	}
	if ($r != 0)
	{    # request to  setup  KRB5
		if ($< == 0)
		{ 

			NodeUtils->runcmd(
				"/usr/bin/startcondresp NodeFullInstallComplete GatherKRB5keytabs",
				-1
			);    #dont display errors

			my $rc;
			my $distro = NodeUtils->distribution();
			if ($distro =~ /SLES/)
			{     # if SLES
				$$attrs{'SetupKRB5'} = 4;    # default to 4
				                             # Format the principal name
				my $msname1 = NetworkUtils->getRSCThostname;
				my $msname  = lc($msname1);
				if (
					(-e "$CSMKEYTAB.$msname.keytab")    # exists then ok
					&& !(-z "$CSMKEYTAB.$msname.keytab")
				   )
				{
					$rc = 0;
				}
				else
				{    # tell them they must set up Kerberos
					MessageUtils->message(   'I',                'IMsgBAD_K_VALUE_UNSUPPORTED',
							  "ctsrcmdp.$msname", "$CSMKEYTAB.$msname.keytab");
				}
			}
			else
			{        # not SLES we can do some setup
				if (   ($r == 1)
					|| ($r == 3)
					|| ($r == 5)
					|| ($r == 7)
					|| ($r == 9)
					|| ($r == 11)
					|| ($r == 13)
					|| ($r == 15))
				{    # request to setup server
					if (NodeUtils->isAIX())
					{    # only valid on AIX
						$rc = InstallKRB5Utils->setupKRB5server;
						if ($rc != 0)
						{
							MessageUtils->message('E1', 'EMsg_KRB5_Setup_Err');
						}
					}
					else
					{    # setup server only valid on AIX MS
						MessageUtils->message('E1', 'EMsgKRB5InvalidRequest');

					}
				}    # end request setup server
				if (   ($r == 4)
					|| ($r == 5)
					|| ($r == 6)
					|| ($r == 7)
					|| ($r == 8)
					|| ($r == 9)
					|| ($r == 10)
					|| ($r == 11)
					|| ($r == 12)
					|| ($r == 13)
					|| ($r == 14)
					|| ($r == 15))
				{    # request to setup principal
					my @attrlist = ($r);
					my @empty_array;    # get all managed nodes
					$rc =
					  InstallKRB5Utils->setupKRB5rcmdprincs(\@attrlist,
															\@empty_array);
					if ($rc != 0)
					{
						MessageUtils->message('E1', 'EMsg_KRB5_Setup_Err');
					}
				}    # end request setup principals
			}    # end SLES
		}
		else
		{        # not root
			MessageUtils->message('E1', 'EMsgKRB5NonRoot');

		}
	}    # end !=0
	else
	{   #stopping KRB5
		#stop condresp
		#don't display errors
		NodeUtils->runcmd( "/usr/bin/stopcondresp NodeFullInstallComplete GatherKRB5keytabs", -1);
	}
}
