diff --git a/doc/src/sgml/func.sgml b/doc/src/sgml/func.sgml index 88145c5b80868c8bea21cd464c53b8285de8772c..cb7fe38000bfcd49a897db7b91727d431abb2aa1 100644 --- a/doc/src/sgml/func.sgml +++ b/doc/src/sgml/func.sgml @@ -17454,7 +17454,8 @@ SELECT set_config('log_statement_stats', 'off', false); </entry> <entry><type>boolean</type></entry> <entry>Cancel a backend's current query. This is also allowed if the - calling role is a member of the role whose backend is being canceled, + calling role is a member of the role whose backend is being canceled or + the calling role has been granted <literal>pg_signal_backend</literal>, however only superusers can cancel superuser backends. </entry> </row> @@ -17478,8 +17479,9 @@ SELECT set_config('log_statement_stats', 'off', false); </entry> <entry><type>boolean</type></entry> <entry>Terminate a backend. This is also allowed if the calling role - is a member of the role whose backend is being terminated, however only - superusers can terminate superuser backends. + is a member of the role whose backend is being terminated or the + calling role has been granted <literal>pg_signal_backend</literal>, + however only superusers can terminate superuser backends. </entry> </row> </tbody> diff --git a/doc/src/sgml/user-manag.sgml b/doc/src/sgml/user-manag.sgml index d1b6e5990dbfd953ab93ad0551d30f169bef6584..7eaefe58c2fe03a8d9fd2c0d88d49bee96b8b96e 100644 --- a/doc/src/sgml/user-manag.sgml +++ b/doc/src/sgml/user-manag.sgml @@ -483,6 +483,57 @@ DROP ROLE doomed_role; </para> </sect1> + <sect1 id="default-roles"> + <title>Default Roles</title> + + <indexterm zone="default-roles"> + <primary>role</> + </indexterm> + + <para> + <productname>PostgreSQL</productname> provides a set of default roles + which provide access to certain, commonly needed, privileged capabilities + and information. Administrators can GRANT these roles to users and/or + other roles in their environment, providing those users with access to + the specified capabilities and information. + </para> + + <para> + The default roles are described in <xref linkend="default-roles-table">. + Note that the specific permissions for each of the default roles may + change in the future as additional capabilities are added. Administrators + should monitor the release notes for changes. + </para> + + <table tocentry="1" id="default-roles-table"> + <title>Default Roles</title> + <tgroup cols="2"> + <thead> + <row> + <entry>Role</entry> + <entry>Allowed Access</entry> + </row> + </thead> + <tbody> + <row> + <entry>pg_signal_backend</entry> + <entry>Send signals to other backends (eg: cancel query, terminate).</entry> + </row> + </tbody> + </tgroup> + </table> + + <para> + Administrators can grant access to these roles to users using the GRANT + command: + +<programlisting> +GRANT pg_signal_backend TO admin_user; +</programlisting> + </para> + + </sect1> + <sect1 id="perm-functions"> <title>Function and Trigger Security</title> diff --git a/src/backend/utils/adt/misc.c b/src/backend/utils/adt/misc.c index ebc7bb388a7b3b66530b8f05ea895d26fcfbe9bd..a44fa38173ad730dbea0c86d2ba5234114b35e0d 100644 --- a/src/backend/utils/adt/misc.c +++ b/src/backend/utils/adt/misc.c @@ -21,6 +21,7 @@ #include <unistd.h> #include "access/sysattr.h" +#include "catalog/pg_authid.h" #include "catalog/catalog.h" #include "catalog/pg_tablespace.h" #include "catalog/pg_type.h" @@ -244,7 +245,8 @@ pg_signal_backend(int pid, int sig) return SIGNAL_BACKEND_NOSUPERUSER; /* Users can signal backends they have role membership in. */ - if (!has_privs_of_role(GetUserId(), proc->roleId)) + if (!has_privs_of_role(GetUserId(), proc->roleId) && + !has_privs_of_role(GetUserId(), DEFAULT_ROLE_SIGNAL_BACKENDID)) return SIGNAL_BACKEND_NOPERMISSION; /* @@ -290,7 +292,7 @@ pg_cancel_backend(PG_FUNCTION_ARGS) if (r == SIGNAL_BACKEND_NOPERMISSION) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - (errmsg("must be a member of the role whose query is being canceled")))); + (errmsg("must be a member of the role whose query is being canceled or member of pg_signal_backend")))); PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS); } @@ -314,7 +316,7 @@ pg_terminate_backend(PG_FUNCTION_ARGS) if (r == SIGNAL_BACKEND_NOPERMISSION) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), - (errmsg("must be a member of the role whose process is being terminated")))); + (errmsg("must be a member of the role whose process is being terminated or member of pg_signal_backend")))); PG_RETURN_BOOL(r == SIGNAL_BACKEND_SUCCESS); } diff --git a/src/include/catalog/catversion.h b/src/include/catalog/catversion.h index 6d254ba133cf42e225cd75e9daf03afa5774c37c..5b7053da067e6af105725dcef50e8ec5da322468 100644 --- a/src/include/catalog/catversion.h +++ b/src/include/catalog/catversion.h @@ -53,6 +53,6 @@ */ /* yyyymmddN */ -#define CATALOG_VERSION_NO 201604071 +#define CATALOG_VERSION_NO 201604082 #endif diff --git a/src/include/catalog/pg_authid.h b/src/include/catalog/pg_authid.h index c1630833b815924e489445461068bae689fd2a19..533081def6eb627ef02fecdd2b0cb8e669d4d0fa 100644 --- a/src/include/catalog/pg_authid.h +++ b/src/include/catalog/pg_authid.h @@ -93,10 +93,16 @@ typedef FormData_pg_authid *Form_pg_authid; * * The uppercase quantities will be replaced at initdb time with * user choices. + * + * If adding new default roles or changing the OIDs below, be sure to add or + * update the #defines which follow as appropriate. * ---------------- */ DATA(insert OID = 10 ( "POSTGRES" t t t t t t t -1 _null_ _null_)); +DATA(insert OID = 4200 ( "pg_signal_backend" f t f f f f f -1 _null_ _null_)); + +#define BOOTSTRAP_SUPERUSERID 10 -#define BOOTSTRAP_SUPERUSERID 10 +#define DEFAULT_ROLE_SIGNAL_BACKENDID 4200 #endif /* PG_AUTHID_H */ diff --git a/src/test/regress/expected/rolenames.out b/src/test/regress/expected/rolenames.out index 01b3b90ec14dcc877dcafd5309f601f87e76b305..15a97abe1951c73bfdece40cfa86cfa11bbead77 100644 --- a/src/test/regress/expected/rolenames.out +++ b/src/test/regress/expected/rolenames.out @@ -824,6 +824,11 @@ ERROR: role "pg_abcdef" is reserved DETAIL: Cannot GRANT roles to a reserved role. SET ROLE pg_testrole; -- error ERROR: invalid value for parameter "role": "pg_testrole" +SET ROLE pg_signal_backend; --error +ERROR: invalid value for parameter "role": "pg_signal_backend" +CREATE SCHEMA test_schema AUTHORIZATION pg_signal_backend; --error +ERROR: role "pg_signal_backend" is reserved +DETAIL: Cannot specify reserved role as owner. UPDATE pg_proc SET proacl = null WHERE proname LIKE 'testagg_'; SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_'; proname | proacl diff --git a/src/test/regress/sql/rolenames.sql b/src/test/regress/sql/rolenames.sql index 1e0e9af8da1935d684eae766dbc436620bdcb188..b58a16359b25702ea4005259890e75640f8e6a94 100644 --- a/src/test/regress/sql/rolenames.sql +++ b/src/test/regress/sql/rolenames.sql @@ -385,6 +385,8 @@ GRANT testrol0 TO pg_abc; -- error GRANT pg_abc TO pg_abcdef; -- error SET ROLE pg_testrole; -- error +SET ROLE pg_signal_backend; --error +CREATE SCHEMA test_schema AUTHORIZATION pg_signal_backend; --error UPDATE pg_proc SET proacl = null WHERE proname LIKE 'testagg_'; SELECT proname, proacl FROM pg_proc WHERE proname LIKE 'testagg_';