Add privilege diagnostic script for database privilege analysis
- privilege_diagnostic.sh: Comprehensive script to analyze database privileges - Checks database access privileges, roles, and globals.sql content - Helps diagnose privilege preservation issues after restore - Includes detailed reporting of privilege states and backup contents
This commit is contained in:
99
privilege_diagnostic.sh
Executable file
99
privilege_diagnostic.sh
Executable file
@@ -0,0 +1,99 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
#
|
||||||
|
# Database Privilege Diagnostic Script
|
||||||
|
# Run this on both hosts to compare privilege states
|
||||||
|
#
|
||||||
|
|
||||||
|
echo "=============================================="
|
||||||
|
echo "Database Privilege Diagnostic Report"
|
||||||
|
echo "Host: $(hostname)"
|
||||||
|
echo "Date: $(date)"
|
||||||
|
echo "User: $(whoami)"
|
||||||
|
echo "=============================================="
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "1. DATABASE LIST WITH PRIVILEGES:"
|
||||||
|
echo "=================================="
|
||||||
|
sudo -u postgres psql -c "\l"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "2. DATABASE PRIVILEGES (Detailed):"
|
||||||
|
echo "=================================="
|
||||||
|
sudo -u postgres psql -c "
|
||||||
|
SELECT
|
||||||
|
datname as database_name,
|
||||||
|
datacl as access_privileges,
|
||||||
|
datdba::regrole as owner
|
||||||
|
FROM pg_database
|
||||||
|
WHERE datname NOT IN ('template0', 'template1')
|
||||||
|
ORDER BY datname;
|
||||||
|
"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "3. ROLE/USER LIST:"
|
||||||
|
echo "=================="
|
||||||
|
sudo -u postgres psql -c "\du"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "4. DATABASE-SPECIFIC GRANTS:"
|
||||||
|
echo "============================"
|
||||||
|
for db in $(sudo -u postgres psql -tAc "SELECT datname FROM pg_database WHERE datname NOT IN ('template0', 'template1', 'postgres')"); do
|
||||||
|
echo "--- Database: $db ---"
|
||||||
|
sudo -u postgres psql -d "$db" -c "
|
||||||
|
SELECT
|
||||||
|
schemaname,
|
||||||
|
tablename,
|
||||||
|
tableowner,
|
||||||
|
tablespace
|
||||||
|
FROM pg_tables
|
||||||
|
WHERE schemaname = 'public'
|
||||||
|
LIMIT 5;
|
||||||
|
" 2>/dev/null || echo "Could not connect to $db"
|
||||||
|
done
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "5. GLOBAL OBJECT PRIVILEGES:"
|
||||||
|
echo "============================"
|
||||||
|
sudo -u postgres psql -c "
|
||||||
|
SELECT
|
||||||
|
rolname,
|
||||||
|
rolsuper,
|
||||||
|
rolcreaterole,
|
||||||
|
rolcreatedb,
|
||||||
|
rolcanlogin
|
||||||
|
FROM pg_roles
|
||||||
|
WHERE rolname NOT LIKE 'pg_%'
|
||||||
|
ORDER BY rolname;
|
||||||
|
"
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "6. CHECK globals.sql CONTENT (if exists):"
|
||||||
|
echo "========================================"
|
||||||
|
LATEST_CLUSTER=$(find /var/lib/pgsql/db_backups -name "cluster_*.tar.gz" -type f -printf '%T@ %p\n' 2>/dev/null | sort -n | tail -1 | cut -d' ' -f2-)
|
||||||
|
if [ -n "$LATEST_CLUSTER" ]; then
|
||||||
|
echo "Latest cluster backup: $LATEST_CLUSTER"
|
||||||
|
TEMP_DIR="/tmp/privilege_check_$$"
|
||||||
|
mkdir -p "$TEMP_DIR"
|
||||||
|
tar -xzf "$LATEST_CLUSTER" -C "$TEMP_DIR" 2>/dev/null
|
||||||
|
if [ -f "$TEMP_DIR/globals.sql" ]; then
|
||||||
|
echo "globals.sql content:"
|
||||||
|
echo "==================="
|
||||||
|
head -50 "$TEMP_DIR/globals.sql"
|
||||||
|
echo ""
|
||||||
|
echo "... (showing first 50 lines, check full file if needed)"
|
||||||
|
echo ""
|
||||||
|
echo "Database creation commands in globals.sql:"
|
||||||
|
grep -i "CREATE DATABASE\|GRANT.*DATABASE" "$TEMP_DIR/globals.sql" || echo "No database grants found"
|
||||||
|
else
|
||||||
|
echo "No globals.sql found in backup"
|
||||||
|
fi
|
||||||
|
rm -rf "$TEMP_DIR"
|
||||||
|
else
|
||||||
|
echo "No cluster backup found to examine"
|
||||||
|
fi
|
||||||
|
|
||||||
|
echo ""
|
||||||
|
echo "=============================================="
|
||||||
|
echo "Diagnostic complete. Save this output and"
|
||||||
|
echo "compare between hosts to identify differences."
|
||||||
|
echo "=============================================="
|
||||||
216
privilege_report_testhost.txt
Normal file
216
privilege_report_testhost.txt
Normal file
@@ -0,0 +1,216 @@
|
|||||||
|
==============================================
|
||||||
|
Database Privilege Diagnostic Report
|
||||||
|
Host: psqldb
|
||||||
|
Date: Tue Nov 11 08:09:36 AM UTC 2025
|
||||||
|
User: root
|
||||||
|
==============================================
|
||||||
|
|
||||||
|
1. DATABASE LIST WITH PRIVILEGES:
|
||||||
|
==================================
|
||||||
|
List of databases
|
||||||
|
Name | Owner | Encoding | Locale Provider | Collate | Ctype | ICU Locale | ICU Rules | Access privileges
|
||||||
|
-------------------------+----------+----------+-----------------+-------------+-------------+------------+-----------+-----------------------
|
||||||
|
backup_test_db | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
cli_test_db | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
cluster_restore_test | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
final_test_db | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
large_test_db | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
menu_test_db | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
ownership_test | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
perfect_test_db | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
postgres | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
restored_ownership_test | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
template0 | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | | =c/postgres +
|
||||||
|
| | | | | | | | postgres=CTc/postgres
|
||||||
|
template1 | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | | =c/postgres +
|
||||||
|
| | | | | | | | postgres=CTc/postgres
|
||||||
|
test_restore_timing | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
test_sample_backup | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
test_single_backup | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
timing_test_db | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
ultimate_test_db | postgres | UTF8 | libc | en_US.UTF-8 | en_US.UTF-8 | | |
|
||||||
|
(17 rows)
|
||||||
|
|
||||||
|
|
||||||
|
2. DATABASE PRIVILEGES (Detailed):
|
||||||
|
==================================
|
||||||
|
database_name | access_privileges | owner
|
||||||
|
-------------------------+-------------------+----------
|
||||||
|
backup_test_db | | postgres
|
||||||
|
cli_test_db | | postgres
|
||||||
|
cluster_restore_test | | postgres
|
||||||
|
final_test_db | | postgres
|
||||||
|
large_test_db | | postgres
|
||||||
|
menu_test_db | | postgres
|
||||||
|
ownership_test | | postgres
|
||||||
|
perfect_test_db | | postgres
|
||||||
|
postgres | | postgres
|
||||||
|
restored_ownership_test | | postgres
|
||||||
|
test_restore_timing | | postgres
|
||||||
|
test_sample_backup | | postgres
|
||||||
|
test_single_backup | | postgres
|
||||||
|
timing_test_db | | postgres
|
||||||
|
ultimate_test_db | | postgres
|
||||||
|
(15 rows)
|
||||||
|
|
||||||
|
|
||||||
|
3. ROLE/USER LIST:
|
||||||
|
==================
|
||||||
|
List of roles
|
||||||
|
Role name | Attributes
|
||||||
|
-----------+------------------------------------------------------------
|
||||||
|
postgres | Superuser, Create role, Create DB, Replication, Bypass RLS
|
||||||
|
testowner |
|
||||||
|
|
||||||
|
|
||||||
|
4. DATABASE-SPECIFIC GRANTS:
|
||||||
|
============================
|
||||||
|
--- Database: ultimate_test_db ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+-----------+------------+------------
|
||||||
|
public | test_data | postgres |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--- Database: backup_test_db ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+------------+------------+------------
|
||||||
|
public | users | postgres |
|
||||||
|
public | audit_log | postgres |
|
||||||
|
public | documents | postgres |
|
||||||
|
public | user_files | postgres |
|
||||||
|
public | images | postgres |
|
||||||
|
(5 rows)
|
||||||
|
|
||||||
|
--- Database: cli_test_db ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+------------+------------+------------
|
||||||
|
public | test_table | postgres |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--- Database: cluster_restore_test ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+-----------+------------+------------
|
||||||
|
(0 rows)
|
||||||
|
|
||||||
|
--- Database: final_test_db ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+------------+------------+------------
|
||||||
|
public | test_table | postgres |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--- Database: large_test_db ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+------------------+------------+------------
|
||||||
|
public | large_test_table | postgres |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--- Database: menu_test_db ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+------------+------------+------------
|
||||||
|
public | test_table | postgres |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--- Database: ownership_test ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+-----------+------------+------------
|
||||||
|
public | test_data | testowner |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--- Database: perfect_test_db ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+-----------+------------+------------
|
||||||
|
public | test_data | postgres |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--- Database: restored_ownership_test ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+-----------+------------+------------
|
||||||
|
public | test_data | postgres |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--- Database: test_restore_timing ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+------------+------------+------------
|
||||||
|
public | test_table | postgres |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--- Database: test_sample_backup ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+--------------+------------+------------
|
||||||
|
public | sample_table | postgres |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--- Database: test_single_backup ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+------------+------------+------------
|
||||||
|
public | test_table | postgres |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
--- Database: timing_test_db ---
|
||||||
|
schemaname | tablename | tableowner | tablespace
|
||||||
|
------------+-------------------+------------+------------
|
||||||
|
public | timing_test_table | postgres |
|
||||||
|
(1 row)
|
||||||
|
|
||||||
|
|
||||||
|
5. GLOBAL OBJECT PRIVILEGES:
|
||||||
|
============================
|
||||||
|
rolname | rolsuper | rolcreaterole | rolcreatedb | rolcanlogin
|
||||||
|
-----------+----------+---------------+-------------+-------------
|
||||||
|
postgres | t | t | t | t
|
||||||
|
testowner | f | f | f | t
|
||||||
|
(2 rows)
|
||||||
|
|
||||||
|
|
||||||
|
6. CHECK globals.sql CONTENT (if exists):
|
||||||
|
========================================
|
||||||
|
Latest cluster backup: /var/lib/pgsql/db_backups/cluster_20251110_134826.tar.gz
|
||||||
|
globals.sql content:
|
||||||
|
===================
|
||||||
|
--
|
||||||
|
-- PostgreSQL database cluster dump
|
||||||
|
--
|
||||||
|
|
||||||
|
\restrict sWNr7ksTDJbnJSKSJBd9MGA4t0POFSLcEqaGMSM1uwA3cEmyGaIpD0VJrmAKQjX
|
||||||
|
|
||||||
|
SET default_transaction_read_only = off;
|
||||||
|
|
||||||
|
SET client_encoding = 'UTF8';
|
||||||
|
SET standard_conforming_strings = on;
|
||||||
|
|
||||||
|
--
|
||||||
|
-- Roles
|
||||||
|
--
|
||||||
|
|
||||||
|
CREATE ROLE postgres;
|
||||||
|
ALTER ROLE postgres WITH SUPERUSER INHERIT CREATEROLE CREATEDB LOGIN REPLICATION BYPASSRLS PASSWORD 'SCRAM-SHA-256$4096:8CqV4BNYEk6/Au1ub4otRQ==$PhSfnKEs49UZ6g4CgnFbLlhvbcq5nSkS4RMP5MTqf7E=:xg+3j/oZIF1mbu6SydJbqLem9Bd+ONNK2JeftY7hbL4=';
|
||||||
|
CREATE ROLE testowner;
|
||||||
|
ALTER ROLE testowner WITH NOSUPERUSER INHERIT NOCREATEROLE NOCREATEDB LOGIN NOREPLICATION NOBYPASSRLS PASSWORD 'SCRAM-SHA-256$4096:3TGJ9Dl+y75j46aWS8NtQw==$2C7ebcOIj7vNoIFM54gtUZnjw/UR8h6BorF1g/MLKTQ=:YIMFknJmXGHxvR+rAN2eXtL7LS4ng+iDnqmFkffSsss=';
|
||||||
|
|
||||||
|
--
|
||||||
|
-- User Configurations
|
||||||
|
--
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
\unrestrict sWNr7ksTDJbnJSKSJBd9MGA4t0POFSLcEqaGMSM1uwA3cEmyGaIpD0VJrmAKQjX
|
||||||
|
|
||||||
|
--
|
||||||
|
-- PostgreSQL database cluster dump complete
|
||||||
|
--
|
||||||
|
|
||||||
|
|
||||||
|
... (showing first 50 lines, check full file if needed)
|
||||||
|
|
||||||
|
Database creation commands in globals.sql:
|
||||||
|
No database grants found
|
||||||
|
|
||||||
|
==============================================
|
||||||
|
Diagnostic complete. Save this output and
|
||||||
|
compare between hosts to identify differences.
|
||||||
|
==============================================
|
||||||
Reference in New Issue
Block a user