blob: 0d226acc64b93be3b87e0385d0f767e585d9cf42 (
plain) (
blame)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
|
#!/bin/ash -- sourced
# do not kill all root processes :)
[ "x${PAM_USER}" = "xroot" ] && return 0
USERID=$(id -u "$PAM_USER")
[ -z "$USERID" ] && USERID="$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}\\s" | wc -l)
if [ "$SESSIONCOUNT" = "0" ]; then
# last session, close all ghost user processes
pkill -u "${USERID}"
# check if user's processes are still running
for TIMEOUT in 1 1 1 FAIL; do
if ! ps -o pid,s -u "$USERID" -U "$USERID" | grep -q -v -E "PID|Z"; then
# nothing running anymore
break
fi
if [ "$TIMEOUT" = "FAIL" ]; then
# still something running, send SIGKILL
pkill -9 -u "${USERID}"
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}\\s" | wc -l)
if [ "$SESSIONCOUNT" = "0" ]; then
# unmount the home directory structure
USER_HOME=$(getent passwd "$USERID" | awk -F ':' '{print $6}')
if [ -n "$USER_HOME" ]; then
for TIMEOUT in 0 0 1 2 FAIL; do
OK=yes
UOPT=
[ "$TIMEOUT" = "FAIL" ] && UOPT="-l"
for dir in $( < "/proc/mounts" awk '{print $2}' | grep -e "^${USER_HOME}\$" -e "^${USER_HOME}/" | sort -r ); do
umount $UOPT "$dir" || OK=no # no quotes
done
[ "$TIMEOUT" = "FAIL" -o "$OK" = "yes" ] && break
sleep "$TIMEOUT"
done
fi
fi
} &
true
|