mirror of
https://github.com/postgres/postgres.git
synced 2025-07-28 23:42:10 +03:00
Use GRANT system to manage access to sensitive functions
Now that pg_dump will properly dump out any ACL changes made to functions which exist in pg_catalog, switch to using the GRANT system to manage access to those functions. This means removing 'if (!superuser()) ereport()' checks from the functions themselves and then REVOKEing EXECUTE right from 'public' for these functions in system_views.sql. Reviews by Alexander Korotkov, Jose Luis Tallon
This commit is contained in:
@ -66,6 +66,9 @@ nonexclusive_base_backup_cleanup(int code, Datum arg)
|
||||
* contains the user-supplied label string (typically this would be used
|
||||
* to tell where the backup dump will be stored) and the starting time and
|
||||
* starting WAL location for the dump.
|
||||
*
|
||||
* Permission checking for this function is managed through the normal
|
||||
* GRANT system.
|
||||
*/
|
||||
Datum
|
||||
pg_start_backup(PG_FUNCTION_ARGS)
|
||||
@ -79,11 +82,6 @@ pg_start_backup(PG_FUNCTION_ARGS)
|
||||
|
||||
backupidstr = text_to_cstring(backupid);
|
||||
|
||||
if (!superuser() && !has_rolreplication(GetUserId()))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("must be superuser or replication role to run a backup")));
|
||||
|
||||
if (exclusive_backup_running || nonexclusive_backup_running)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
@ -142,17 +140,15 @@ pg_start_backup(PG_FUNCTION_ARGS)
|
||||
* Note: this version is only called to stop an exclusive backup. The function
|
||||
* pg_stop_backup_v2 (overloaded as pg_stop_backup in SQL) is called to
|
||||
* stop non-exclusive backups.
|
||||
*
|
||||
* Permission checking for this function is managed through the normal
|
||||
* GRANT system.
|
||||
*/
|
||||
Datum
|
||||
pg_stop_backup(PG_FUNCTION_ARGS)
|
||||
{
|
||||
XLogRecPtr stoppoint;
|
||||
|
||||
if (!superuser() && !has_rolreplication(GetUserId()))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be superuser or replication role to run a backup"))));
|
||||
|
||||
if (nonexclusive_backup_running)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
@ -179,6 +175,9 @@ pg_stop_backup(PG_FUNCTION_ARGS)
|
||||
* Works the same as pg_stop_backup, except for non-exclusive backups it returns
|
||||
* the backup label and tablespace map files as text fields in as part of the
|
||||
* resultset.
|
||||
*
|
||||
* Permission checking for this function is managed through the normal
|
||||
* GRANT system.
|
||||
*/
|
||||
Datum
|
||||
pg_stop_backup_v2(PG_FUNCTION_ARGS)
|
||||
@ -205,11 +204,6 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS)
|
||||
errmsg("materialize mode required, but it is not " \
|
||||
"allowed in this context")));
|
||||
|
||||
if (!superuser() && !has_rolreplication(GetUserId()))
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be superuser or replication role to run a backup"))));
|
||||
|
||||
/* Build a tuple descriptor for our result type */
|
||||
if (get_call_result_type(fcinfo, NULL, &tupdesc) != TYPEFUNC_COMPOSITE)
|
||||
elog(ERROR, "return type must be a row type");
|
||||
@ -285,17 +279,15 @@ pg_stop_backup_v2(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* pg_switch_xlog: switch to next xlog file
|
||||
*
|
||||
* Permission checking for this function is managed through the normal
|
||||
* GRANT system.
|
||||
*/
|
||||
Datum
|
||||
pg_switch_xlog(PG_FUNCTION_ARGS)
|
||||
{
|
||||
XLogRecPtr switchpoint;
|
||||
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be superuser to switch transaction log files"))));
|
||||
|
||||
if (RecoveryInProgress())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
@ -312,6 +304,9 @@ pg_switch_xlog(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* pg_create_restore_point: a named point for restore
|
||||
*
|
||||
* Permission checking for this function is managed through the normal
|
||||
* GRANT system.
|
||||
*/
|
||||
Datum
|
||||
pg_create_restore_point(PG_FUNCTION_ARGS)
|
||||
@ -320,11 +315,6 @@ pg_create_restore_point(PG_FUNCTION_ARGS)
|
||||
char *restore_name_str;
|
||||
XLogRecPtr restorepoint;
|
||||
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be superuser to create a restore point"))));
|
||||
|
||||
if (RecoveryInProgress())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
@ -546,15 +536,13 @@ pg_xlogfile_name(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* pg_xlog_replay_pause - pause recovery now
|
||||
*
|
||||
* Permission checking for this function is managed through the normal
|
||||
* GRANT system.
|
||||
*/
|
||||
Datum
|
||||
pg_xlog_replay_pause(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be superuser to control recovery"))));
|
||||
|
||||
if (!RecoveryInProgress())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
@ -568,15 +556,13 @@ pg_xlog_replay_pause(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* pg_xlog_replay_resume - resume recovery now
|
||||
*
|
||||
* Permission checking for this function is managed through the normal
|
||||
* GRANT system.
|
||||
*/
|
||||
Datum
|
||||
pg_xlog_replay_resume(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be superuser to control recovery"))));
|
||||
|
||||
if (!RecoveryInProgress())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
|
||||
|
@ -1005,3 +1005,24 @@ RETURNS jsonb
|
||||
LANGUAGE INTERNAL
|
||||
STRICT IMMUTABLE
|
||||
AS 'jsonb_insert';
|
||||
|
||||
-- The default permissions for functions mean that anyone can execute them.
|
||||
-- A number of functions shouldn't be executable by just anyone, but rather
|
||||
-- than use explicit 'superuser()' checks in those functions, we use the GRANT
|
||||
-- system to REVOKE access to those functions at initdb time. Administrators
|
||||
-- can later change who can access these functions, or leave them as only
|
||||
-- available to superuser / cluster owner, if they choose.
|
||||
REVOKE EXECUTE ON FUNCTION pg_start_backup(text, boolean, boolean) FROM public;
|
||||
REVOKE EXECUTE ON FUNCTION pg_stop_backup() FROM public;
|
||||
REVOKE EXECUTE ON FUNCTION pg_stop_backup(boolean) FROM public;
|
||||
REVOKE EXECUTE ON FUNCTION pg_create_restore_point(text) FROM public;
|
||||
REVOKE EXECUTE ON FUNCTION pg_switch_xlog() FROM public;
|
||||
REVOKE EXECUTE ON FUNCTION pg_xlog_replay_pause() FROM public;
|
||||
REVOKE EXECUTE ON FUNCTION pg_xlog_replay_resume() FROM public;
|
||||
REVOKE EXECUTE ON FUNCTION pg_rotate_logfile() FROM public;
|
||||
REVOKE EXECUTE ON FUNCTION pg_reload_conf() FROM public;
|
||||
|
||||
REVOKE EXECUTE ON FUNCTION pg_stat_reset() FROM public;
|
||||
REVOKE EXECUTE ON FUNCTION pg_stat_reset_shared(text) FROM public;
|
||||
REVOKE EXECUTE ON FUNCTION pg_stat_reset_single_table_counters(oid) FROM public;
|
||||
REVOKE EXECUTE ON FUNCTION pg_stat_reset_single_function_counters(oid) FROM public;
|
||||
|
@ -1217,6 +1217,9 @@ pgstat_drop_relation(Oid relid)
|
||||
* pgstat_reset_counters() -
|
||||
*
|
||||
* Tell the statistics collector to reset counters for our database.
|
||||
*
|
||||
* Permission checking for this function is managed through the normal
|
||||
* GRANT system.
|
||||
* ----------
|
||||
*/
|
||||
void
|
||||
@ -1227,11 +1230,6 @@ pgstat_reset_counters(void)
|
||||
if (pgStatSock == PGINVALID_SOCKET)
|
||||
return;
|
||||
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("must be superuser to reset statistics counters")));
|
||||
|
||||
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETCOUNTER);
|
||||
msg.m_databaseid = MyDatabaseId;
|
||||
pgstat_send(&msg, sizeof(msg));
|
||||
@ -1241,6 +1239,9 @@ pgstat_reset_counters(void)
|
||||
* pgstat_reset_shared_counters() -
|
||||
*
|
||||
* Tell the statistics collector to reset cluster-wide shared counters.
|
||||
*
|
||||
* Permission checking for this function is managed through the normal
|
||||
* GRANT system.
|
||||
* ----------
|
||||
*/
|
||||
void
|
||||
@ -1251,11 +1252,6 @@ pgstat_reset_shared_counters(const char *target)
|
||||
if (pgStatSock == PGINVALID_SOCKET)
|
||||
return;
|
||||
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("must be superuser to reset statistics counters")));
|
||||
|
||||
if (strcmp(target, "archiver") == 0)
|
||||
msg.m_resettarget = RESET_ARCHIVER;
|
||||
else if (strcmp(target, "bgwriter") == 0)
|
||||
@ -1274,6 +1270,9 @@ pgstat_reset_shared_counters(const char *target)
|
||||
* pgstat_reset_single_counter() -
|
||||
*
|
||||
* Tell the statistics collector to reset a single counter.
|
||||
*
|
||||
* Permission checking for this function is managed through the normal
|
||||
* GRANT system.
|
||||
* ----------
|
||||
*/
|
||||
void
|
||||
@ -1284,11 +1283,6 @@ pgstat_reset_single_counter(Oid objoid, PgStat_Single_Reset_Type type)
|
||||
if (pgStatSock == PGINVALID_SOCKET)
|
||||
return;
|
||||
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("must be superuser to reset statistics counters")));
|
||||
|
||||
pgstat_setheader(&msg.m_hdr, PGSTAT_MTYPE_RESETSINGLECOUNTER);
|
||||
msg.m_databaseid = MyDatabaseId;
|
||||
msg.m_resettype = type;
|
||||
|
@ -321,15 +321,13 @@ pg_terminate_backend(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* Signal to reload the database configuration
|
||||
*
|
||||
* Permission checking for this function is managed through the normal
|
||||
* GRANT system.
|
||||
*/
|
||||
Datum
|
||||
pg_reload_conf(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be superuser to signal the postmaster"))));
|
||||
|
||||
if (kill(PostmasterPid, SIGHUP))
|
||||
{
|
||||
ereport(WARNING,
|
||||
@ -343,15 +341,13 @@ pg_reload_conf(PG_FUNCTION_ARGS)
|
||||
|
||||
/*
|
||||
* Rotate log file
|
||||
*
|
||||
* Permission checking for this function is managed through the normal
|
||||
* GRANT system.
|
||||
*/
|
||||
Datum
|
||||
pg_rotate_logfile(PG_FUNCTION_ARGS)
|
||||
{
|
||||
if (!superuser())
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
(errmsg("must be superuser to rotate log files"))));
|
||||
|
||||
if (!Logging_collector)
|
||||
{
|
||||
ereport(WARNING,
|
||||
|
Reference in New Issue
Block a user