diff options
author | Tom Lane <tgl@sss.pgh.pa.us> | 2009-02-06 21:15:12 +0000 |
---|---|---|
committer | Tom Lane <tgl@sss.pgh.pa.us> | 2009-02-06 21:15:12 +0000 |
commit | 7449427a1e6a099bc7e76164cb99a01d5e87237b (patch) | |
tree | 05883ab8f6d2c91c3b75892ab566bfac84ff0b59 /src/backend/commands/copy.c | |
parent | 0274e1b9499d98c66182321aafb829faa5f49e41 (diff) | |
download | postgresql-7449427a1e6a099bc7e76164cb99a01d5e87237b.tar.gz postgresql-7449427a1e6a099bc7e76164cb99a01d5e87237b.zip |
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
Diffstat (limited to 'src/backend/commands/copy.c')
-rw-r--r-- | src/backend/commands/copy.c | 39 |
1 files changed, 28 insertions, 11 deletions
diff --git a/src/backend/commands/copy.c b/src/backend/commands/copy.c index c2e2c822052..550e7e661fd 100644 --- a/src/backend/commands/copy.c +++ b/src/backend/commands/copy.c @@ -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 { |