#!/usr/bin/perl
# IBM_PROLOG_BEGIN_TAG 
# This is an automatically generated prolog. 
#  
#  
#  
# Licensed Materials - Property of IBM 
#  
# (C) COPYRIGHT International Business Machines Corp. 2004,2019 
# 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 
# sccsid = "@(#)57   1.13   src/rsct/rm/LPRM/cli/bin/chlpracl.perl, LPRM, rsct_rady, rady2035a 11/12/15 16:38:28"
######################################################################
#                                                                    #
# Module: chlpracl                                                   #
#                                                                    #
# Purpose:                                                           #
#   chlpracl  - Change the access controls for an LPRM resource.     #
#                                                                    #
# Syntax:                                                            #
#   To add one or more accesses to an LPRM Resource ACL:             #
#   chlpracl [-a|-n host1[,host2,...]|-r] [-o] [-h] [-TV] Name       #
#   Id Perm [Id Perm ...]                                            #
#                                                                    #
#   To add one or more accesses to an LPRM Resource ACL using the    #
#   same permissions:                                                #
#   chlpracl [-a|-n host1[,host2,...]|-r] -l [-o] [-h] [-TV]  Name   #
#   Id [Id...] Perm                                                  #
#                                                                    #
#   To delete one or more accesses from an LPRM Resource ACL:        #
#   chlpracl [-a|-n host1[,host2,...]|-r] -d [-h] [-TV] Name Id      #
#   [Id...]                                                          #
#                                                                    #
#   To add or delete accesses to an LPRM Resource ACL with the       #
#   accesses specified in a file:                                    #
#   chlpracl [-a|-n host1[,host2,...]] [-o|-d] -f File_name [-h]     #
#   [-TV]                                                            # 
#                                                                    #
#   To set an LPRM Resource ACL to use the Resource Shared ACL, or   #
#   to deny all accesses:                                            #
#   chlpracl [-a|-n host1[,host2,...]|-r] {-b|-x} [-h] [-TV] Name    #
#                                                                    #
#   To set all of the LPRM Resource ACLs to use the Resource Shared  #
#   ACL, or to deny all accesses:                                    #
#   chlpracl [-a|-n host1[,host2,...]] {-B|-X} [-h] [-TV]            #
#                                                                    #
#                                                                    #
# Flags:                                                             #
#   -a      Changes the LPRM Resource ACLs on all nodes in the       #
#           domain.                                                  #
#   -d      The ACL entry for the Id specified is deleted from the   #
#           LPRM Resource ACL.                                       #
#   -f      The accesses are specified in a file. Each line of the   #
#           file will be a resource name, an id and permission for   #
#           that ID.  If -d is used with -f, only the name and id is #
#           used.  Anything else is ignored.                         #
#   -b      Sets the LPRM Resource ACL to use the Resource Shared    # 
#           ACL.                                                     #
#   -B      Sets all LPRM Resource ACLs to use the Resource Shared   # 
#           ACL.                                                     #
#   -l      There is a list of Ids followed by a single permission.  #
#   -n host1[,host2,...]                                             #
#           Changes the LPRM Resource ACLs on the nodes specified in #
#           the domain.                                              #
#   -o      Overwrite any existing ACL entries.                      #
#   -r      The Name parameter is a resource handle.                 #
#   -x      Sets the LPRM Resource ACL to deny all accesses.         #
#   -X      Sets all LPRM Resource ACLs to deny all accesses.        #
#   -h      Help. Writes the command's usage statement to standard   #
#           output.                                                  #
#   -T      Trace. Writes the command's trace messages to standard   #
#           error. For your software-service organization's use only.#
#   -V      Verbose. Writes the command's verbose messages to        #
#           standard output.                                         #
#                                                                    #
# Parameters:                                                        #
#   Name    Name of the LPRM resource.                               #
#   Id      The network identity of the user.                        #
#   Perm    The permission the ID is to have.                        #
#                                                                    #
# Description:                                                       #
#   The chlpracl command changes the ACL associated with an LPRM     #
#   resource.  This command allows an access to be added to or       #
#   deleted from an LPRM Resource ACL.  The LPRM Resource ACL        #
#   controls access to resource operations.
#                                                                    #
# Exit Values:                                                       #
#   0  LPRM_CLI_SUCCESS      Command completed successfully.         #
#   1  LPRM_CLI_RMC_ERROR    Command terminated due to an underlying #
#                            RMC error.                              #
#   2  LPRM_CLI_ERROR        Command terminated due to an underlying #
#                            error in the command script.            #
#   3  LPRM_CLI_BAD_FLAG     Command terminated due to user          #
#                            specifying an invalid flag.             #
#   4  LPRM_CLI_BAD_OPERAND  Command terminated due to user          #
#                            specifying a bad operand.               #
#   5  LPRM_CLI_USER_ERROR   Command terminated due to a user error, #
#                            for example specifying a name that      #
#                            already exists.                         #
#                                                                    #
# Examples:                                                          #
#   1. To allow user joe on nodeA to have write permission to the    #
#      LPRM resource named Think_1 run on nodeA:                     #
#      chlpracl Think_1 joe@LOCALHOST w                              #
#                                                                    #
# Man Page:                                                          #
#   For the most current detailed description of this command see    #
#   the chlpracl man page in /opt/rsct/man.                     #
#                                                                    #
#--------------------------------------------------------------------#
# Inputs:                                                            #
#   /opt/rsct/msgmaps/lprmcli.lslpriacl.map  -                  # 
#       message mapping                                              #
#                                                                    #
# Outputs:                                                           #
#   stdout - none.                                                   #
#   stderr - any error message.                                      #
#                                                                    #
# External Ref:                                                      #
#   Commands: ctdspmsg                                               #
#   Modules:  LPRM_cli_utils.pm, LPRM_cli_rc.pm,                     #
#             LPRM_cli_include.pm, CT_cli_utils.pm                   #
#   Perl library routines: Getopt::Std                               #
#                                                                    #
# Tab Settings:                                                      #
#   4 and tabs should be expanded to spaces before saving this file. #
#   in vi:  (:set ts=4  and   :%!expand -4)                          #
#                                                                    #
# Change Activity:                                                   #
#   050105 JAC 112254: Initial design & write.                       #
#   050128 JAC 117280: Fix for -l not working.                       #
#   050128 JAC 117199: Display error when no parameters specified.   #
#   050203 JAC 117535: Change call to process_api_error.             #
#   050210 JAC 117760: Don't allow -o and -d.                        #
#   050220 JAC 118098: Fix message typo.                             #
#   050222 JAC 118184: Fix another message typo.                     #
#   050224 JAC 118185: Correct some input checking.                  #
#   050303 JAC 118168: Put quotes around node names for select_str.  #
#   050304 JAC 118242: Add -r to mean Name is a resource handle.     #
#   071028 JAC 146726: set delimiters for calling -api commands.     #
######################################################################

#--------------------------------------------------------------------#
# General Program Flow/Logic:                                        #
#                                                                    #
# 1. Parse command line flags and operands.                          #
# 2. Print usage if -h specified.                                    #
# 3. Set the appropriate management scope.                           #
# 4. Call RMC command chrsrcacl. Also pass along -VT if necessary.   #
# 5. Return back any errors.                                         #
#                                                                    #
#--------------------------------------------------------------------#

#--------------------------------------------------------------------#
# Included Libraries and Extensions                                  #
#--------------------------------------------------------------------#
use lib "/opt/rsct/pm";
use locale;
use Getopt::Std;

use CT_cli_utils qw(printIMsg
                    printEMsg);

use LPRM_cli_rc qw(LPRM_CLI_SUCCESS LPRM_CLI_RMC_ERROR
                   LPRM_CLI_ERROR LPRM_CLI_BAD_FLAG
                   LPRM_CLI_BAD_OPERAND LPRM_CLI_USER_ERROR);
use LPRM_cli_utils qw(error_exit
                      printCIMsg
                      printCEMsg
                      process_api_error
                      process_exit_code
                      get_names_ids_perms_from_file
                      get_names_ids_from_file
                      ispermvalid);
use LPRM_cli_include qw($TRUE $FALSE
                       $RMC_LOCAL_SCOPE $RMC_LOCAL2_SCOPE
                       $RMC_DM_SR_LOCAL_SCOPE
                       $DELIMITERI $DELIMITERO
                       $CTBINDIR $CTDIR);

#--------------------------------------------------------------------#
# Global Variables                                                   #
#--------------------------------------------------------------------#
$Trace = $FALSE;                        # default - trace off
$Verbose = $FALSE;                      # default - verbose turned off

$Opt_Deny = $FALSE;                     # default - no deny access
$Opt_DenyAll = $FALSE;                  # default - no deny all access
$Opt_AllNodes = $FALSE;                 # default - not all nodes      
$Opt_NodeList = $FALSE;                 # default - not node list       
$Opt_NameIsRH = $FALSE;                 # default - no RH
$Opt_Overwrite = $FALSE;                # default - no overwrite
$Opt_IDlist = $FALSE;			# default - not ID ID Perm 
$Opt_Delete = $FALSE;			# default - not delete
$Opt_Filename = $FALSE;         	# default - no filename
$Opt_Shared = $FALSE;           	# default - no shared acl used 
$Opt_SharedAll = $FALSE;           	# default - no shared acl used all

$PROGNAME = "chlpracl";                # Program Name for messages
$LSMSG = "$CTBINDIR/ctdspmsg";          # list / display message rtn
$MSGCAT = "lprmcli.cat";                # msg catalogue for this cmd
$ENV{'MSGMAPPATH'} = "$CTDIR/msgmaps";  # msg maps used by $LSMSG

#--------------------------------------------------------------------#
# Variables                                                          #
#--------------------------------------------------------------------#
my @parameters = ();                    # input parameters 
my $node_list = "";                     # node list from -n
my $select_node_list = "";              # node list for select string
my $file_name = "";                     # file name from -f
my $id = "";                            # user id
my $perm = "";                          # user permission
my $cmd_opts = "";                      # chrsrcacl-api options
my $cmd_parms = "";                     # chrsrcacl-api parameters
my @cmd_out = ();                       # chrsrcacl-api output
my $select_str = "";                    # select string + node list
my $prev_resource_name = "";            # name of resource to change
my $resource_name = "";                 # name of resource to change
$names_from_file = "";                  # array of names from file
$ids_from_file = "";                    # array of ids from file
$perms_from_file = "";                  # array of permissions from file
$cmd_str =  "";                         # stores command specification

my $i = 0;                              # loop counter

#--------------------------------------------------------------------#
# Main Code                                                          #
#--------------------------------------------------------------------#
my $rc = 0;

# parse the command line, exit if there are errors 
($rc, $node_list, $file_name, @parameters) = &parse_cmd_line;
($rc == 0) || error_exit($rc);

if ($Verbose) { printIMsg("IMsgchlpraclStart"); }

if ($Trace) { $cmd_opts = $cmd_opts." -T"; }
if ($Verbose) { $cmd_opts = $cmd_opts." -V"; }

if ($Verbose) { printIMsg("IMsgchlpraclSetScope"); }

# if -a, -n, and -r were not specified, set local RMC scope
if ( (!$Opt_AllNodes) && (!$Opt_NodeList) && (!$Opt_NameIsRH) ) {
   $ENV{CT_MANAGEMENT_SCOPE} = $RMC_LOCAL_SCOPE;
}
# set DM/SR scope is scope is not set
else {

   # if CT_MANAGEMENT_SCOPE is not defined, set it to 4 for DM/SR/Local scope
   if (!defined $ENV{CT_MANAGEMENT_SCOPE}) {
      $ENV{CT_MANAGEMENT_SCOPE} = $RMC_DM_SR_LOCAL_SCOPE;
   }

   # if it's defined, it shouldn't be local.  If it's local, set it
   # to 4 for DM/SR/Local scope
   else {
      if ($ENV{CT_MANAGEMENT_SCOPE} == $RMC_LOCAL_SCOPE ||
          $ENV{CT_MANAGEMENT_SCOPE} == $RMC_LOCAL2_SCOPE) {
             $ENV{CT_MANAGEMENT_SCOPE} = $RMC_DM_SR_LOCAL_SCOPE;
      }
   }
}

if ($Verbose) { printIMsg("IMsgchlpraclProcessOptions"); }

# process the command
# if it's not file input, set up the call to chrsrcacl-api
if (!$Opt_Filename) {

   # if -X or -B is used, the differnt syntax for chrsrcacl-api is needed
   if ($Opt_SharedAll || $Opt_DenyAll) { 

      # set use Resource Shared ACL for all resources -B specified
      if ($Opt_SharedAll) { $cmd_opts = $cmd_opts . " -S "; }

      # set deny access for all resources if -X specified
      if ($Opt_DenyAll) { $cmd_opts = $cmd_opts . " -X "; }

      # set up the selection string to get all Names and the right nodes
      if ($Opt_NodeList) { 
         # quote the node names
         $select_node_list = $node_list;
         $select_node_list = "'" . $select_node_list . "'";
         $select_node_list =~ s/,/','/g;
         $select_str = "(Name like '%')&&(NodeNameList|<{$select_node_list})"
      }
      else {
         $select_str = "(Name like '%')";
      }

      # call chrsrcacl-api
      if ($Verbose) { printIMsg("IMsgchlpraclModifyAcl"); }
      if ($Trace) { print STDERR "$PROGNAME: calling chrsrcacl-api\n";}

      @cmd_out=`$CTBINDIR/chrsrcacl-api $cmd_opts -I ${DELIMITERI} -D ${DELIMITERO} -s "IBM.LPCommands${DELIMITERI}${select_str}" 2>&1`;
   } # end of if -X or -B 

   # if it's an change to a single resource acl
   else { 

      # set use Resource Shared ACL for resource -b specified
      if ($Opt_Shared) { $cmd_opts = $cmd_opts . " -S "; }

      # set deny access for resource if -x specified
      if ($Opt_Deny) { $cmd_opts = $cmd_opts . " -X "; }

      # use over-write if -o specified
      if ($Opt_Overwrite) { $cmd_opts = $cmd_opts . " -O "; }

      # get the resource name from the input parameters
      # (it might be a RH (-r specified)
      $resource_name = shift(@parameters);

      # build id/permission string
      if ($Opt_Delete) {
         # build list of ids with 'Z' permission for delete
         foreach $id (@parameters) {
            chomp($id);
            $cmd_parms = $cmd_parms . $DELIMITERI . $id . $DELIMITERI . "Z";
         }
      }

      elsif ($Opt_IDlist){
         # build list using last one as permission
         $perm = $parameters[$#parameters];

         # is it a valid permission
         $rc = ispermvalid($perm);
         if ($rc !=0) {
            printCEMsg("EMsgLPRMcliBadPerm",$perm);
            exit(LPRM_CLI_USER_ERROR);
         }

         # form id/perm list
         for ($i=0; $i<$#parameters; $i++) { 
            $id = $parameters[$i];
            chomp($id);
            $cmd_parms = $cmd_parms . $DELIMITERI . $id . $DELIMITERI . $perm;
         }
      }

      else {  # it's a id/perm repeating list
         # must be an even number of parameters (remember 0 origin)
         if (($#parameters % 2) == 0) {
            printCEMsg("EMsgLPRMcliBadIdPermList");
            exit(LPRM_CLI_USER_ERROR);
         }

         # form id/perm list
         for ($i=0; $i<=$#parameters; $i=$i+2) { 
            $id = $parameters[$i];
            chomp($id);
            $perm = $parameters[$i+1];
            chomp($perm);

            # is it a valid permission
            $rc = ispermvalid($perm);
            if ($rc !=0) {
               printCEMsg("EMsgLPRMcliBadPerm",$perm);
               exit(LPRM_CLI_USER_ERROR);
            }
            $cmd_parms = $cmd_parms . $DELIMITERI . $id . $DELIMITERI . $perm;
         }
      }

      # call chrsrcacl-api
      if ($Verbose) { printIMsg("IMsgchlpraclModifyAcl"); }
      if ($Trace) { print STDERR "$PROGNAME: calling chrsrcacl-api\n";}

      # if -r specified, use RH format
      if ( $Opt_NameIsRH ) {
         @cmd_out=`$CTBINDIR/chrsrcacl-api $cmd_opts -I ${DELIMITERI} -D ${DELIMITERO} -r "${resource_name}"${cmd_parms} 2>&1`;
      }
      else {
         @cmd_out=`$CTBINDIR/chrsrcacl-api $cmd_opts -I ${DELIMITERI} -D ${DELIMITERO} -o IBM.LPCommands${DELIMITERI}${resource_name}${DELIMITERI}${node_list}${cmd_parms} 2>&1`;
      }

   } # end of it's a single resource ACL change
} # end of it's not a file

# else it's file input
else {
   if ($Verbose) { printIMsg("IMsgchlpraclProcessFileInput"); }

   # get the names, ids, and permissions from the file
   if ($Opt_Delete) {
      ($names_from_file, $ids_from_file) = get_names_ids_from_file($file_name);
   }
   else {
      ($names_from_file, $ids_from_file, $perms_from_file) = get_names_ids_perms_from_file($file_name);
   }

   # form chrsrcacl-api command(s)
   if ( $#$names_from_file >= 0 ) {

      # get the initial values to give the command
      $resource_name = $$names_from_file[0];
      $prev_resource_name = $resource_name;
      $id = $$ids_from_file[0];

      if ($Opt_Delete) { $perm = "Z"; }
      else { $perm = $$perms_from_file[0]; }
 
      # first go through for the command 
      $cmd_str = " -I ${DELIMITERI} -D ${DELIMITERO} -o IBM.LPCommands${DELIMITERI}${resource_name}${DELIMITERI}${node_list}${DELIMITERI}${id}${DELIMITERI}${perm}";

      # go through the rest of the stuff from the file
      for ($i=1; $i<=$#$names_from_file; $i++) {

         # get the next values to give the command
         $resource_name = $$names_from_file[$i];
         $id = $$ids_from_file[$i];

         if ($Opt_Delete) { $perm = "Z"; }
         else { $perm = $$perms_from_file[$i]; }

         # add to this previous command or create a new one
         if ($resource_name eq $prev_resource_name) {
            $cmd_str = $cmd_str . "${DELIMITERI}${id}${DELIMITERI}${perm}";
         }
         else {
            $prev_resource_name = $resource_name;
            $cmd_str = $cmd_str . "  -o IBM.LPCommands${DELIMITERI}${resource_name}${DELIMITERI}${node_list}${DELIMITERI}${id}${DELIMITERI}${perm}";
         }
      } # end for loop 

      # call chrsrcacl-api
      if ($Verbose) { printIMsg("IMsgchlpraclModifyAcl"); }
      if ($Trace) { print STDERR "$PROGNAME: calling chrsrcacl-api\n";}

      @cmd_out=`$CTBINDIR/chrsrcacl-api $cmd_opts $cmd_str 2>&1`;
   } # end if there are names to process (from the file)
   else {

      printCEMsg("EMsgLPRMcliInputFileHasNoData",$file_name);
      exit(LPRM_CLI_USER_ERROR);
   }
}

# process the result from previous chrsrcacl-api calls
# capture the return code from chrsrcacl-api
$rc = $?;
$rc = process_exit_code($rc);

if ($Trace) { print STDERR "chrsrcacl-api results:\n";
              print STDERR "@cmd_out";}

if ($Trace) { print STDERR "$PROGNAME: chrsrcacl-api returned $rc\n";}

if ($Verbose) { printIMsg("IMsgchlpraclProcessErrors"); }

# show any errors if there was a bad rc
if ($rc != 0) {
   process_api_error($DELIMITERO,$rc,@cmd_out);
}

if ($Verbose) { printIMsg("IMsgchlpraclEnd"); }

exit($rc); 

#--------------------------------------------------------------------#
# End Main Code                                                      #
#--------------------------------------------------------------------#


#--------------------------------------------------------------------#
# parse_cmd_line - Parse the command line for options and operands.  #
#   Set appropriate global variables as outlined below, make sure we #
#   have a valid combination of arguments / options.                 #
#                                                                    #
# Return:                                                            #
#   $rc   0                  Command line parsed fine, no problem.   #
#         LPRM_CLI_BAD_FLAG  Command line contained a bad flag.      #
#   $parameters              Resource name and/or list of ids and    #
#                            permissions.                            #
#   $node_list               List of nodes for -n.                   #
#   $file_name               File name for -f.                       #
#                                                                    #
# Global Variables Modified:                                         #
#   $Verbose           output   True (-V) turn Verbose mode on.      #
#   $Trace             output   True (-T) turn Trace mode on.        #
#   $Opt_Deny          output   True (-x) deny access specified.     #
#   $Opt_DenyAll       output   True (-X) deny access all resources. #
#   $Opt_Shared        output   True (-b) use shared acl.            #
#   $Opt_SharedAll     output   True (-B) all use shared acl.        #
#   $Opt_AllNodes      output   True (-a) all nodes specified.       #
#   $Opt_NodeList      output   True (-n) nodes listed.              #
#   $Opt_Overwrite     output   True (-o) overwrite specified.       #
#   $Opt_NameIsRH      output   True (-r) Name is RH specified.      #
#   $Opt_IDlist        output   True (-l) multi Ids w/1 permission.  #
#   $Opt_Delete        output   True (-d) delete specified.          #
#   $Opt_Filename      output   True (-f) filename specified.        #
#--------------------------------------------------------------------#
sub parse_cmd_line 
{
my(@original_argv) = @ARGV;
my @parameters = ();                    # Ids/permission list
my $node_list = "";                     # nodes for -n 
my $file_name = "";                     # file name for -f  
my %opts = ();

# Process the command line...
if (!&getopts('abBdf:hln:orxXTV', \%opts)) {  # Gather options; 
                                        # if errors
    &print_usage;                       # display proper usage
    return LPRM_CLI_BAD_FLAG;           # return bad rc - bad flag 
}

# process h flag
if (defined $opts{h}) {                 # -h, help request
    &print_usage;                       # print usage statement
    exit(0);                            # all done with good return!
}

if (defined $opts{T}) {                 # -T turn trace on
    $Trace = $TRUE;
}

if (defined $opts{V}) {                 # -V turn verbose mode on
    $Verbose = $TRUE;
}

if (defined $opts{a}) {                 # -a for all nodes in domain
    $Opt_AllNodes = $TRUE;              # -a flag specified
}

if (defined $opts{n}) {                 # -n for list of nodes
    # error if -a is specified
    if ($Opt_AllNodes) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-a","-n");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    $Opt_NodeList = $TRUE;              # -n flag specified
    $node_list = $opts{n};
}

if (defined $opts{r}) {                 # -r for Name is a RH
    # error if -a is specified
    if ($Opt_AllNodes) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-a","-r");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -n is specified
    if ($Opt_NodeList) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-n","-r");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    $Opt_NameIsRH = $TRUE;              # -r flag specified
}

if (defined $opts{d}) {                 # -d to delete access
    $Opt_Delete = $TRUE;                # -d flag specified
}

if (defined $opts{f}) {                 # -f for file input
    # error if -r is specified
    if ($Opt_NameIsRH) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-r","-f");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    if ($#ARGV >=0) {                   # can't have parameters for -f
       printCEMsg("EMsgLPRMcliInvalidNumberOfOperands");
       &print_usage;
       return LPRM_CLI_BAD_OPERAND;
    }
    $Opt_Filename = $TRUE;              # -f flag specified
    $file_name = $opts{f};
}

if (defined $opts{l}) {                 # -l for list of Ids
    # error if -d is specified
    if ($Opt_Delete) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-l","-d");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -f is specified
    if ($Opt_Filename) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-l","-f");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    $Opt_IDlist = $TRUE;                # -l flag specified
}

if (defined $opts{o}) {                 # -o to overwrite access
    # error if -d is specified
    if ($Opt_Delete) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-o","-d");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    $Opt_Overwrite = $TRUE;             # -o flag specified
}

if (defined $opts{x}) {                 # -x for deny access
    if ($#ARGV !=0) {                   # need only a name for -x
       printCEMsg("EMsgLPRMcliInvalidNumberOfOperands");
       &print_usage;
       return LPRM_CLI_BAD_OPERAND;
    }
    # error if -d is specified
    if ($Opt_Delete) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-x","-d");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -f is specified
    if ($Opt_Filename) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-x","-f");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -l is specified
    if ($Opt_IDlist) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-x","-l");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    $Opt_Deny = $TRUE;                  # -x flag specified
}

if (defined $opts{b}) {                 # -b to use shared acl
    if ($#ARGV !=0) {                   # need only a name for -b
       printCEMsg("EMsgLPRMcliInvalidNumberOfOperands");
       &print_usage;
       return LPRM_CLI_BAD_OPERAND;
    }
    # error if -d is specified
    if ($Opt_Delete) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-b","-d");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -f is specified
    if ($Opt_Filename) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-b","-f");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -l is specified
    if ($Opt_IDlist) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-b","-l");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -x is specified
    if ($Opt_Deny) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-b","-x");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    $Opt_Shared = $TRUE;                   # -b flag specified
}

if (defined $opts{X}) {                 # -X to deny access to all
    if ($#ARGV >=0) {                   # no parameters for -X
       printCEMsg("EMsgLPRMcliInvalidNumberOfOperands");
       &print_usage;
       return LPRM_CLI_BAD_OPERAND;
    }
    # error if -d is specified
    if ($Opt_Delete) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-X","-d");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -f is specified
    if ($Opt_Filename) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-X","-f");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -l is specified
    if ($Opt_IDlist) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-X","-l");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -x is specified
    if ($Opt_Deny) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-X","-x");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -i is specified
    if ($Opt_Shared) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-X","-b");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -r is specified
    if ($Opt_NameIsRH) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-X","-r");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    $Opt_DenyAll = $TRUE;               # -X flag specified
}

if (defined $opts{B}) {                 # -B to have all use shared acl
    if ($#ARGV >=0) {                   # no parameters for -B
       printCEMsg("EMsgLPRMcliInvalidNumberOfOperands");
       &print_usage;
       return LPRM_CLI_BAD_OPERAND;
    }
    # error if -d is specified
    if ($Opt_Delete) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-B","-d");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -f is specified
    if ($Opt_Filename) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-B","-f");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -l is specified
    if ($Opt_IDlist) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-B","-l");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -x is specified
    if ($Opt_Deny) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-B","-x");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -b is specified
    if ($Opt_Shared) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-B","-b");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -X is specified
    if ($Opt_DenyAll) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-B","-X");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    # error if -r is specified
    if ($Opt_NameIsRH) {
       printCEMsg("EMsgLPRMcliImproperUsageCombination","-B","-r");
       &print_usage;
       return LPRM_CLI_BAD_FLAG;
    }
    $Opt_SharedAll = $TRUE;             # -I flag specified
}


# Get the arguments...
# Operands:  Name or Name followed by Id perm Id perm OR Id Id perm
if ($#ARGV >= 0) {                      # Name and Ids and perms
   # if -d used, must be at least 2 arguments for Name ID
   if ( $Opt_Delete ) {
      if (! ($#ARGV >= 1 )) {
         printCEMsg("EMsgLPRMcliInvalidNumberOfOperands");
         &print_usage;
         return LPRM_CLI_BAD_OPERAND;
      }
      @parameters = @ARGV;                 # get them all
   }
   # if -x or -b used, Name is required (only)
   elsif ( $Opt_Deny || $Opt_Shared ) {
      if (! ($#ARGV == 0) ) {
         printCEMsg("EMsgLPRMcliInvalidNumberOfOperands");
         &print_usage;
         return LPRM_CLI_BAD_OPERAND;
      }
      @parameters = @ARGV;                 # get them all
   }
   # else there must be at least 3 arguments
   elsif ( $#ARGV <= 1 ) {
      printCEMsg("EMsgLPRMcliInvalidNumberOfOperands");
      &print_usage;
      return LPRM_CLI_BAD_OPERAND;
   }
   else {
      @parameters = @ARGV;                 # get them all
   }
}
else {
   # if no args, display error unless -f|-B|-X used
   if (! ($Opt_DenyAll || $Opt_Filename || $Opt_SharedAll) ) {
      printCEMsg("EMsgLPRMcliInvalidNumberOfOperands");
      &print_usage;
      return LPRM_CLI_BAD_OPERAND;
   }
}

return(0, $node_list, $file_name, @parameters);     # success

}   # end parse_cmd_line


#--------------------------------------------------------------------#
# print_usage : print the usage statement (syntax) to stdout.        #
#--------------------------------------------------------------------#
sub print_usage
{
&printIMsg("IMsgchlpraclUsage");
}   # end print_usage