#!/usr/bin/env bash # 007-postgres-admin-role - Make the iwanhae Linux user a PostgreSQL # superuser so it can administer the cluster via peer auth (psql with no # password, like the postgres OS user). Requires 006 (cluster running). # up: CREATE ROLE iwanhae LOGIN SUPERUSER (idempotent; re-run promotes) # down: DROP ROLE iwanhae (with hint if it owns objects in some database) set -euo pipefail ROLE=iwanhae role_exists() { runuser -u postgres -- psql -v ON_ERROR_STOP=1 -tAc \ "SELECT 1 FROM pg_roles WHERE rolname='$ROLE'" | grep -q 1 } case "${1:-}" in up) if role_exists; then runuser -u postgres -- psql -v ON_ERROR_STOP=1 -qc \ "ALTER ROLE $ROLE WITH LOGIN SUPERUSER" echo " role $ROLE already existed - promoted to LOGIN SUPERUSER" else runuser -u postgres -- psql -v ON_ERROR_STOP=1 -qc \ "CREATE ROLE $ROLE WITH LOGIN SUPERUSER" echo " role $ROLE created: LOGIN SUPERUSER" fi # end-to-end proof: connect over the unix socket as the OS user (peer) check=$(runuser -u "$ROLE" -- psql -d postgres -tAc \ "SELECT current_user || ' (superuser=' || rolsuper || ')' FROM pg_roles WHERE rolname = current_user") echo " peer-auth check: $check" ;; status) if [[ $EUID -eq 0 ]]; then q() { runuser -u postgres -- psql -d postgres -v ON_ERROR_STOP=1 -tAc "$1"; } elif psql -d postgres -tAc 'SELECT 1' >/dev/null 2>&1; then q() { psql -d postgres -v ON_ERROR_STOP=1 -tAc "$1"; } else echo "? needs root or peer DB access to verify" exit 2 fi row=$(q "SELECT rolsuper::text || '/' || rolcanlogin FROM pg_roles WHERE rolname='$ROLE'") [[ -n $row ]] || { echo "DRIFT role $ROLE does not exist"; exit 1; } [[ $row == true/true ]] || { echo "DRIFT role $ROLE super/login=$row (want true/true)"; exit 1; } echo "OK role $ROLE exists: superuser + login" ;; down) if role_exists; then if runuser -u postgres -- psql -v ON_ERROR_STOP=1 -qc "DROP ROLE $ROLE"; then echo " role $ROLE dropped" else echo "cannot drop $ROLE - it owns objects. In EVERY database it has objects run:" >&2 echo " runuser -u postgres -- psql -d -c 'DROP OWNED BY $ROLE;'" >&2 exit 1 fi else echo " role $ROLE does not exist - nothing to do" fi ;; esac