mirror of
https://github.com/postgres/postgres.git
synced 2025-07-30 11:03:19 +03:00
Simplify permissions for LOCK TABLE.
The prior behavior was confusing and hard to document. For instance, if you had UPDATE privileges, you could lock a table in any lock mode except ACCESS SHARE mode. Now, if granted a privilege to lock at a given mode, one also has privileges to lock at a less-conflicting mode. MAINTAIN, UPDATE, DELETE, and TRUNCATE privileges allow any lock mode. INSERT privileges allow ROW EXCLUSIVE (or below). SELECT privileges allow ACCESS SHARE. Reviewed-by: Nathan Bossart Discussion: https://postgr.es/m/9550c76535404a83156252b25a11babb4792ea1e.camel%40j-davis.com
This commit is contained in:
@ -292,16 +292,16 @@ LockTableAclCheck(Oid reloid, LOCKMODE lockmode, Oid userid)
|
||||
AclResult aclresult;
|
||||
AclMode aclmask;
|
||||
|
||||
/* Verify adequate privilege */
|
||||
if (lockmode == AccessShareLock)
|
||||
aclmask = ACL_SELECT;
|
||||
else if (lockmode == RowExclusiveLock)
|
||||
aclmask = ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE;
|
||||
else
|
||||
aclmask = ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE;
|
||||
/* any of these privileges permit any lock mode */
|
||||
aclmask = ACL_MAINTAIN | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE;
|
||||
|
||||
/* MAINTAIN privilege allows all lock modes */
|
||||
aclmask |= ACL_MAINTAIN;
|
||||
/* SELECT privileges also permit ACCESS SHARE and below */
|
||||
if (lockmode <= AccessShareLock)
|
||||
aclmask |= ACL_SELECT;
|
||||
|
||||
/* INSERT privileges also permit ROW EXCLUSIVE and below */
|
||||
if (lockmode <= RowExclusiveLock)
|
||||
aclmask |= ACL_INSERT;
|
||||
|
||||
aclresult = pg_class_aclcheck(reloid, userid, aclmask);
|
||||
|
||||
|
@ -2706,13 +2706,13 @@ CREATE TABLE lock_table (a int);
|
||||
GRANT SELECT ON lock_table TO regress_locktable_user;
|
||||
SET SESSION AUTHORIZATION regress_locktable_user;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should fail
|
||||
ERROR: permission denied for table lock_table
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail
|
||||
ERROR: permission denied for table lock_table
|
||||
ROLLBACK;
|
||||
@ -2722,13 +2722,12 @@ REVOKE SELECT ON lock_table FROM regress_locktable_user;
|
||||
GRANT INSERT ON lock_table TO regress_locktable_user;
|
||||
SET SESSION AUTHORIZATION regress_locktable_user;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
|
||||
ERROR: permission denied for table lock_table
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail
|
||||
ERROR: permission denied for table lock_table
|
||||
ROLLBACK;
|
||||
@ -2738,13 +2737,12 @@ REVOKE INSERT ON lock_table FROM regress_locktable_user;
|
||||
GRANT UPDATE ON lock_table TO regress_locktable_user;
|
||||
SET SESSION AUTHORIZATION regress_locktable_user;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
|
||||
ERROR: permission denied for table lock_table
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
\c
|
||||
@ -2753,13 +2751,12 @@ REVOKE UPDATE ON lock_table FROM regress_locktable_user;
|
||||
GRANT DELETE ON lock_table TO regress_locktable_user;
|
||||
SET SESSION AUTHORIZATION regress_locktable_user;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
|
||||
ERROR: permission denied for table lock_table
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
\c
|
||||
@ -2768,17 +2765,30 @@ REVOKE DELETE ON lock_table FROM regress_locktable_user;
|
||||
GRANT TRUNCATE ON lock_table TO regress_locktable_user;
|
||||
SET SESSION AUTHORIZATION regress_locktable_user;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
|
||||
ERROR: permission denied for table lock_table
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
\c
|
||||
REVOKE TRUNCATE ON lock_table FROM regress_locktable_user;
|
||||
-- LOCK TABLE and MAINTAIN permission
|
||||
GRANT MAINTAIN ON lock_table TO regress_locktable_user;
|
||||
SET SESSION AUTHORIZATION regress_locktable_user;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
\c
|
||||
REVOKE MAINTAIN ON lock_table FROM regress_locktable_user;
|
||||
-- clean up
|
||||
DROP TABLE lock_table;
|
||||
DROP USER regress_locktable_user;
|
||||
@ -2920,14 +2930,6 @@ REINDEX INDEX maintain_test_a_idx;
|
||||
ERROR: must be owner of index maintain_test_a_idx
|
||||
REINDEX SCHEMA reindex_test;
|
||||
ERROR: must be owner of schema reindex_test
|
||||
BEGIN;
|
||||
LOCK TABLE maintain_test IN ACCESS SHARE MODE;
|
||||
ERROR: permission denied for table maintain_test
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE maintain_test IN ACCESS EXCLUSIVE MODE;
|
||||
ERROR: permission denied for table maintain_test
|
||||
COMMIT;
|
||||
RESET ROLE;
|
||||
SET ROLE regress_maintain;
|
||||
VACUUM maintain_test;
|
||||
@ -2939,12 +2941,6 @@ REINDEX TABLE maintain_test;
|
||||
REINDEX INDEX maintain_test_a_idx;
|
||||
REINDEX SCHEMA reindex_test;
|
||||
ERROR: must be owner of schema reindex_test
|
||||
BEGIN;
|
||||
LOCK TABLE maintain_test IN ACCESS SHARE MODE;
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE maintain_test IN ACCESS EXCLUSIVE MODE;
|
||||
COMMIT;
|
||||
RESET ROLE;
|
||||
SET ROLE regress_maintain_all;
|
||||
VACUUM maintain_test;
|
||||
@ -2955,12 +2951,6 @@ REFRESH MATERIALIZED VIEW refresh_test;
|
||||
REINDEX TABLE maintain_test;
|
||||
REINDEX INDEX maintain_test_a_idx;
|
||||
REINDEX SCHEMA reindex_test;
|
||||
BEGIN;
|
||||
LOCK TABLE maintain_test IN ACCESS SHARE MODE;
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE maintain_test IN ACCESS EXCLUSIVE MODE;
|
||||
COMMIT;
|
||||
RESET ROLE;
|
||||
DROP TABLE maintain_test;
|
||||
DROP MATERIALIZED VIEW refresh_test;
|
||||
|
@ -1707,12 +1707,12 @@ CREATE TABLE lock_table (a int);
|
||||
GRANT SELECT ON lock_table TO regress_locktable_user;
|
||||
SET SESSION AUTHORIZATION regress_locktable_user;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should fail
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should fail
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail
|
||||
ROLLBACK;
|
||||
\c
|
||||
@ -1722,12 +1722,12 @@ REVOKE SELECT ON lock_table FROM regress_locktable_user;
|
||||
GRANT INSERT ON lock_table TO regress_locktable_user;
|
||||
SET SESSION AUTHORIZATION regress_locktable_user;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should fail
|
||||
ROLLBACK;
|
||||
\c
|
||||
@ -1737,12 +1737,12 @@ REVOKE INSERT ON lock_table FROM regress_locktable_user;
|
||||
GRANT UPDATE ON lock_table TO regress_locktable_user;
|
||||
SET SESSION AUTHORIZATION regress_locktable_user;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
\c
|
||||
@ -1752,12 +1752,12 @@ REVOKE UPDATE ON lock_table FROM regress_locktable_user;
|
||||
GRANT DELETE ON lock_table TO regress_locktable_user;
|
||||
SET SESSION AUTHORIZATION regress_locktable_user;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
\c
|
||||
@ -1767,17 +1767,32 @@ REVOKE DELETE ON lock_table FROM regress_locktable_user;
|
||||
GRANT TRUNCATE ON lock_table TO regress_locktable_user;
|
||||
SET SESSION AUTHORIZATION regress_locktable_user;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should fail
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
\c
|
||||
REVOKE TRUNCATE ON lock_table FROM regress_locktable_user;
|
||||
|
||||
-- LOCK TABLE and MAINTAIN permission
|
||||
GRANT MAINTAIN ON lock_table TO regress_locktable_user;
|
||||
SET SESSION AUTHORIZATION regress_locktable_user;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS SHARE MODE; -- should pass
|
||||
ROLLBACK;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ROW EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE lock_table IN ACCESS EXCLUSIVE MODE; -- should pass
|
||||
COMMIT;
|
||||
\c
|
||||
REVOKE MAINTAIN ON lock_table FROM regress_locktable_user;
|
||||
|
||||
-- clean up
|
||||
DROP TABLE lock_table;
|
||||
DROP USER regress_locktable_user;
|
||||
@ -1884,12 +1899,6 @@ REFRESH MATERIALIZED VIEW refresh_test;
|
||||
REINDEX TABLE maintain_test;
|
||||
REINDEX INDEX maintain_test_a_idx;
|
||||
REINDEX SCHEMA reindex_test;
|
||||
BEGIN;
|
||||
LOCK TABLE maintain_test IN ACCESS SHARE MODE;
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE maintain_test IN ACCESS EXCLUSIVE MODE;
|
||||
COMMIT;
|
||||
RESET ROLE;
|
||||
|
||||
SET ROLE regress_maintain;
|
||||
@ -1901,12 +1910,6 @@ REFRESH MATERIALIZED VIEW refresh_test;
|
||||
REINDEX TABLE maintain_test;
|
||||
REINDEX INDEX maintain_test_a_idx;
|
||||
REINDEX SCHEMA reindex_test;
|
||||
BEGIN;
|
||||
LOCK TABLE maintain_test IN ACCESS SHARE MODE;
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE maintain_test IN ACCESS EXCLUSIVE MODE;
|
||||
COMMIT;
|
||||
RESET ROLE;
|
||||
|
||||
SET ROLE regress_maintain_all;
|
||||
@ -1918,12 +1921,6 @@ REFRESH MATERIALIZED VIEW refresh_test;
|
||||
REINDEX TABLE maintain_test;
|
||||
REINDEX INDEX maintain_test_a_idx;
|
||||
REINDEX SCHEMA reindex_test;
|
||||
BEGIN;
|
||||
LOCK TABLE maintain_test IN ACCESS SHARE MODE;
|
||||
COMMIT;
|
||||
BEGIN;
|
||||
LOCK TABLE maintain_test IN ACCESS EXCLUSIVE MODE;
|
||||
COMMIT;
|
||||
RESET ROLE;
|
||||
|
||||
DROP TABLE maintain_test;
|
||||
|
Reference in New Issue
Block a user