diff options
Diffstat (limited to 'src/backend/catalog/aclchk.c')
| -rw-r--r-- | src/backend/catalog/aclchk.c | 127 |
1 files changed, 125 insertions, 2 deletions
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index b06e587a1b..8b2599a99f 100644 --- a/src/backend/catalog/aclchk.c +++ b/src/backend/catalog/aclchk.c @@ -8,7 +8,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.155 2009/10/05 19:24:35 tgl Exp $ + * $PostgreSQL: pgsql/src/backend/catalog/aclchk.c,v 1.156 2009/10/12 20:39:39 tgl Exp $ * * NOTES * See acl.h. @@ -110,6 +110,8 @@ static void SetDefaultACLsInSchemas(InternalDefaultACL *iacls, List *nspnames); static void SetDefaultACL(InternalDefaultACL *iacls); static List *objectNamesToOids(GrantObjectType objtype, List *objnames); +static List *objectsInSchemaToOids(GrantObjectType objtype, List *nspnames); +static List *getRelationsInNamespace(Oid namespaceId, char relkind); static void expand_col_privileges(List *colnames, Oid table_oid, AclMode this_privileges, AclMode *col_privileges, @@ -335,7 +337,22 @@ ExecuteGrantStmt(GrantStmt *stmt) */ istmt.is_grant = stmt->is_grant; istmt.objtype = stmt->objtype; - istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects); + + /* Collect the OIDs of the target objects */ + switch (stmt->targtype) + { + case ACL_TARGET_OBJECT: + istmt.objects = objectNamesToOids(stmt->objtype, stmt->objects); + break; + case ACL_TARGET_ALL_IN_SCHEMA: + istmt.objects = objectsInSchemaToOids(stmt->objtype, stmt->objects); + break; + /* ACL_TARGET_DEFAULTS should not be seen here */ + default: + elog(ERROR, "unrecognized GrantStmt.targtype: %d", + (int) stmt->targtype); + } + /* all_privs to be filled below */ /* privileges to be filled below */ istmt.col_privs = NIL; /* may get filled below */ @@ -657,6 +674,112 @@ objectNamesToOids(GrantObjectType objtype, List *objnames) } /* + * objectsInSchemaToOids + * + * Find all objects of a given type in specified schemas, and make a list + * of their Oids. We check USAGE privilege on the schemas, but there is + * no privilege checking on the individual objects here. + */ +static List * +objectsInSchemaToOids(GrantObjectType objtype, List *nspnames) +{ + List *objects = NIL; + ListCell *cell; + + foreach(cell, nspnames) + { + char *nspname = strVal(lfirst(cell)); + Oid namespaceId; + List *objs; + + namespaceId = LookupExplicitNamespace(nspname); + + switch (objtype) + { + case ACL_OBJECT_RELATION: + /* Process both regular tables and views */ + objs = getRelationsInNamespace(namespaceId, RELKIND_RELATION); + objects = list_concat(objects, objs); + objs = getRelationsInNamespace(namespaceId, RELKIND_VIEW); + objects = list_concat(objects, objs); + break; + case ACL_OBJECT_SEQUENCE: + objs = getRelationsInNamespace(namespaceId, RELKIND_SEQUENCE); + objects = list_concat(objects, objs); + break; + case ACL_OBJECT_FUNCTION: + { + ScanKeyData key[1]; + Relation rel; + HeapScanDesc scan; + HeapTuple tuple; + + ScanKeyInit(&key[0], + Anum_pg_proc_pronamespace, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(namespaceId)); + + rel = heap_open(ProcedureRelationId, AccessShareLock); + scan = heap_beginscan(rel, SnapshotNow, 1, key); + + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + objects = lappend_oid(objects, HeapTupleGetOid(tuple)); + } + + heap_endscan(scan); + heap_close(rel, AccessShareLock); + } + break; + default: + /* should not happen */ + elog(ERROR, "unrecognized GrantStmt.objtype: %d", + (int) objtype); + } + } + + return objects; +} + +/* + * getRelationsInNamespace + * + * Return Oid list of relations in given namespace filtered by relation kind + */ +static List * +getRelationsInNamespace(Oid namespaceId, char relkind) +{ + List *relations = NIL; + ScanKeyData key[2]; + Relation rel; + HeapScanDesc scan; + HeapTuple tuple; + + ScanKeyInit(&key[0], + Anum_pg_class_relnamespace, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(namespaceId)); + ScanKeyInit(&key[1], + Anum_pg_class_relkind, + BTEqualStrategyNumber, F_CHAREQ, + CharGetDatum(relkind)); + + rel = heap_open(RelationRelationId, AccessShareLock); + scan = heap_beginscan(rel, SnapshotNow, 2, key); + + while ((tuple = heap_getnext(scan, ForwardScanDirection)) != NULL) + { + relations = lappend_oid(relations, HeapTupleGetOid(tuple)); + } + + heap_endscan(scan); + heap_close(rel, AccessShareLock); + + return relations; +} + + +/* * ALTER DEFAULT PRIVILEGES statement */ void |
