Skip to content

Commit bea0f8e

Browse files
committed
Github Issue 24: check PQresultStatus for pg_stop_backup()
1 parent 3b45f96 commit bea0f8e

File tree

2 files changed

+116
-8
lines changed

2 files changed

+116
-8
lines changed

src/backup.c

Lines changed: 21 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -1544,6 +1544,7 @@ pg_stop_backup(pgBackup *backup)
15441544
pgFile *file;
15451545
size_t len;
15461546
char *val = NULL;
1547+
char *stop_backup_query;
15471548

15481549
/*
15491550
* We will use this values if there are no transactions between start_lsn
@@ -1600,26 +1601,25 @@ pg_stop_backup(pgBackup *backup)
16001601
* pg_stop_backup(false) copy of the backup label and tablespace map
16011602
* so they can be written to disk by the caller.
16021603
*/
1603-
sent = pgut_send(conn,
1604-
"SELECT"
1604+
stop_backup_query = "SELECT"
16051605
" pg_catalog.txid_snapshot_xmax(pg_catalog.txid_current_snapshot()),"
16061606
" current_timestamp(0)::timestamptz,"
16071607
" lsn,"
16081608
" labelfile,"
16091609
" spcmapfile"
1610-
" FROM pg_catalog.pg_stop_backup(false)",
1611-
0, NULL, WARNING);
1610+
" FROM pg_catalog.pg_stop_backup(false)";
1611+
16121612
}
16131613
else
16141614
{
16151615

1616-
sent = pgut_send(conn,
1617-
"SELECT"
1616+
stop_backup_query = "SELECT"
16181617
" pg_catalog.txid_snapshot_xmax(pg_catalog.txid_current_snapshot()),"
16191618
" current_timestamp(0)::timestamptz,"
1620-
" pg_catalog.pg_stop_backup() as lsn",
1621-
0, NULL, WARNING);
1619+
" pg_catalog.pg_stop_backup() as lsn";
16221620
}
1621+
1622+
sent = pgut_send(conn, stop_backup_query, 0, NULL, WARNING);
16231623
pg_stop_backup_is_sent = true;
16241624
if (!sent)
16251625
elog(ERROR, "Failed to send pg_stop_backup query");
@@ -1664,10 +1664,23 @@ pg_stop_backup(pgBackup *backup)
16641664
break;
16651665
}
16661666
}
1667+
1668+
/* Check successfull execution of pg_stop_backup() */
16671669
if (!res)
16681670
elog(ERROR, "pg_stop backup() failed");
16691671
else
1672+
{
1673+
switch (PQresultStatus(res))
1674+
{
1675+
case PGRES_TUPLES_OK:
1676+
case PGRES_COMMAND_OK:
1677+
break;
1678+
default:
1679+
elog(ERROR, "query failed: %s query was: %s",
1680+
PQerrorMessage(conn), stop_backup_query);
1681+
}
16701682
elog(INFO, "pg_stop backup() successfully executed");
1683+
}
16711684

16721685
backup_in_progress = false;
16731686

tests/auth_test.py

Lines changed: 95 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
import os
77
import unittest
88
import signal
9+
import time
910

1011
from .helpers.ptrack_helpers import ProbackupTest, ProbackupException
1112
from testgres import StartNodeException
@@ -20,6 +21,100 @@
2021
skip_test = True
2122

2223

24+
class SimpleAuthTest(ProbackupTest, unittest.TestCase):
25+
26+
# @unittest.skip("skip")
27+
def test_backup_via_unpriviledged_user(self):
28+
"""
29+
Make node, create unpriviledged user, try to
30+
run a backups without EXECUTE rights on
31+
certain functions
32+
"""
33+
fname = self.id().split('.')[3]
34+
node = self.make_simple_node(
35+
base_dir="{0}/{1}/node".format(module_name, fname),
36+
set_replication=True,
37+
initdb_params=['--data-checksums'],
38+
pg_options={'wal_level': 'replica', 'max_wal_senders': '2'}
39+
)
40+
backup_dir = os.path.join(self.tmp_path, module_name, fname, 'backup')
41+
self.init_pb(backup_dir)
42+
self.add_instance(backup_dir, 'node', node)
43+
self.set_archiving(backup_dir, 'node', node)
44+
node.start()
45+
46+
node.safe_psql("postgres", "CREATE ROLE backup with LOGIN")
47+
48+
try:
49+
self.backup_node(
50+
backup_dir, 'node', node, options=['-U', 'backup'])
51+
self.assertEqual(
52+
1, 0,
53+
"Expecting Error due to missing grant on EXECUTE.")
54+
except ProbackupException as e:
55+
self.assertIn(
56+
"ERROR: query failed: ERROR: permission denied "
57+
"for function pg_start_backup", e.message,
58+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
59+
repr(e.message), self.cmd))
60+
61+
node.safe_psql(
62+
"postgres",
63+
"GRANT EXECUTE ON FUNCTION"
64+
" pg_start_backup(text, boolean, boolean) TO backup;")
65+
66+
time.sleep(1)
67+
try:
68+
self.backup_node(
69+
backup_dir, 'node', node, options=['-U', 'backup'])
70+
self.assertEqual(
71+
1, 0,
72+
"Expecting Error due to missing grant on EXECUTE.")
73+
except ProbackupException as e:
74+
self.assertIn(
75+
"ERROR: query failed: ERROR: permission denied for function "
76+
"pg_create_restore_point\nquery was: "
77+
"SELECT pg_catalog.pg_create_restore_point($1)", e.message,
78+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
79+
repr(e.message), self.cmd))
80+
81+
node.safe_psql(
82+
"postgres",
83+
"GRANT EXECUTE ON FUNCTION"
84+
" pg_create_restore_point(text) TO backup;")
85+
86+
time.sleep(1)
87+
88+
try:
89+
self.backup_node(
90+
backup_dir, 'node', node, options=['-U', 'backup'])
91+
self.assertEqual(
92+
1, 0,
93+
"Expecting Error due to missing grant on EXECUTE.")
94+
except ProbackupException as e:
95+
self.assertIn(
96+
"ERROR: query failed: ERROR: permission denied "
97+
"for function pg_stop_backup", e.message,
98+
'\n Unexpected Error Message: {0}\n CMD: {1}'.format(
99+
repr(e.message), self.cmd))
100+
101+
if self.get_version(node) < self.version_to_num('10.0'):
102+
node.safe_psql(
103+
"postgres",
104+
"GRANT EXECUTE ON FUNCTION pg_stop_backup(boolean) TO backup")
105+
else:
106+
node.safe_psql(
107+
"postgres",
108+
"GRANT EXECUTE ON FUNCTION "
109+
"pg_stop_backup(boolean, boolean) TO backup")
110+
111+
self.backup_node(
112+
backup_dir, 'node', node, options=['-U', 'backup'])
113+
114+
# Clean after yourself
115+
self.del_test_dir(module_name, fname)
116+
117+
23118
class AuthTest(unittest.TestCase):
24119
pb = None
25120
node = None

0 commit comments

Comments
 (0)