#!/bin/bash
# ansipa-smb-setup.sh — configure the Samba scan-results and LUKS-key shares on the IPA container.
#
# Runs on every container start via ansipa-smb.service so that smb.conf and
# Samba users are always in place after container restarts (ephemeral rootfs).
#
# Password sources (first match wins per variable):
#   1. Environment variable         (first boot / explicit override)
#   2. /data/samba/ansipa-smb.env  (persisted from first boot)
#
# Shares:
#   ansipa-scans      — write-only for 'scanupload'; clients push scan results here.
#   ansipa-luks-keys  — write-only for 'luks-upload' (Ansible controller);
#                       read for members of the 'KeyAdmin' Linux group.
#                       Add a Samba user to KeyAdmin to grant key-read access:
#                         useradd -r -G KeyAdmin <user>
#                         smbpasswd -a <user>

set -euo pipefail

LOG_TAG="ansipa-smb-setup"
SCAN_BASE="/data/scan-results"
LUKS_BASE="/data/luks-keys"
SMB_CONF="/etc/samba/smb.conf"
SMB_USER="scanupload"
LUKS_UPLOAD_USER="luks-upload"
KEYADMIN_GROUP="KeyAdmin"
ENV_FILE="/data/samba/ansipa-smb.env"

log()  { echo "[$LOG_TAG] $*"; }
die()  { echo "[$LOG_TAG][ERROR] $*" >&2; exit 1; }

# ── Resolve passwords ─────────────────────────────────────────────────────────
SMB_PASS="${SMB_SCAN_PASSWORD:-}"
LUKS_PASS="${LUKS_KEY_UPLOAD_PASSWORD:-}"

if [[ -f "$ENV_FILE" ]]; then
    # shellcheck source=/dev/null
    source "$ENV_FILE"
    SMB_PASS="${SMB_SCAN_PASSWORD:-$SMB_PASS}"
    LUKS_PASS="${LUKS_KEY_UPLOAD_PASSWORD:-$LUKS_PASS}"
fi

[[ -z "$SMB_PASS"  ]] && die "SMB_SCAN_PASSWORD not set and $ENV_FILE not present. Set it in .env."
[[ -z "$LUKS_PASS" ]] && die "LUKS_KEY_UPLOAD_PASSWORD not set and $ENV_FILE not present. Set it in .env."

# ── Persist for subsequent restarts ──────────────────────────────────────────
mkdir -p "$(dirname "$ENV_FILE")"
{
    printf 'SMB_SCAN_PASSWORD=%q\n'       "$SMB_PASS"
    printf 'LUKS_KEY_UPLOAD_PASSWORD=%q\n' "$LUKS_PASS"
} > "$ENV_FILE"
chmod 600 "$ENV_FILE"

# ── Directory structure (idempotent) ──────────────────────────────────────────
mkdir -p "$SCAN_BASE/archive" "$SCAN_BASE/alerts"
mkdir -p "$LUKS_BASE"

# ── KeyAdmin group ────────────────────────────────────────────────────────────
if ! getent group "$KEYADMIN_GROUP" &>/dev/null; then
    groupadd -r "$KEYADMIN_GROUP"
    log "Created group: $KEYADMIN_GROUP"
fi

# ── System users ──────────────────────────────────────────────────────────────
if ! id "$SMB_USER" &>/dev/null; then
    useradd -r -s /sbin/nologin -d "$SCAN_BASE" -M "$SMB_USER"
    log "Created system user: $SMB_USER"
fi

if ! id "$LUKS_UPLOAD_USER" &>/dev/null; then
    useradd -r -s /sbin/nologin -d "$LUKS_BASE" -M -G "$KEYADMIN_GROUP" "$LUKS_UPLOAD_USER"
    log "Created system user: $LUKS_UPLOAD_USER (member of $KEYADMIN_GROUP)"
else
    # Ensure group membership is correct after container recreations
    usermod -aG "$KEYADMIN_GROUP" "$LUKS_UPLOAD_USER"
fi

chown -R "$SMB_USER:$SMB_USER" "$SCAN_BASE"
chown -R "root:$KEYADMIN_GROUP" "$LUKS_BASE"
chmod 2750 "$LUKS_BASE"   # setgid so new files inherit KeyAdmin group

# ── smb.conf ──────────────────────────────────────────────────────────────────
log "Writing $SMB_CONF"
cat > "$SMB_CONF" <<CONF
[global]
    workgroup = WORKGROUP
    server string = Ansipa Security Server
    security = user
    map to guest = never
    # Store passdb on the persistent volume so passwords survive container restarts.
    passdb backend = tdbsam:/data/samba/passdb.tdb
    log file = /var/log/samba/log.%m
    max log size = 50
    # Disable printing subsystem entirely.
    load printers = no
    printing = bsd
    printcap name = /dev/null
    disable spoolss = yes

[ansipa-scans]
    comment = Ansipa scan results — managed by ansipa-enforce-policies
    path = $SCAN_BASE
    valid users = $SMB_USER
    read only = no
    browseable = no
    create mask = 0644
    directory mask = 0755
    force user = $SMB_USER

[ansipa-luks-keys]
    comment = Ansipa LUKS backup keys — KeyAdmin read, luks-upload write only
    path = $LUKS_BASE
    valid users = @$KEYADMIN_GROUP
    read only = yes
    write list = $LUKS_UPLOAD_USER
    browseable = no
    create mask = 0640
    directory mask = 0750
CONF

# ── Samba passwords (idempotent — smbpasswd -a adds or updates) ───────────────
_smb_set_pass() {
    local user="$1" pass="$2"
    log "Setting Samba password for $user"
    printf '%s\n%s\n' "$pass" "$pass" | smbpasswd -a -s "$user" 2>/dev/null || \
    printf '%s\n%s\n' "$pass" "$pass" | smbpasswd    -s "$user" 2>/dev/null || \
    log "WARN: smbpasswd returned non-zero for $user (may already be set correctly)"
}

_smb_set_pass "$SMB_USER"          "$SMB_PASS"
_smb_set_pass "$LUKS_UPLOAD_USER"  "$LUKS_PASS"

# ── Server-side scan checker cron (hourly, analysed on the IPA server itself) ─
# Always (re-)write: /etc/cron.d is on the ephemeral container layer and is
# lost on container recreation, so we must restore it on every start.
cat > /etc/cron.d/ansipa-check-scans <<'CRON'
# ansipa: analyze client scan logs and write alerts — managed, do not edit.
0 * * * * root /usr/local/sbin/ansipa-check-scans.sh 2>&1 | logger -t ansipa-check-scans
CRON
chmod 644 /etc/cron.d/ansipa-check-scans
log "Installed hourly scan-checker cron"

log "Samba setup complete. Share: //localhost/ansipa-scans  user: $SMB_USER"
