From 73c794a0cce148c2848adfb06be9aac985ac41d8 Mon Sep 17 00:00:00 2001
From: Daniel Farina <daniel@heroku.com>
Date: Sun, 18 Mar 2012 20:08:37 -0700
Subject: [PATCH] Extend same-role backend management to pg_terminate_backend

This makes it more similar to pg_cancel_backend, except it gives users
the ability to close runaway connections entirely.

Signed-off-by: Daniel Farina <daniel@heroku.com>
---
 doc/src/sgml/func.sgml       |    6 +++++-
 src/backend/utils/adt/misc.c |   12 +++++++-----
 2 files changed, 12 insertions(+), 6 deletions(-)

diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml
index 34fea16..7cece3a 100644
*** a/doc/src/sgml/func.sgml
--- b/doc/src/sgml/func.sgml
***************
*** 14403,14409 **** SELECT set_config('log_statement_stats', 'off', false);
          <literal><function>pg_terminate_backend(<parameter>pid</parameter> <type>int</>)</function></literal>
          </entry>
         <entry><type>boolean</type></entry>
!        <entry>Terminate a backend</entry>
        </row>
       </tbody>
      </tgroup>
--- 14403,14413 ----
          <literal><function>pg_terminate_backend(<parameter>pid</parameter> <type>int</>)</function></literal>
          </entry>
         <entry><type>boolean</type></entry>
!        <entry>Terminate a backend.  You can execute this against
!         another backend that has exactly the same role as the user
!         calling the function.  In all other cases, you must be a
!         superuser.
!        </entry>
        </row>
       </tbody>
      </tgroup>
*** a/src/backend/utils/adt/misc.c
--- b/src/backend/utils/adt/misc.c
***************
*** 162,179 **** pg_cancel_backend(PG_FUNCTION_ARGS)
  }
  
  /*
!  * Signal to terminate a backend process.  Only allowed by superuser.
   */
  Datum
  pg_terminate_backend(PG_FUNCTION_ARGS)
  {
! 	if (!superuser())
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
! 			 errmsg("must be superuser to terminate other server processes"),
! 				 errhint("You can cancel your own processes with pg_cancel_backend().")));
  
! 	PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0), SIGTERM) == SIGNAL_BACKEND_SUCCESS);
  }
  
  /*
--- 162,181 ----
  }
  
  /*
!  * Signal to terminate a backend process.  This is allowed if you are superuser
!  * or have the same role as the process being terminated.
   */
  Datum
  pg_terminate_backend(PG_FUNCTION_ARGS)
  {
! 	int			r = pg_signal_backend(PG_GETARG_INT32(0), SIGTERM);
! 
! 	if (r == SIGNAL_BACKEND_NOPERMISSION)
  		ereport(ERROR,
  				(errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
! 				 (errmsg("must be superuser or have the same role to terminate backends running in other server processes"))));
  
! 	PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS);
  }
  
  /*
