mirror of https://github.com/postgres/postgres
This patch allows "PGC_SUSET" parameters to be set by non-superusers if they have been explicitly granted the privilege to do so. The privilege to perform ALTER SYSTEM SET/RESET on a specific parameter can also be granted. Such privileges are cluster-wide, not per database. They are tracked in a new shared catalog, pg_parameter_acl. Granting and revoking these new privileges works as one would expect. One caveat is that PGC_USERSET GUCs are unaffected by the SET privilege --- one could wish that those were handled by a revocable grant to PUBLIC, but they are not, because we couldn't make it robust enough for GUCs defined by extensions. Mark Dilger, reviewed at various times by Andrew Dunstan, Robert Haas, Joshua Brindle, and myself Discussion: https://postgr.es/m/3D691E20-C1D5-4B80-8BA5-6BEB63AF3029@enterprisedb.compull/81/head
parent
2ef6f11b0c
commit
a0ffa885e4
@ -0,0 +1,118 @@ |
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* |
||||||
|
* pg_parameter_acl.c |
||||||
|
* routines to support manipulation of the pg_parameter_acl relation |
||||||
|
* |
||||||
|
* Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group |
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California |
||||||
|
* |
||||||
|
* |
||||||
|
* IDENTIFICATION |
||||||
|
* src/backend/catalog/pg_parameter_acl.c |
||||||
|
* |
||||||
|
*------------------------------------------------------------------------- |
||||||
|
*/ |
||||||
|
#include "postgres.h" |
||||||
|
|
||||||
|
#include "access/table.h" |
||||||
|
#include "catalog/catalog.h" |
||||||
|
#include "catalog/indexing.h" |
||||||
|
#include "catalog/objectaccess.h" |
||||||
|
#include "catalog/pg_namespace.h" |
||||||
|
#include "catalog/pg_parameter_acl.h" |
||||||
|
#include "utils/builtins.h" |
||||||
|
#include "utils/pg_locale.h" |
||||||
|
#include "utils/rel.h" |
||||||
|
#include "utils/syscache.h" |
||||||
|
|
||||||
|
|
||||||
|
/*
|
||||||
|
* ParameterAclLookup - Given a configuration parameter name, |
||||||
|
* look up the associated configuration parameter ACL's OID. |
||||||
|
* |
||||||
|
* If missing_ok is false, throw an error if ACL entry not found. If |
||||||
|
* true, just return InvalidOid. |
||||||
|
*/ |
||||||
|
Oid |
||||||
|
ParameterAclLookup(const char *parameter, bool missing_ok) |
||||||
|
{ |
||||||
|
Oid oid; |
||||||
|
char *parname; |
||||||
|
|
||||||
|
/* Convert name to the form it should have in pg_parameter_acl... */ |
||||||
|
parname = convert_GUC_name_for_parameter_acl(parameter); |
||||||
|
|
||||||
|
/* ... and look it up */ |
||||||
|
oid = GetSysCacheOid1(PARAMETERACLNAME, Anum_pg_parameter_acl_oid, |
||||||
|
PointerGetDatum(cstring_to_text(parname))); |
||||||
|
|
||||||
|
if (!OidIsValid(oid) && !missing_ok) |
||||||
|
ereport(ERROR, |
||||||
|
(errcode(ERRCODE_UNDEFINED_OBJECT), |
||||||
|
errmsg("parameter ACL \"%s\" does not exist", parameter))); |
||||||
|
|
||||||
|
pfree(parname); |
||||||
|
|
||||||
|
return oid; |
||||||
|
} |
||||||
|
|
||||||
|
/*
|
||||||
|
* ParameterAclCreate |
||||||
|
* |
||||||
|
* Add a new tuple to pg_parameter_acl. |
||||||
|
* |
||||||
|
* parameter: the parameter name to create an entry for. |
||||||
|
* Caller should have verified that there's no such entry already. |
||||||
|
* |
||||||
|
* Returns the new entry's OID. |
||||||
|
*/ |
||||||
|
Oid |
||||||
|
ParameterAclCreate(const char *parameter) |
||||||
|
{ |
||||||
|
Oid parameterId; |
||||||
|
char *parname; |
||||||
|
Relation rel; |
||||||
|
TupleDesc tupDesc; |
||||||
|
HeapTuple tuple; |
||||||
|
Datum values[Natts_pg_parameter_acl]; |
||||||
|
bool nulls[Natts_pg_parameter_acl]; |
||||||
|
|
||||||
|
/*
|
||||||
|
* To prevent cluttering pg_parameter_acl with useless entries, insist |
||||||
|
* that the name be valid. |
||||||
|
*/ |
||||||
|
if (!check_GUC_name_for_parameter_acl(parameter)) |
||||||
|
ereport(ERROR, |
||||||
|
(errcode(ERRCODE_INVALID_NAME), |
||||||
|
errmsg("invalid parameter name \"%s\"", |
||||||
|
parameter))); |
||||||
|
|
||||||
|
/* Convert name to the form it should have in pg_parameter_acl. */ |
||||||
|
parname = convert_GUC_name_for_parameter_acl(parameter); |
||||||
|
|
||||||
|
/*
|
||||||
|
* Create and insert a new record containing a null ACL. |
||||||
|
* |
||||||
|
* We don't take a strong enough lock to prevent concurrent insertions, |
||||||
|
* relying instead on the unique index. |
||||||
|
*/ |
||||||
|
rel = table_open(ParameterAclRelationId, RowExclusiveLock); |
||||||
|
tupDesc = RelationGetDescr(rel); |
||||||
|
MemSet(values, 0, sizeof(values)); |
||||||
|
MemSet(nulls, false, sizeof(nulls)); |
||||||
|
parameterId = GetNewOidWithIndex(rel, |
||||||
|
ParameterAclOidIndexId, |
||||||
|
Anum_pg_parameter_acl_oid); |
||||||
|
values[Anum_pg_parameter_acl_oid - 1] = ObjectIdGetDatum(parameterId); |
||||||
|
values[Anum_pg_parameter_acl_parname - 1] = |
||||||
|
PointerGetDatum(cstring_to_text(parname)); |
||||||
|
nulls[Anum_pg_parameter_acl_paracl - 1] = true; |
||||||
|
tuple = heap_form_tuple(tupDesc, values, nulls); |
||||||
|
CatalogTupleInsert(rel, tuple); |
||||||
|
|
||||||
|
/* Close pg_parameter_acl, but keep lock till commit. */ |
||||||
|
heap_freetuple(tuple); |
||||||
|
table_close(rel, NoLock); |
||||||
|
|
||||||
|
return parameterId; |
||||||
|
} |
@ -0,0 +1,62 @@ |
|||||||
|
/*-------------------------------------------------------------------------
|
||||||
|
* |
||||||
|
* pg_parameter_acl.h |
||||||
|
* definition of the "configuration parameter ACL" system catalog |
||||||
|
* (pg_parameter_acl). |
||||||
|
* |
||||||
|
* |
||||||
|
* Portions Copyright (c) 1996-2022, PostgreSQL Global Development Group |
||||||
|
* Portions Copyright (c) 1994, Regents of the University of California |
||||||
|
* |
||||||
|
* src/include/catalog/pg_parameter_acl.h |
||||||
|
* |
||||||
|
* NOTES |
||||||
|
* The Catalog.pm module reads this file and derives schema |
||||||
|
* information. |
||||||
|
* |
||||||
|
*------------------------------------------------------------------------- |
||||||
|
*/ |
||||||
|
#ifndef PG_PARAMETER_ACL_H |
||||||
|
#define PG_PARAMETER_ACL_H |
||||||
|
|
||||||
|
#include "catalog/genbki.h" |
||||||
|
#include "catalog/pg_parameter_acl_d.h" |
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* pg_parameter_acl definition. cpp turns this into |
||||||
|
* typedef struct FormData_pg_parameter_acl |
||||||
|
* ---------------- |
||||||
|
*/ |
||||||
|
CATALOG(pg_parameter_acl,8924,ParameterAclRelationId) BKI_SHARED_RELATION |
||||||
|
{ |
||||||
|
Oid oid; /* oid */ |
||||||
|
|
||||||
|
#ifdef CATALOG_VARLEN /* variable-length fields start here */ |
||||||
|
/* name of parameter */ |
||||||
|
text parname BKI_FORCE_NOT_NULL; |
||||||
|
|
||||||
|
/* access permissions */ |
||||||
|
aclitem paracl[1] BKI_DEFAULT(_null_); |
||||||
|
#endif |
||||||
|
} FormData_pg_parameter_acl; |
||||||
|
|
||||||
|
|
||||||
|
/* ----------------
|
||||||
|
* Form_pg_parameter_acl corresponds to a pointer to a tuple with |
||||||
|
* the format of pg_parameter_acl relation. |
||||||
|
* ---------------- |
||||||
|
*/ |
||||||
|
typedef FormData_pg_parameter_acl *Form_pg_parameter_acl; |
||||||
|
|
||||||
|
DECLARE_TOAST(pg_parameter_acl, 8925, 8926); |
||||||
|
#define PgParameterAclToastTable 8925 |
||||||
|
#define PgParameterAclToastIndex 8926 |
||||||
|
|
||||||
|
DECLARE_UNIQUE_INDEX(pg_parameter_acl_parname_index, 8927, ParameterAclParnameIndexId, on pg_parameter_acl using btree(parname text_ops)); |
||||||
|
DECLARE_UNIQUE_INDEX_PKEY(pg_parameter_acl_oid_index, 8928, ParameterAclOidIndexId, on pg_parameter_acl using btree(oid oid_ops)); |
||||||
|
|
||||||
|
|
||||||
|
extern Oid ParameterAclLookup(const char *parameter, bool missing_ok); |
||||||
|
extern Oid ParameterAclCreate(const char *parameter); |
||||||
|
|
||||||
|
#endif /* PG_PARAMETER_ACL_H */ |
@ -0,0 +1,526 @@ |
|||||||
|
-- |
||||||
|
-- Tests for privileges on GUCs. |
||||||
|
-- This is unsafe because changes will affect other databases in the cluster. |
||||||
|
-- |
||||||
|
-- Test with a superuser role. |
||||||
|
CREATE ROLE regress_admin SUPERUSER; |
||||||
|
-- Perform operations as user 'regress_admin'. |
||||||
|
SET SESSION AUTHORIZATION regress_admin; |
||||||
|
-- PGC_BACKEND |
||||||
|
SET ignore_system_indexes = OFF; -- fail, cannot be set after connection start |
||||||
|
ERROR: parameter "ignore_system_indexes" cannot be set after connection start |
||||||
|
RESET ignore_system_indexes; -- fail, cannot be set after connection start |
||||||
|
ERROR: parameter "ignore_system_indexes" cannot be set after connection start |
||||||
|
ALTER SYSTEM SET ignore_system_indexes = OFF; -- ok |
||||||
|
ALTER SYSTEM RESET ignore_system_indexes; -- ok |
||||||
|
-- PGC_INTERNAL |
||||||
|
SET block_size = 50; -- fail, cannot be changed |
||||||
|
ERROR: parameter "block_size" cannot be changed |
||||||
|
RESET block_size; -- fail, cannot be changed |
||||||
|
ERROR: parameter "block_size" cannot be changed |
||||||
|
ALTER SYSTEM SET block_size = 50; -- fail, cannot be changed |
||||||
|
ERROR: parameter "block_size" cannot be changed |
||||||
|
ALTER SYSTEM RESET block_size; -- fail, cannot be changed |
||||||
|
ERROR: parameter "block_size" cannot be changed |
||||||
|
-- PGC_POSTMASTER |
||||||
|
SET autovacuum_freeze_max_age = 1000050000; -- fail, requires restart |
||||||
|
ERROR: parameter "autovacuum_freeze_max_age" cannot be changed without restarting the server |
||||||
|
RESET autovacuum_freeze_max_age; -- fail, requires restart |
||||||
|
ERROR: parameter "autovacuum_freeze_max_age" cannot be changed without restarting the server |
||||||
|
ALTER SYSTEM SET autovacuum_freeze_max_age = 1000050000; -- ok |
||||||
|
ALTER SYSTEM RESET autovacuum_freeze_max_age; -- ok |
||||||
|
ALTER SYSTEM SET config_file = '/usr/local/data/postgresql.conf'; -- fail, cannot be changed |
||||||
|
ERROR: parameter "config_file" cannot be changed |
||||||
|
ALTER SYSTEM RESET config_file; -- fail, cannot be changed |
||||||
|
ERROR: parameter "config_file" cannot be changed |
||||||
|
-- PGC_SIGHUP |
||||||
|
SET autovacuum = OFF; -- fail, requires reload |
||||||
|
ERROR: parameter "autovacuum" cannot be changed now |
||||||
|
RESET autovacuum; -- fail, requires reload |
||||||
|
ERROR: parameter "autovacuum" cannot be changed now |
||||||
|
ALTER SYSTEM SET autovacuum = OFF; -- ok |
||||||
|
ALTER SYSTEM RESET autovacuum; -- ok |
||||||
|
-- PGC_SUSET |
||||||
|
SET lc_messages = 'C'; -- ok |
||||||
|
RESET lc_messages; -- ok |
||||||
|
ALTER SYSTEM SET lc_messages = 'C'; -- ok |
||||||
|
ALTER SYSTEM RESET lc_messages; -- ok |
||||||
|
-- PGC_SU_BACKEND |
||||||
|
SET jit_debugging_support = OFF; -- fail, cannot be set after connection start |
||||||
|
ERROR: parameter "jit_debugging_support" cannot be set after connection start |
||||||
|
RESET jit_debugging_support; -- fail, cannot be set after connection start |
||||||
|
ERROR: parameter "jit_debugging_support" cannot be set after connection start |
||||||
|
ALTER SYSTEM SET jit_debugging_support = OFF; -- ok |
||||||
|
ALTER SYSTEM RESET jit_debugging_support; -- ok |
||||||
|
-- PGC_USERSET |
||||||
|
SET DateStyle = 'ISO, MDY'; -- ok |
||||||
|
RESET DateStyle; -- ok |
||||||
|
ALTER SYSTEM SET DateStyle = 'ISO, MDY'; -- ok |
||||||
|
ALTER SYSTEM RESET DateStyle; -- ok |
||||||
|
ALTER SYSTEM SET ssl_renegotiation_limit = 0; -- fail, cannot be changed |
||||||
|
ERROR: parameter "ssl_renegotiation_limit" cannot be changed |
||||||
|
ALTER SYSTEM RESET ssl_renegotiation_limit; -- fail, cannot be changed |
||||||
|
ERROR: parameter "ssl_renegotiation_limit" cannot be changed |
||||||
|
-- Finished testing superuser |
||||||
|
-- Create non-superuser with privileges to configure host resource usage |
||||||
|
CREATE ROLE regress_host_resource_admin NOSUPERUSER; |
||||||
|
-- Revoke privileges not yet granted |
||||||
|
REVOKE SET, ALTER SYSTEM ON PARAMETER work_mem FROM regress_host_resource_admin; |
||||||
|
REVOKE SET, ALTER SYSTEM ON PARAMETER zero_damaged_pages FROM regress_host_resource_admin; |
||||||
|
-- Check the new role does not yet have privileges on parameters |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET, ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
-- Check inappropriate and nonsense privilege types |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SELECT, UPDATE, CREATE'); |
||||||
|
ERROR: unrecognized privilege type: "SELECT" |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'USAGE'); |
||||||
|
ERROR: unrecognized privilege type: "USAGE" |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'WHATEVER'); |
||||||
|
ERROR: unrecognized privilege type: "WHATEVER" |
||||||
|
-- Revoke, grant, and revoke again a SUSET parameter not yet granted |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
REVOKE SET ON PARAMETER zero_damaged_pages FROM regress_host_resource_admin; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
GRANT SET ON PARAMETER zero_damaged_pages TO regress_host_resource_admin; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
REVOKE SET ON PARAMETER zero_damaged_pages FROM regress_host_resource_admin; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
-- Revoke, grant, and revoke again a USERSET parameter not yet granted |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
REVOKE SET ON PARAMETER work_mem FROM regress_host_resource_admin; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
GRANT SET ON PARAMETER work_mem TO regress_host_resource_admin; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
REVOKE SET ON PARAMETER work_mem FROM regress_host_resource_admin; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
-- Revoke privileges from a non-existent custom GUC. This should not create |
||||||
|
-- entries in the catalog. |
||||||
|
REVOKE ALL ON PARAMETER "none.such" FROM regress_host_resource_admin; |
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'none.such'; |
||||||
|
?column? |
||||||
|
---------- |
||||||
|
(0 rows) |
||||||
|
|
||||||
|
-- Grant and then revoke privileges on the non-existent custom GUC. Check that |
||||||
|
-- a do-nothing entry is not left in the catalogs after the revoke. |
||||||
|
GRANT ALL ON PARAMETER none.such TO regress_host_resource_admin; |
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'none.such'; |
||||||
|
?column? |
||||||
|
---------- |
||||||
|
1 |
||||||
|
(1 row) |
||||||
|
|
||||||
|
REVOKE ALL ON PARAMETER "None.Such" FROM regress_host_resource_admin; |
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'none.such'; |
||||||
|
?column? |
||||||
|
---------- |
||||||
|
(0 rows) |
||||||
|
|
||||||
|
-- Can't grant on a non-existent core GUC. |
||||||
|
GRANT ALL ON PARAMETER no_such_guc TO regress_host_resource_admin; -- fail |
||||||
|
ERROR: invalid parameter name "no_such_guc" |
||||||
|
-- Initially there are no privileges and no catalog entry for this GUC. |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET, ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'enable_material'; |
||||||
|
?column? |
||||||
|
---------- |
||||||
|
(0 rows) |
||||||
|
|
||||||
|
-- GRANT SET creates an entry: |
||||||
|
GRANT SET ON PARAMETER enable_material TO PUBLIC; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET, ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'enable_material'; |
||||||
|
?column? |
||||||
|
---------- |
||||||
|
1 |
||||||
|
(1 row) |
||||||
|
|
||||||
|
-- Now grant ALTER SYSTEM: |
||||||
|
GRANT ALL ON PARAMETER enable_material TO PUBLIC; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET, ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'enable_material'; |
||||||
|
?column? |
||||||
|
---------- |
||||||
|
1 |
||||||
|
(1 row) |
||||||
|
|
||||||
|
-- REVOKE ALTER SYSTEM brings us back to just the SET privilege: |
||||||
|
REVOKE ALTER SYSTEM ON PARAMETER enable_material FROM PUBLIC; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET, ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'enable_material'; |
||||||
|
?column? |
||||||
|
---------- |
||||||
|
1 |
||||||
|
(1 row) |
||||||
|
|
||||||
|
-- And this should remove the entry altogether: |
||||||
|
REVOKE SET ON PARAMETER enable_material FROM PUBLIC; |
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'enable_material'; |
||||||
|
?column? |
||||||
|
---------- |
||||||
|
(0 rows) |
||||||
|
|
||||||
|
-- Grant privileges on parameters to the new non-superuser role |
||||||
|
GRANT SET, ALTER SYSTEM ON PARAMETER |
||||||
|
autovacuum_work_mem, hash_mem_multiplier, max_stack_depth, |
||||||
|
shared_buffers, temp_file_limit, work_mem |
||||||
|
TO regress_host_resource_admin; |
||||||
|
-- Check the new role now has privilges on parameters |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET, ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'ALTER SYSTEM'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET WITH GRANT OPTION, ALTER SYSTEM WITH GRANT OPTION'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
f |
||||||
|
(1 row) |
||||||
|
|
||||||
|
-- Check again the inappropriate and nonsense privilege types. The prior |
||||||
|
-- similar check was performed before any entry for work_mem existed. |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SELECT, UPDATE, CREATE'); |
||||||
|
ERROR: unrecognized privilege type: "SELECT" |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'USAGE'); |
||||||
|
ERROR: unrecognized privilege type: "USAGE" |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'WHATEVER'); |
||||||
|
ERROR: unrecognized privilege type: "WHATEVER" |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'WHATEVER WITH GRANT OPTION'); |
||||||
|
ERROR: unrecognized privilege type: "WHATEVER WITH GRANT OPTION" |
||||||
|
-- Check other function signatures |
||||||
|
SELECT has_parameter_privilege((SELECT oid FROM pg_catalog.pg_authid WHERE rolname = 'regress_host_resource_admin'), |
||||||
|
'max_stack_depth', |
||||||
|
'SET'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT has_parameter_privilege('hash_mem_multiplier', 'set'); |
||||||
|
has_parameter_privilege |
||||||
|
------------------------- |
||||||
|
t |
||||||
|
(1 row) |
||||||
|
|
||||||
|
-- Check object identity functions |
||||||
|
SELECT pg_describe_object(tableoid, oid, 0) |
||||||
|
FROM pg_parameter_acl WHERE parname = 'work_mem'; |
||||||
|
pg_describe_object |
||||||
|
-------------------- |
||||||
|
parameter work_mem |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT pg_identify_object(tableoid, oid, 0) |
||||||
|
FROM pg_parameter_acl WHERE parname = 'work_mem'; |
||||||
|
pg_identify_object |
||||||
|
------------------------------ |
||||||
|
("parameter ACL",,,work_mem) |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT pg_identify_object_as_address(tableoid, oid, 0) |
||||||
|
FROM pg_parameter_acl WHERE parname = 'work_mem'; |
||||||
|
pg_identify_object_as_address |
||||||
|
--------------------------------- |
||||||
|
("parameter ACL",{work_mem},{}) |
||||||
|
(1 row) |
||||||
|
|
||||||
|
SELECT classid::regclass, |
||||||
|
(SELECT parname FROM pg_parameter_acl WHERE oid = goa.objid) AS parname, |
||||||
|
objsubid |
||||||
|
FROM pg_get_object_address('parameter ACL', '{work_mem}', '{}') goa; |
||||||
|
classid | parname | objsubid |
||||||
|
------------------+----------+---------- |
||||||
|
pg_parameter_acl | work_mem | 0 |
||||||
|
(1 row) |
||||||
|
|
||||||
|
-- Perform some operations as user 'regress_host_resource_admin' |
||||||
|
SET SESSION AUTHORIZATION regress_host_resource_admin; |
||||||
|
ALTER SYSTEM SET autovacuum_work_mem = 32; -- ok, privileges have been granted |
||||||
|
ALTER SYSTEM SET ignore_system_indexes = OFF; -- fail, insufficient privileges |
||||||
|
ERROR: permission denied to set parameter "ignore_system_indexes" |
||||||
|
ALTER SYSTEM RESET autovacuum_multixact_freeze_max_age; -- fail, insufficient privileges |
||||||
|
ERROR: permission denied to set parameter "autovacuum_multixact_freeze_max_age" |
||||||
|
SET jit_provider = 'llvmjit'; -- fail, insufficient privileges |
||||||
|
ERROR: parameter "jit_provider" cannot be changed without restarting the server |
||||||
|
SELECT set_config ('jit_provider', 'llvmjit', true); -- fail, insufficient privileges |
||||||
|
ERROR: parameter "jit_provider" cannot be changed without restarting the server |
||||||
|
ALTER SYSTEM SET shared_buffers = 50; -- ok |
||||||
|
ALTER SYSTEM RESET shared_buffers; -- ok |
||||||
|
SET autovacuum_work_mem = 50; -- cannot be changed now |
||||||
|
ERROR: parameter "autovacuum_work_mem" cannot be changed now |
||||||
|
ALTER SYSTEM RESET temp_file_limit; -- ok |
||||||
|
SET TimeZone = 'Europe/Helsinki'; -- ok |
||||||
|
RESET TimeZone; -- ok |
||||||
|
SET max_stack_depth = 2048; -- ok, privileges have been granted |
||||||
|
RESET max_stack_depth; -- ok, privileges have been granted |
||||||
|
ALTER SYSTEM SET max_stack_depth = 2048; -- ok, privileges have been granted |
||||||
|
ALTER SYSTEM RESET max_stack_depth; -- ok, privileges have been granted |
||||||
|
SET lc_messages = 'C'; -- fail, insufficient privileges |
||||||
|
ERROR: permission denied to set parameter "lc_messages" |
||||||
|
RESET lc_messages; -- fail, insufficient privileges |
||||||
|
ERROR: permission denied to set parameter "lc_messages" |
||||||
|
ALTER SYSTEM SET lc_messages = 'C'; -- fail, insufficient privileges |
||||||
|
ERROR: permission denied to set parameter "lc_messages" |
||||||
|
ALTER SYSTEM RESET lc_messages; -- fail, insufficient privileges |
||||||
|
ERROR: permission denied to set parameter "lc_messages" |
||||||
|
SELECT set_config ('temp_buffers', '8192', false); -- ok |
||||||
|
set_config |
||||||
|
------------ |
||||||
|
64MB |
||||||
|
(1 row) |
||||||
|
|
||||||
|
ALTER SYSTEM RESET autovacuum_work_mem; -- ok, privileges have been granted |
||||||
|
ALTER SYSTEM RESET ALL; -- fail, insufficient privileges |
||||||
|
ERROR: permission denied to perform ALTER SYSTEM RESET ALL |
||||||
|
-- Check dropping/revoking behavior |
||||||
|
SET SESSION AUTHORIZATION regress_admin; |
||||||
|
DROP ROLE regress_host_resource_admin; -- fail, privileges remain |
||||||
|
ERROR: role "regress_host_resource_admin" cannot be dropped because some objects depend on it |
||||||
|
DETAIL: privileges for parameter autovacuum_work_mem |
||||||
|
privileges for parameter hash_mem_multiplier |
||||||
|
privileges for parameter max_stack_depth |
||||||
|
privileges for parameter shared_buffers |
||||||
|
privileges for parameter temp_file_limit |
||||||
|
privileges for parameter work_mem |
||||||
|
-- Use "revoke" to remove the privileges and allow the role to be dropped |
||||||
|
REVOKE SET, ALTER SYSTEM ON PARAMETER |
||||||
|
autovacuum_work_mem, hash_mem_multiplier, max_stack_depth, |
||||||
|
shared_buffers, temp_file_limit, work_mem |
||||||
|
FROM regress_host_resource_admin; |
||||||
|
DROP ROLE regress_host_resource_admin; -- ok |
||||||
|
-- Try that again, but use "drop owned by" instead of "revoke" |
||||||
|
CREATE ROLE regress_host_resource_admin NOSUPERUSER; |
||||||
|
SET SESSION AUTHORIZATION regress_host_resource_admin; |
||||||
|
ALTER SYSTEM SET autovacuum_work_mem = 32; -- fail, privileges not yet granted |
||||||
|
ERROR: permission denied to set parameter "autovacuum_work_mem" |
||||||
|
SET SESSION AUTHORIZATION regress_admin; |
||||||
|
GRANT SET, ALTER SYSTEM ON PARAMETER |
||||||
|
autovacuum_work_mem, hash_mem_multiplier, max_stack_depth, |
||||||
|
shared_buffers, temp_file_limit, work_mem |
||||||
|
TO regress_host_resource_admin; |
||||||
|
DROP ROLE regress_host_resource_admin; -- fail, privileges remain |
||||||
|
ERROR: role "regress_host_resource_admin" cannot be dropped because some objects depend on it |
||||||
|
DETAIL: privileges for parameter autovacuum_work_mem |
||||||
|
privileges for parameter hash_mem_multiplier |
||||||
|
privileges for parameter max_stack_depth |
||||||
|
privileges for parameter shared_buffers |
||||||
|
privileges for parameter temp_file_limit |
||||||
|
privileges for parameter work_mem |
||||||
|
DROP OWNED BY regress_host_resource_admin RESTRICT; -- cascade should not be needed |
||||||
|
SET SESSION AUTHORIZATION regress_host_resource_admin; |
||||||
|
ALTER SYSTEM SET autovacuum_work_mem = 32; -- fail, "drop owned" has dropped privileges |
||||||
|
ERROR: permission denied to set parameter "autovacuum_work_mem" |
||||||
|
SET SESSION AUTHORIZATION regress_admin; |
||||||
|
DROP ROLE regress_host_resource_admin; -- ok |
||||||
|
-- Check that "reassign owned" doesn't affect privileges |
||||||
|
CREATE ROLE regress_host_resource_admin NOSUPERUSER; |
||||||
|
CREATE ROLE regress_host_resource_newadmin NOSUPERUSER; |
||||||
|
GRANT SET, ALTER SYSTEM ON PARAMETER |
||||||
|
autovacuum_work_mem, hash_mem_multiplier, max_stack_depth, |
||||||
|
shared_buffers, temp_file_limit, work_mem |
||||||
|
TO regress_host_resource_admin; |
||||||
|
REASSIGN OWNED BY regress_host_resource_admin TO regress_host_resource_newadmin; |
||||||
|
SET SESSION AUTHORIZATION regress_host_resource_admin; |
||||||
|
ALTER SYSTEM SET autovacuum_work_mem = 32; -- ok, "reassign owned" did not change privileges |
||||||
|
ALTER SYSTEM RESET autovacuum_work_mem; -- ok |
||||||
|
SET SESSION AUTHORIZATION regress_admin; |
||||||
|
DROP ROLE regress_host_resource_admin; -- fail, privileges remain |
||||||
|
ERROR: role "regress_host_resource_admin" cannot be dropped because some objects depend on it |
||||||
|
DETAIL: privileges for parameter autovacuum_work_mem |
||||||
|
privileges for parameter hash_mem_multiplier |
||||||
|
privileges for parameter max_stack_depth |
||||||
|
privileges for parameter shared_buffers |
||||||
|
privileges for parameter temp_file_limit |
||||||
|
privileges for parameter work_mem |
||||||
|
DROP ROLE regress_host_resource_newadmin; -- ok, nothing was transferred |
||||||
|
-- Use "drop owned by" so we can drop the role |
||||||
|
DROP OWNED BY regress_host_resource_admin; -- ok |
||||||
|
DROP ROLE regress_host_resource_admin; -- ok |
||||||
|
-- Clean up |
||||||
|
RESET SESSION AUTHORIZATION; |
||||||
|
DROP ROLE regress_admin; -- ok |
@ -0,0 +1,237 @@ |
|||||||
|
-- |
||||||
|
-- Tests for privileges on GUCs. |
||||||
|
-- This is unsafe because changes will affect other databases in the cluster. |
||||||
|
-- |
||||||
|
|
||||||
|
-- Test with a superuser role. |
||||||
|
CREATE ROLE regress_admin SUPERUSER; |
||||||
|
|
||||||
|
-- Perform operations as user 'regress_admin'. |
||||||
|
SET SESSION AUTHORIZATION regress_admin; |
||||||
|
|
||||||
|
-- PGC_BACKEND |
||||||
|
SET ignore_system_indexes = OFF; -- fail, cannot be set after connection start |
||||||
|
RESET ignore_system_indexes; -- fail, cannot be set after connection start |
||||||
|
ALTER SYSTEM SET ignore_system_indexes = OFF; -- ok |
||||||
|
ALTER SYSTEM RESET ignore_system_indexes; -- ok |
||||||
|
-- PGC_INTERNAL |
||||||
|
SET block_size = 50; -- fail, cannot be changed |
||||||
|
RESET block_size; -- fail, cannot be changed |
||||||
|
ALTER SYSTEM SET block_size = 50; -- fail, cannot be changed |
||||||
|
ALTER SYSTEM RESET block_size; -- fail, cannot be changed |
||||||
|
-- PGC_POSTMASTER |
||||||
|
SET autovacuum_freeze_max_age = 1000050000; -- fail, requires restart |
||||||
|
RESET autovacuum_freeze_max_age; -- fail, requires restart |
||||||
|
ALTER SYSTEM SET autovacuum_freeze_max_age = 1000050000; -- ok |
||||||
|
ALTER SYSTEM RESET autovacuum_freeze_max_age; -- ok |
||||||
|
ALTER SYSTEM SET config_file = '/usr/local/data/postgresql.conf'; -- fail, cannot be changed |
||||||
|
ALTER SYSTEM RESET config_file; -- fail, cannot be changed |
||||||
|
-- PGC_SIGHUP |
||||||
|
SET autovacuum = OFF; -- fail, requires reload |
||||||
|
RESET autovacuum; -- fail, requires reload |
||||||
|
ALTER SYSTEM SET autovacuum = OFF; -- ok |
||||||
|
ALTER SYSTEM RESET autovacuum; -- ok |
||||||
|
-- PGC_SUSET |
||||||
|
SET lc_messages = 'C'; -- ok |
||||||
|
RESET lc_messages; -- ok |
||||||
|
ALTER SYSTEM SET lc_messages = 'C'; -- ok |
||||||
|
ALTER SYSTEM RESET lc_messages; -- ok |
||||||
|
-- PGC_SU_BACKEND |
||||||
|
SET jit_debugging_support = OFF; -- fail, cannot be set after connection start |
||||||
|
RESET jit_debugging_support; -- fail, cannot be set after connection start |
||||||
|
ALTER SYSTEM SET jit_debugging_support = OFF; -- ok |
||||||
|
ALTER SYSTEM RESET jit_debugging_support; -- ok |
||||||
|
-- PGC_USERSET |
||||||
|
SET DateStyle = 'ISO, MDY'; -- ok |
||||||
|
RESET DateStyle; -- ok |
||||||
|
ALTER SYSTEM SET DateStyle = 'ISO, MDY'; -- ok |
||||||
|
ALTER SYSTEM RESET DateStyle; -- ok |
||||||
|
ALTER SYSTEM SET ssl_renegotiation_limit = 0; -- fail, cannot be changed |
||||||
|
ALTER SYSTEM RESET ssl_renegotiation_limit; -- fail, cannot be changed |
||||||
|
-- Finished testing superuser |
||||||
|
|
||||||
|
-- Create non-superuser with privileges to configure host resource usage |
||||||
|
CREATE ROLE regress_host_resource_admin NOSUPERUSER; |
||||||
|
-- Revoke privileges not yet granted |
||||||
|
REVOKE SET, ALTER SYSTEM ON PARAMETER work_mem FROM regress_host_resource_admin; |
||||||
|
REVOKE SET, ALTER SYSTEM ON PARAMETER zero_damaged_pages FROM regress_host_resource_admin; |
||||||
|
-- Check the new role does not yet have privileges on parameters |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET, ALTER SYSTEM'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'ALTER SYSTEM'); |
||||||
|
-- Check inappropriate and nonsense privilege types |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SELECT, UPDATE, CREATE'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'USAGE'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'WHATEVER'); |
||||||
|
-- Revoke, grant, and revoke again a SUSET parameter not yet granted |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'ALTER SYSTEM'); |
||||||
|
REVOKE SET ON PARAMETER zero_damaged_pages FROM regress_host_resource_admin; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'ALTER SYSTEM'); |
||||||
|
GRANT SET ON PARAMETER zero_damaged_pages TO regress_host_resource_admin; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'ALTER SYSTEM'); |
||||||
|
REVOKE SET ON PARAMETER zero_damaged_pages FROM regress_host_resource_admin; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'zero_damaged_pages', 'ALTER SYSTEM'); |
||||||
|
-- Revoke, grant, and revoke again a USERSET parameter not yet granted |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'ALTER SYSTEM'); |
||||||
|
REVOKE SET ON PARAMETER work_mem FROM regress_host_resource_admin; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'ALTER SYSTEM'); |
||||||
|
GRANT SET ON PARAMETER work_mem TO regress_host_resource_admin; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'ALTER SYSTEM'); |
||||||
|
REVOKE SET ON PARAMETER work_mem FROM regress_host_resource_admin; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'ALTER SYSTEM'); |
||||||
|
|
||||||
|
-- Revoke privileges from a non-existent custom GUC. This should not create |
||||||
|
-- entries in the catalog. |
||||||
|
REVOKE ALL ON PARAMETER "none.such" FROM regress_host_resource_admin; |
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'none.such'; |
||||||
|
-- Grant and then revoke privileges on the non-existent custom GUC. Check that |
||||||
|
-- a do-nothing entry is not left in the catalogs after the revoke. |
||||||
|
GRANT ALL ON PARAMETER none.such TO regress_host_resource_admin; |
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'none.such'; |
||||||
|
REVOKE ALL ON PARAMETER "None.Such" FROM regress_host_resource_admin; |
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'none.such'; |
||||||
|
-- Can't grant on a non-existent core GUC. |
||||||
|
GRANT ALL ON PARAMETER no_such_guc TO regress_host_resource_admin; -- fail |
||||||
|
|
||||||
|
-- Initially there are no privileges and no catalog entry for this GUC. |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'ALTER SYSTEM'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET, ALTER SYSTEM'); |
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'enable_material'; |
||||||
|
-- GRANT SET creates an entry: |
||||||
|
GRANT SET ON PARAMETER enable_material TO PUBLIC; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'ALTER SYSTEM'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET, ALTER SYSTEM'); |
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'enable_material'; |
||||||
|
-- Now grant ALTER SYSTEM: |
||||||
|
GRANT ALL ON PARAMETER enable_material TO PUBLIC; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'ALTER SYSTEM'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET, ALTER SYSTEM'); |
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'enable_material'; |
||||||
|
-- REVOKE ALTER SYSTEM brings us back to just the SET privilege: |
||||||
|
REVOKE ALTER SYSTEM ON PARAMETER enable_material FROM PUBLIC; |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'ALTER SYSTEM'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'enable_material', 'SET, ALTER SYSTEM'); |
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'enable_material'; |
||||||
|
-- And this should remove the entry altogether: |
||||||
|
REVOKE SET ON PARAMETER enable_material FROM PUBLIC; |
||||||
|
SELECT 1 FROM pg_parameter_acl WHERE parname = 'enable_material'; |
||||||
|
|
||||||
|
-- Grant privileges on parameters to the new non-superuser role |
||||||
|
GRANT SET, ALTER SYSTEM ON PARAMETER |
||||||
|
autovacuum_work_mem, hash_mem_multiplier, max_stack_depth, |
||||||
|
shared_buffers, temp_file_limit, work_mem |
||||||
|
TO regress_host_resource_admin; |
||||||
|
-- Check the new role now has privilges on parameters |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET, ALTER SYSTEM'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'ALTER SYSTEM'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SET WITH GRANT OPTION, ALTER SYSTEM WITH GRANT OPTION'); |
||||||
|
-- Check again the inappropriate and nonsense privilege types. The prior |
||||||
|
-- similar check was performed before any entry for work_mem existed. |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'SELECT, UPDATE, CREATE'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'USAGE'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'WHATEVER'); |
||||||
|
SELECT has_parameter_privilege('regress_host_resource_admin', 'work_mem', 'WHATEVER WITH GRANT OPTION'); |
||||||
|
|
||||||
|
-- Check other function signatures |
||||||
|
SELECT has_parameter_privilege((SELECT oid FROM pg_catalog.pg_authid WHERE rolname = 'regress_host_resource_admin'), |
||||||
|
'max_stack_depth', |
||||||
|
'SET'); |
||||||
|
SELECT has_parameter_privilege('hash_mem_multiplier', 'set'); |
||||||
|
|
||||||
|
-- Check object identity functions |
||||||
|
SELECT pg_describe_object(tableoid, oid, 0) |
||||||
|
FROM pg_parameter_acl WHERE parname = 'work_mem'; |
||||||
|
SELECT pg_identify_object(tableoid, oid, 0) |
||||||
|
FROM pg_parameter_acl WHERE parname = 'work_mem'; |
||||||
|
SELECT pg_identify_object_as_address(tableoid, oid, 0) |
||||||
|
FROM pg_parameter_acl WHERE parname = 'work_mem'; |
||||||
|
SELECT classid::regclass, |
||||||
|
(SELECT parname FROM pg_parameter_acl WHERE oid = goa.objid) AS parname, |
||||||
|
objsubid |
||||||
|
FROM pg_get_object_address('parameter ACL', '{work_mem}', '{}') goa; |
||||||
|
|
||||||
|
-- Perform some operations as user 'regress_host_resource_admin' |
||||||
|
SET SESSION AUTHORIZATION regress_host_resource_admin; |
||||||
|
ALTER SYSTEM SET autovacuum_work_mem = 32; -- ok, privileges have been granted |
||||||
|
ALTER SYSTEM SET ignore_system_indexes = OFF; -- fail, insufficient privileges |
||||||
|
ALTER SYSTEM RESET autovacuum_multixact_freeze_max_age; -- fail, insufficient privileges |
||||||
|
SET jit_provider = 'llvmjit'; -- fail, insufficient privileges |
||||||
|
SELECT set_config ('jit_provider', 'llvmjit', true); -- fail, insufficient privileges |
||||||
|
ALTER SYSTEM SET shared_buffers = 50; -- ok |
||||||
|
ALTER SYSTEM RESET shared_buffers; -- ok |
||||||
|
SET autovacuum_work_mem = 50; -- cannot be changed now |
||||||
|
ALTER SYSTEM RESET temp_file_limit; -- ok |
||||||
|
SET TimeZone = 'Europe/Helsinki'; -- ok |
||||||
|
RESET TimeZone; -- ok |
||||||
|
SET max_stack_depth = 2048; -- ok, privileges have been granted |
||||||
|
RESET max_stack_depth; -- ok, privileges have been granted |
||||||
|
ALTER SYSTEM SET max_stack_depth = 2048; -- ok, privileges have been granted |
||||||
|
ALTER SYSTEM RESET max_stack_depth; -- ok, privileges have been granted |
||||||
|
SET lc_messages = 'C'; -- fail, insufficient privileges |
||||||
|
RESET lc_messages; -- fail, insufficient privileges |
||||||
|
ALTER SYSTEM SET lc_messages = 'C'; -- fail, insufficient privileges |
||||||
|
ALTER SYSTEM RESET lc_messages; -- fail, insufficient privileges |
||||||
|
SELECT set_config ('temp_buffers', '8192', false); -- ok |
||||||
|
ALTER SYSTEM RESET autovacuum_work_mem; -- ok, privileges have been granted |
||||||
|
ALTER SYSTEM RESET ALL; -- fail, insufficient privileges |
||||||
|
|
||||||
|
-- Check dropping/revoking behavior |
||||||
|
SET SESSION AUTHORIZATION regress_admin; |
||||||
|
DROP ROLE regress_host_resource_admin; -- fail, privileges remain |
||||||
|
-- Use "revoke" to remove the privileges and allow the role to be dropped |
||||||
|
REVOKE SET, ALTER SYSTEM ON PARAMETER |
||||||
|
autovacuum_work_mem, hash_mem_multiplier, max_stack_depth, |
||||||
|
shared_buffers, temp_file_limit, work_mem |
||||||
|
FROM regress_host_resource_admin; |
||||||
|
DROP ROLE regress_host_resource_admin; -- ok |
||||||
|
|
||||||
|
-- Try that again, but use "drop owned by" instead of "revoke" |
||||||
|
CREATE ROLE regress_host_resource_admin NOSUPERUSER; |
||||||
|
SET SESSION AUTHORIZATION regress_host_resource_admin; |
||||||
|
ALTER SYSTEM SET autovacuum_work_mem = 32; -- fail, privileges not yet granted |
||||||
|
SET SESSION AUTHORIZATION regress_admin; |
||||||
|
GRANT SET, ALTER SYSTEM ON PARAMETER |
||||||
|
autovacuum_work_mem, hash_mem_multiplier, max_stack_depth, |
||||||
|
shared_buffers, temp_file_limit, work_mem |
||||||
|
TO regress_host_resource_admin; |
||||||
|
DROP ROLE regress_host_resource_admin; -- fail, privileges remain |
||||||
|
DROP OWNED BY regress_host_resource_admin RESTRICT; -- cascade should not be needed |
||||||
|
SET SESSION AUTHORIZATION regress_host_resource_admin; |
||||||
|
ALTER SYSTEM SET autovacuum_work_mem = 32; -- fail, "drop owned" has dropped privileges |
||||||
|
SET SESSION AUTHORIZATION regress_admin; |
||||||
|
DROP ROLE regress_host_resource_admin; -- ok |
||||||
|
|
||||||
|
-- Check that "reassign owned" doesn't affect privileges |
||||||
|
CREATE ROLE regress_host_resource_admin NOSUPERUSER; |
||||||
|
CREATE ROLE regress_host_resource_newadmin NOSUPERUSER; |
||||||
|
GRANT SET, ALTER SYSTEM ON PARAMETER |
||||||
|
autovacuum_work_mem, hash_mem_multiplier, max_stack_depth, |
||||||
|
shared_buffers, temp_file_limit, work_mem |
||||||
|
TO regress_host_resource_admin; |
||||||
|
REASSIGN OWNED BY regress_host_resource_admin TO regress_host_resource_newadmin; |
||||||
|
SET SESSION AUTHORIZATION regress_host_resource_admin; |
||||||
|
ALTER SYSTEM SET autovacuum_work_mem = 32; -- ok, "reassign owned" did not change privileges |
||||||
|
ALTER SYSTEM RESET autovacuum_work_mem; -- ok |
||||||
|
SET SESSION AUTHORIZATION regress_admin; |
||||||
|
DROP ROLE regress_host_resource_admin; -- fail, privileges remain |
||||||
|
DROP ROLE regress_host_resource_newadmin; -- ok, nothing was transferred |
||||||
|
-- Use "drop owned by" so we can drop the role |
||||||
|
DROP OWNED BY regress_host_resource_admin; -- ok |
||||||
|
DROP ROLE regress_host_resource_admin; -- ok |
||||||
|
|
||||||
|
-- Clean up |
||||||
|
RESET SESSION AUTHORIZATION; |
||||||
|
DROP ROLE regress_admin; -- ok |
Loading…
Reference in new issue