*** pgsql/src/backend/commands/copy.c 2009/01/02 20:42:00 1.304 --- pgsql/src/backend/commands/copy.c 2009/02/06 21:15:11 1.305 *************** *** 8,14 **** * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.303 2009/01/01 17:23:37 momjian Exp $ * *------------------------------------------------------------------------- */ --- 8,14 ---- * * * IDENTIFICATION ! * $PostgreSQL: pgsql/src/backend/commands/copy.c,v 1.304 2009/01/02 20:42:00 tgl Exp $ * *------------------------------------------------------------------------- */ *************** CopyLoadRawBuf(CopyState cstate) *** 711,717 **** * or write to a file. * * Do not allow the copy if user doesn't have proper permission to access ! * the table. */ uint64 DoCopy(const CopyStmt *stmt, const char *queryString) --- 711,717 ---- * or write to a file. * * Do not allow the copy if user doesn't have proper permission to access ! * the table or the specifically requested columns. */ uint64 DoCopy(const CopyStmt *stmt, const char *queryString) *************** DoCopy(const CopyStmt *stmt, const char *** 723,729 **** List *force_quote = NIL; List *force_notnull = NIL; AclMode required_access = (is_from ? ACL_INSERT : ACL_SELECT); ! AclResult aclresult; ListCell *option; TupleDesc tupDesc; int num_phys_attrs; --- 723,730 ---- List *force_quote = NIL; List *force_notnull = NIL; AclMode required_access = (is_from ? ACL_INSERT : ACL_SELECT); ! AclMode relPerms; ! AclMode remainingPerms; ListCell *option; TupleDesc tupDesc; int num_phys_attrs; *************** DoCopy(const CopyStmt *stmt, const char *** 973,985 **** cstate->rel = heap_openrv(stmt->relation, (is_from ? RowExclusiveLock : AccessShareLock)); /* 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)); /* check read-only transaction */ if (XactReadOnly && is_from && --- 974,1004 ---- cstate->rel = heap_openrv(stmt->relation, (is_from ? RowExclusiveLock : AccessShareLock)); + tupDesc = RelationGetDescr(cstate->rel); + /* Check relation permissions. */ ! 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 && *************** DoCopy(const CopyStmt *stmt, const char *** 994,1001 **** (errcode(ERRCODE_UNDEFINED_COLUMN), errmsg("table \"%s\" does not have OIDs", RelationGetRelationName(cstate->rel)))); - - tupDesc = RelationGetDescr(cstate->rel); } else { --- 1013,1018 ----