#!/bin/bash
#
# kursuser.sh - Kursteilnehmer-Accounts anlegen, loeschen, pruefen
#
#   ./kursuser.sh create        Benutzer anlegen (Home + Passwort)
#   ./kursuser.sh delete        Benutzer inkl. Home loeschen
#   ./kursuser.sh status        Auflisten, welche Accounts existieren
#
# Optionen:
#   -p PREFIX   Namenspraefix       (Default: kit)
#   -n ANZAHL   Anzahl Accounts     (Default: 13)
#   -s START    erste Nummer        (Default: 1)
#   -w PASS     Passwort            (Default: 123Start$)
#   -m          Maildir gleich mit anlegen
#   -f          nicht nachfragen (fuer delete)
#
# Beispiele:
#   ./kursuser.sh create -m
#   ./kursuser.sh create -p sec -n 20
#   ./kursuser.sh delete -f
#

PREFIX="kit"
COUNT=13
START=1
PASS='123Start$'
SHELL_USER="/bin/bash"
HOME_MODE=750
MKMAILDIR=0
FORCE=0

# ---------------------------------------------------------------- Hilfsroutinen

info() { printf '  %s\n' "$*"; }
ok()   { printf '  [ ok ] %s\n' "$*"; }
skip() { printf '  [skip] %s\n' "$*"; }
err()  { printf '  [FEHL] %s\n' "$*" >&2; }

usage() {
    sed -n '2,25p' "$0" | sed 's/^#\{0,1\} \{0,1\}//'
    exit 1
}

# Erzeugt die Liste der Benutzernamen, z.B. kit01 kit02 ... kit13
userlist() {
    local i
    for (( i=START; i<START+COUNT; i++ )); do
        printf '%s%02d\n' "$PREFIX" "$i"
    done
}

# ---------------------------------------------------------------- Parameter

ACTION="$1"
[ -z "$ACTION" ] && usage
shift

while getopts "p:n:s:w:mfh" opt; do
    case "$opt" in
        p) PREFIX="$OPTARG" ;;
        n) COUNT="$OPTARG" ;;
        s) START="$OPTARG" ;;
        w) PASS="$OPTARG" ;;
        m) MKMAILDIR=1 ;;
        f) FORCE=1 ;;
        h|*) usage ;;
    esac
done

if [ "$(id -u)" -ne 0 ]; then
    err "Bitte als root ausfuehren."
    exit 1
fi

# ---------------------------------------------------------------- Aktionen

do_create() {
    info "Lege ${COUNT} Accounts an (Praefix: ${PREFIX})"
    local u
    for u in $(userlist); do

        if id "$u" >/dev/null 2>&1; then
            skip "$u existiert bereits"
            continue
        fi

        if ! useradd -m -d "/home/$u" -s "$SHELL_USER" "$u"; then
            err "$u konnte nicht angelegt werden"
            continue
        fi

        # -c SHA512 umgeht PAM, sonst blockt pwquality einfache Passwoerter
        if ! echo "$u:$PASS" | chpasswd -c SHA512; then
            err "$u - Passwort konnte nicht gesetzt werden"
            continue
        fi

        chmod "$HOME_MODE" "/home/$u"

        if [ "$MKMAILDIR" -eq 1 ]; then
            install -d -o "$u" -g "$u" -m 700 \
                "/home/$u/Maildir" \
                "/home/$u/Maildir/cur" \
                "/home/$u/Maildir/new" \
                "/home/$u/Maildir/tmp"
        fi

        ok "$u angelegt"
    done
}

do_delete() {
    local vorhanden u
    vorhanden=$(for u in $(userlist); do id "$u" >/dev/null 2>&1 && echo "$u"; done)

    if [ -z "$vorhanden" ]; then
        info "Keine passenden Accounts gefunden - nichts zu tun."
        return 0
    fi

    info "Folgende Accounts werden MIT Home-Verzeichnis geloescht:"
    echo "$vorhanden" | tr '\n' ' ' | fold -s -w 70 | sed 's/^/    /'
    echo

    if [ "$FORCE" -ne 1 ]; then
        read -r -p "  Wirklich loeschen? [j/N] " antwort
        case "$antwort" in
            j|J|y|Y) ;;
            *) info "Abgebrochen."; return 0 ;;
        esac
    fi

    for u in $vorhanden; do
        # laufende Prozesse und Sessions beenden, sonst meckert userdel
        pkill -u "$u" >/dev/null 2>&1
        sleep 0.2
        pkill -9 -u "$u" >/dev/null 2>&1

        if userdel -r "$u" >/dev/null 2>&1; then
            ok "$u geloescht"
        else
            err "$u - userdel fehlgeschlagen"
        fi
    done
}

do_status() {
    local u vorhanden=0 fehlend=0
    for u in $(userlist); do
        if id "$u" >/dev/null 2>&1; then
            printf '  %-10s vorhanden   home: %s\n' \
                "$u" "$(getent passwd "$u" | cut -d: -f6)"
            vorhanden=$((vorhanden+1))
        else
            printf '  %-10s fehlt\n' "$u"
            fehlend=$((fehlend+1))
        fi
    done
    echo
    info "${vorhanden} vorhanden, ${fehlend} fehlen"
}

case "$ACTION" in
    create|anlegen)  do_create ;;
    delete|loeschen) do_delete ;;
    status|check)    do_status ;;
    *) usage ;;
esac
