diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index 63ec6fd..dc46123 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -14,6 +14,8 @@ */ #include "postgres.h" +#include "storage/proc.h" + #include #include #include @@ -74,13 +76,34 @@ current_query(PG_FUNCTION_ARGS) static bool pg_signal_backend(int pid, int sig) { - if (!superuser()) - ereport(ERROR, - (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - (errmsg("must be superuser to signal other server processes")))); + PGPROC *proc = NULL; - if (!IsBackendPid(pid)) - { + if (IsBackendPid(pid)) + { + proc = BackendPidGetProc(pid); + + if (superuser() || proc->roleId == GetUserId()) + { + /* If we have setsid(), signal the backend's whole process group */ +#ifdef HAVE_SETSID + if (kill(-pid, sig)) +#else + if (kill(pid, sig)) +#endif + { + /* Just a warning to allow loops */ + ereport(WARNING, + (errmsg("could not send signal to process %d: %m", pid))); + return false; + } + return true; + } else { + ereport(ERROR, + (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), + (errmsg("must be the same user or superuser to signal other server processes")))); + return false; + } + } else { /* * This is just a warning so a loop-through-resultset will not abort * if one backend terminated on it's own during the run @@ -88,21 +111,7 @@ pg_signal_backend(int pid, int sig) ereport(WARNING, (errmsg("PID %d is not a PostgreSQL server process", pid))); return false; - } - - /* If we have setsid(), signal the backend's whole process group */ -#ifdef HAVE_SETSID - if (kill(-pid, sig)) -#else - if (kill(pid, sig)) -#endif - { - /* Again, just a warning to allow loops */ - ereport(WARNING, - (errmsg("could not send signal to process %d: %m", pid))); - return false; - } - return true; + } } Datum