#!/bin/sh
###############################################################################
# Authorization utility for IBM i
#
# Copyright IBM Corp. 2012
# The source code for this program is not published or other-
# wise divested of its trade secrets, irrespective of what has
# been deposited with the U.S. Copyright Office.
# 
# ----------------------------------------------------------------------------
#
# 

usage() {
  echo ""
  echo "Usage: $0"
  echo "  --rolename        server"
  echo "  --userprofilename user_profile_name [options] "
  echo ""
  echo "Options:"
  echo "  --userdir wlp_usr_dir"
  echo "  --outputdir wlp_output_dir"
  echo ""
  echo ""
  echo "You must have *ALLOBJ special permission, own or have *OBJMGT authority" 
  echo "to all objects in the specified directory subtrees to use the GRANTAUTH"
  echo "command."
  exit 1
}

##
## isMemberNoCase: Case insensitive check for $1 in the list comprising the rest
## of the args. The result is set in isMemberNoCaseResult.
isMemberNoCase() {
  isMemberNoCaseResult=
  key=$1
  shift
  arglist=$@
  for string in $arglist
  do
    if [ ${#string} -eq ${#key} ] && [ `echo "${string}" | grep -i "${key}"` ]; then
      isMemberNoCaseResult=true; break
    fi
  done 
}

##
## set_wlp_install_dir: set WLP_INSTALL_DIR
set_wlp_install_dir() {
        CUR_DIR=`pwd`
        WLP_DIR=`dirname ${0}`/../../../../
        cd "${WLP_DIR}"
        WLP_INSTALL_DIR=`pwd`
        cd "${CUR_DIR}"
}


##
## readServerEnv: Read server.env file and export environment variables.
readServerEnv()
{
  if [ -f "$1" ]; then
    while read -r line; do
      case $line in
      \#*);;
      *=*)
        # Only accept alphanumeric variable names to avoid eval complexities.
        if var=`echo "$line" | sed -e 's/^\([a-zA-Z0-9_][a-zA-Z0-9_]*\)=.*/\1/'`; then
          value=\'`echo "$line" | sed -e 's/[^=]*=//' -e s/\'/\'\"\'\"\'/g`\'
          eval "$var=$value; export $var"
        fi
      esac
    done < "$1"
  fi
}

##
## installEnvDefaults: Set variable defaults for a non-server or nonexistent
##                     server command.
installEnvDefaults()
{
  readServerEnv "${WLP_INSTALL_DIR}/etc/default.env"

  if [ -z "${WLP_USER_DIR}" ]
  then
    if [ -z "${WLP_DEFAULT_USER_DIR}" ]
    then
      WLP_DEFAULT_USER_DIR=${WLP_INSTALL_DIR}/usr
    fi
    WLP_USER_DIR=${WLP_DEFAULT_USER_DIR}
  fi

  if [ -z "${WLP_OUTPUT_DIR}" ]
  then
    if [ -z "${WLP_DEFAULT_OUTPUT_DIR}" ]
    then
      WLP_DEFAULT_OUTPUT_DIR=${WLP_USER_DIR}/servers
    fi
    WLP_OUTPUT_DIR=${WLP_DEFAULT_OUTPUT_DIR}
  fi

}


##
## grantDirAllRX: Grant read only permission to the uid for the user directory
## $1 is the uid
## $2 is the directory
grantDirAllRX() {
  chmod o= ${2} 
  if [ $? != 0 ]; then
    echo "Error: Failed to grant *PUBLIC *EXCLUDE authority to ${2}."
    ERR_CHK=1
  else 
    echo "Granted *PUBLIC *EXCLUDE authority to ${2}."
  fi
  system "CHGAUT OBJ('${2}') USER(${1}) DTAAUT(*RX) OBJAUT(*NONE) SUBTREE(*ALL)"
  if [ $? = 0 ]; then
    echo "Granted explicit *RX authority to user ${1} on all objects in directory ${2}."
  else
    echo "Error: Failed to grant explicit *RX authority to user ${1} on all objects in directory ${2}."
    ERR_CHK=1
  fi
}

##
## grantDirAllRWX: Grant read, write and execute permission to uid for the directory
## $1 is the uid
## $2 is the directory
grantDirAllRWX() {
  chmod o= ${2}
  if [ $? != 0 ]; then
    echo "Error: Failed to grant *PUBLIC *EXCLUDE authority to ${2}."
    ERR_CHK=1
  else 
    echo "Granted *PUBLIC *EXCLUDE authority to ${2}."
  fi
  chown -R $1 $2
  if [ $? = 0 ]; then
    echo "Changed ownership of all objects in directory ${2} to ${1}."
  else
    echo "Error: Failed to change ownership of all objects in directory ${2} to ${1}."
    ERR_CHK=1
  fi
#  if [ -e ${2}/servers/.classCache ]; then
#    rm -R ${2}/servers/.classCache
#  fi
}

##
## grantServerAuthOutputDirServers: Grant the server role to the uid for output directories
## configured in servers/*/server.env
## $1 is the uid
## $2 is the default user directory
## $3 is the defalut output directory
grantServerAuthOutputDirServers() {
  if [ -d ${2}/servers ]; then
    FILENAMES=$(ls ${2}/servers)
    for SERVERNAME in $FILENAMES
    do
      WLP_OUTPUT_DIR=$3
      readServerEnv ${2}/servers/${SERVERNAME}/server.env
      isMemberNoCase ${WLP_OUTPUT_DIR} ${OUTPUT_DIR_NAMES}
      if [ ! ${isMemberNoCaseResult} ]; then 
        OUTPUT_DIR_NAMES="${OUTPUT_DIR_NAMES} ${WLP_OUTPUT_DIR}"
        grantDirAllRWX ${1} ${WLP_OUTPUT_DIR}
      fi
    done
  fi
}

##
## grantServerAuthUserDirAll: Grant the server role to the uid for output directories
## configured in servers/*/server.env and *RX or *RWX to the user directory depending
## on whether all servers have output directories defined for them.
## $1 is the uid
## $2 is the user directory
grantServerAuthUserDirAll() {
  WLP_USER_DIR=$2
  WLP_OUTPUT_DIR=${2}/servers
  grantDirAllRX $1 ${WLP_USER_DIR}
  OUTPUT_DIR_NAMES=
  grantServerAuthOutputDirServers $1 $2 ${WLP_OUTPUT_DIR}
}


##
## grantServerAuthAll: Grant the server role to the uid for the user and output directories
## belonging to this installation
## $1 is the uid
grantServerAuthAll() {
  readServerEnv ${WLP_INSTALL_DIR}/etc/server.env
  installEnvDefaults
  grantDirAllRX $1 ${WLP_USER_DIR}
  grantDirAllRWX ${1} ${WLP_OUTPUT_DIR}
  OUTPUT_DIR_NAMES=${WLP_OUTPUT_DIR}
  grantServerAuthOutputDirServers ${1} ${WLP_USER_DIR} ${WLP_OUTPUT_DIR}
}

if [ "`uname`" != "OS400" ]; then
  echo "The $0 command is supported only for IBM i."
  exit 1
fi

WLPUSERDIR=
WLPOUTPUTDIR=
ROLENAME=
USERPROFILENAME=

while [ $# -gt 0 ]; do
  case $1 in
    '--userdir') if [ $# -gt 1 ]; then
	WLPUSERDIR=$2;shift
      fi
    ;;
    '--outputdir') if [ $# -gt 1 ]; then
	WLPOUTPUTDIR=$2;shift
      fi
    ;;
    '--rolename') if [ $# -gt 1 ]; then
        ROLENAME=$2;shift
        if [ ${ROLENAME} != "server" ]; then
          usage
        fi
      fi
    ;;
    '--userprofilename') if [ $# -gt 1 ]; then
        USERPROFILENAME=$2;shift
      fi
    ;;
    *) usage
    ;;
  esac
  shift
done

if [ ! ${ROLENAME} ] || [ ! ${USERPROFILENAME} ]; then
  usage
fi

ERR_CHK=0
set_wlp_install_dir

OUTPUT_DIR_NAMES=
if [ ! ${WLPUSERDIR} ] && [ ! ${WLPOUTPUTDIR} ]; then
  grantServerAuthAll ${USERPROFILENAME} 
fi
if [ ${WLPUSERDIR} ]; then
  grantServerAuthUserDirAll ${USERPROFILENAME} ${WLPUSERDIR}
fi
if [ ${WLPOUTPUTDIR} ]; then
  grantDirAllRWX ${USERPROFILENAME} ${WLPOUTPUTDIR}
fi

exit ${ERR_CHK}