#!/bin/bash
#  Copyright (c) 2018, Oracle and/or its affiliates. All rights reserved.
#
#  Install SELinux modules for SGD

if [ -f $TTAMSG/common -a -f $TTAMSG/security_selinux ]; then
  . $TTAMSG/common
  . $TTAMSG/security_selinux
else
  echo "Unable to open message file: $TTAMSG/security_selinux"
  exit 1
fi


set -o nounset -o pipefail

scripts_dir="$TTAINSTDIR/bin/scripts"
selinux_log="$TTAINSTDIR/var/log/sgd-selinux.log"
working_dir="/tmp/sgd-selinux-tmp"


touch "$selinux_log"
printf "\n\nRun: ../tarantella security selinux: $(date) \n" >> "$selinux_log"

# Function to cleanup if we exit early due to an error
function cleanup {
    
    if [ "$PWD" == "$working_dir" ]
    then
        popd &>>"$selinux_log"
    fi

    rm -rf "$working_dir" &>> "$selinux_log"
}


function load_selinux_modules {
    
    # setup the temp working dir
    setup_working_dir

    echo "load sgd selinux modules" >> "$selinux_log"

    # change directory stack to the working dir where we put generated files
    pushd "$working_dir" &>>"$selinux_log"

    # convert type enforcement files (.te) into policy modules (.mod)
    ${SE_checkmodule} -M -m -o $cups_mod $cups_te &>> "$selinux_log"
    ${SE_checkmodule} -M -m -o $xauth_mod $xauth_te &>> "$selinux_log"

    # compile policy modules (.mod) into policy packages (.pp)
    ${SE_semodule_package} -o $cups_pp -m $cups_mod &>> "$selinux_log"
    ${SE_semodule_package} -o $xauth_pp -m $xauth_mod &>> "$selinux_log"

    # load the policy packages that have just been built
    ${SE_semodule} -i $xauth_pp $cups_pp &>> "$selinux_log"
    if [ $? -ne 0 ]
    then
        echo "${SE_semodule}: ${selinux_err_load_module_failed}" \
        | tee -a "$selinux_log"
        exit 1
    fi

    # clean up working dir 
    popd &>>"$selinux_log"

    echo "${selinux_load_successful}" | tee -a  "$selinux_log"
}


function remove_selinux_modules {
    
    echo "remove sgd selinux modules" >> "$selinux_log"

    all_modules="$xauth_policy $cups_policy"
    # remove each selinux module
    for module in $all_modules
    do
        ${SE_semodule} -r "$module" &>> "$selinux_log"
        if [ $? -ne 0 ]
        then
            echo "$selinux_remove_failed $module" | tee -a "$selinux_log"
            echo "$selinux_see_log $selinux_log"
        else
            echo "$selinux_remove_successful $module" | tee -a "$selinux_log"
        fi
    done
}


function setup_working_dir {
    
    # create temp working dir & copy .te files to working dir
    echo "create temp working dir: $working_dir, for module install" >> "$selinux_log"
    rm -rf "$working_dir" &>> "$selinux_log"
    mkdir -p "$working_dir"  &>> "$selinux_log"

    cp  "$scripts_dir/$cups_te" "$scripts_dir/$xauth_te" "$working_dir" \
        &>> "$selinux_log"
}


# run clean up function on unexpected exit
trap cleanup EXIT

# search for commands used in installation
SE_checkmodule=$(command -v checkmodule)
SE_semodule_package=$(command -v semodule_package)
SE_semodule=$(command -v semodule)

# check if SELinux commands we need exist
if [[ -z "$SE_checkmodule" || -z "$SE_semodule_package" || -z "$SE_semodule" ]]
then
    echo "${selinux_err_cmd_not_available}" &>> "$selinux_log"
    exit 1;
fi

# check if SELinux commands we need are executable
if ! [[ -x "$SE_checkmodule" || -x "$SE_semodule_package" || -x "$SE_semodule" ]]
then
    echo "${selinux_err_cmd_not_execable}" &>> "$selinux_log"
    exit 1;
fi

# names of the SELinux policies
cups_policy="ssgdcups"
xauth_policy="ssgdxauth"

# type enforcement files that contain policy we wish to load
cups_te="${cups_policy}-1.0.1.te"
xauth_te="${xauth_policy}-1.0.0.te"

cups_mod="${cups_policy}.mod"
xauth_mod="${xauth_policy}.mod"

cups_pp="${cups_policy}.pp"
xauth_pp="${xauth_policy}.pp"


# parse command line params
if [ "$#" -gt 1 ]
then
    usage
    exit 1
fi

if [ "$#" -eq 0 ]
then
    load_selinux_modules
    exit 0
fi

case "$1" in
    --remove) remove_selinux_modules; exit 0;;
    --help) echo "${selinux_usage}"; exit 0;;
    *) echo "${selinux_short_usage}"; exit 1;;
esac
