]> git.giorgioravera.it Git - scripts.git/commitdiff
Added script to check domain healtj
authorGiorgio Ravera <giorgio.ravera@gmail.com>
Sun, 18 Jan 2026 17:52:13 +0000 (18:52 +0100)
committerGiorgio Ravera <giorgio.ravera@gmail.com>
Sun, 18 Jan 2026 17:52:13 +0000 (18:52 +0100)
domain_check.sh [new file with mode: 0755]

diff --git a/domain_check.sh b/domain_check.sh
new file mode 100755 (executable)
index 0000000..468c02c
--- /dev/null
@@ -0,0 +1,172 @@
+#!/usr/bin/env bash
+# Samba NT4 + OpenLDAP â€” Domain Health Check (v1.4 FULL)
+# Autore: Copilot per Giorgio Ravera
+# Uso: sudo ./domain_health_check_v1.4.sh
+# Note: esegue controlli su SID, utenti, gruppi, LDAP e mapping Samba.
+
+set -uo pipefail
+
+# ---- Colori & contatori ----
+GREEN="\e[32m"; YELLOW="\e[33m"; RED="\e[31m"; CYAN="\e[36m"; BOLD="\e[1m"; RESET="\e[0m"
+pass_n=0; warn_n=0; fail_n=0
+ok()    { echo -e "${GREEN}[OK]${RESET}  $*"; ((pass_n++)) || true; }
+warn()  { echo -e "${YELLOW}[WARN]${RESET} $*"; ((warn_n++)) || true; }
+fail()  { echo -e "${RED}[FAIL]${RESET} $*"; ((fail_n++)) || true; }
+info()  { echo -e "${CYAN}[*]${RESET}    $*"; }
+hr()    { echo -e "${BOLD}------------------------------------------------------------${RESET}"; }
+
+if [[ $(id -u) -ne 0 ]]; then
+  warn "Esegui come root per ottenere tutti i risultati (alcuni comandi richiedono privilegi).";
+fi
+
+# Comandi utili (non tutti obbligatori)
+CMDS=(net pdbedit getent awk sed grep cut sort uniq slapcat ldapsearch testparm id)
+for c in "${CMDS[@]}"; do command -v "$c" >/dev/null 2>&1 || warn "Comando non trovato: $c (alcuni check potrebbero essere saltati)"; done
+
+# --- CHECKS ---
+check_sids() {
+  hr; info "Controllo SID di dominio vs SID locale"
+  command -v net >/dev/null 2>&1 || { warn "net non disponibile"; return; }
+  local local_sid domain_sid
+  local_sid=$(net getlocalsid 2>/dev/null | awk -F': ' '{print $2}' | tr -d '\r\n')
+  domain_sid=$(net getdomainsid 2>/dev/null | awk -F': ' '{print $2}' | tr -d '\r\n')
+  [[ -n "$local_sid"  ]] && info "Local SID:   $local_sid"  || warn "Impossibile leggere Local SID"
+  [[ -n "$domain_sid" ]] && info "Domain SID:  $domain_sid" || warn "Impossibile leggere Domain SID"
+  [[ -n "$local_sid" && -n "$domain_sid" ]] && {
+    [[ "$local_sid" == "$domain_sid" ]] && ok "SID locale e di dominio coincidono" || fail "SID locale e di dominio NON coincidono"; }
+}
+
+check_admin_500_512() {
+  hr; info "Verifica Administrator (RID 500) e Primary Group (512)"
+  command -v pdbedit >/dev/null 2>&1 || { warn "pdbedit non disponibile"; return; }
+  if pdbedit -L | cut -d: -f1 | grep -qx "admin"; then
+    local out; out=$(pdbedit -L -v admin 2>/dev/null)
+    echo "$out" | grep -Eq "User SID: .*-500$" && ok "admin ha RID 500" || fail "admin NON ha RID 500"
+    echo "$out" | grep -Eq "Primary Group SID: .*-512$" && ok "admin ha Primary Group 512 (Domain Admins)" || fail "admin NON ha Primary Group 512"
+  else
+    warn "Utente 'admin' non trovato, cerco chi ha RID 500"
+    local u; u=$(pdbedit -L -v 2>/dev/null | awk '/User SID:/ {sid=$3} /Unix username:/ {user=$3} {if (sid ~ /-500$/) print user}' | head -n1)
+    [[ -n "$u" ]] && ok "Trovato utente con RID 500: $u" || fail "Nessun utente con RID 500 trovato"
+  fi
+}
+
+check_admin_membership() {
+  hr; info "Verifica membership effettiva di 'admin' in Domain Admins (gid 512)"
+  command -v id >/dev/null 2>&1 || { warn "id non disponibile"; return; }
+  if id admin >/dev/null 2>&1; then
+    id admin | grep -Eq 'gid=512\(| 512\(' && ok "'admin' ha gid primario 512 (Domain Admins) oppure Ã¨ membro di 512" || warn "'admin' non appare con gid/membro 512 nell'output di id"
+  else
+    warn "Utente 'admin' non risolto da id(1)"
+  fi
+}
+
+check_low_rids() {
+  hr; info "Verifica RIDs bassi indesiderati (<1000, esclusi 500 e 501)"
+  command -v pdbedit >/dev/null 2>&1 || { warn "pdbedit non disponibile"; return; }
+  local bad; bad=$(pdbedit -L -v 2>/dev/null | awk '/User SID:/ {sid=$3; split(sid,a,"-"); rid=a[length(a)]; if (rid+0 < 1000 && rid != 500 && rid != 501) print sid}')
+  [[ -z "$bad" ]] && ok "Nessun utente con RID anomalo basso" || fail "RIDs bassi trovati:\n$bad"
+}
+
+check_guest_501() {
+  hr; info "Verifica account Guest (RID 501)"
+  command -v pdbedit >/dev/null 2>&1 || { warn "pdbedit non disponibile"; return; }
+  # Usa AWK per evitare problemi con '$' nei pattern
+  local found
+  found=$(pdbedit -L -v 2>/dev/null | awk '
+    /^Unix username:/ {user=$3}
+    /^User SID:/      {sid=$3; n=split(sid,a,"-"); rid=a[n]; if (rid==501) {print user ":" sid}}
+  ')
+  if [[ -n "$found" ]]; then
+    ok "Account Guest trovato: $found"
+  else
+    warn "RID 501 non trovato. (Inusuale per NT4, verifica configurazione)"
+  fi
+}
+
+check_groupmap_core() {
+  hr; info "Verifica groupmap core (512, 513, 514, 515)"
+  command -v net >/dev/null 2>&1 || { warn "net non disponibile"; return; }
+  local gm; gm=$(net groupmap list 2>/dev/null)
+  [[ -z "$gm" ]] && { warn "net groupmap list non ha restituito output"; return; }
+  echo "$gm" | grep -Fq -- "-512)" && ok "Domain Admins (512) presente"    || fail "Domain Admins (512) mancante"
+  echo "$gm" | grep -Fq -- "-513)" && ok "Domain Users (513) presente"     || fail "Domain Users (513) mancante"
+  echo "$gm" | grep -Fq -- "-514)" && ok "Domain Guests (514) presente"    || fail "Domain Guests (514) mancante"
+  echo "$gm" | grep -Fq -- "-515)" && ok "Domain Computers (515) presente" || fail "Domain Computers (515) mancante"
+}
+
+check_group_name_collisions() {
+  hr; info "Verifica collisioni di NOME gruppo tra sorgenti (files/ldap)"
+  command -v getent >/dev/null 2>&1 || { warn "getent non disponibile"; return; }
+  local dups; dups=$(getent group | cut -d: -f1 | sort | uniq -d)
+  [[ -z "$dups" ]] && ok "Nessuna collisione di nome gruppo rilevata" || warn "Collisioni nomi gruppo rilevate:\n$dups"
+}
+
+check_nobody_guest_split() {
+  hr; info "Verifica separazione nobody (locale) vs guest (LDAP)"
+  command -v getent >/dev/null 2>&1 || { warn "getent non disponibile"; return; }
+  local nb ge; nb=$(getent passwd nobody); ge=$(getent passwd guest)
+  [[ -n "$nb" ]] && ok "nobody locale presente: $(echo "$nb" | cut -d: -f1,3,4,7)" || warn "nobody locale non trovato"
+  if [[ -n "$ge" ]]; then
+    local uid gid; uid=$(echo "$ge" | cut -d: -f3); gid=$(echo "$ge" | cut -d: -f4)
+    [[ "$uid" == "65534" && "$gid" == "514" ]] && ok "guest LDAP coerente (uid=65534, gid=514)" || warn "guest LDAP anomalo (atteso uid=65534,gid=514): $(echo "$ge" | cut -d: -f1,3,4,7)"
+  else
+    warn "guest LDAP non trovato"
+  fi
+}
+
+check_ldap_domain_objects() {
+  hr; info "Verifica oggetti sambaDomain in LDAP"
+  if command -v slapcat >/dev/null 2>&1; then
+    local count sid arid
+    count=$(slapcat -n 1 2>/dev/null | grep -c "^objectClass: sambaDomain")
+    sid=$(slapcat -n 1 2>/dev/null | awk -F': ' '/^sambaSID:/ {print $2}' | sort -u)
+    arid=$(slapcat -n 1 2>/dev/null | awk -F': ' '/^sambaAlgorithmicRidBase:/ {print $2}' | tr -d '\r\n')
+    info "sambaDomain objects: $count"
+    info "sambaSID (dominio) trovato/i: $(echo "$sid" | tr '\n' ' ')"
+    [[ "$count" -eq 1 ]] && ok "Unico oggetto sambaDomain presente" || warn "Attesi 1 sambaDomain, trovati $count"
+    [[ -n "$arid" ]] && ok "sambaAlgorithmicRidBase=$arid" || warn "sambaAlgorithmicRidBase non trovato"
+  else
+    warn "slapcat non disponibile: salto controlli oggetto sambaDomain"
+  fi
+}
+
+check_machine_accounts() {
+  hr; info "Verifica account macchina (uid che terminano con $) con primary group 515"
+  command -v slapcat >/dev/null 2>&1 || { warn "slapcat non disponibile"; return; }
+  local bad
+  bad=$(slapcat -n 1 2>/dev/null | awk '/^dn: uid=.*\$,/ {inhost=1; uid=$2} /^sambaPrimaryGroupSID:/ {if (inhost){pg=$2; if (pg !~ /-515$/) print uid" -> "pg; inhost=0}}')
+  [[ -z "$bad" ]] && ok "Tutti gli account macchina hanno primary group 515 (Domain Computers)" || warn "Account macchina con primary group non 515:\n$bad"
+}
+
+check_testparm() {
+  hr; info "Validazione configurazione Samba con testparm"
+  command -v testparm >/dev/null 2>&1 || { warn "testparm non disponibile"; return; }
+  if testparm -s >/dev/null 2>&1; then
+    ok "testparm OK (configurazione Samba valida)"
+  else
+    fail "testparm ha rilevato errori nella configurazione"
+    testparm -s 2>&1 | sed -n '1,120p'
+  fi
+}
+
+summary() {
+  hr; echo -e "${BOLD}Riepilogo:${RESET} PASS=$pass_n  WARN=$warn_n  FAIL=$fail_n"; [[ $fail_n -eq 0 ]] && exit 0 || exit 1
+}
+
+main() {
+  echo -e "${BOLD}Samba NT4 + OpenLDAP â€” Health Check (v1.4 FULL)${RESET}"
+  check_sids
+  check_admin_500_512
+  check_admin_membership
+  check_low_rids
+  check_guest_501
+  check_groupmap_core
+  check_group_name_collisions
+  check_nobody_guest_split
+  check_ldap_domain_objects
+  check_machine_accounts
+  check_testparm
+  summary
+}
+
+main "$@"