Files
PacketStation/deploy/samba/entrypoint.sh
T

138 lines
4.4 KiB
Bash
Raw Normal View History

#!/usr/bin/env bash
# Samba AD DC for CI. Provisions PSTEST.LOCAL on first start, makes the TLS certificates,
# seeds the OU tree, groups and users once, refreshes /export, then runs samba in the foreground.
# Never prints a password. Run as root (Samba needs it). tini is PID 1.
set -euo pipefail
REALM=PSTEST.LOCAL
DOMAIN=PSTEST
HOST=dc1
FQDN=dc1.pstest.local
STATE=/var/lib/samba
PRIVATE=$STATE/private
TLS=$PRIVATE/tls
CONF_DIR=$STATE/etc # smb.conf lives on the volume so it survives a recreated container
CONF=$CONF_DIR/smb.conf
EXPORT=/export
ADMIN_SECRET=/run/secrets/samba_admin_password
log() { echo "samba-dc: $*"; }
read_secret() {
# One line, CR stripped. Never echoed.
local f=$1
if [ ! -s "$f" ]; then
log "missing or empty secret file $f" >&2
exit 1
fi
head -n 1 "$f" | tr -d '\r\n'
}
make_tls() {
log "making the CI CA and the server certificate"
mkdir -p "$TLS"
local tmp
tmp=$(mktemp -d)
openssl req -x509 -new -nodes -newkey rsa:3072 -sha256 -days 3650 \
-keyout "$TLS/ca.key" -out "$TLS/ca.pem" -subj "/CN=PSTEST CI CA" \
-addext "basicConstraints=critical,CA:TRUE" \
-addext "keyUsage=critical,keyCertSign,cRLSign" \
-addext "subjectKeyIdentifier=hash" 2>/dev/null
openssl req -new -nodes -newkey rsa:3072 -sha256 \
-keyout "$TLS/key.pem" -out "$tmp/server.csr" -subj "/CN=$FQDN" 2>/dev/null
cat > "$tmp/server.ext" <<EXT
basicConstraints=critical,CA:FALSE
keyUsage=critical,digitalSignature,keyEncipherment
extendedKeyUsage=serverAuth
subjectAltName=DNS:$FQDN,DNS:$HOST
subjectKeyIdentifier=hash
authorityKeyIdentifier=keyid,issuer
EXT
openssl x509 -req -sha256 -days 3650 -in "$tmp/server.csr" \
-CA "$TLS/ca.pem" -CAkey "$TLS/ca.key" -CAcreateserial -CAserial "$tmp/ca.srl" \
-extfile "$tmp/server.ext" -out "$TLS/cert.pem" 2>/dev/null
rm -rf "$tmp"
# Samba refuses a private key that others can read.
chmod 0600 "$TLS/key.pem" "$TLS/ca.key"
chmod 0644 "$TLS/ca.pem" "$TLS/cert.pem"
openssl verify -CAfile "$TLS/ca.pem" "$TLS/cert.pem" >/dev/null
}
set_global() {
# Add lines right after [global] in smb.conf.
local line
for line in "$@"; do
sed -i "/^\[global\]/a $line" "$CONF"
done
}
provision() {
log "provisioning $REALM (first start)"
local adminpass
adminpass=$(read_secret "$ADMIN_SECRET")
rm -f /etc/samba/smb.conf
mkdir -p "$CONF_DIR"
# The sysvol ACL step needs security.* xattrs, so the container runs with CAP_SYS_ADMIN
# (compose.ci.yaml). Samba 4.17 has no --use-xattrs option. --dns-backend=NONE: the stack
# resolves names itself.
samba-tool domain provision \
--use-rfc2307 \
--realm="$REALM" \
--domain="$DOMAIN" \
--host-name="$HOST" \
--server-role=dc \
--dns-backend=NONE \
--adminpass="$adminpass" >/var/log/samba-provision.log 2>&1 || {
log "provision failed; last lines of the log follow" >&2
tail -n 40 /var/log/samba-provision.log >&2
exit 1
}
unset adminpass
mv /etc/samba/smb.conf "$CONF"
ln -sf "$CONF" /etc/samba/smb.conf
make_tls
# Simple binds only over TLS (LDAPS or STARTTLS), like PESCO's DCs. Plain LDAP simple binds fail.
set_global \
"ldap server require strong auth = allow_sasl_over_tls" \
"tls keyfile = $TLS/key.pem" \
"tls certfile = $TLS/cert.pem" \
"tls cafile = $TLS/ca.pem" \
"tls enabled = yes"
# Relaxed policy: CI passwords are random per run and never change.
samba-tool domain passwordsettings set \
--complexity=off --min-pwd-age=0 --max-pwd-age=0 --history-length=0 >/dev/null
cp "$PRIVATE/krb5.conf" /etc/krb5.conf 2>/dev/null || true
log "provisioned"
}
if [ ! -f "$PRIVATE/sam.ldb" ]; then
provision
else
log "already provisioned; skipping"
ln -sf "$CONF" /etc/samba/smb.conf
cp "$PRIVATE/krb5.conf" /etc/krb5.conf 2>/dev/null || true
fi
# Seed once, offline, before samba starts. samba-tool writes sam.ldb directly.
if [ ! -f "$PRIVATE/.seeded" ]; then
/usr/local/bin/seed.sh
date -u +%Y-%m-%dT%H:%M:%SZ > "$PRIVATE/.seeded"
else
log "already seeded; skipping"
fi
# Refresh the export on every start: the CA, the users file and the seeded marker.
mkdir -p "$EXPORT"
chmod 0755 "$EXPORT"
rm -f "$EXPORT/seeded"
install -m 0444 "$TLS/ca.pem" "$EXPORT/ca.pem"
install -m 0444 "$PRIVATE/users.json" "$EXPORT/users.json"
cp "$PRIVATE/.seeded" "$EXPORT/seeded"
chmod 0444 "$EXPORT/seeded"
log "exported ca.pem and users.json to $EXPORT"
log "starting samba"
exec samba -i -F --no-process-group