diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index 30199b4..f19c2e5 100644 *** a/src/backend/utils/adt/misc.c --- b/src/backend/utils/adt/misc.c *************** *** 33,38 **** --- 33,39 ---- #include "storage/procarray.h" #include "utils/builtins.h" #include "tcop/tcopprot.h" + #include "storage/proc.h" #define atooid(x) ((Oid) strtoul((x), NULL, 10)) *************** current_query(PG_FUNCTION_ARGS) *** 68,83 **** PG_RETURN_NULL(); } /* * Functions to send signals to other backends. */ 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")))); if (!IsBackendPid(pid)) { --- 69,81 ---- PG_RETURN_NULL(); } + /* * Functions to send signals to other backends. */ static bool pg_signal_backend(int pid, int sig) { if (!IsBackendPid(pid)) { *************** pg_signal_backend(int pid, int sig) *** 105,120 **** return true; } Datum pg_cancel_backend(PG_FUNCTION_ARGS) { ! PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0), SIGINT)); } Datum pg_terminate_backend(PG_FUNCTION_ARGS) { ! PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0), SIGTERM)); } Datum --- 103,160 ---- return true; } + + /* Allow users to cancel their own queries running under the given backend PID. + * Superusers may cancel anyone's queries. + */ Datum pg_cancel_backend(PG_FUNCTION_ARGS) { ! int BackendPid = PG_GETARG_INT32(0); ! Oid SessionUserId = GetUserId(); ! PGPROC *backend_proc = BackendPidGetProc(BackendPid); ! Oid TargetRoleId; ! ! if (backend_proc == NULL) ! { ! ereport(WARNING, (errmsg("Unable to find backend with PID: %u", BackendPid))); ! PG_RETURN_BOOL(false); ! } ! TargetRoleId = backend_proc->roleId; ! ! ereport(NOTICE, (errmsg("Your session ID: %u. Desired backend to kill: %u. roleId which is using this backend: %u", (int) SessionUserId, (int) BackendPid, (int) TargetRoleId))); ! ! if (superuser()) ! { ! ereport(NOTICE, (errmsg("superuser() check passed!"))); ! PG_RETURN_BOOL(pg_signal_backend(BackendPid, SIGINT)); ! } ! else if (TargetRoleId == SessionUserId) ! { ! ereport(NOTICE, (errmsg("roleIds match, so you may kill."))); ! PG_RETURN_BOOL(pg_signal_backend(BackendPid, SIGINT)); ! } ! else ! { ! ereport(WARNING, (errmsg("You may not kill the desired backend, since you are not superuser and your roleId differs."))); ! PG_RETURN_BOOL(false); ! } } Datum pg_terminate_backend(PG_FUNCTION_ARGS) { ! if (!superuser()) ! { ! ereport(ERROR, ! (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), ! (errmsg("must be superuser to terminate other server processes")))); ! PG_RETURN_BOOL(false); ! } ! else ! { ! PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0), SIGTERM)); ! } } Datum