Browse Source

PostgreSQL: Correctly set database owner and schema object owner

Also, grant permission to create schema objects when given "rw"
abilities.
master
Peter J. Jones 4 months ago
parent
commit
9547da5974
Signed by: Peter Jones <pjones@devalot.com> GPG Key ID: 9DAFAA8D01941E49

+ 2
- 0
modules/services/databases/postgresql/create-grant.sh View File

@@ -91,6 +91,8 @@ echo_grants() {
fi

if [ "$option_access" = "w" ] || [ "$option_access" = "rw" ]; then
echo "GRANT CREATE ON SCHEMA public TO $option_user;"

echo "GRANT $w_list ON ALL TABLES IN SCHEMA public TO $option_user;"
echo "ALTER DEFAULT PRIVILEGES IN SCHEMA public GRANT $w_list ON TABLES TO $option_user;"


+ 9
- 1
modules/services/databases/postgresql/default.nix View File

@@ -218,6 +218,13 @@ let
owner = find [database.owner];
in (concatMapStringsSep "\n" (createReadGrant database) ro) +
(concatMapStringsSep "\n" (createGrant database) rw);

# Update database and object ownership:
updateOwners = database: ''
${scripts}/bin/update-owner.sh \
-d "${database.name}" \
-o "${database.owner}"
'';
in
{
#### Interface
@@ -268,7 +275,8 @@ in
'' + (concatMapStringsSep "\n" createUser (attrValues cfg.accounts))
+ (lockAccounts (attrValues cfg.accounts))
+ (concatMapStringsSep "\n" createDB (attrValues cfg.databases))
+ (concatMapStringsSep "\n" createGrants (attrValues cfg.databases));
+ (concatMapStringsSep "\n" createGrants (attrValues cfg.databases))
+ (concatMapStringsSep "\n" updateOwners (attrValues cfg.databases));
};
};
}

+ 1
- 0
modules/services/databases/postgresql/scripts.nix View File

@@ -16,6 +16,7 @@ pkgs.stdenvNoCC.mkDerivation {
substituteAll ${./create-db.sh} $out/bin/create-db.sh
substituteAll ${./create-grant.sh} $out/bin/create-grant.sh
substituteAll ${./nologin.sh} $out/bin/nologin.sh
substituteAll ${./update-owner.sh} $out/bin/update-owner.sh

chmod 555 $out/bin/*.sh
'';

+ 110
- 0
modules/services/databases/postgresql/update-owner.sh View File

@@ -0,0 +1,110 @@
#!/bin/bash

################################################################################
# Update object ownership.
set -e

################################################################################
option_owner=""
option_database=""
option_schema="public"

################################################################################
usage () {
cat <<EOF
Usage: update-owner.sh [options]

-d NAME Database name to alter
-h This message
-o NAME Object owner

EOF
}

################################################################################
while getopts "d:ho:" o; do
case "${o}" in
d) option_database=$OPTARG
;;

h) usage
exit
;;

o) option_owner=$OPTARG
;;

*) exit 1
;;
esac
done

shift $((OPTIND-1))

################################################################################
_psql() {
@sudo@ -u @superuser@ -H psql "$@"
}

################################################################################
set_database_owner_sql() {
echo "ALTER DATABASE $option_database OWNER TO $option_owner;"
}

################################################################################
# Send STDIN to psql and output just the row data.
list_selected_rows() {
_psql --tuples-only --no-align --dbname="$option_database"
}

################################################################################
list_tables() {
local schema=$1

echo "SELECT tablename FROM pg_tables WHERE schemaname = '${schema}';" | \
list_selected_rows
}

################################################################################
list_sequences() {
local schema=$1

echo "SELECT sequence_name FROM information_schema.sequences WHERE sequence_schema = '${schema}';" | \
list_selected_rows
}

################################################################################
list_views() {
local schema=$1

echo "SELECT table_name FROM information_schema.views WHERE table_schema = '${schema}';" | \
list_selected_rows
}

################################################################################
update_object_owner() {
local object_type=$1
local object=$2

echo "ALTER $object_type \"$object\" OWNER TO $option_owner;"
}

################################################################################
sql_file=$(mktemp)
set_database_owner_sql > "$sql_file"

for t in $(list_tables "$option_schema"); do
update_object_owner "TABLE" "$t" >> "$sql_file"
done

for s in $(list_sequences "$option_schema"); do
update_object_owner "SEQUENCE" "$s" >> "$sql_file"
done

for v in $(list_views "$option_schema"); do
update_object_owner "VIEW" "$v" >> "$sql_file"
done

chown @superuser@ "$sql_file"
_psql --dbname="$option_database" --file="$sql_file" --single-transaction
rm "$sql_file"

Loading…
Cancel
Save