#!/bin/sh

# Configure glexec on package installation or upgrade.
# This script is intended for use from a %postinst script, although
# it can be used at any time by the system administrator
#
# This script will configure
# /etc/lcmaps/lcmaps-glexec.db
# /etc/glexec.conf

# Synopsis:
usage() {
    cat >&2 <<EOF
Configure glexec/LCMAPS based on authorisation framework.

Usage: $0 [options] <framework> [ endpoint ... ]

Options:
 -l FILE,   --log-file         file to send logging to (default is use syslog)
 -c FILE,   --lcmaps-log-file  file to log LCMAPS messages to.
 -L {0-5},  --log-level        the level of verbosity in logging (default 3)
 -w UIDs,   --white-list       comma-separated list of users that may 
                               use glexec
 -A URI,    --pepc-actionid    the action ID to request from the ARGUS
                               framework
 -R URI,    --pepc-resourceid  the resource ID to request from the ARGUS
                               framework

For package maintainers:
 -o FILE,   --config-file      The name of the config file to write instead of
                               /etc/glexec.conf.
 -d FILE,   --lcmaps-db        The name of the LCMAPS db file, instead of
                               /etc/lcmaps/lcmaps-glexec.db

The framework is one of:
 scas  - the Site Central Authorisation System
 argus - the ARGUS framework
 local - no central authorisation

For 'scas' and 'argus' one or more endpoints are required.
EOF

}

# variables

# full path of the configuration files
lcmapsdb="/etc/lcmaps/lcmaps-glexec.db"
lcmapsdbdir=`dirname "$lcmapsdb"`
glexecconf="/etc/glexec.conf"

scasconfig() {

    sep=
    scasendpoints=
    for i in "$@" ; do
	scasendpoints="$scasendpoints$sep\" --endpoint $i\""
	sep="
             "
    done

    # Make sure the directory exists before creating the file
    test -d "$lcmapsdbdir" || mkdir -p "$lcmapsdbdir"

    cat > $lcmapsdb <<EOF
# LCMAPS config file for glexec generated by $0 on `date`

# where to look for modules
path = /usr/lib64/lcmaps

# module definitions
verify_proxy = "lcmaps_verify_proxy.mod"
               " -certdir /etc/grid-security/certificates"
               " --allow-limited-proxy"

scasclient = "lcmaps_scas_client.mod"
             " -capath /etc/grid-security/certificates"
             $scasendpoints
             " -resourcetype wn"
             " -actiontype execute-now"

# policies
glexec_get_account:
verify_proxy -> scasclient

EOF
}

argusconfig() {
    sep=
    argusendpoints=
    for i in "$@" ; do
	argusendpoints="$argusendpoints$sep\" --pep-daemon-endpoint-url $i\""
	sep="
              "
    done

    # Make sure the directory exists before creating the file
    test -d "$lcmapsdbdir" || mkdir -p "$lcmapsdbdir"

    cat > $lcmapsdb <<EOF
# LCMAPS config file for glexec generated by $0 on `date`

# where to look for modules
path = /usr/lib64/lcmaps

# module definitions
verify_proxy = "lcmaps_verify_proxy.mod"
               " -certdir /etc/grid-security/certificates"
               " --allow-limited-proxy"

pepc        = "lcmaps_c_pep.mod"
              $argusendpoints
              " -resourceid $resourceid"
              " -actionid $actionid"
              " -capath /etc/grid-security/certificates"
	      " -pep-certificate-mode implicit"

# policies
glexec_get_account:
verify_proxy -> pepc
EOF

}


localconfig() {

    # Make sure the directory exists before creating the file
    test -d "$lcmapsdbdir" || mkdir -p "$lcmapsdbdir"

    cat > $lcmapsdb <<EOF
# LCMAPS config file for glexec generated by $0 on `date`

# where to look for modules
path = /usr/lib64/lcmaps

# module definitions
verify_proxy = "lcmaps_verify_proxy.mod"
               " -certdir /etc/grid-security/certificates"
               " --allow-limited-proxy"

localaccount = "lcmaps_localaccount.mod"
               " -gridmapfile /etc/grid-security/grid-mapfile"

glexec_get_account:
verify_proxy -> localaccount

EOF
}


# Start here.

if [ $# -lt 1 ]; then
    usage
    exit 1
fi

# parse command-line options

TEMP=`getopt -o l:c:w:L:A:R:o:d: --long log-file:,lcmaps-log-file:,white-list:,log-level:,pepc-actionid:,pepc-resourceid:,config-file:,lcmaps-db: -- "$@"`

if [ $? != 0 ] ; then usage ; exit 1 ; fi

eval set -- "$TEMP"

logfile=
lclogfile=
whitelist=
loglevel=3
actionid=http://glite.org/xacml/action/execute
resourceid=http://authz-interop.org/xacml/resource/resource-type/wn

while true ; do
    case "$1" in
	-l|--log-file) 
	    logfile="$2"
	    shift 2
	    ;;
	-c|--lcmaps-log-file) 
	    lclogfile="$2"
	    shift 2
	    ;;
	-w|--white-list)
	    whitelist="$2"
	    shift 2
	    ;;
	-L|--log-level)
	    loglevel="$2"
	    shift 2
	    ;;
	-A|--pepc-actionid)
	    actionid="$2"
	    shift 2
	    ;;
	-R|--pepc-resourceid)
	    resourceid="$2"
	    shift 2
	    ;;
	-o|--config-file)
	    glexecconf="$2"
	    shift 2
	    ;;
	-d|lcmaps-db)
	    lcmapsdb="$2"
	    shift 2
	    ;;
        --) 
	    shift
	    break
	    ;;
        *) 
	    echo "internal error" >&2
	    exit 1
	    ;;
    esac
done

# Parse remaining command-line arguments
case $1 in
    scas)
	shift
	scasconfig "$@"
	;;
    argus)
	shift
	argusconfig "$@"
	;;
    local)
	localconfig
	;;
    *)
	echo "Error: unknown framework '$1'" >&2
	usage
	exit 1
	;;
esac

# write the glexec configuration file
: "${TMPDIR:=/tmp}"
dir=`(umask 077 && mktemp -d "$TMPDIR/glexecXXXXXX") 2>/dev/null` && \
    test -d "$dir" || {
    echo "Failed to create temporary directory" >&2
    exit 1
}
tmpglexecconf="$dir/glexecconf"

cat > $tmpglexecconf <<EOF
## glexec.conf file. See glexec.conf(5) for details, defaults etc.
##
## In switching mode (glexec binary executed (effectively) by root),
## this file should have permissions 0400, owned by user glexec,
## in logging-only mode, it should NOT be writable by group/others.
##

[glexec]
EOF

if [ ! -z "$logfile" ]; then
    cat >> $tmpglexecconf <<EOF
log_destination			    = file
log_file			    = $logfile
EOF
else
    cat >> $tmpglexecconf <<EOF
# log_destination		    = syslog
# log_file			    = /var/log/glexec/glexec_log
EOF
fi

cat >> $tmpglexecconf <<EOF    
log_level			    = $loglevel
# diff_syslog_levels		    = yes
# syslog_facility		    = LOG_DAEMON
# log_file_group		    = root

# user_identity_switch_by	    = glexec
use_lcas			    = no

EOF

if [ ! -z "$whitelist" ]; then
    cat >> $tmpglexecconf <<EOF    
user_white_list			    = $whitelist
EOF
else
    cat >> $tmpglexecconf <<EOF    
# user_white_list		    =
EOF
fi

cat >> $tmpglexecconf <<EOF    
# group_white_list		    = glexec
# linger			    = yes
# linger_as_payload		    = no
# force_payload_background	    = no
# close_fds                         = yes

# term_delay			    = 5
# kill_delay			    = 1
# use_setpgid			    = yes
# extra_sighandlers		    = yes

# epilogue                          =
# epilogue_user                     = root
# epilogue_group                    = root
# epilogue_timeout                  = 300

# target_lock_mechanism		    = flock
# input_lock_mechanism		    = flock
# create_target_proxy		    = yes

# certdir			    =
# vomsdir			    =
# backlog_path			    =

# omission_private_key_white_list   =
# preserve_env_variables	    =
# pedantic_security_checks	    = no
# prohibit_exec_via_symlink	    = no

# lcas_libdir			    =
# lcas_moduledir_sfx		    = /lcas
# lcas_db_file			    = /etc/lcas/lcas-glexec.db
EOF
if [ ! -z "$lclogfile" ]; then
    cat >> $tmpglexecconf <<EOF
lcas_log_file			    = $lclogfile
EOF
else
    cat >> $tmpglexecconf <<EOF
# lcas_log_file			    = /var/log/glexec/lcas_lcmaps.log
EOF
fi
cat >> $tmpglexecconf <<EOF
lcas_debug_level		    = $loglevel

# lcmaps_libdir			    =
# lcmaps_moduledir_sfx		    = /lcmaps
# lcmaps_db_file		    = /etc/lcmaps/lcmaps-glexec.db
# lcmaps_voms_verification	    = yes
EOF
if [ ! -z "$lclogfile" ]; then
    cat >> $tmpglexecconf <<EOF
lcmaps_log_file			    = $lclogfile
EOF
else
    cat >> $tmpglexecconf <<EOF
# lcmaps_log_file		    = /var/log/glexec/lcas_lcmaps.log
EOF
fi
cat >> $tmpglexecconf <<EOF
lcmaps_debug_level		    = $loglevel
# lcmaps_get_account_policy	    = glexec_get_account
EOF

mv $tmpglexecconf $glexecconf
rm -rf "$dir"
chgrp glexec $glexecconf
chmod 640 $glexecconf
