mirror of
https://git.postgresql.org/git/postgresql.git
synced 2024-12-15 08:20:16 +08:00
sepgsql: Move some code from hooks.c to label.c
This is some preliminary refactoring related to a pending patch to allow sepgsql-enable sessions to make dynamic label transitions. But this commit doesn't involve any functional change: it just puts some bits of code in more logical places. KaiGai Kohei
This commit is contained in:
parent
337b6f5ecf
commit
d44a3fb55d
@ -18,7 +18,6 @@
|
|||||||
#include "commands/seclabel.h"
|
#include "commands/seclabel.h"
|
||||||
#include "executor/executor.h"
|
#include "executor/executor.h"
|
||||||
#include "fmgr.h"
|
#include "fmgr.h"
|
||||||
#include "libpq/auth.h"
|
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "tcop/utility.h"
|
#include "tcop/utility.h"
|
||||||
#include "utils/guc.h"
|
#include "utils/guc.h"
|
||||||
@ -36,10 +35,7 @@ void _PG_init(void);
|
|||||||
* Saved hook entries (if stacked)
|
* Saved hook entries (if stacked)
|
||||||
*/
|
*/
|
||||||
static object_access_hook_type next_object_access_hook = NULL;
|
static object_access_hook_type next_object_access_hook = NULL;
|
||||||
static ClientAuthentication_hook_type next_client_auth_hook = NULL;
|
|
||||||
static ExecutorCheckPerms_hook_type next_exec_check_perms_hook = NULL;
|
static ExecutorCheckPerms_hook_type next_exec_check_perms_hook = NULL;
|
||||||
static needs_fmgr_hook_type next_needs_fmgr_hook = NULL;
|
|
||||||
static fmgr_hook_type next_fmgr_hook = NULL;
|
|
||||||
static ProcessUtility_hook_type next_ProcessUtility_hook = NULL;
|
static ProcessUtility_hook_type next_ProcessUtility_hook = NULL;
|
||||||
static ExecutorStart_hook_type next_ExecutorStart_hook = NULL;
|
static ExecutorStart_hook_type next_ExecutorStart_hook = NULL;
|
||||||
|
|
||||||
@ -81,48 +77,6 @@ sepgsql_get_debug_audit(void)
|
|||||||
return sepgsql_debug_audit;
|
return sepgsql_debug_audit;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* sepgsql_client_auth
|
|
||||||
*
|
|
||||||
* Entrypoint of the client authentication hook.
|
|
||||||
* It switches the client label according to getpeercon(), and the current
|
|
||||||
* performing mode according to the GUC setting.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
sepgsql_client_auth(Port *port, int status)
|
|
||||||
{
|
|
||||||
char *context;
|
|
||||||
|
|
||||||
if (next_client_auth_hook)
|
|
||||||
(*next_client_auth_hook) (port, status);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* In the case when authentication failed, the supplied socket shall be
|
|
||||||
* closed soon, so we don't need to do anything here.
|
|
||||||
*/
|
|
||||||
if (status != STATUS_OK)
|
|
||||||
return;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Getting security label of the peer process using API of libselinux.
|
|
||||||
*/
|
|
||||||
if (getpeercon_raw(port->sock, &context) < 0)
|
|
||||||
ereport(FATAL,
|
|
||||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
|
||||||
errmsg("SELinux: unable to get peer label: %m")));
|
|
||||||
|
|
||||||
sepgsql_set_client_label(context);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Switch the current performing mode from INTERNAL to either DEFAULT or
|
|
||||||
* PERMISSIVE.
|
|
||||||
*/
|
|
||||||
if (sepgsql_permissive)
|
|
||||||
sepgsql_set_mode(SEPGSQL_MODE_PERMISSIVE);
|
|
||||||
else
|
|
||||||
sepgsql_set_mode(SEPGSQL_MODE_DEFAULT);
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sepgsql_object_access
|
* sepgsql_object_access
|
||||||
*
|
*
|
||||||
@ -220,121 +174,6 @@ sepgsql_exec_check_perms(List *rangeTabls, bool abort)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
* sepgsql_needs_fmgr_hook
|
|
||||||
*
|
|
||||||
* It informs the core whether the supplied function is trusted procedure,
|
|
||||||
* or not. If true, sepgsql_fmgr_hook shall be invoked at start, end, and
|
|
||||||
* abort time of function invocation.
|
|
||||||
*/
|
|
||||||
static bool
|
|
||||||
sepgsql_needs_fmgr_hook(Oid functionId)
|
|
||||||
{
|
|
||||||
ObjectAddress object;
|
|
||||||
|
|
||||||
if (next_needs_fmgr_hook &&
|
|
||||||
(*next_needs_fmgr_hook) (functionId))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* SELinux needs the function to be called via security_definer wrapper,
|
|
||||||
* if this invocation will take a domain-transition. We call these
|
|
||||||
* functions as trusted-procedure, if the security policy has a rule that
|
|
||||||
* switches security label of the client on execution.
|
|
||||||
*/
|
|
||||||
if (sepgsql_avc_trusted_proc(functionId) != NULL)
|
|
||||||
return true;
|
|
||||||
|
|
||||||
/*
|
|
||||||
* Even if not a trusted-procedure, this function should not be inlined
|
|
||||||
* unless the client has db_procedure:{execute} permission. Please note
|
|
||||||
* that it shall be actually failed later because of same reason with
|
|
||||||
* ACL_EXECUTE.
|
|
||||||
*/
|
|
||||||
object.classId = ProcedureRelationId;
|
|
||||||
object.objectId = functionId;
|
|
||||||
object.objectSubId = 0;
|
|
||||||
if (!sepgsql_avc_check_perms(&object,
|
|
||||||
SEPG_CLASS_DB_PROCEDURE,
|
|
||||||
SEPG_DB_PROCEDURE__EXECUTE,
|
|
||||||
SEPGSQL_AVC_NOAUDIT, false))
|
|
||||||
return true;
|
|
||||||
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
|
||||||
* sepgsql_fmgr_hook
|
|
||||||
*
|
|
||||||
* It switches security label of the client on execution of trusted
|
|
||||||
* procedures.
|
|
||||||
*/
|
|
||||||
static void
|
|
||||||
sepgsql_fmgr_hook(FmgrHookEventType event,
|
|
||||||
FmgrInfo *flinfo, Datum *private)
|
|
||||||
{
|
|
||||||
struct
|
|
||||||
{
|
|
||||||
char *old_label;
|
|
||||||
char *new_label;
|
|
||||||
Datum next_private;
|
|
||||||
} *stack;
|
|
||||||
|
|
||||||
switch (event)
|
|
||||||
{
|
|
||||||
case FHET_START:
|
|
||||||
stack = (void *) DatumGetPointer(*private);
|
|
||||||
if (!stack)
|
|
||||||
{
|
|
||||||
MemoryContext oldcxt;
|
|
||||||
|
|
||||||
oldcxt = MemoryContextSwitchTo(flinfo->fn_mcxt);
|
|
||||||
stack = palloc(sizeof(*stack));
|
|
||||||
stack->old_label = NULL;
|
|
||||||
stack->new_label = sepgsql_avc_trusted_proc(flinfo->fn_oid);
|
|
||||||
stack->next_private = 0;
|
|
||||||
|
|
||||||
MemoryContextSwitchTo(oldcxt);
|
|
||||||
|
|
||||||
/*
|
|
||||||
* process:transition permission between old and new label,
|
|
||||||
* when user tries to switch security label of the client
|
|
||||||
* on execution of trusted procedure.
|
|
||||||
*/
|
|
||||||
if (stack->new_label)
|
|
||||||
sepgsql_avc_check_perms_label(stack->new_label,
|
|
||||||
SEPG_CLASS_PROCESS,
|
|
||||||
SEPG_PROCESS__TRANSITION,
|
|
||||||
NULL, true);
|
|
||||||
|
|
||||||
*private = PointerGetDatum(stack);
|
|
||||||
}
|
|
||||||
Assert(!stack->old_label);
|
|
||||||
if (stack->new_label)
|
|
||||||
stack->old_label = sepgsql_set_client_label(stack->new_label);
|
|
||||||
|
|
||||||
if (next_fmgr_hook)
|
|
||||||
(*next_fmgr_hook) (event, flinfo, &stack->next_private);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case FHET_END:
|
|
||||||
case FHET_ABORT:
|
|
||||||
stack = (void *) DatumGetPointer(*private);
|
|
||||||
|
|
||||||
if (next_fmgr_hook)
|
|
||||||
(*next_fmgr_hook) (event, flinfo, &stack->next_private);
|
|
||||||
|
|
||||||
if (stack->old_label)
|
|
||||||
sepgsql_set_client_label(stack->old_label);
|
|
||||||
stack->old_label = NULL;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
elog(ERROR, "unexpected event type: %d", (int) event);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* sepgsql_executor_start
|
* sepgsql_executor_start
|
||||||
*
|
*
|
||||||
@ -465,8 +304,6 @@ sepgsql_utility_command(Node *parsetree,
|
|||||||
void
|
void
|
||||||
_PG_init(void)
|
_PG_init(void)
|
||||||
{
|
{
|
||||||
char *context;
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* We allow to load the SE-PostgreSQL module on single-user-mode or
|
* We allow to load the SE-PostgreSQL module on single-user-mode or
|
||||||
* shared_preload_libraries settings only.
|
* shared_preload_libraries settings only.
|
||||||
@ -522,33 +359,16 @@ _PG_init(void)
|
|||||||
NULL,
|
NULL,
|
||||||
NULL);
|
NULL);
|
||||||
|
|
||||||
/*
|
|
||||||
* Set up dummy client label.
|
|
||||||
*
|
|
||||||
* XXX - note that PostgreSQL launches background worker process like
|
|
||||||
* autovacuum without authentication steps. So, we initialize sepgsql_mode
|
|
||||||
* with SEPGSQL_MODE_INTERNAL, and client_label with the security context
|
|
||||||
* of server process. Later, it also launches background of user session.
|
|
||||||
* In this case, the process is always hooked on post-authentication, and
|
|
||||||
* we can initialize the sepgsql_mode and client_label correctly.
|
|
||||||
*/
|
|
||||||
if (getcon_raw(&context) < 0)
|
|
||||||
ereport(ERROR,
|
|
||||||
(errcode(ERRCODE_INTERNAL_ERROR),
|
|
||||||
errmsg("SELinux: failed to get server security label: %m")));
|
|
||||||
sepgsql_set_client_label(context);
|
|
||||||
|
|
||||||
/* Initialize userspace access vector cache */
|
/* Initialize userspace access vector cache */
|
||||||
sepgsql_avc_init();
|
sepgsql_avc_init();
|
||||||
|
|
||||||
|
/* Initialize security label of the client and related stuff */
|
||||||
|
sepgsql_init_client_label();
|
||||||
|
|
||||||
/* Security label provider hook */
|
/* Security label provider hook */
|
||||||
register_label_provider(SEPGSQL_LABEL_TAG,
|
register_label_provider(SEPGSQL_LABEL_TAG,
|
||||||
sepgsql_object_relabel);
|
sepgsql_object_relabel);
|
||||||
|
|
||||||
/* Client authentication hook */
|
|
||||||
next_client_auth_hook = ClientAuthentication_hook;
|
|
||||||
ClientAuthentication_hook = sepgsql_client_auth;
|
|
||||||
|
|
||||||
/* Object access hook */
|
/* Object access hook */
|
||||||
next_object_access_hook = object_access_hook;
|
next_object_access_hook = object_access_hook;
|
||||||
object_access_hook = sepgsql_object_access;
|
object_access_hook = sepgsql_object_access;
|
||||||
@ -557,13 +377,6 @@ _PG_init(void)
|
|||||||
next_exec_check_perms_hook = ExecutorCheckPerms_hook;
|
next_exec_check_perms_hook = ExecutorCheckPerms_hook;
|
||||||
ExecutorCheckPerms_hook = sepgsql_exec_check_perms;
|
ExecutorCheckPerms_hook = sepgsql_exec_check_perms;
|
||||||
|
|
||||||
/* Trusted procedure hooks */
|
|
||||||
next_needs_fmgr_hook = needs_fmgr_hook;
|
|
||||||
needs_fmgr_hook = sepgsql_needs_fmgr_hook;
|
|
||||||
|
|
||||||
next_fmgr_hook = fmgr_hook;
|
|
||||||
fmgr_hook = sepgsql_fmgr_hook;
|
|
||||||
|
|
||||||
/* ProcessUtility hook */
|
/* ProcessUtility hook */
|
||||||
next_ProcessUtility_hook = ProcessUtility_hook;
|
next_ProcessUtility_hook = ProcessUtility_hook;
|
||||||
ProcessUtility_hook = sepgsql_utility_command;
|
ProcessUtility_hook = sepgsql_utility_command;
|
||||||
|
@ -22,6 +22,7 @@
|
|||||||
#include "catalog/pg_proc.h"
|
#include "catalog/pg_proc.h"
|
||||||
#include "commands/dbcommands.h"
|
#include "commands/dbcommands.h"
|
||||||
#include "commands/seclabel.h"
|
#include "commands/seclabel.h"
|
||||||
|
#include "libpq/auth.h"
|
||||||
#include "libpq/libpq-be.h"
|
#include "libpq/libpq-be.h"
|
||||||
#include "miscadmin.h"
|
#include "miscadmin.h"
|
||||||
#include "utils/builtins.h"
|
#include "utils/builtins.h"
|
||||||
@ -34,6 +35,13 @@
|
|||||||
|
|
||||||
#include <selinux/label.h>
|
#include <selinux/label.h>
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Saved hook entries (if stacked)
|
||||||
|
*/
|
||||||
|
static ClientAuthentication_hook_type next_client_auth_hook = NULL;
|
||||||
|
static needs_fmgr_hook_type next_needs_fmgr_hook = NULL;
|
||||||
|
static fmgr_hook_type next_fmgr_hook = NULL;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* client_label
|
* client_label
|
||||||
*
|
*
|
||||||
@ -47,14 +55,197 @@ sepgsql_get_client_label(void)
|
|||||||
return client_label;
|
return client_label;
|
||||||
}
|
}
|
||||||
|
|
||||||
char *
|
/*
|
||||||
sepgsql_set_client_label(char *new_label)
|
* sepgsql_client_auth
|
||||||
|
*
|
||||||
|
* Entrypoint of the client authentication hook.
|
||||||
|
* It switches the client label according to getpeercon(), and the current
|
||||||
|
* performing mode according to the GUC setting.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sepgsql_client_auth(Port *port, int status)
|
||||||
{
|
{
|
||||||
char *old_label = client_label;
|
if (next_client_auth_hook)
|
||||||
|
(*next_client_auth_hook) (port, status);
|
||||||
|
|
||||||
client_label = new_label;
|
/*
|
||||||
|
* In the case when authentication failed, the supplied socket shall be
|
||||||
|
* closed soon, so we don't need to do anything here.
|
||||||
|
*/
|
||||||
|
if (status != STATUS_OK)
|
||||||
|
return;
|
||||||
|
|
||||||
return old_label;
|
/*
|
||||||
|
* Getting security label of the peer process using API of libselinux.
|
||||||
|
*/
|
||||||
|
if (getpeercon_raw(port->sock, &client_label) < 0)
|
||||||
|
ereport(FATAL,
|
||||||
|
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||||
|
errmsg("SELinux: unable to get peer label: %m")));
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Switch the current performing mode from INTERNAL to either DEFAULT or
|
||||||
|
* PERMISSIVE.
|
||||||
|
*/
|
||||||
|
if (sepgsql_get_permissive())
|
||||||
|
sepgsql_set_mode(SEPGSQL_MODE_PERMISSIVE);
|
||||||
|
else
|
||||||
|
sepgsql_set_mode(SEPGSQL_MODE_DEFAULT);
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sepgsql_needs_fmgr_hook
|
||||||
|
*
|
||||||
|
* It informs the core whether the supplied function is trusted procedure,
|
||||||
|
* or not. If true, sepgsql_fmgr_hook shall be invoked at start, end, and
|
||||||
|
* abort time of function invocation.
|
||||||
|
*/
|
||||||
|
static bool
|
||||||
|
sepgsql_needs_fmgr_hook(Oid functionId)
|
||||||
|
{
|
||||||
|
ObjectAddress object;
|
||||||
|
|
||||||
|
if (next_needs_fmgr_hook &&
|
||||||
|
(*next_needs_fmgr_hook) (functionId))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* SELinux needs the function to be called via security_definer wrapper,
|
||||||
|
* if this invocation will take a domain-transition. We call these
|
||||||
|
* functions as trusted-procedure, if the security policy has a rule that
|
||||||
|
* switches security label of the client on execution.
|
||||||
|
*/
|
||||||
|
if (sepgsql_avc_trusted_proc(functionId) != NULL)
|
||||||
|
return true;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* Even if not a trusted-procedure, this function should not be inlined
|
||||||
|
* unless the client has db_procedure:{execute} permission. Please note
|
||||||
|
* that it shall be actually failed later because of same reason with
|
||||||
|
* ACL_EXECUTE.
|
||||||
|
*/
|
||||||
|
object.classId = ProcedureRelationId;
|
||||||
|
object.objectId = functionId;
|
||||||
|
object.objectSubId = 0;
|
||||||
|
if (!sepgsql_avc_check_perms(&object,
|
||||||
|
SEPG_CLASS_DB_PROCEDURE,
|
||||||
|
SEPG_DB_PROCEDURE__EXECUTE,
|
||||||
|
SEPGSQL_AVC_NOAUDIT, false))
|
||||||
|
return true;
|
||||||
|
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sepgsql_fmgr_hook
|
||||||
|
*
|
||||||
|
* It switches security label of the client on execution of trusted
|
||||||
|
* procedures.
|
||||||
|
*/
|
||||||
|
static void
|
||||||
|
sepgsql_fmgr_hook(FmgrHookEventType event,
|
||||||
|
FmgrInfo *flinfo, Datum *private)
|
||||||
|
{
|
||||||
|
struct
|
||||||
|
{
|
||||||
|
char *old_label;
|
||||||
|
char *new_label;
|
||||||
|
Datum next_private;
|
||||||
|
} *stack;
|
||||||
|
|
||||||
|
switch (event)
|
||||||
|
{
|
||||||
|
case FHET_START:
|
||||||
|
stack = (void *) DatumGetPointer(*private);
|
||||||
|
if (!stack)
|
||||||
|
{
|
||||||
|
MemoryContext oldcxt;
|
||||||
|
|
||||||
|
oldcxt = MemoryContextSwitchTo(flinfo->fn_mcxt);
|
||||||
|
stack = palloc(sizeof(*stack));
|
||||||
|
stack->old_label = NULL;
|
||||||
|
stack->new_label = sepgsql_avc_trusted_proc(flinfo->fn_oid);
|
||||||
|
stack->next_private = 0;
|
||||||
|
|
||||||
|
MemoryContextSwitchTo(oldcxt);
|
||||||
|
|
||||||
|
/*
|
||||||
|
* process:transition permission between old and new label,
|
||||||
|
* when user tries to switch security label of the client
|
||||||
|
* on execution of trusted procedure.
|
||||||
|
*/
|
||||||
|
if (stack->new_label)
|
||||||
|
sepgsql_avc_check_perms_label(stack->new_label,
|
||||||
|
SEPG_CLASS_PROCESS,
|
||||||
|
SEPG_PROCESS__TRANSITION,
|
||||||
|
NULL, true);
|
||||||
|
|
||||||
|
*private = PointerGetDatum(stack);
|
||||||
|
}
|
||||||
|
Assert(!stack->old_label);
|
||||||
|
if (stack->new_label)
|
||||||
|
{
|
||||||
|
stack->old_label = client_label;
|
||||||
|
client_label = stack->new_label;
|
||||||
|
}
|
||||||
|
if (next_fmgr_hook)
|
||||||
|
(*next_fmgr_hook) (event, flinfo, &stack->next_private);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FHET_END:
|
||||||
|
case FHET_ABORT:
|
||||||
|
stack = (void *) DatumGetPointer(*private);
|
||||||
|
|
||||||
|
if (next_fmgr_hook)
|
||||||
|
(*next_fmgr_hook) (event, flinfo, &stack->next_private);
|
||||||
|
|
||||||
|
if (stack->new_label)
|
||||||
|
{
|
||||||
|
client_label = stack->old_label;
|
||||||
|
stack->old_label = NULL;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
elog(ERROR, "unexpected event type: %d", (int) event);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
|
* sepgsql_init_client_label
|
||||||
|
*
|
||||||
|
* This routine initialize security label of the client, and set up related
|
||||||
|
* hooks to be invoked later.
|
||||||
|
*/
|
||||||
|
void
|
||||||
|
sepgsql_init_client_label(void)
|
||||||
|
{
|
||||||
|
/*
|
||||||
|
* Set up dummy client label.
|
||||||
|
*
|
||||||
|
* XXX - note that PostgreSQL launches background worker process like
|
||||||
|
* autovacuum without authentication steps. So, we initialize sepgsql_mode
|
||||||
|
* with SEPGSQL_MODE_INTERNAL, and client_label with the security context
|
||||||
|
* of server process. Later, it also launches background of user session.
|
||||||
|
* In this case, the process is always hooked on post-authentication, and
|
||||||
|
* we can initialize the sepgsql_mode and client_label correctly.
|
||||||
|
*/
|
||||||
|
if (getcon_raw(&client_label) < 0)
|
||||||
|
ereport(ERROR,
|
||||||
|
(errcode(ERRCODE_INTERNAL_ERROR),
|
||||||
|
errmsg("SELinux: failed to get server security label: %m")));
|
||||||
|
|
||||||
|
/* Client authentication hook */
|
||||||
|
next_client_auth_hook = ClientAuthentication_hook;
|
||||||
|
ClientAuthentication_hook = sepgsql_client_auth;
|
||||||
|
|
||||||
|
/* Trusted procedure hooks */
|
||||||
|
next_needs_fmgr_hook = needs_fmgr_hook;
|
||||||
|
needs_fmgr_hook = sepgsql_needs_fmgr_hook;
|
||||||
|
|
||||||
|
next_fmgr_hook = fmgr_hook;
|
||||||
|
fmgr_hook = sepgsql_fmgr_hook;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -267,7 +267,7 @@ extern void sepgsql_avc_init(void);
|
|||||||
* label.c
|
* label.c
|
||||||
*/
|
*/
|
||||||
extern char *sepgsql_get_client_label(void);
|
extern char *sepgsql_get_client_label(void);
|
||||||
extern char *sepgsql_set_client_label(char *new_label);
|
extern void sepgsql_init_client_label(void);
|
||||||
extern char *sepgsql_get_label(Oid relOid, Oid objOid, int32 subId);
|
extern char *sepgsql_get_label(Oid relOid, Oid objOid, int32 subId);
|
||||||
|
|
||||||
extern void sepgsql_object_relabel(const ObjectAddress *object,
|
extern void sepgsql_object_relabel(const ObjectAddress *object,
|
||||||
|
Loading…
Reference in New Issue
Block a user