summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStephen Frost2015-05-11 19:44:12 +0000
committerStephen Frost2015-05-11 19:44:12 +0000
commitfa2642438f189c2b169ace3ac1df19533b9c7781 (patch)
tree7a455813a35d03230771870778bd9a47962c916e
parent9d15292cfc581d2916778b79df0f0e86e032a677 (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.sgml8
-rw-r--r--src/backend/commands/lockcmds.c12
2 files changed, 13 insertions, 7 deletions
diff --git a/doc/src/sgml/ref/lock.sgml b/doc/src/sgml/ref/lock.sgml
index 913afe76dd4..b946eab3039 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 bdec2ff545c..a1670821aa4 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;
}