Skip to content

Commit 1e2cc53

Browse files
committed
postgresql: Fix authentication for setup and backup
- Use peer auth during initial setup to allow passwordless role creation - After setup, switch to hybrid auth: system user keeps peer (for backups), all other users require scram-sha-256 - Host connections always require scram-sha-256 - Update backup commands to use peer auth (no -h flag)
1 parent 7149c5a commit 1e2cc53

File tree

2 files changed

+55
-23
lines changed

2 files changed

+55
-23
lines changed

spk/postgresql/src/service-setup.sh

Lines changed: 47 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -17,10 +17,38 @@ BACKUP_DATE=$(date +%Y-%m-%d)
1717
PG_BACKUP_CONF_DIR="${PG_BACKUP}/config_${BACKUP_DATE}"
1818
PG_BACKUP_DUMP_DIR="${PG_BACKUP}/databases_${BACKUP_DATE}"
1919

20+
# Helper function to run commands as the effective user
21+
# On DSM 7: scripts run as package user, so run directly
22+
# On DSM 6: scripts run as root, so use su to switch user
23+
run_as_user()
24+
{
25+
if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -ge 7 ]; then
26+
eval "$@"
27+
else
28+
su - ${EFF_USER} -s /bin/sh -c "$@"
29+
fi
30+
}
31+
2032
validate_preuninst()
2133
{
2234
# Validate backup directory if user requested database backup
2335
if [ "${wizard_pg_dump_database}" = "true" ]; then
36+
# Validate password by attempting to connect
37+
# Start server temporarily for validation
38+
run_as_user "${SYNOPKG_PKGDEST}/bin/pg_ctl -D ${DATABASE_DIR} -l ${LOG_FILE} start"
39+
40+
export PGPASSWORD="${wizard_pg_password}"
41+
if ! ${SYNOPKG_PKGDEST}/bin/psql -h localhost -p ${SERVICE_PORT} -U ${EFF_USER} -d postgres -c "SELECT 1" > /dev/null 2>&1; then
42+
unset PGPASSWORD
43+
run_as_user "${SYNOPKG_PKGDEST}/bin/pg_ctl -D ${DATABASE_DIR} stop"
44+
echo "Incorrect PostgreSQL administrator password"
45+
exit 1
46+
fi
47+
unset PGPASSWORD
48+
49+
# Stop server after validation
50+
run_as_user "${SYNOPKG_PKGDEST}/bin/pg_ctl -D ${DATABASE_DIR} stop"
51+
2452
if [ -z "${PG_BACKUP}" ]; then
2553
echo "Error: Backup directory path is empty."
2654
exit 1
@@ -40,18 +68,6 @@ validate_preuninst()
4068
fi
4169
}
4270

43-
# Helper function to run commands as the effective user
44-
# On DSM 7: scripts run as package user, so run directly
45-
# On DSM 6: scripts run as root, so use su to switch user
46-
run_as_user()
47-
{
48-
if [ "${SYNOPKG_DSM_VERSION_MAJOR}" -ge 7 ]; then
49-
eval "$@"
50-
else
51-
su - ${EFF_USER} -s /bin/sh -c "$@"
52-
fi
53-
}
54-
5571
service_postinst()
5672
{
5773
# On DSM 6 (running as root), create data directory and set ownership
@@ -68,8 +84,9 @@ service_postinst()
6884
chown ${EFF_USER}:$(id -gn ${EFF_USER}) "${PWFILE}"
6985
fi
7086

71-
# Initialize with scram-sha-256 authentication and password file
72-
run_as_user "${SYNOPKG_PKGDEST}/bin/initdb -D ${DATABASE_DIR} --encoding=UTF8 --locale=en_US.UTF8 --auth-local=scram-sha-256 --auth-host=scram-sha-256 --pwfile=${PWFILE}"
87+
# Initialize database with peer auth for local connections (allows setup without password)
88+
# scram-sha-256 for host connections from the start
89+
run_as_user "${SYNOPKG_PKGDEST}/bin/initdb -D ${DATABASE_DIR} --encoding=UTF8 --locale=en_US.UTF8 --auth-local=peer --auth-host=scram-sha-256 --pwfile=${PWFILE}"
7390

7491
# Remove password file after initialization
7592
rm -f "${PWFILE}"
@@ -85,12 +102,17 @@ service_postinst()
85102
# Start server temporarily to create roles
86103
run_as_user "${SYNOPKG_PKGDEST}/bin/pg_ctl -D ${DATABASE_DIR} -l ${LOG_FILE} start"
87104

88-
# Set password for the system user (connect via Unix socket)
105+
# Set password for the system user (peer auth allows connection without password via Unix socket)
89106
run_as_user "${SYNOPKG_PKGDEST}/bin/psql -h ${SYNOPKG_PKGVAR} -p ${SERVICE_PORT} -d postgres -c \"ALTER ROLE \\\"${EFF_USER}\\\" WITH PASSWORD '${PG_PASSWORD}';\""
90107

91-
# Create administrator role from wizard (connect via Unix socket)
108+
# Create administrator role from wizard (peer auth via Unix socket)
92109
run_as_user "${SYNOPKG_PKGDEST}/bin/psql -h ${SYNOPKG_PKGVAR} -p ${SERVICE_PORT} -d postgres -c \"CREATE ROLE ${PG_USERNAME} PASSWORD '${PG_PASSWORD}' SUPERUSER CREATEDB CREATEROLE INHERIT LOGIN REPLICATION BYPASSRLS;\""
93110

111+
# Switch local authentication to scram-sha-256 for regular users
112+
# Keep peer auth for the system user (sc-postgresql) to allow passwordless backups
113+
# Order matters: first matching rule wins, so system user rule must come first
114+
run_as_user "sed -e 's/^local.*all.*all.*peer$/local all ${EFF_USER} peer\\nlocal all all scram-sha-256/' -i ${HBA_FILE}"
115+
94116
# Stop server (will be started by DSM)
95117
run_as_user "${SYNOPKG_PKGDEST}/bin/pg_ctl -D ${DATABASE_DIR} stop"
96118
}
@@ -102,20 +124,23 @@ service_preuninst()
102124
# Start server for backup
103125
run_as_user "${SYNOPKG_PKGDEST}/bin/pg_ctl -D ${DATABASE_DIR} -l ${LOG_FILE} start"
104126

105-
# Create backup directories with package user ownership
106-
install -d -o ${EFF_USER} -g $(id -gn ${EFF_USER}) -m 755 "${PG_BACKUP_CONF_DIR}"
107-
install -d -o ${EFF_USER} -g $(id -gn ${EFF_USER}) -m 755 "${PG_BACKUP_DUMP_DIR}"
127+
# Create backup directories (running as root has write access to shared folders)
128+
mkdir -p "${PG_BACKUP_CONF_DIR}"
129+
mkdir -p "${PG_BACKUP_DUMP_DIR}"
108130

109131
# Backup configuration files
110132
cp "${DATABASE_DIR}/pg_hba.conf" "${PG_BACKUP_CONF_DIR}/"
111133
cp "${DATABASE_DIR}/pg_ident.conf" "${PG_BACKUP_CONF_DIR}/"
112134
cp "${DATABASE_DIR}/postgresql.auto.conf" "${PG_BACKUP_CONF_DIR}/"
113135
cp "${DATABASE_DIR}/postgresql.conf" "${PG_BACKUP_CONF_DIR}/"
114136

115-
# Dump all databases (excluding templates) - connect via Unix socket
116-
for database in $(run_as_user "${SYNOPKG_PKGDEST}/bin/psql -h ${SYNOPKG_PKGVAR} -A -t -p ${SERVICE_PORT} -d postgres -c 'SELECT datname FROM pg_database WHERE datistemplate = false'"); do
117-
run_as_user "${SYNOPKG_PKGDEST}/bin/pg_dump -h ${SYNOPKG_PKGVAR} -p ${SERVICE_PORT} -Fc ${database} -f ${PG_BACKUP_DUMP_DIR}/${database}.dump"
137+
# Dump all databases (excluding templates)
138+
# Use TCP/IP connection with password (PGPASSWORD) - runs as root to write to shared folders
139+
export PGPASSWORD="${wizard_pg_password}"
140+
for database in $(${SYNOPKG_PKGDEST}/bin/psql -h localhost -p ${SERVICE_PORT} -U ${EFF_USER} -A -t -d postgres -c 'SELECT datname FROM pg_database WHERE datistemplate = false'); do
141+
${SYNOPKG_PKGDEST}/bin/pg_dump -h localhost -p ${SERVICE_PORT} -U ${EFF_USER} -Fc ${database} -f "${PG_BACKUP_DUMP_DIR}/${database}.dump"
118142
done
143+
unset PGPASSWORD
119144

120145
# Stop server
121146
run_as_user "${SYNOPKG_PKGDEST}/bin/pg_ctl -D ${DATABASE_DIR} stop"

spk/postgresql/src/wizard/uninstall_uifile

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,9 +10,16 @@
1010
"desc": "Export databases and configuration files before uninstalling",
1111
"defaultValue": true
1212
}]
13+
}, {
14+
"type": "password",
15+
"desc": "Enter the PostgreSQL administrator password for database backup",
16+
"subitems": [{
17+
"key": "wizard_pg_password",
18+
"desc": "Administrator password"
19+
}]
1320
}, {
1421
"type": "textfield",
15-
"desc": "Specify the backup directory. The directory must be writable by the package user (sc-postgresql).",
22+
"desc": "Specify the backup directory.",
1623
"subitems": [{
1724
"key": "wizard_pg_dump_directory",
1825
"desc": "Backup directory",

0 commit comments

Comments
 (0)