diff options
Diffstat (limited to 'src/backend')
-rw-r--r-- | src/backend/catalog/aclchk.c | 127 | ||||
-rw-r--r-- | src/backend/nodes/copyfuncs.c | 3 | ||||
-rw-r--r-- | src/backend/nodes/equalfuncs.c | 3 | ||||
-rw-r--r-- | src/backend/parser/gram.y | 52 |
4 files changed, 177 insertions, 8 deletions
diff --git a/src/backend/catalog/aclchk.c b/src/backend/catalog/aclchk.c index b06e587a1b1..8b2599a99f5 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 diff --git a/src/backend/nodes/copyfuncs.c b/src/backend/nodes/copyfuncs.c index 8365586a00b..efbb0f57be6 100644 --- a/src/backend/nodes/copyfuncs.c +++ b/src/backend/nodes/copyfuncs.c @@ -15,7 +15,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.445 2009/10/12 19:49:24 adunstan Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/copyfuncs.c,v 1.446 2009/10/12 20:39:39 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -2350,6 +2350,7 @@ _copyGrantStmt(GrantStmt *from) GrantStmt *newnode = makeNode(GrantStmt); COPY_SCALAR_FIELD(is_grant); + COPY_SCALAR_FIELD(targtype); COPY_SCALAR_FIELD(objtype); COPY_NODE_FIELD(objects); COPY_NODE_FIELD(privileges); diff --git a/src/backend/nodes/equalfuncs.c b/src/backend/nodes/equalfuncs.c index 2c916af1b78..de5497c4920 100644 --- a/src/backend/nodes/equalfuncs.c +++ b/src/backend/nodes/equalfuncs.c @@ -22,7 +22,7 @@ * Portions Copyright (c) 1994, Regents of the University of California * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.367 2009/10/12 19:49:24 adunstan Exp $ + * $PostgreSQL: pgsql/src/backend/nodes/equalfuncs.c,v 1.368 2009/10/12 20:39:40 tgl Exp $ * *------------------------------------------------------------------------- */ @@ -990,6 +990,7 @@ static bool _equalGrantStmt(GrantStmt *a, GrantStmt *b) { COMPARE_SCALAR_FIELD(is_grant); + COMPARE_SCALAR_FIELD(targtype); COMPARE_SCALAR_FIELD(objtype); COMPARE_NODE_FIELD(objects); COMPARE_NODE_FIELD(privileges); diff --git a/src/backend/parser/gram.y b/src/backend/parser/gram.y index 50ce33070fd..4f502876438 100644 --- a/src/backend/parser/gram.y +++ b/src/backend/parser/gram.y @@ -11,7 +11,7 @@ * * * IDENTIFICATION - * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.683 2009/10/12 19:49:24 adunstan Exp $ + * $PostgreSQL: pgsql/src/backend/parser/gram.y,v 2.684 2009/10/12 20:39:41 tgl Exp $ * * HISTORY * AUTHOR DATE MAJOR EVENT @@ -95,6 +95,7 @@ /* Private struct for the result of privilege_target production */ typedef struct PrivTarget { + GrantTargetType targtype; GrantObjectType objtype; List *objs; } PrivTarget; @@ -480,7 +481,7 @@ static TypeName *TableFuncTypeName(List *columns); EXCLUDING EXCLUSIVE EXECUTE EXISTS EXPLAIN EXTERNAL EXTRACT FALSE_P FAMILY FETCH FIRST_P FLOAT_P FOLLOWING FOR FORCE FOREIGN FORWARD - FREEZE FROM FULL FUNCTION + FREEZE FROM FULL FUNCTION FUNCTIONS GLOBAL GRANT GRANTED GREATEST GROUP_P @@ -518,13 +519,13 @@ static TypeName *TableFuncTypeName(List *columns); RELATIVE_P RELEASE RENAME REPEATABLE REPLACE REPLICA RESET RESTART RESTRICT RETURNING RETURNS REVOKE RIGHT ROLE ROLLBACK ROW ROWS RULE - SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE + SAVEPOINT SCHEMA SCROLL SEARCH SECOND_P SECURITY SELECT SEQUENCE SEQUENCES SERIALIZABLE SERVER SESSION SESSION_USER SET SETOF SHARE SHOW SIMILAR SIMPLE SMALLINT SOME STABLE STANDALONE_P START STATEMENT STATISTICS STDIN STDOUT STORAGE STRICT_P STRIP_P SUBSTRING SUPERUSER_P SYMMETRIC SYSID SYSTEM_P - TABLE TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP + TABLE TABLES TABLESPACE TEMP TEMPLATE TEMPORARY TEXT_P THEN TIME TIMESTAMP TO TRAILING TRANSACTION TREAT TRIGGER TRIM TRUE_P TRUNCATE TRUSTED TYPE_P @@ -4321,6 +4322,7 @@ GrantStmt: GRANT privileges ON privilege_target TO grantee_list GrantStmt *n = makeNode(GrantStmt); n->is_grant = true; n->privileges = $2; + n->targtype = ($4)->targtype; n->objtype = ($4)->objtype; n->objects = ($4)->objs; n->grantees = $6; @@ -4337,6 +4339,7 @@ RevokeStmt: n->is_grant = false; n->grant_option = false; n->privileges = $2; + n->targtype = ($4)->targtype; n->objtype = ($4)->objtype; n->objects = ($4)->objs; n->grantees = $6; @@ -4350,6 +4353,7 @@ RevokeStmt: n->is_grant = false; n->grant_option = true; n->privileges = $5; + n->targtype = ($7)->targtype; n->objtype = ($7)->objtype; n->objects = ($7)->objs; n->grantees = $9; @@ -4432,6 +4436,7 @@ privilege_target: qualified_name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = ACL_OBJECT_RELATION; n->objs = $1; $$ = n; @@ -4439,6 +4444,7 @@ privilege_target: | TABLE qualified_name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = ACL_OBJECT_RELATION; n->objs = $2; $$ = n; @@ -4446,6 +4452,7 @@ privilege_target: | SEQUENCE qualified_name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = ACL_OBJECT_SEQUENCE; n->objs = $2; $$ = n; @@ -4453,6 +4460,7 @@ privilege_target: | FOREIGN DATA_P WRAPPER name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = ACL_OBJECT_FDW; n->objs = $4; $$ = n; @@ -4460,6 +4468,7 @@ privilege_target: | FOREIGN SERVER name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = ACL_OBJECT_FOREIGN_SERVER; n->objs = $3; $$ = n; @@ -4467,6 +4476,7 @@ privilege_target: | FUNCTION function_with_argtypes_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = ACL_OBJECT_FUNCTION; n->objs = $2; $$ = n; @@ -4474,6 +4484,7 @@ privilege_target: | DATABASE name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = ACL_OBJECT_DATABASE; n->objs = $2; $$ = n; @@ -4481,6 +4492,7 @@ privilege_target: | LANGUAGE name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = ACL_OBJECT_LANGUAGE; n->objs = $2; $$ = n; @@ -4488,6 +4500,7 @@ privilege_target: | SCHEMA name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = ACL_OBJECT_NAMESPACE; n->objs = $2; $$ = n; @@ -4495,10 +4508,35 @@ privilege_target: | TABLESPACE name_list { PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_OBJECT; n->objtype = ACL_OBJECT_TABLESPACE; n->objs = $2; $$ = n; } + | ALL TABLES IN_P SCHEMA name_list + { + PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_ALL_IN_SCHEMA; + n->objtype = ACL_OBJECT_RELATION; + n->objs = $5; + $$ = n; + } + | ALL SEQUENCES IN_P SCHEMA name_list + { + PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_ALL_IN_SCHEMA; + n->objtype = ACL_OBJECT_SEQUENCE; + n->objs = $5; + $$ = n; + } + | ALL FUNCTIONS IN_P SCHEMA name_list + { + PrivTarget *n = (PrivTarget *) palloc(sizeof(PrivTarget)); + n->targtype = ACL_TARGET_ALL_IN_SCHEMA; + n->objtype = ACL_OBJECT_FUNCTION; + n->objs = $5; + $$ = n; + } ; @@ -4648,6 +4686,7 @@ DefACLAction: GrantStmt *n = makeNode(GrantStmt); n->is_grant = true; n->privileges = $2; + n->targtype = ACL_TARGET_DEFAULTS; n->objtype = $4; n->objects = NIL; n->grantees = $6; @@ -4661,6 +4700,7 @@ DefACLAction: n->is_grant = false; n->grant_option = false; n->privileges = $2; + n->targtype = ACL_TARGET_DEFAULTS; n->objtype = $4; n->objects = NIL; n->grantees = $6; @@ -4674,6 +4714,7 @@ DefACLAction: n->is_grant = false; n->grant_option = true; n->privileges = $5; + n->targtype = ACL_TARGET_DEFAULTS; n->objtype = $7; n->objects = NIL; n->grantees = $9; @@ -10535,6 +10576,7 @@ unreserved_keyword: | FORCE | FORWARD | FUNCTION + | FUNCTIONS | GLOBAL | GRANTED | HANDLER @@ -10644,6 +10686,7 @@ unreserved_keyword: | SECOND_P | SECURITY | SEQUENCE + | SEQUENCES | SERIALIZABLE | SERVER | SESSION @@ -10664,6 +10707,7 @@ unreserved_keyword: | SUPERUSER_P | SYSID | SYSTEM_P + | TABLES | TABLESPACE | TEMP | TEMPLATE |