diff options
Diffstat (limited to 'src/backend/commands')
-rw-r--r-- | src/backend/commands/analyze.c | 9 | ||||
-rw-r--r-- | src/backend/commands/tablecmds.c | 62 | ||||
-rw-r--r-- | src/backend/commands/tablespace.c | 4 | ||||
-rw-r--r-- | src/backend/commands/trigger.c | 33 | ||||
-rw-r--r-- | src/backend/commands/tsearchcmds.c | 4 | ||||
-rw-r--r-- | src/backend/commands/user.c | 14 |
6 files changed, 73 insertions, 53 deletions
diff --git a/src/backend/commands/analyze.c b/src/backend/commands/analyze.c index 5f6a2c42de6..33447b671f1 100644 --- a/src/backend/commands/analyze.c +++ b/src/backend/commands/analyze.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.132 2009/01/06 23:46:06 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/commands/analyze.c,v 1.133 2009/01/22 20:16:01 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -705,11 +705,12 @@ examine_attribute(Relation onerel, int attnum) return NULL; /* - * Create the VacAttrStats struct. + * Create the VacAttrStats struct. Note that we only have a copy of + * the fixed fields of the pg_attribute tuple. */ stats = (VacAttrStats *) palloc0(sizeof(VacAttrStats)); - stats->attr = (Form_pg_attribute) palloc(ATTRIBUTE_TUPLE_SIZE); - memcpy(stats->attr, attr, ATTRIBUTE_TUPLE_SIZE); + stats->attr = (Form_pg_attribute) palloc(ATTRIBUTE_FIXED_PART_SIZE); + memcpy(stats->attr, attr, ATTRIBUTE_FIXED_PART_SIZE); typtuple = SearchSysCache(TYPEOID, ObjectIdGetDatum(attr->atttypid), 0, 0, 0); diff --git a/src/backend/commands/tablecmds.c b/src/backend/commands/tablecmds.c index 061d45c30ac..397e010acaf 100644 --- a/src/backend/commands/tablecmds.c +++ b/src/backend/commands/tablecmds.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.277 2009/01/12 08:54:26 petere Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablecmds.c,v 1.278 2009/01/22 20:16:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -246,6 +246,7 @@ static int transformFkeyGetPrimaryKey(Relation pkrel, Oid *indexOid, static Oid transformFkeyCheckAttrs(Relation pkrel, int numattrs, int16 *attnums, Oid *opclasses); +static void checkFkeyPermissions(Relation rel, int16 *attnums, int natts); static void validateForeignKeyConstraint(FkConstraint *fkconstraint, Relation rel, Relation pkrel, Oid constraintOid); static void createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, @@ -3589,6 +3590,7 @@ ATExecAddColumn(AlteredTableInfo *tab, Relation rel, attribute.attisdropped = false; attribute.attislocal = colDef->is_local; attribute.attinhcount = colDef->inhcount; + /* attribute.attacl is handled by InsertPgAttributeTuple */ ReleaseSysCache(typeTuple); @@ -4473,15 +4475,14 @@ ATAddCheckConstraint(List **wqueue, AlteredTableInfo *tab, Relation rel, * Add a foreign-key constraint to a single table * * Subroutine for ATExecAddConstraint. Must already hold exclusive - * lock on the rel, and have done appropriate validity/permissions checks - * for it. + * lock on the rel, and have done appropriate validity checks for it. + * We do permissions checks here, however. */ static void ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, FkConstraint *fkconstraint) { Relation pkrel; - AclResult aclresult; int16 pkattnum[INDEX_MAX_KEYS]; int16 fkattnum[INDEX_MAX_KEYS]; Oid pktypoid[INDEX_MAX_KEYS]; @@ -4506,10 +4507,7 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, pkrel = heap_openrv(fkconstraint->pktable, AccessExclusiveLock); /* - * Validity and permissions checks - * - * Note: REFERENCES permissions checks are redundant with CREATE TRIGGER, - * but we may as well error out sooner instead of later. + * Validity checks (permission checks wait till we have the column numbers) */ if (pkrel->rd_rel->relkind != RELKIND_RELATION) ereport(ERROR, @@ -4517,24 +4515,12 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, errmsg("referenced relation \"%s\" is not a table", RelationGetRelationName(pkrel)))); - aclresult = pg_class_aclcheck(RelationGetRelid(pkrel), GetUserId(), - ACL_REFERENCES); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_CLASS, - RelationGetRelationName(pkrel)); - if (!allowSystemTableMods && IsSystemRelation(pkrel)) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("permission denied: \"%s\" is a system catalog", RelationGetRelationName(pkrel)))); - aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), - ACL_REFERENCES); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_CLASS, - RelationGetRelationName(rel)); - /* * Disallow reference from permanent table to temp table or vice versa. * (The ban on perm->temp is for fairly obvious reasons. The ban on @@ -4599,6 +4585,12 @@ ATAddForeignKeyConstraint(AlteredTableInfo *tab, Relation rel, } /* + * Now we can check permissions. + */ + checkFkeyPermissions(pkrel, pkattnum, numpks); + checkFkeyPermissions(rel, fkattnum, numfks); + + /* * Look up the equality operators to use in the constraint. * * Note that we have to be careful about the difference between the actual @@ -5016,6 +5008,30 @@ transformFkeyCheckAttrs(Relation pkrel, return indexoid; } +/* Permissions checks for ADD FOREIGN KEY */ +static void +checkFkeyPermissions(Relation rel, int16 *attnums, int natts) +{ + Oid roleid = GetUserId(); + AclResult aclresult; + int i; + + /* Okay if we have relation-level REFERENCES permission */ + aclresult = pg_class_aclcheck(RelationGetRelid(rel), roleid, + ACL_REFERENCES); + if (aclresult == ACLCHECK_OK) + return; + /* Else we must have REFERENCES on each column */ + for (i = 0; i < natts; i++) + { + aclresult = pg_attribute_aclcheck(RelationGetRelid(rel), attnums[i], + roleid, ACL_REFERENCES); + if (aclresult != ACLCHECK_OK) + aclcheck_error(aclresult, ACL_KIND_CLASS, + RelationGetRelationName(rel)); + } +} + /* * Scan the existing rows in a table to verify they meet a proposed FK * constraint. @@ -5123,7 +5139,7 @@ CreateFKCheckTrigger(RangeVar *myRel, FkConstraint *fkconstraint, fk_trigger->constrrel = fkconstraint->pktable; fk_trigger->args = NIL; - (void) CreateTrigger(fk_trigger, constraintOid); + (void) CreateTrigger(fk_trigger, constraintOid, false); /* Make changes-so-far visible */ CommandCounterIncrement(); @@ -5204,7 +5220,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, } fk_trigger->args = NIL; - (void) CreateTrigger(fk_trigger, constraintOid); + (void) CreateTrigger(fk_trigger, constraintOid, false); /* Make changes-so-far visible */ CommandCounterIncrement(); @@ -5256,7 +5272,7 @@ createForeignKeyTriggers(Relation rel, FkConstraint *fkconstraint, } fk_trigger->args = NIL; - (void) CreateTrigger(fk_trigger, constraintOid); + (void) CreateTrigger(fk_trigger, constraintOid, false); } /* diff --git a/src/backend/commands/tablespace.c b/src/backend/commands/tablespace.c index 54818ff34d7..b81381a6ea8 100644 --- a/src/backend/commands/tablespace.c +++ b/src/backend/commands/tablespace.c @@ -37,7 +37,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.60 2009/01/20 18:59:37 heikki Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tablespace.c,v 1.61 2009/01/22 20:16:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -455,7 +455,7 @@ DropTableSpace(DropTableSpaceStmt *stmt) /* * Remove dependency on owner. */ - deleteSharedDependencyRecordsFor(TableSpaceRelationId, tablespaceoid); + deleteSharedDependencyRecordsFor(TableSpaceRelationId, tablespaceoid, 0); /* * Acquire TablespaceCreateLock to ensure that no TablespaceCreateDbspace diff --git a/src/backend/commands/trigger.c b/src/backend/commands/trigger.c index 699493c3350..ce276e5fe55 100644 --- a/src/backend/commands/trigger.c +++ b/src/backend/commands/trigger.c @@ -7,7 +7,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.245 2009/01/22 19:16:31 heikki Exp $ + * $PostgreSQL: pgsql/src/backend/commands/trigger.c,v 1.246 2009/01/22 20:16:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -74,11 +74,16 @@ static void AfterTriggerSaveEvent(ResultRelInfo *relinfo, int event, * be made to link the trigger to that constraint. constraintOid is zero when * executing a user-entered CREATE TRIGGER command. * + * If checkPermissions is true we require ACL_TRIGGER permissions on the + * relation. If not, the caller already checked permissions. (This is + * currently redundant with constraintOid being zero, but it's clearer to + * have a separate argument.) + * * Note: can return InvalidOid if we decided to not create a trigger at all, * but a foreign-key constraint. This is a kluge for backwards compatibility. */ Oid -CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid) +CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid, bool checkPermissions) { int16 tgtype; int2vector *tgattr; @@ -117,37 +122,27 @@ CreateTrigger(CreateTrigStmt *stmt, Oid constraintOid) errmsg("permission denied: \"%s\" is a system catalog", RelationGetRelationName(rel)))); - /* permission checks */ + if (stmt->isconstraint && stmt->constrrel != NULL) + constrrelid = RangeVarGetRelid(stmt->constrrel, false); - if (stmt->isconstraint) + /* permission checks */ + if (checkPermissions) { - /* constraint trigger */ aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), - ACL_REFERENCES); + ACL_TRIGGER); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_CLASS, RelationGetRelationName(rel)); - if (stmt->constrrel != NULL) + if (OidIsValid(constrrelid)) { - constrrelid = RangeVarGetRelid(stmt->constrrel, false); - aclresult = pg_class_aclcheck(constrrelid, GetUserId(), - ACL_REFERENCES); + ACL_TRIGGER); if (aclresult != ACLCHECK_OK) aclcheck_error(aclresult, ACL_KIND_CLASS, get_rel_name(constrrelid)); } } - else - { - /* regular trigger */ - aclresult = pg_class_aclcheck(RelationGetRelid(rel), GetUserId(), - ACL_TRIGGER); - if (aclresult != ACLCHECK_OK) - aclcheck_error(aclresult, ACL_KIND_CLASS, - RelationGetRelationName(rel)); - } /* Compute tgtype */ TRIGGER_CLEAR_TYPE(tgtype); diff --git a/src/backend/commands/tsearchcmds.c b/src/backend/commands/tsearchcmds.c index f9248a2b674..7276cd50d40 100644 --- a/src/backend/commands/tsearchcmds.c +++ b/src/backend/commands/tsearchcmds.c @@ -9,7 +9,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/commands/tsearchcmds.c,v 1.15 2009/01/01 17:23:40 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/tsearchcmds.c,v 1.16 2009/01/22 20:16:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1255,7 +1255,7 @@ makeConfigurationDependencies(HeapTuple tuple, bool removeOld, if (removeOld) { deleteDependencyRecordsFor(myself.classId, myself.objectId); - deleteSharedDependencyRecordsFor(myself.classId, myself.objectId); + deleteSharedDependencyRecordsFor(myself.classId, myself.objectId, 0); } /* diff --git a/src/backend/commands/user.c b/src/backend/commands/user.c index a013e80ac94..7c1da42bc3e 100644 --- a/src/backend/commands/user.c +++ b/src/backend/commands/user.c @@ -6,7 +6,7 @@ * Portions Copyright (c) 1996-2009, PostgreSQL Global Development Group * Portions Copyright (c) 1994, Regents of the University of California * - * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.184 2009/01/01 17:23:40 momjian Exp $ + * $PostgreSQL: pgsql/src/backend/commands/user.c,v 1.185 2009/01/22 20:16:02 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -1123,9 +1123,17 @@ GrantRole(GrantRoleStmt *stmt) */ foreach(item, stmt->granted_roles) { - char *rolename = strVal(lfirst(item)); - Oid roleid = get_roleid_checked(rolename); + AccessPriv *priv = (AccessPriv *) lfirst(item); + char *rolename = priv->priv_name; + Oid roleid; + + /* Must reject priv(columns) and ALL PRIVILEGES(columns) */ + if (rolename == NULL || priv->cols != NIL) + ereport(ERROR, + (errcode(ERRCODE_INVALID_GRANT_OPERATION), + errmsg("column names cannot be included in GRANT/REVOKE ROLE"))); + roleid = get_roleid_checked(rolename); if (stmt->is_grant) AddRoleMems(rolename, roleid, stmt->grantee_roles, grantee_ids, |