diff options
Diffstat (limited to 'contrib/sepgsql/hooks.c')
-rw-r--r-- | contrib/sepgsql/hooks.c | 211 |
1 files changed, 122 insertions, 89 deletions
diff --git a/contrib/sepgsql/hooks.c b/contrib/sepgsql/hooks.c index fabd04b71d..d5338fa38d 100644 --- a/contrib/sepgsql/hooks.c +++ b/contrib/sepgsql/hooks.c @@ -4,7 +4,7 @@ * * Entrypoints of the hooks in PostgreSQL, and dispatches the callbacks. * - * Copyright (c) 2010-2012, PostgreSQL Global Development Group + * Copyright (c) 2010-2014, PostgreSQL Global Development Group * * ------------------------------------------------------------------------- */ @@ -38,7 +38,6 @@ void _PG_init(void); static object_access_hook_type next_object_access_hook = NULL; static ExecutorCheckPerms_hook_type next_exec_check_perms_hook = NULL; static ProcessUtility_hook_type next_ProcessUtility_hook = NULL; -static ExecutorStart_hook_type next_ExecutorStart_hook = NULL; /* * Contextual information on DDL commands @@ -97,53 +96,55 @@ sepgsql_object_access(ObjectAccessType access, switch (access) { case OAT_POST_CREATE: - switch (classId) { - case DatabaseRelationId: - sepgsql_database_post_create(objectId, + ObjectAccessPostCreate *pc_arg = arg; + bool is_internal; + + is_internal = pc_arg ? pc_arg->is_internal : false; + + switch (classId) + { + case DatabaseRelationId: + Assert(!is_internal); + sepgsql_database_post_create(objectId, sepgsql_context_info.createdb_dtemplate); - break; + break; - case NamespaceRelationId: - sepgsql_schema_post_create(objectId); - break; + case NamespaceRelationId: + Assert(!is_internal); + sepgsql_schema_post_create(objectId); + break; - case RelationRelationId: - if (subId == 0) - { - /* - * All cases we want to apply permission checks on - * creation of a new relation are invocation of the - * heap_create_with_catalog via DefineRelation or - * OpenIntoRel. Elsewhere, we need neither assignment - * of security label nor permission checks. - */ - switch (sepgsql_context_info.cmdtype) + case RelationRelationId: + if (subId == 0) { - case T_CreateStmt: - case T_ViewStmt: - case T_CreateSeqStmt: - case T_CompositeTypeStmt: - case T_CreateForeignTableStmt: - case T_SelectStmt: - sepgsql_relation_post_create(objectId); - break; - default: - /* via make_new_heap() */ + /* + * The cases in which we want to apply permission + * checks on creation of a new relation correspond + * to direct user invocation. For internal uses, + * that is creation of toast tables, index rebuild + * or ALTER TABLE commands, we need neither + * assignment of security labels nor permission + * checks. + */ + if (is_internal) break; + + sepgsql_relation_post_create(objectId); } - } - else - sepgsql_attribute_post_create(objectId, subId); - break; + else + sepgsql_attribute_post_create(objectId, subId); + break; - case ProcedureRelationId: - sepgsql_proc_post_create(objectId); - break; + case ProcedureRelationId: + Assert(!is_internal); + sepgsql_proc_post_create(objectId); + break; - default: - /* Ignore unsupported object classes */ - break; + default: + /* Ignore unsupported object classes */ + break; + } } break; @@ -187,6 +188,80 @@ sepgsql_object_access(ObjectAccessType access, } break; + case OAT_POST_ALTER: + { + ObjectAccessPostAlter *pa_arg = arg; + bool is_internal = pa_arg->is_internal; + + switch (classId) + { + case DatabaseRelationId: + Assert(!is_internal); + sepgsql_database_setattr(objectId); + break; + + case NamespaceRelationId: + Assert(!is_internal); + sepgsql_schema_setattr(objectId); + break; + + case RelationRelationId: + if (subId == 0) + { + /* + * A case when we don't want to apply permission + * check is that relation is internally altered + * without user's intention. E.g, no need to check + * on toast table/index to be renamed at end of + * the table rewrites. + */ + if (is_internal) + break; + + sepgsql_relation_setattr(objectId); + } + else + sepgsql_attribute_setattr(objectId, subId); + break; + + case ProcedureRelationId: + Assert(!is_internal); + sepgsql_proc_setattr(objectId); + break; + + default: + /* Ignore unsupported object classes */ + break; + } + } + break; + + case OAT_NAMESPACE_SEARCH: + { + ObjectAccessNamespaceSearch *ns_arg = arg; + + /* + * If stacked extension already decided not to allow users to + * search this schema, we just stick with that decision. + */ + if (!ns_arg->result) + break; + + Assert(classId == NamespaceRelationId); + Assert(ns_arg->result); + ns_arg->result + = sepgsql_schema_search(objectId, + ns_arg->ereport_on_violation); + } + break; + + case OAT_FUNCTION_EXECUTE: + { + Assert(classId == ProcedureRelationId); + sepgsql_proc_execute(objectId); + } + break; + default: elog(ERROR, "unexpected object access type: %d", (int) access); break; @@ -216,46 +291,6 @@ sepgsql_exec_check_perms(List *rangeTabls, bool abort) } /* - * sepgsql_executor_start - * - * It saves contextual information during ExecutorStart to distinguish - * a case with/without permission checks later. - */ -static void -sepgsql_executor_start(QueryDesc *queryDesc, int eflags) -{ - sepgsql_context_info_t saved_context_info = sepgsql_context_info; - - PG_TRY(); - { - if (queryDesc->operation == CMD_SELECT) - sepgsql_context_info.cmdtype = T_SelectStmt; - else if (queryDesc->operation == CMD_INSERT) - sepgsql_context_info.cmdtype = T_InsertStmt; - else if (queryDesc->operation == CMD_DELETE) - sepgsql_context_info.cmdtype = T_DeleteStmt; - else if (queryDesc->operation == CMD_UPDATE) - sepgsql_context_info.cmdtype = T_UpdateStmt; - - /* - * XXX - If queryDesc->operation is not above four cases, an error - * shall be raised on the following executor stage soon. - */ - if (next_ExecutorStart_hook) - (*next_ExecutorStart_hook) (queryDesc, eflags); - else - standard_ExecutorStart(queryDesc, eflags); - } - PG_CATCH(); - { - sepgsql_context_info = saved_context_info; - PG_RE_THROW(); - } - PG_END_TRY(); - sepgsql_context_info = saved_context_info; -} - -/* * sepgsql_utility_command * * It tries to rough-grained control on utility commands; some of them can @@ -264,8 +299,8 @@ sepgsql_executor_start(QueryDesc *queryDesc, int eflags) static void sepgsql_utility_command(Node *parsetree, const char *queryString, + ProcessUtilityContext context, ParamListInfo params, - bool isTopLevel, DestReceiver *dest, #ifdef PGXC bool sentToRemote, @@ -330,15 +365,17 @@ sepgsql_utility_command(Node *parsetree, } if (next_ProcessUtility_hook) - (*next_ProcessUtility_hook) (parsetree, queryString, params, - isTopLevel, dest, + (*next_ProcessUtility_hook) (parsetree, queryString, + context, params, + dest, #ifdef PGXC sentToRemote, #endif completionTag); else - standard_ProcessUtility(parsetree, queryString, params, - isTopLevel, dest, + standard_ProcessUtility(parsetree, queryString, + context, params, + dest, #ifdef PGXC sentToRemote, #endif @@ -436,10 +473,6 @@ _PG_init(void) next_ProcessUtility_hook = ProcessUtility_hook; ProcessUtility_hook = sepgsql_utility_command; - /* ExecutorStart hook */ - next_ExecutorStart_hook = ExecutorStart_hook; - ExecutorStart_hook = sepgsql_executor_start; - /* init contextual info */ memset(&sepgsql_context_info, 0, sizeof(sepgsql_context_info)); } |