mirror of
https://github.com/postgres/postgres.git
synced 2025-11-07 19:06:32 +03:00
Introduce pg_signal_autovacuum_worker.
Since commit 3a9b18b309, roles with privileges of pg_signal_backend
cannot signal autovacuum workers. Many users treated the ability
to signal autovacuum workers as a feature instead of a bug, so we
are reintroducing it via a new predefined role. Having privileges
of this new role, named pg_signal_autovacuum_worker, only permits
signaling autovacuum workers. It does not permit signaling other
types of superuser backends.
Bumps catversion.
Author: Kirill Reshke
Reviewed-by: Anthony Leung, Michael Paquier, Andrey Borodin
Discussion: https://postgr.es/m/CALdSSPhC4GGmbnugHfB9G0%3DfAxjCSug_-rmL9oUh0LTxsyBfsg%40mail.gmail.com
This commit is contained in:
@@ -34,8 +34,9 @@
|
||||
* role as the backend being signaled. For "dangerous" signals, an explicit
|
||||
* check for superuser needs to be done prior to calling this function.
|
||||
*
|
||||
* Returns 0 on success, 1 on general failure, 2 on normal permission error
|
||||
* and 3 if the caller needs to be a superuser.
|
||||
* Returns 0 on success, 1 on general failure, 2 on normal permission error,
|
||||
* 3 if the caller needs to be a superuser, and 4 if the caller needs to have
|
||||
* privileges of pg_signal_autovacuum_worker.
|
||||
*
|
||||
* In the event of a general failure (return code 1), a warning message will
|
||||
* be emitted. For permission errors, doing that is the responsibility of
|
||||
@@ -45,6 +46,7 @@
|
||||
#define SIGNAL_BACKEND_ERROR 1
|
||||
#define SIGNAL_BACKEND_NOPERMISSION 2
|
||||
#define SIGNAL_BACKEND_NOSUPERUSER 3
|
||||
#define SIGNAL_BACKEND_NOAUTOVAC 4
|
||||
static int
|
||||
pg_signal_backend(int pid, int sig)
|
||||
{
|
||||
@@ -77,15 +79,27 @@ pg_signal_backend(int pid, int sig)
|
||||
/*
|
||||
* Only allow superusers to signal superuser-owned backends. Any process
|
||||
* not advertising a role might have the importance of a superuser-owned
|
||||
* backend, so treat it that way.
|
||||
* backend, so treat it that way. As an exception, we allow roles with
|
||||
* privileges of pg_signal_autovacuum_worker to signal autovacuum workers
|
||||
* (which do not advertise a role).
|
||||
*
|
||||
* Otherwise, users can signal backends for roles they have privileges of.
|
||||
*/
|
||||
if ((!OidIsValid(proc->roleId) || superuser_arg(proc->roleId)) &&
|
||||
!superuser())
|
||||
return SIGNAL_BACKEND_NOSUPERUSER;
|
||||
if (!OidIsValid(proc->roleId) || superuser_arg(proc->roleId))
|
||||
{
|
||||
ProcNumber procNumber = GetNumberFromPGProc(proc);
|
||||
PgBackendStatus *procStatus = pgstat_get_beentry_by_proc_number(procNumber);
|
||||
|
||||
/* Users can signal backends they have role membership in. */
|
||||
if (!has_privs_of_role(GetUserId(), proc->roleId) &&
|
||||
!has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND))
|
||||
if (procStatus && procStatus->st_backendType == B_AUTOVAC_WORKER)
|
||||
{
|
||||
if (!has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_AUTOVACUUM_WORKER))
|
||||
return SIGNAL_BACKEND_NOAUTOVAC;
|
||||
}
|
||||
else if (!superuser())
|
||||
return SIGNAL_BACKEND_NOSUPERUSER;
|
||||
}
|
||||
else if (!has_privs_of_role(GetUserId(), proc->roleId) &&
|
||||
!has_privs_of_role(GetUserId(), ROLE_PG_SIGNAL_BACKEND))
|
||||
return SIGNAL_BACKEND_NOPERMISSION;
|
||||
|
||||
/*
|
||||
@@ -130,6 +144,13 @@ pg_cancel_backend(PG_FUNCTION_ARGS)
|
||||
errdetail("Only roles with the %s attribute may cancel queries of roles with the %s attribute.",
|
||||
"SUPERUSER", "SUPERUSER")));
|
||||
|
||||
if (r == SIGNAL_BACKEND_NOAUTOVAC)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("permission denied to cancel query"),
|
||||
errdetail("Only roles with privileges of the \"%s\" role may cancel autovacuum workers.",
|
||||
"pg_signal_autovacuum_worker")));
|
||||
|
||||
if (r == SIGNAL_BACKEND_NOPERMISSION)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
@@ -236,6 +257,13 @@ pg_terminate_backend(PG_FUNCTION_ARGS)
|
||||
errdetail("Only roles with the %s attribute may terminate processes of roles with the %s attribute.",
|
||||
"SUPERUSER", "SUPERUSER")));
|
||||
|
||||
if (r == SIGNAL_BACKEND_NOAUTOVAC)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
errmsg("permission denied to terminate process"),
|
||||
errdetail("Only roles with privileges of the \"%s\" role may terminate autovacuum workers.",
|
||||
"pg_signal_autovacuum_worker")));
|
||||
|
||||
if (r == SIGNAL_BACKEND_NOPERMISSION)
|
||||
ereport(ERROR,
|
||||
(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
|
||||
|
||||
Reference in New Issue
Block a user