#!/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}"