#!/bin/bash
#< Limit user logins to a specified number of sessions

# In order to use this script, you should add lines along the lines of the following to /etc/profile

######## START: Pertinent section from /etc/profile #########
# LIMITED_USERS must be : delimited including start and end of variable
#LIMITED_USERS=":wspratt:kevin:"
# SESSION_LIMIT - total number of sessions user is allowed to have to the server
#SESSION_LIMIT="3"
#/bin/echo "${LIMITED_USERS}" | /bin/grep ":$( /bin/whoami ):" >/dev/null 2>&1
#if [ "$?" -eq "0" ]; then
#   # Don't want limited users busting out here...
#   trap 'logout' 1 2 3 15
#   RESULT=$( /usr/local/bin/login_limiter.sh -u $( /bin/whoami ) -n ${SESSION_LIMIT} )
#   if [ "${RESULT}" = "ALLOW" ]; then
#      :
#   elif [ "${RESULT}" = "DENY" ]; then
#      /bin/echo "====[ ERROR: $( /bin/whoami ) has exceeded their permitted session count ]===="
#      /bin/echo "You are permitted to have ${SESSION_LIMIT} concurrent sessions open"
#      /bin/echo "to this machine. You must log off one of your sessions"
#      /bin/echo "in order to initiate a new one"
#      /usr/bin/sleep 10
#      logout
#   else
#      # If the script doesn't produce ALLOW or DENY, it must have exited with
#      # an error - we default to permit access
#      :
#   fi
#fi
######## END: Pertinent section from /etc/profile #########

AWK="/usr/bin/awk"
BASENAME="/usr/bin/basename"
ECHO="/usr/bin/echo"
EGREP="/bin/egrep"
GREP="/bin/grep"
WC="/usr/bin/wc"
WHO="/usr/bin/who"

NUM=0
NUM_FLAG=0
USERNAME=""
USERNAME_FLAG=0
THIS_PROG=$( ${BASENAME} $0 )

VERBOSE=0
ERROR=0
SUCCESS=0

function usage {
   ${ECHO} "Usage: ${THIS_PROG} [-v] -u <username> -n <num_sessions>" >&2
}

function print_error {
   ${ECHO} "Error: $@" >&2
}

function check_num_sessions {
   ${ECHO} "${NUM}" | ${EGREP} "^[0-9]+$" >/dev/null 2>&1
   if [ "$?" -ne "0" ]; then
      return 1
   else
      return 0
   fi
}

function check_valid_user {
   if [ "${USERNAME}" = "root" ]; then
      return 2
   fi
   ${GREP} "^${USERNAME}:" /etc/passwd >/dev/null 2>&1
   if [ "$?" -ne "0" ]; then
      return 1
   else
      return 0
   fi
}

function count_sessions {
   SESSION_COUNT=$( ${WHO} | ${AWK} '{print $1}' | ${GREP} "^${USERNAME}$" | ${WC} -l )
   (( VERBOSE_FLAG )) && {
      if [ "${SESSION_COUNT}" -eq "0" ]; then
         ${ECHO} "User ${USERNAME} is not logged in"
      elif [ "${SESSION_COUNT}" -eq "1" ]; then
         ${ECHO} "User ${USERNAME} is logged in to ${SESSION_COUNT} session"
      else
         ${ECHO} "User ${USERNAME} is logged in to ${SESSION_COUNT} sessions"
      fi
   }
   if [ "${SESSION_COUNT}" -gt "${NUM}" ]; then
      return 1
   else
      return 0
   fi
}

while getopts ":n:u:v" OPTION; do
   case "${OPTION}" in
      "n")   if [ "${NUM_FLAG}" -ne "0" ]; then
                (( VERBOSE_FLAG )) && {
                   print_error "More than one -n option specified"
                }
                usage
                exit ${ERROR}
             fi
             NUM_FLAG=1
             NUM="${OPTARG}"
             ;;
      "u")   if [ "${USERNAME_FLAG}" -ne "0" ]; then
                (( VERBOSE_FLAG )) && {
                   print_error "More than one -u option specified"
                }
                usage
                exit ${ERROR}
             fi
             USERNAME_FLAG=1
             USERNAME="${OPTARG}"
             ;;
      "v")   VERBOSE_FLAG=1
             ;;
      *)     usage
             exit ${ERROR}
             ;;
   esac
done

shift $(( ${OPTIND} - 1 ))

if [ "$#" -ne "0" ]; then
   (( VERBOSE_FLAG )) && {  
      print_error "Extra args passed"
   }
   usage
   exit ${ERROR}
fi

if [ "${USERNAME_FLAG}" -eq "0" ]; then
   (( VERBOSE_FLAG )) && {  
      print_error "No -u option specified"
   }
   usage
   exit ${ERROR}
fi

if [ "${NUM_FLAG}" -eq "0" ]; then
   (( VERBOSE_FLAG )) && {  
      print_error "No -n option specified"
   }
   usage
   exit ${ERROR}
fi

check_num_sessions || {
   print_error "Please specify integer value only for -n"
   exit ${ERROR}
}

check_valid_user
RETURN=$?

if [ "${RETURN}" -eq "1" ]; then
   print_error "User ${USERNAME} non-existant on this host"
   exit ${ERROR}
elif [ "${RETURN}" -eq "2" ]; then
   print_error "Limiting root logins not permitted"
   exit ${ERROR}
fi

count_sessions
if [ "$?" -eq "0" ]; then
   ${ECHO} "ALLOW"
else
   ${ECHO} "DENY"
fi

exit ${SUCCESS}