diff options
author | Stephen Frost | 2015-05-11 19:44:12 +0000 |
---|---|---|
committer | Stephen Frost | 2015-05-11 19:44:12 +0000 |
commit | fa2642438f189c2b169ace3ac1df19533b9c7781 (patch) | |
tree | 7a455813a35d03230771870778bd9a47962c916e | |
parent | 9d15292cfc581d2916778b79df0f0e86e032a677 (diff) |
Allow LOCK TABLE .. ROW EXCLUSIVE MODE with INSERT
INSERT acquires RowExclusiveLock during normal operation and therefore
it makes sense to allow LOCK TABLE .. ROW EXCLUSIVE MODE to be executed
by users who have INSERT rights on a table (even if they don't have
UPDATE or DELETE).
Not back-patching this as it's a behavior change which, strictly
speaking, loosens security restrictions.
Per discussion with Tom and Robert (circa 2013).
-rw-r--r-- | doc/src/sgml/ref/lock.sgml | 8 | ||||
-rw-r--r-- | src/backend/commands/lockcmds.c | 12 |
2 files changed, 13 insertions, 7 deletions
diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml index 913afe76dd..b946eab303 100644 --- a/doc/src/sgml/ref/lock.sgml +++ b/doc/src/sgml/ref/lock.sgml @@ -161,9 +161,11 @@ LOCK [ TABLE ] [ ONLY ] <replaceable class="PARAMETER">name</replaceable> [ * ] <para> <literal>LOCK TABLE ... IN ACCESS SHARE MODE</> requires <literal>SELECT</> - privileges on the target table. All other forms of <command>LOCK</> - require table-level <literal>UPDATE</>, <literal>DELETE</>, or - <literal>TRUNCATE</> privileges. + privileges on the target table. <literal>LOCK TABLE ... IN ROW EXCLUSIVE + MODE</> requires <literal>INSERT</>, <literal>UPDATE</>, <literal>DELETE</>, + or <literal>TRUNCATE</> privileges on the target table. All other forms of + <command>LOCK</> require table-level <literal>UPDATE</>, <literal>DELETE</>, + or <literal>TRUNCATE</> privileges. </para> <para> diff --git a/src/backend/commands/lockcmds.c b/src/backend/commands/lockcmds.c index bdec2ff545..a1670821aa 100644 --- a/src/backend/commands/lockcmds.c +++ b/src/backend/commands/lockcmds.c @@ -169,13 +169,17 @@ static AclResult LockTableAclCheck(Oid reloid, LOCKMODE lockmode) { AclResult aclresult; + AclMode aclmask; /* Verify adequate privilege */ if (lockmode == AccessShareLock) - aclresult = pg_class_aclcheck(reloid, GetUserId(), - ACL_SELECT); + aclmask = ACL_SELECT; + else if (lockmode == RowExclusiveLock) + aclmask = ACL_INSERT | ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE; else - aclresult = pg_class_aclcheck(reloid, GetUserId(), - ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE); + aclmask = ACL_UPDATE | ACL_DELETE | ACL_TRUNCATE; + + aclresult = pg_class_aclcheck(reloid, GetUserId(), aclmask); + return aclresult; } |