]> granicus.if.org Git - postgresql/commitdiff
Allow pg_terminate_backend() to be used on backends with matching role.
authorRobert Haas <rhaas@postgresql.org>
Tue, 26 Jun 2012 20:16:52 +0000 (16:16 -0400)
committerRobert Haas <rhaas@postgresql.org>
Tue, 26 Jun 2012 20:16:52 +0000 (16:16 -0400)
A similar change was made previously for pg_cancel_backend, so now it
all matches again.

Dan Farina, reviewed by Fujii Masao, Noah Misch, and Jeff Davis,
with slight kibitzing on the doc changes by me.

doc/src/sgml/func.sgml
doc/src/sgml/high-availability.sgml
src/backend/utils/adt/misc.c

index 595523e3ebadb0c85cc353407238442729bef90b..4f539428e28a4aa81f96fb5ad65c9b514c391b2c 100644 (file)
@@ -14393,7 +14393,11 @@ 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>
+       <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>
@@ -14414,9 +14418,8 @@ SELECT set_config('log_statement_stats', 'off', false);
     <command>postgres</command> processes on the server (using
     <application>ps</> on Unix or the <application>Task
     Manager</> on <productname>Windows</>).
-    For the less restrictive <function>pg_cancel_backend</>, the role of an
-    active backend can be found from
-    the <structfield>usename</structfield> column of the
+    The role of an active backend can be found from the
+    <structfield>usename</structfield> column of the
     <structname>pg_stat_activity</structname> view.
    </para>
 
index c268bfb8d3f424a96b68c1e8d5646e7d46728413..4eb37d246100243cc256da7519856b3470ff032f 100644 (file)
@@ -1969,13 +1969,15 @@ LOG:  database system is ready to accept read only connections
    </para>
 
    <para>
-    <function>pg_cancel_backend()</> will work on user backends, but not the
-    Startup process, which performs recovery. <structname>pg_stat_activity</structname> does not
-    show an entry for the Startup process, nor do recovering transactions
-    show as active. As a result, <structname>pg_prepared_xacts</structname> is always empty during
-    recovery. If you wish to resolve in-doubt prepared transactions,
-    view <literal>pg_prepared_xacts</> on the primary and issue commands to
-    resolve transactions there.
+    <function>pg_cancel_backend()</>
+    and <function>pg_terminate_backend()</> will work on user backends,
+    but not the Startup process, which performs
+    recovery. <structname>pg_stat_activity</structname> does not show an
+    entry for the Startup process, nor do recovering transactions show
+    as active. As a result, <structname>pg_prepared_xacts</structname>
+    is always empty during recovery. If you wish to resolve in-doubt
+    prepared transactions, view <literal>pg_prepared_xacts</> on the
+    primary and issue commands to resolve transactions there.
    </para>
 
    <para>
index 96e692766bfd6ffcb922acbe6c9219338425c5f7..f3c7860f0c37f4411744c2d092bb4257cd27a98c 100644 (file)
@@ -162,18 +162,20 @@ pg_cancel_backend(PG_FUNCTION_ARGS)
 }
 
 /*
- * Signal to terminate a backend process.  Only allowed by superuser.
+ * 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)
 {
-       if (!superuser())
+       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 to terminate other server processes"),
-                                errhint("You can cancel your own processes with pg_cancel_backend().")));
+                                (errmsg("must be superuser or have the same role to terminate backends running in other server processes"))));
 
-       PG_RETURN_BOOL(pg_signal_backend(PG_GETARG_INT32(0), SIGTERM) == SIGNAL_BACKEND_SUCCESS);
+       PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS);
 }
 
 /*