diff options
Diffstat (limited to 'core/modules/pam/data/opt/openslx/scripts/pam_script_ses_close')
-rwxr-xr-x | core/modules/pam/data/opt/openslx/scripts/pam_script_ses_close | 83 |
1 files changed, 83 insertions, 0 deletions
diff --git a/core/modules/pam/data/opt/openslx/scripts/pam_script_ses_close b/core/modules/pam/data/opt/openslx/scripts/pam_script_ses_close new file mode 100755 index 00000000..cd35a86b --- /dev/null +++ b/core/modules/pam/data/opt/openslx/scripts/pam_script_ses_close @@ -0,0 +1,83 @@ +#!/bin/ash + +# Needed as pam_script clears PATH +export PATH="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin:/opt/openslx/sbin:/opt/openslx/bin" + +# can only work if script is run as root +[ "x$(whoami)" = "xroot" ] || exit 0 + +# NSA needs to know +if [ "x$PAM_SERVICE" != "xsu" -a "x$PAM_SERVICE" != "xsudo" ]; then + . /opt/openslx/config + if [ "x$SLX_REMOTE_LOG_SESSIONS" = "xyes" -o "x$PAM_USER" = "xroot" ]; then + slxlog "session-close" "$PAM_USER logged out on $PAM_TTY" + elif [ "x$SLX_REMOTE_LOG_SESSIONS" = "xanonymous" ]; then + slxlog "session-close" "User logged out on $PAM_TTY" + fi +fi + +# source hooks if there are any +if [ -d "/opt/openslx/scripts/pam_script_ses_close.d" ]; then + for HOOK in $(ls "/opt/openslx/scripts/pam_script_ses_close.d"); do + # failure is non-critical + . "/opt/openslx/scripts/pam_script_ses_close.d/$HOOK" || slxlog "pam-sesclose-hooks" "Could not source '$HOOK'." + done +fi + +# do not kill all root processes :) +[ "x${PAM_USER}" = "xroot" ] && exit 0 + +# Async block: Check if user has no session open anymore, if not +# kill any remaining processes belonging to the user and unmount +# everything at $USERHOME and below. +{ + sleep 2 # Give things some time + # Use who (utmp) to determine sessions by the user. loginctl might be nicer, but + # a simple show-user $USER will also include detached sessions (eg. screen) which + # makes this quite pointless. This needs to be investigated some day. + SESSIONCOUNT=$(who | grep "^${PAM_USER}\\b" | wc -l) + if [ "$SESSIONCOUNT" = "0" ]; then + + # last session, close all ghost user processes + pkill -u "${PAM_USER}" + + # check if user's processes are still running + for TIMEOUT in 1 1 2 FAIL; do + if ! ps -o pid,s -u "$PAM_USER" -U "$PAM_USER" | grep -q -v -E "PID|Z"; then + # nothing running anymore + break + fi + if [ "$TIMEOUT" = "FAIL" ]; then + # still something running, send SIGKILL + pkill -9 -u "${PAM_USER}" + else + # give some time + sleep "${TIMEOUT}" + fi + done + + fi + + # just to be sure we check again, since the pkilling above might have taken some time... + SESSIONCOUNT=$(who | grep "^${PAM_USER}\\b" | wc -l) + if [ "$SESSIONCOUNT" = "0" ]; then + + # unmount the home directory structure + USER_HOME=$(getent passwd "$PAM_USER" | awk -F ':' '{print $6}') + if [ -n "$USER_HOME" ]; then + for TIMEOUT in 0 0 2 2 FAIL; do + OK=yes + for dir in $(cat /proc/mounts | awk '{print $2}' | grep -e "^${USER_HOME}\$" -e "^${USER_HOME}/.*\$"); do + umount "$dir" || OK=no + done + [ "$TIMEOUT" = "FAIL" -o "$OK" = "yes" ] && break + sleep "$TIMEOUT" + done + fi + + fi + +} & + +exit 0 + |