SambaDC/scripts/mksecrets.sh
2026-09-24 11:29:54 -05:00

48 lines
1.8 KiB
Bash
Executable file

#!/usr/bin/env bash
# Create the secrets directory with a strong random administrator password (or keep your own).
# ./scripts/mksecrets.sh -> generates secrets/ad_admin.password (0600)
# ./scripts/mksecrets.sh 'mypw' -> stores the given password
set -euo pipefail
cd "$(dirname "$0")/.."
umask 077
mkdir -p secrets
# Same trap as backup.sh: Docker may have created this dir root-owned for a bind mount.
if [ ! -w secrets ]; then
echo "!! 'secrets' is not writable by $(whoami) (owned $(stat -c '%U:%G %a' secrets)) - fix: sudo chown $(whoami) secrets" >&2
exit 1
fi
F=secrets/ad_admin.password
if [ -e "$F" ] && [ -z "${1:-}" ]; then
echo "refusing to overwrite existing $F" >&2
echo "use 'make passwd' to rotate, or delete it first" >&2
exit 1
fi
if [ -n "${1:-}" ]; then
printf '%s' "$1" > "$F"
else
# 24 chars, upper+lower+digit+symbol -> comfortably clears AD complexity.
# Deliberately no `tr ... | head -c N`: under `set -o pipefail` the SIGPIPE that kills
# `tr` when head exits makes the whole pipeline fail (exit 141). One byte per dd instead.
gen_class() { # $1 = char set, $2 = how many chars
s=""
while [ "${#s}" -lt "$2" ]; do
c="$(dd if=/dev/urandom bs=1 count=1 2>/dev/null | tr -dc "$1")"
[ -n "$c" ] && s="${s}${c}"
done
printf '%s' "$s"
}
pw="$(gen_class 'A-HJ-NP-Za-km-z2-9' 6)"
pw+="$(gen_class 'A-Z' 3)"
pw+="$(gen_class 'a-z' 8)"
pw+="$(gen_class '#@%!$^&*' 3)"
printf '%s' "$pw" > "$F"
fi
chmod 600 "$F"
echo "wrote $F (mode $(stat -c '%a' "$F"))"
echo " password length: $(tr -d '\n' < "$F" | wc -c)"
echo " store it in your password vault now; nothing else prints it again."
echo " AD also needs an admin UPN; login as ${AD_REALM:-AD.EXAMPLE.COM}\\${AD_ADMIN_USER:-administrator}"