|
#!/bin/bash |
|
|
|
# /opt/scripts/logout_idle_users.log |
|
|
|
LOGFILE="/opt/scripts/logout_idle_users.log" |
|
|
|
# Function to log messages to both stderr and log file |
|
log_message() { |
|
local message="$1" |
|
echo "$message" >&2 |
|
echo "$(date) - $message" >> "$LOGFILE" |
|
logger -t logout_idle_users "$message" # Send to syslog |
|
} |
|
|
|
# Get all logged-in users (excluding system users) |
|
users=$(who | awk '{print $1}' | sort | uniq) |
|
|
|
for user in $users; do |
|
# Skip system users and root |
|
if [[ "$user" == "root" || "$user" == "_*" ]]; then |
|
log_message "Skipping system user: $user" |
|
continue |
|
fi |
|
|
|
# Get the user ID |
|
user_id=$(id -u "$user") |
|
|
|
# Get idle time (extract only the first match) |
|
idle_time=$(w -h "$user" | awk '{print $5}' | head -n1) |
|
|
|
if [[ -z "$idle_time" || "$idle_time" == "-" || "$idle_time" == "w" ]]; then |
|
log_message "Skipping user $user due to invalid or missing idle time." |
|
continue |
|
fi |
|
|
|
# Convert idle time to seconds |
|
if [[ "$idle_time" =~ ^([0-9]+):([0-9]+)$ ]]; then |
|
idle_seconds=$(( ${BASH_REMATCH[1]} * 3600 + ${BASH_REMATCH[2]} * 60 )) |
|
elif [[ "$idle_time" =~ ^([0-9]+)$ ]]; then |
|
idle_seconds=$(( ${BASH_REMATCH[1]} * 60 )) |
|
elif [[ "$idle_time" =~ ^([0-9]+)d ]]; then |
|
idle_seconds=$(( ${BASH_REMATCH[1]} * 86400 )) # Convert days to seconds |
|
else |
|
log_message "Unable to parse idle time for user $user: $idle_time" |
|
continue |
|
fi |
|
|
|
log_message "User $user has been idle for $idle_seconds seconds." |
|
|
|
# If idle for more than 2 days (172800 seconds), log them out |
|
if [ "$idle_seconds" -gt 172800 ]; then |
|
log_message "User $user has been idle for more than 2 days. Attempting to log out." |
|
|
|
# Attempt logout using launchctl bootout (alternative method) |
|
bootout_output=$(sudo launchctl bootout user/"$user_id" 2>&1) |
|
bootout_status=$? |
|
|
|
if [ "$bootout_status" -eq 0 ]; then |
|
log_message "Successfully logged out user $user using launchctl bootout." |
|
else |
|
log_message "Failed to log out user $user using launchctl bootout. Error: $bootout_output" |
|
log_message "Attempting killall loginwindow." |
|
|
|
# Try logout via killall loginwindow |
|
loginwindow_output=$(sudo launchctl asuser "$user_id" sudo killall loginwindow 2>&1) |
|
loginwindow_status=$? |
|
|
|
if [ "$loginwindow_status" -eq 0 ]; then |
|
log_message "Successfully logged out user $user using killall loginwindow." |
|
else |
|
log_message "Failed to log out user $user using killall loginwindow. Error: $loginwindow_output" |
|
log_message "Attempting pkill." |
|
|
|
# If all else fails, use pkill as a last resort |
|
pkill_output=$(sudo pkill -TERM -u "$user" 2>&1) |
|
pkill_status=$? |
|
|
|
sleep 5 |
|
|
|
if who | grep -q "^$user\b"; then |
|
force_kill_output=$(sudo pkill -KILL -u "$user" 2>&1) |
|
log_message "Forcefully logged out user $user due to inactivity. Error: ${force_kill_output:-No error output}" |
|
else |
|
log_message "Gracefully logged out user $user. pkill output: ${pkill_output:-No error output}" |
|
fi |
|
fi |
|
fi |
|
fi |
|
done |