195 lines
7.4 KiB
Bash
Executable file
195 lines
7.4 KiB
Bash
Executable file
#!/usr/bin/env bash
|
|
# ============================================================================
|
|
# BastionGuard - Riavvio dei servizi --user per TUTTI gli utenti
|
|
# ----------------------------------------------------------------------------
|
|
# Pensato per essere chiamato dal pacchetto Debian (postinst, triggers,
|
|
# o un dpkg trigger su /usr/lib/systemd/user/) dopo un upgrade dei binari
|
|
# o delle unit user-level di BastionGuard.
|
|
#
|
|
# Lo script gira SEMPRE come root e:
|
|
# 1. Fa "systemctl --global daemon-reload" così le unit installate in
|
|
# /usr/lib/systemd/user/ vengono ripescate dai futuri manager utente.
|
|
# 2. Trova TUTTI gli utenti con un user-manager systemd attivo:
|
|
# - sessioni attive (loginctl list-users)
|
|
# - utenti lingering (loginctl show-user --property=Linger)
|
|
# - utenti con /run/user/<uid> esistente
|
|
# 3. Per ognuno fa:
|
|
# - daemon-reload sul SUO bus (--global non aggiorna i manager già vivi)
|
|
# - try-restart di tutte le unit BastionGuard-*.service realmente
|
|
# installate per quell'utente
|
|
# 4. Salta utenti di sistema (UID < 1000) e utenti senza /run/user/<uid>.
|
|
#
|
|
# Exit code: sempre 0 (non blocca dpkg --configure).
|
|
#
|
|
# Posizione: /usr/share/BastionGuard/data/scripts/
|
|
# Esempio di chiamata da debian/postinst:
|
|
#
|
|
# if [ "$1" = "configure" ] || [ "$1" = "triggered" ]; then
|
|
# /usr/share/BastionGuard/data/scripts/BastionGuard-restart-user-services.sh || true
|
|
# fi
|
|
# ============================================================================
|
|
|
|
set -u
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# Lista delle unit --user di BastionGuard.
|
|
# Tieni allineato con i .service spediti in /usr/lib/systemd/user/.
|
|
# ----------------------------------------------------------------------------
|
|
ALL_SERVICES=(
|
|
"BastionGuard-cef.service"
|
|
"BastionGuard-mailproxy.service"
|
|
"BastionGuard-pacd.service"
|
|
"BastionGuard-phishing-scanner.service"
|
|
"BastionGuard-phishing-updater.service"
|
|
"BastionGuard-privacyd.service"
|
|
"BastionGuard-ransomware-alert.service"
|
|
"BastionGuard-ransomware-realtime-alert.service"
|
|
"BastionGuard-ransomware-realtime.service"
|
|
"BastionGuard-ransomware-scanner.service"
|
|
"BastionGuard-usbd.service"
|
|
"BastionGuard-useragent.service"
|
|
)
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# Logging (stderr, prefissato, no colori per non sporcare apt)
|
|
# ----------------------------------------------------------------------------
|
|
log() { printf '[BastionGuard] %s\n' "$*" >&2; }
|
|
warn() { printf '[BastionGuard] WARN: %s\n' "$*" >&2; }
|
|
err() { printf '[BastionGuard] ERR : %s\n' "$*" >&2; }
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# Prerequisiti
|
|
# ----------------------------------------------------------------------------
|
|
if ! command -v systemctl >/dev/null 2>&1; then
|
|
log "systemctl non presente, salto il riavvio dei servizi user."
|
|
exit 0
|
|
fi
|
|
|
|
# In chroot/container /run/systemd/system non esiste: niente da fare.
|
|
if [[ ! -d /run/systemd/system ]]; then
|
|
log "systemd non in esecuzione (chroot/container?), salto."
|
|
exit 0
|
|
fi
|
|
|
|
if [[ "$EUID" -ne 0 ]]; then
|
|
err "Questo script va eseguito come root (chiamato dal package manager)."
|
|
exit 0
|
|
fi
|
|
|
|
# UID minimo "umano". Standard è 1000 su Debian/Ubuntu/Fedora/openSUSE/Arch,
|
|
# ma rispettiamo /etc/login.defs se diverso.
|
|
UID_MIN=1000
|
|
if [[ -r /etc/login.defs ]]; then
|
|
_u="$(awk '/^[[:space:]]*UID_MIN/ {print $2; exit}' /etc/login.defs 2>/dev/null || true)"
|
|
[[ "$_u" =~ ^[0-9]+$ ]] && UID_MIN="$_u"
|
|
fi
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# Step 1: daemon-reload globale (futuri manager utente).
|
|
# ----------------------------------------------------------------------------
|
|
log "systemctl daemon-reload"
|
|
systemctl daemon-reload >/dev/null 2>&1 || \
|
|
warn "daemon-reload fallito (best-effort)"
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# Step 2: enumerazione utenti con user-manager attivo.
|
|
# ----------------------------------------------------------------------------
|
|
declare -A USERS_SET=()
|
|
|
|
if command -v loginctl >/dev/null 2>&1; then
|
|
# Tutti gli utenti noti a logind
|
|
while IFS= read -r _user; do
|
|
[[ -z "$_user" ]] && continue
|
|
USERS_SET["$_user"]=1
|
|
done < <(loginctl list-users --no-legend 2>/dev/null | awk '{print $2}')
|
|
fi
|
|
|
|
# Utenti con /run/user/<uid>: cattura sia logged-in sia lingering.
|
|
for d in /run/user/*; do
|
|
[[ -d "$d" ]] || continue
|
|
uid="$(basename "$d")"
|
|
[[ "$uid" =~ ^[0-9]+$ ]] || continue
|
|
[[ "$uid" -lt $UID_MIN ]] && continue
|
|
user="$(getent passwd "$uid" | cut -d: -f1)"
|
|
[[ -n "$user" ]] && USERS_SET["$user"]=1
|
|
done
|
|
|
|
if [[ ${#USERS_SET[@]} -eq 0 ]]; then
|
|
log "Nessun utente con sessione/linger attivo: niente da riavviare."
|
|
exit 0
|
|
fi
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# run_as_user <user> <systemctl args...>
|
|
#
|
|
# Esegue "systemctl --user <args>" nel contesto del manager utente di <user>.
|
|
# Stesso pattern di src/Backend.cpp (runuser ... systemctl --user) e
|
|
# src/wizard/wizard_setup.cpp (export XDG_RUNTIME_DIR/DBUS_SESSION_BUS_ADDRESS).
|
|
# ----------------------------------------------------------------------------
|
|
run_as_user() {
|
|
local user="$1"; shift
|
|
local uid
|
|
uid="$(id -u "$user" 2>/dev/null)" || return 2
|
|
[[ "$uid" -lt $UID_MIN ]] && return 3
|
|
[[ -d "/run/user/$uid" ]] || return 4
|
|
|
|
runuser -u "$user" -- env \
|
|
XDG_RUNTIME_DIR="/run/user/$uid" \
|
|
DBUS_SESSION_BUS_ADDRESS="unix:path=/run/user/$uid/bus" \
|
|
systemctl --user "$@"
|
|
}
|
|
|
|
# ----------------------------------------------------------------------------
|
|
# Step 3: per ogni utente, daemon-reload + try-restart delle unit installate.
|
|
# ----------------------------------------------------------------------------
|
|
total_users=0
|
|
ok_users=0
|
|
|
|
for user in "${!USERS_SET[@]}"; do
|
|
uid="$(id -u "$user" 2>/dev/null || true)"
|
|
if [[ -z "$uid" || "$uid" -lt $UID_MIN ]]; then
|
|
continue
|
|
fi
|
|
if [[ ! -d "/run/user/$uid" ]]; then
|
|
warn "Utente '$user' (uid=$uid) senza /run/user/$uid, salto."
|
|
continue
|
|
fi
|
|
|
|
total_users=$((total_users + 1))
|
|
log "→ Utente '$user' (uid=$uid)"
|
|
|
|
# daemon-reload del manager utente vivo
|
|
run_as_user "$user" daemon-reload >/dev/null 2>&1 || \
|
|
warn " daemon-reload utente fallito"
|
|
|
|
user_fail=0
|
|
user_done=0
|
|
|
|
for svc in "${ALL_SERVICES[@]}"; do
|
|
# L'unit è installata per questo utente?
|
|
if ! run_as_user "$user" list-unit-files "$svc" >/dev/null 2>&1; then
|
|
continue
|
|
fi
|
|
|
|
# try-restart: riavvia solo se è già in esecuzione. Più sicuro in
|
|
# postinst: non riaccende servizi che l'utente aveva fermato.
|
|
# Cambia in "restart" se vuoi forzare l'avvio.
|
|
if run_as_user "$user" try-restart "$svc" >/dev/null 2>&1; then
|
|
log " ✔ try-restart $svc"
|
|
user_done=$((user_done + 1))
|
|
else
|
|
warn " ✘ try-restart $svc fallito"
|
|
user_fail=$((user_fail + 1))
|
|
fi
|
|
done
|
|
|
|
if [[ $user_fail -eq 0 ]]; then
|
|
ok_users=$((ok_users + 1))
|
|
log " utente '$user': $user_done unit riavviate."
|
|
else
|
|
log " utente '$user': $user_done OK, $user_fail errori."
|
|
fi
|
|
done
|
|
|
|
log "Riepilogo: $ok_users/$total_users utenti gestiti senza errori."
|
|
exit 0
|