mirror of
https://github.com/postgres/postgres.git
synced 2025-07-03 20:02:46 +03:00
Clean up some loose ends from the column privileges patch: add
has_column_privilege and has_any_column_privilege SQL functions; fix the information_schema views that are supposed to pay attention to column privileges; adjust pg_stats to show stats for any column you have select privilege on; and fix COPY to allow copying a subset of columns if the user has suitable per-column privileges for all the columns. To improve efficiency of some of the information_schema views, extend the has_xxx_privilege functions to allow inquiring about the OR of a set of privileges in just one call. This is just exposing capability that already existed in the underlying aclcheck routines. In passing, make the information_schema views report the owner's own privileges as being grantable, since Postgres assumes this even when the grant option bit is not set in the ACL. This is a longstanding oversight. Also, make the new has_xxx_privilege functions for foreign data objects follow the same coding conventions used by the older ones. Stephen Frost and Tom Lane
This commit is contained in:
@ -8,7 +8,7 @@
|
||||
*
|
||||
*
|
||||
* IDENTIFICATION
|
||||
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.304 2009/01/02 20:42:00 tgl Exp $
|
||||
* $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.305 2009/02/06 21:15:11 tgl Exp $
|
||||
*
|
||||
*-------------------------------------------------------------------------
|
||||
*/
|
||||
@ -711,7 +711,7 @@ CopyLoadRawBuf(CopyState cstate)
|
||||
* or write to a file.
|
||||
*
|
||||
* Do not allow the copy if user doesn't have proper permission to access
|
||||
* the table.
|
||||
* the table or the specifically requested columns.
|
||||
*/
|
||||
uint64
|
||||
DoCopy(const CopyStmt *stmt, const char *queryString)
|
||||
@ -723,7 +723,8 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
|
||||
List *force_quote = NIL;
|
||||
List *force_notnull = NIL;
|
||||
AclMode required_access = (is_from ? ACL_INSERT : ACL_SELECT);
|
||||
AclResult aclresult;
|
||||
AclMode relPerms;
|
||||
AclMode remainingPerms;
|
||||
ListCell *option;
|
||||
TupleDesc tupDesc;
|
||||
int num_phys_attrs;
|
||||
@ -973,13 +974,31 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
|
||||
cstate->rel = heap_openrv(stmt->relation,
|
||||
(is_from ? RowExclusiveLock : AccessShareLock));
|
||||
|
||||
tupDesc = RelationGetDescr(cstate->rel);
|
||||
|
||||
/* Check relation permissions. */
|
||||
aclresult = pg_class_aclcheck(RelationGetRelid(cstate->rel),
|
||||
GetUserId(),
|
||||
required_access);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult, ACL_KIND_CLASS,
|
||||
RelationGetRelationName(cstate->rel));
|
||||
relPerms = pg_class_aclmask(RelationGetRelid(cstate->rel), GetUserId(),
|
||||
required_access, ACLMASK_ALL);
|
||||
remainingPerms = required_access & ~relPerms;
|
||||
if (remainingPerms != 0)
|
||||
{
|
||||
/* We don't have table permissions, check per-column permissions */
|
||||
List *attnums;
|
||||
ListCell *cur;
|
||||
|
||||
attnums = CopyGetAttnums(tupDesc, cstate->rel, attnamelist);
|
||||
foreach(cur, attnums)
|
||||
{
|
||||
int attnum = lfirst_int(cur);
|
||||
|
||||
if (pg_attribute_aclcheck(RelationGetRelid(cstate->rel),
|
||||
attnum,
|
||||
GetUserId(),
|
||||
remainingPerms) != ACLCHECK_OK)
|
||||
aclcheck_error(ACLCHECK_NO_PRIV, ACL_KIND_CLASS,
|
||||
RelationGetRelationName(cstate->rel));
|
||||
}
|
||||
}
|
||||
|
||||
/* check read-only transaction */
|
||||
if (XactReadOnly && is_from &&
|
||||
@ -994,8 +1013,6 @@ DoCopy(const CopyStmt *stmt, const char *queryString)
|
||||
(errcode(ERRCODE_UNDEFINED_COLUMN),
|
||||
errmsg("table \"%s\" does not have OIDs",
|
||||
RelationGetRelationName(cstate->rel))));
|
||||
|
||||
tupDesc = RelationGetDescr(cstate->rel);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
Reference in New Issue
Block a user