#!/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