#!/bin/sh

po_domain="alterator-secsetup"
alterator_api_version=1

. alterator-sh-functions


ACCESS_CONFIG=/etc/security/access.conf
BLOCK_ENTER="# START_BLOCKTERM_SECTION"
BLOCK_EXIT="# END_BLOCKTERM_SECTION"
CACHE="/var/cache/alterator/blockterm"

CONTROL_PATH=/usr/sbin/control

cache_reset(){
    rm -rf -- "$CACHE"
    mkdir -p -- "$CACHE"
}

access_remove(){
    sed -i "/$BLOCK_ENTER/,/$BLOCK_EXIT/d" $ACCESS_CONFIG
}

access_read(){
    sed "1,/$BLOCK_ENTER/d;/$BLOCK_EXIT/,\$d" $ACCESS_CONFIG | awk -F: '{gsub(/ /, "", $2); print $2 $3}'
}

get_first(){
    echo $1
}

get_last(){
    shift
    echo $@
}

cache_write(){
    local IFS=$'\n'
    for record in $(access_read)
    do
        local IFS=' '
        FN=$CACHE/$(get_first $record)
        STR=$(get_last $record)
        >$FN
        for s in $STR
        do
            echo $s>>$FN
        done
    done
}

access_write(){
    echo "$BLOCK_ENTER" >> $ACCESS_CONFIG
    for i in $(ls $CACHE)
    do
        if [ -s $CACHE/$i ]
        then
            echo "- : $i : $(echo $(cat $CACHE/$i))" >> $ACCESS_CONFIG
        fi
    done
    echo "$BLOCK_EXIT" >> $ACCESS_CONFIG
}


block_add(){
    local IFS=";"
    for k in $2
    do
        echo "$k">>"$CACHE/$1"
    done
    sort "$CACHE/$1">"$CACHE/.tmp"
    cat "$CACHE/.tmp">"$CACHE/$1"
    rm -rf "$CACHE/.tmp"
}

block_remove(){
    local IFS=";"
    for k in $2
    do
        subst "/^$k$/d" "$CACHE/$1"
    done
}


blocked_list(){
    cat "$CACHE/$1"
}

tty_list(){
    if [ -n "$1" -a -f "$CACHE/$1" ]
    then
        ls -1 /sys/class/tty | grep -E "^tty[S]?[0-9]*$" | sort | comm -23 - "$CACHE/$1"
    else
        ls -1 /sys/class/tty | grep -E "^tty[S]?[0-9]*$" | sort
    fi
}

user_list(){
    getent passwd | awk -F: '{if ($3>=1000) print $1}' | sort
}


pam_access_set(){
    case "$1" in
        "#t") /usr/sbin/control pam_access enabled ;;
        "#f") /usr/sbin/control pam_access disabled ;;
    esac
}

#### MAIN LOOP ####

cache_reset
cache_write

on_message() {
  case "$in_action" in
    read)
        ! [ $($CONTROL_PATH 'pam_access') == 'enabled' ]
        write_bool_param pamcontrol "$?"
        ;;
    write)
        pam_access_set "$in_pamcontrol"
        case "$in__objects" in
            blockadd)
                [ -n "$in_user" -a -n "$in_tty" ] || return
                block_add "$in_user" "$in_tty"
                ;;
            blockremove)
                [ -n "$in_user" -a -n "$in_tty" ] || return
                block_remove "$in_user" "$in_tty"
                ;;
        esac
        ;;
    list)
        case "$in__objects" in
            userlist)
                user_list | write_enum
                ;;
            ttylist)
                [ -n "$in_user" ] || return
                [ "#f" != "$in_user" ] || return
                tty_list "$in_user" | write_enum
                ;;
            blocked)
                [ -n "$in_user" ] || return
                [ "#f" != "$in_user" ] || return
                blocked_list "$in_user" | write_enum
                ;;
        esac
        ;;
    save)
        access_remove
        access_write
        cache_reset
        cache_write
        ;;
    reset)
        cache_reset
        cache_write
        ;;
  esac
}

message_loop
