diff options
| author | Simon Rettberg | 2015-12-26 14:48:09 +0100 |
|---|---|---|
| committer | Simon Rettberg | 2015-12-26 14:48:09 +0100 |
| commit | d70621125a3bc7033962318a0dad54cbeae8c678 (patch) | |
| tree | 56e6d38baabe7da1a69e107a5a8bf28f176fd4e7 /remote/modules | |
| parent | [hardware-stats] Randomize reporting interval offset on boot (diff) | |
| download | tm-scripts-d70621125a3bc7033962318a0dad54cbeae8c678.tar.gz tm-scripts-d70621125a3bc7033962318a0dad54cbeae8c678.tar.xz tm-scripts-d70621125a3bc7033962318a0dad54cbeae8c678.zip | |
[pam] Restructured session close script (pkill & umount part)
Diffstat (limited to 'remote/modules')
| -rwxr-xr-x | remote/modules/pam/data/opt/openslx/scripts/pam_script_ses_close | 100 |
1 files changed, 48 insertions, 52 deletions
diff --git a/remote/modules/pam/data/opt/openslx/scripts/pam_script_ses_close b/remote/modules/pam/data/opt/openslx/scripts/pam_script_ses_close index c80b50bb..cd35a86b 100755 --- a/remote/modules/pam/data/opt/openslx/scripts/pam_script_ses_close +++ b/remote/modules/pam/data/opt/openslx/scripts/pam_script_ses_close @@ -3,6 +3,9 @@ # 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 @@ -13,11 +16,6 @@ if [ "x$PAM_SERVICE" != "xsu" -a "x$PAM_SERVICE" != "xsudo" ]; then fi fi -# do not kill all root processes :) -[ "x${PAM_USER}" = "xroot" ] && exit 0 -# can only work if script is run as root -[ "x$(/usr/bin/whoami)" = "xroot" ] || exit 0 - # 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 @@ -26,62 +24,60 @@ if [ -d "/opt/openslx/scripts/pam_script_ses_close.d" ]; then done fi -OPENSESSION=$(loginctl show-user "$PAM_USER" 2>/dev/null| grep "Sessions=" | cut -c 10-) -SESSIONCOUNT=$(echo "$OPENSESSION" | wc -w) -# When using su/sudo there is no session created, so count up by one -if [ "x$PAM_SERVICE" = "xsu" -o "x$PAM_SERVICE" = "xsudo" ]; then - SESSIONCOUNT=$(( $SESSIONCOUNT + 1 )) -fi - -if [ "$SESSIONCOUNT" -le "1" ]; then +# do not kill all root processes :) +[ "x${PAM_USER}" = "xroot" ] && exit 0 - # last session, close all ghost user processes - usleep 100000 2> /dev/null - pkill -u "${PAM_USER}" +# 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 - # check if user's process are still running - for TIMEOUT in 1 1 2 FAIL; do - if [ "$TIMEOUT" = "FAIL" ]; then - # still something running, send SIGKILL - pkill -9 -u "${PAM_USER}" - break - fi - if ! ps -o pid,s -u "$PAM_USER" -U "$PAM_USER" | grep -q -v -E "PID|Z"; then - # nothing running anymore - break - fi - # give some time - sleep "${TIMEOUT}" - done - - # just to be sure we check if there's no other open session in the meantime - OPEN2=$(loginctl show-user "$PAM_USER" 2>/dev/null | grep "Sessions=" | cut -c 10-) + fi - if [ -z "$OPEN2" -o "x$OPENSESSION" = "x$OPEN2" ]; then + # 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=$(/usr/bin/getent passwd "$PAM_USER" | awk -F ':' '{print $6}') - PERSISTENT="$USER_HOME/PERSISTENT" - if [ -d "$PERSISTENT" ]; then - umount -l -f "$PERSISTENT" || \ - echo "Could not unmount '$PERSISTENT'." - fi - - if grep -q " $USER_HOME tmpfs " "/proc/mounts"; then - umount -l -f "$USER_HOME" 2> /dev/null + 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 -fi - -# source the stuff in pam_script_ses_close.d, if it exists -if [ -d "/opt/openslx/scripts/pam_script_ses_close.d" ]; then - for HOOK in $(ls "/opt/openslx/scripts/pam_script_ses_close.d"); do - # source it, in case of failure do nothing since these scripts are non-critical - . "/opt/openslx/scripts/pam_script_ses_close.d/$HOOK" || slxlog "pam-source-hooks" "Could not source '$HOOK'." - done -fi +} & exit 0 |
