--- /dev/null
+#!/usr/bin/env bash
+# OpenLDAP full backup into a single ZIP (config.ldif + data.ldif)
+# Logging, rotation, error handling
+
+set -euo pipefail
+
+########## CONFIGURAZIONE ##########
+BACKUP_DIR="/root/backup/openldap" # dove salvare i backup
+LOG_FILE="/var/log/openldap_backup.log" # file log
+KEEP_DAYS=30 # quanti giorni mantenere
+
+# Indici DB (tipici: 0=config, 1=dati; adatta se necessario)
+CONFIG_DB=0
+DATA_DB=1
+
+# Opzioni upload remoto (disabilitato di default)
+ENABLE_REMOTE_UPLOAD=false
+REMOTE_USER="backup"
+REMOTE_HOST="nas.example.lan"
+REMOTE_DIR="/srv/backup/openldap"
+####################################
+
+# --- Funzioni utili ---
+timestamp() { date +'%Y-%m-%d %H:%M:%S'; }
+log() { echo "$(timestamp) [INFO] $*" | tee -a "$LOG_FILE"; }
+warn() { echo "$(timestamp) [WARN] $*" | tee -a "$LOG_FILE" >&2; }
+err() { echo "$(timestamp) [ERR ] $*" | tee -a "$LOG_FILE" >&2; }
+
+cleanup_on_error() {
+ err "Backup terminato con errore (codice: $?). Controlla il log: $LOG_FILE"
+}
+trap cleanup_on_error ERR
+
+require_cmd() {
+ command -v "$1" >/dev/null 2>&1 || { err "Comando mancante: $1"; exit 127; }
+}
+
+ensure_root() {
+ if [[ $(id -u) -ne 0 ]]; then
+ err "Esegui questo script come root."
+ exit 1
+ fi
+}
+
+main() {
+ ensure_root
+ require_cmd slapcat
+ require_cmd zip
+ require_cmd find
+ require_cmd tee
+ $ENABLE_REMOTE_UPLOAD && require_cmd rsync
+
+ mkdir -p "$BACKUP_DIR"
+ touch "$LOG_FILE" || { err "Impossibile scrivere su $LOG_FILE"; exit 1; }
+
+ local TS
+ TS=$(date +'%Y%m%d-%H%M%S')
+
+ # Percorsi finali
+ local ZIP_FILE="$BACKUP_DIR/openldap_backup_$TS.zip"
+
+ # Workdir temporanea per creare i file con nomi fissi
+ local TMP_DIR
+ TMP_DIR=$(mktemp -d /tmp/openldap_bkp.XXXXXX)
+
+ # Nomi fissi richiesti per il contenuto dello ZIP
+ local DATA_LDIF="$TMP_DIR/data.ldif"
+ local CONF_LDIF="$TMP_DIR/config.ldif"
+
+ log "===== Avvio backup OpenLDAP ($TS) ====="
+ log "Cartella: $BACKUP_DIR | Log: $LOG_FILE | Rotazione: ${KEEP_DAYS} giorni"
+ log "Indice DB → config: ${CONFIG_DB}, dati: ${DATA_DB}"
+
+ # --- Dump CONFIG (db 0) ---
+ log "Esporto configurazione (db ${CONFIG_DB}) → $CONF_LDIF"
+ slapcat -n "${CONFIG_DB}" -l "$CONF_LDIF"
+ if [[ ! -s "$CONF_LDIF" ]]; then
+ rm -rf "$TMP_DIR"
+ err "File di configurazione vuoto: $CONF_LDIF"
+ exit 2
+ fi
+
+ # --- Dump DATA (db 1) ---
+ log "Esporto dati (db ${DATA_DB}) → $DATA_LDIF"
+ slapcat -n "${DATA_DB}" -l "$DATA_LDIF"
+ if [[ ! -s "$DATA_LDIF" ]]; then
+ rm -rf "$TMP_DIR"
+ err "File dati vuoto: $DATA_LDIF (controlla l'indice del database dati)"
+ exit 4
+ fi
+
+ # --- Crea ZIP singolo con nomi fissi ---
+ # -j: elimina i percorsi, così dentro lo zip ci sono solo data.ldif e config.ldif
+ log "Creo archivio ZIP unico → $ZIP_FILE"
+ ( cd "$TMP_DIR" && zip -q -9 "$ZIP_FILE" "data.ldif" "config.ldif" )
+
+ # Verifica ZIP creato e non vuoto
+ if [[ ! -s "$ZIP_FILE" ]]; then
+ rm -rf "$TMP_DIR"
+ err "Creazione ZIP fallita o archivio vuoto: $ZIP_FILE"
+ exit 5
+ fi
+
+ # Pulizia directory temporanea
+ rm -rf "$TMP_DIR"
+
+ # --- Rotazione: cancella ZIP più vecchi di KEEP_DAYS ---
+ log "Rotazione: elimino ZIP più vecchi di ${KEEP_DAYS} giorni"
+ find "$BACKUP_DIR" -type f -name 'openldap_backup_*.zip' -mtime +"$KEEP_DAYS" -print -delete | tee -a "$LOG_FILE" || true
+
+ # --- Upload remoto opzionale ---
+ if $ENABLE_REMOTE_UPLOAD; then
+ log "Upload remoto su ${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}"
+ rsync -av --partial --inplace --chmod=F600,Du=rwx,Dg=rx,Do= \
+ "$ZIP_FILE" "${REMOTE_USER}@${REMOTE_HOST}:${REMOTE_DIR}/"
+ fi
+
+ log "Backup completato con successo: $(basename "$ZIP_FILE")"
+ log "===== Fine backup OpenLDAP ($TS) ====="
+}
+
+main "$@"