##############################################################################
# Copyright (c) Members of the EGEE Collaboration. 2004.
# See http://www.eu-egee.org/partners/ for details on the copyright
# holders.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
#    http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS
# OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##############################################################################
#
# NAME :        config_glexec_wn
#
# DESCRIPTION : This function configures glexec in the WN.
#               There are two possible operation modes:
#                 - setuid -> identity change actually happens
#                 - logging only -> there's no identity change
#               This function is called by the WN and the TAR WN. Some
#               extra configuration is needed for the TAR WN.
#
# AUTHORS :     Maria.Alandes.Pradillo@cern.ch
#
# NOTES :       - glexec needs user and group 'glexec' to exist. 
#               - setuid programs ignore LD_LIBRARY_PATH and ldconfig 
#                 should be used. This is done in WN but for the TAR WN 
#                 it has to be added in this function. 
#
# YAIM MODULE:  glite-yaim-clients
#
##############################################################################

config_glexec_wn_check () {

  requires $1 VOS GLEXEC_WN_OPMODE X509_VOMS_DIR X509_CERT_DIR GLEXEC_WN_LCASLCMAPS_LOG GLEXEC_WN_SCAS_ENABLED \
      GLEXEC_WN_LCMAPS_CONFIG USERS_CONF GLEXEC_WN_LOG_DESTINATION
  if [ $? -eq 1 ]; then
    exit 1
  fi

  if [ "x${GLEXEC_WN_LOG_DESTINATION}" == "xfile" ]; then
      # this is dead code, GLEXEC_WN_LOG_FILE is set by default
      requires $1 GLEXEC_WN_LOG_FILE
      if [ $? -eq 1 ]; then   
	  exit ${YEX_CONFIG}
      fi   
  fi

####@ Checking if the locking mechanisms do not have typos
  if [ -n "$GLEXEC_WN_TARGET_LOCK" ]; then
      check_locking_mechanism GLEXEC_WN_TARGET_LOCK
  fi
  
  if [ -n "$GLEXEC_WN_INPUT_LOCK" ]; then
      check_locking_mechanism GLEXEC_WN_INPUT_LOCK
  fi

}


config_glexec_wn_setenv () {
    yaimgridenv_set GLEXEC_LOCATION ${GLEXEC_LOCATION}
    return 0
}

# check misspellings
check_locking_mechanism() {
    eval l=\$$1
    case $l in
	flock|fcntl|disabled) ;;
	*)
	    yaimlog ERROR "Illegal value ($l) for $1; must be one of flock, fcntl, disabled"
	    exit $YEX_CONFIG
	    ;;
    esac
}

config_glexec_wn () {

# Internal variables
# This has to be glexec until a fix is done in glexec to use a different user
GLEXEC_WN_USER=glexec
GLEXEC_WN_GROUP=glexec

####@ Checking whether the SCAS support is properly specified
if [ "x${GLEXEC_WN_SCAS_ENABLED}" != "xyes" ] && [ "x${GLEXEC_WN_SCAS_ENABLED}" != "xno" ]; then
  yaimlog ERROR "GLEXEC_WN_SCAS_ENABLED is incorrect. The value should be 'yes' or 'no'. Please, check the value and define it properly."
  exit 1
fi 

####@ Checking whether the operation mode is properly specified
if [ "x${GLEXEC_WN_OPMODE}" != "xsetuid" ] && [ "x${GLEXEC_WN_OPMODE}" != "xlog-only" ]; then
  yaimlog ERROR "GLEXEC_WN_OPMODE is incorrect. The value should be 'setuid' or 'log-only'. Please, check the value and define it properly."
  exit 1
fi 


####@ Checking whether glexec is actually installed
if [ ! -f ${GLEXEC_LOCATION}/sbin/glexec ]; then
  yaimlog ERROR "${GLEXEC_LOCATION}/sbin/glexec doesn't exist. Please, make sure glexec is installed in your system"
  yestr ${YEX_NOSUCHFILE}
  yaimlog ERROR "${YERRORSTR}"
  exit ${YEX_NOSUCHFILE}
fi
chown root:${GLEXEC_WN_GROUP} ${GLEXEC_LOCATION}/sbin/glexec

if [ -f ${GLEXEC_WN_CONFIG} ]; then 
  ####@ Backing up old configuration file
  yaimlog DEBUG "Backing up old configuration file."
  mv ${GLEXEC_WN_CONFIG} ${GLEXEC_WN_CONFIG}.old 2>/dev/null
else
  # This is for the tarball
  if [ ! -d `dirname $GLEXEC_WN_CONFIG` ]; then
     mkdir -p `dirname $GLEXEC_WN_CONFIG`
  fi
  touch ${GLEXEC_WN_CONFIG}
fi

####@ Bulding the user while list that will be allowed to execute glexec
yaimlog DEBUG "Building the user white list"

# The user white list is comprised of all the pools that carry the
# pilot flag in users.conf, plus the verbatim value of 
# $GLEXEC_EXTRA_WHITELIST
userwl=""
for myvo in $VOS ; do
  # I assume pilot accounts are always pool accounts
  newuser=`users_getspecialprefix $myvo ${PILOT_JOB_FLAG} 2>/dev/null`
  if [ ! "x${newuser}" == "x" ]; then
    userwl="$userwl,.$newuser"
  fi
done

# Add GLEXEC_EXTRA_WHITELIST to the whitelist.
# The formatting is comma- or whitespace separated to
# be lenient towards admins who rather act on intuition than
# read documentation.

if [ "x${GLEXEC_EXTRA_WHITELIST}" != "x" ]; then
    # replace whitespace by commas and squeeze
    ewl=`echo -n $GLEXEC_EXTRA_WHITELIST | tr -s '[:space:]' ','`
    userwl="$userwl,$ewl"
fi

glusers=`echo $userwl | sed -e 's/^\,//g'`
if [ "x${glusers}" == "x" ]; then
  ####@ Check that pilot user accounts exist
  yaimlog WARNING "It appears there are no users in the whitelist."
  yaimlog WARNING "This means nobody can run glexec."
  yaimlog WARNING "Please, make sure you define special pool accounts" 
  yaimlog WARNING "in ${USERS_CONF} with flag *${PILOT_JOB_FLAG}*"
  yaimlog WARNING "and that the accounts are actually created in the system." 
  yaimlog WARNING "You may also add whitelist users in the GLEXEC_EXTRA_WHITELIST variable"
fi

yaimlog INFO "Generating glexec configuration file ${GLEXEC_WN_CONFIG}"
####@ Generating glexec configuration file 
cat <<EOF > ${GLEXEC_WN_CONFIG}
#
#  Glexec configuration file
#
[glexec]
silent_logging               = no
log_level                    = ${GLEXEC_WN_LOG_LEVEL}
user_white_list              = ${glusers}
linger                       = yes
user_identity_switch_by      = glexec
EOF
if [ "x$GLEXEC_WN_USE_LCAS" = "xyes" ]; then
    cat <<EOF >> ${GLEXEC_WN_CONFIG}
use_lcas                     = yes
EOF
else
    cat <<EOF >> ${GLEXEC_WN_CONFIG}
use_lcas                     = no
EOF
fi
if [ -n "$GLEXEC_WN_TARGET_LOCK" ]; then
    cat <<EOF >> ${GLEXEC_WN_CONFIG}
target_lock_mechanism        = ${GLEXEC_WN_TARGET_LOCK}
EOF
fi
if [ -n "$GLEXEC_WN_INPUT_LOCK" ]; then
    cat <<EOF >> ${GLEXEC_WN_CONFIG}
input_lock_mechanism         = ${GLEXEC_WN_INPUT_LOCK}
EOF
fi
cat <<EOF >> ${GLEXEC_WN_CONFIG}
lcmaps_db_file               = ${GLEXEC_WN_LCMAPS_CONFIG}
lcmaps_log_file              = ${GLEXEC_WN_LCASLCMAPS_LOG}
lcmaps_debug_level           = ${GLEXEC_WN_LCMAPS_DEBUG_LEVEL}
lcmaps_log_level             = ${GLEXEC_WN_LCMAPS_LOG_LEVEL}
lcmaps_get_account_policy    = glexec_get_account
lcmaps_verify_account_policy = glexec_verify_account

lcas_db_file                 = ${GLEXEC_WN_LCAS_CONFIG}
lcas_log_file                = ${GLEXEC_WN_LCASLCMAPS_LOG}
lcas_debug_level             = ${GLEXEC_WN_LCAS_DEBUG_LEVEL}
lcas_log_level               = ${GLEXEC_WN_LCAS_LOG_LEVEL}
preserve_env_variables       = no
EOF

####@ Specify the log file
yaimlog DEBUG "Specify the log file in the glexec configuration file"
if [ "x${GLEXEC_WN_LOG_DESTINATION}" == "xsyslog" ]; then
  echo "log_destination              = syslog" >> ${GLEXEC_WN_CONFIG}
else
   if [ "x${GLEXEC_WN_LOG_DESTINATION}" == "xfile" ]; then
      echo "log_destination              = file" >> ${GLEXEC_WN_CONFIG}
      echo "log_file                     = ${GLEXEC_WN_LOG_FILE}" >> ${GLEXEC_WN_CONFIG}
   else
     yaimlog ERROR "GLEXEC_WN_LOG_DESTINATION is incorrect. The value should be 'syslog' or 'file'. Please, check the value and define it properly."
     yestr ${YEX_CONFIG}
     exit ${YEX_CONFIG}
   fi
fi

####@ Setting ownership and permissions on the config file
chown root:${GLEXEC_WN_GROUP} ${GLEXEC_WN_CONFIG}
chmod 0640 ${GLEXEC_WN_CONFIG}

if [ "x${GLEXEC_WN_OPMODE}" == "xsetuid" ]; then
  ####@ Configuring setuid mode if selected
  yaimlog INFO "glexec is configured in setuid mode"
  chmod 6111 ${GLEXEC_LOCATION}/sbin/glexec
  chmod o-r ${GLEXEC_WN_CONFIG}
else
  ####@ Configure logging only mode if selected
  yaimlog INFO "glexec is configured in logging only mode"
  chmod 0555 ${GLEXEC_LOCATION}/sbin/glexec
  chmod o+r ${GLEXEC_WN_CONFIG}
fi

return 0

}

