Commit 5ddbe904 authored by Tom Lane's avatar Tom Lane

Refactor low-level aclcheck code to provide useful interfaces for multi-bit

permissions tests in about the same amount of code as before.  Exactly what
the GRANT/REVOKE code ought to be doing is still up for debate, but this
should be helpful in any case, and it already solves an efficiency problem
in executor startup.
parent f739deb5
This diff is collapsed.
...@@ -26,7 +26,7 @@ ...@@ -26,7 +26,7 @@
* *
* *
* IDENTIFICATION * IDENTIFICATION
* $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.230 2004/03/23 19:35:16 tgl Exp $ * $PostgreSQL: pgsql/src/backend/executor/execMain.c,v 1.231 2004/05/11 17:36:12 tgl Exp $
* *
*------------------------------------------------------------------------- *-------------------------------------------------------------------------
*/ */
...@@ -412,28 +412,13 @@ ExecCheckRTEPerms(RangeTblEntry *rte) ...@@ -412,28 +412,13 @@ ExecCheckRTEPerms(RangeTblEntry *rte)
userid = rte->checkAsUser ? rte->checkAsUser : GetUserId(); userid = rte->checkAsUser ? rte->checkAsUser : GetUserId();
/* /*
* For each bit in requiredPerms, apply the required check. (We can't * We must have *all* the requiredPerms bits, so use aclmask not
* do this in one aclcheck call because aclcheck treats multiple bits * aclcheck.
* as OR semantics, when we want AND.)
*
* We use a well-known cute trick for isolating the rightmost one-bit
* in a nonzero word. See nodes/bitmapset.c for commentary.
*/ */
#define RIGHTMOST_ONE(x) ((int32) (x) & -((int32) (x))) if (pg_class_aclmask(relOid, userid, requiredPerms, ACLMASK_ALL)
!= requiredPerms)
while (requiredPerms != 0) aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_CLASS,
{
AclMode thisPerm;
AclResult aclcheck_result;
thisPerm = RIGHTMOST_ONE(requiredPerms);
requiredPerms &= ~thisPerm;
aclcheck_result = pg_class_aclcheck(relOid, userid, thisPerm);
if (aclcheck_result != ACLCHECK_OK)
aclcheck_error(aclcheck_result, ACL_KIND_CLASS,
get_rel_name(relOid)); get_rel_name(relOid));
}
} }
/* /*
......
...@@ -7,7 +7,7 @@ ...@@ -7,7 +7,7 @@
* Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group * Portions Copyright (c) 1996-2003, PostgreSQL Global Development Group
* Portions Copyright (c) 1994, Regents of the University of California * Portions Copyright (c) 1994, Regents of the University of California
* *
* $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.68 2004/05/02 13:38:28 momjian Exp $ * $PostgreSQL: pgsql/src/include/utils/acl.h,v 1.69 2004/05/11 17:36:13 tgl Exp $
* *
* NOTES * NOTES
* An ACL array is simply an array of AclItems, representing the union * An ACL array is simply an array of AclItems, representing the union
...@@ -177,6 +177,12 @@ typedef ArrayType IdList; ...@@ -177,6 +177,12 @@ typedef ArrayType IdList;
#define ACL_ALL_RIGHTS_LANGUAGE (ACL_USAGE) #define ACL_ALL_RIGHTS_LANGUAGE (ACL_USAGE)
#define ACL_ALL_RIGHTS_NAMESPACE (ACL_USAGE|ACL_CREATE) #define ACL_ALL_RIGHTS_NAMESPACE (ACL_USAGE|ACL_CREATE)
/* operation codes for pg_*_aclmask */
typedef enum
{
ACLMASK_ALL, /* normal case: compute all bits */
ACLMASK_ANY /* return when result is known nonzero */
} AclMaskHow;
/* result codes for pg_*_aclcheck */ /* result codes for pg_*_aclcheck */
typedef enum typedef enum
...@@ -228,6 +234,17 @@ extern void ExecuteGrantStmt(GrantStmt *stmt); ...@@ -228,6 +234,17 @@ extern void ExecuteGrantStmt(GrantStmt *stmt);
extern AclId get_grosysid(char *groname); extern AclId get_grosysid(char *groname);
extern char *get_groname(AclId grosysid); extern char *get_groname(AclId grosysid);
extern AclMode pg_class_aclmask(Oid table_oid, AclId userid,
AclMode mask, AclMaskHow how);
extern AclMode pg_database_aclmask(Oid db_oid, AclId userid,
AclMode mask, AclMaskHow how);
extern AclMode pg_proc_aclmask(Oid proc_oid, AclId userid,
AclMode mask, AclMaskHow how);
extern AclMode pg_language_aclmask(Oid lang_oid, AclId userid,
AclMode mask, AclMaskHow how);
extern AclMode pg_namespace_aclmask(Oid nsp_oid, AclId userid,
AclMode mask, AclMaskHow how);
extern AclResult pg_class_aclcheck(Oid table_oid, AclId userid, AclMode mode); extern AclResult pg_class_aclcheck(Oid table_oid, AclId userid, AclMode mode);
extern AclResult pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode); extern AclResult pg_database_aclcheck(Oid db_oid, AclId userid, AclMode mode);
extern AclResult pg_proc_aclcheck(Oid proc_oid, AclId userid, AclMode mode); extern AclResult pg_proc_aclcheck(Oid proc_oid, AclId userid, AclMode mode);
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment