#include "postgres.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "access/genam.h"
#include "access/xact.h"
#include "catalog/catalog.h"
#include "catalog/dependency.h"
#include "catalog/indexing.h"
#include "catalog/pg_attribute.h"
#include "catalog/pg_class.h"
#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "commands/dbcommands.h"
#include "commands/seclabel.h"
#include "libpq/auth.h"
#include "libpq/libpq-be.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/guc.h"
#include "utils/lsyscache.h"
#include "utils/memutils.h"
#include "utils/rel.h"
#include "utils/tqual.h"
#include "sepgsql.h"
#include <selinux/label.h>
Go to the source code of this file.
Data Structures | |
struct | pending_label |
Functions | |
char * | sepgsql_get_client_label (void) |
static void | sepgsql_set_client_label (const char *new_label) |
static void | sepgsql_xact_callback (XactEvent event, void *arg) |
static void | sepgsql_subxact_callback (SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg) |
static void | sepgsql_client_auth (Port *port, int status) |
static bool | sepgsql_needs_fmgr_hook (Oid functionId) |
static void | sepgsql_fmgr_hook (FmgrHookEventType event, FmgrInfo *flinfo, Datum *private) |
void | sepgsql_init_client_label (void) |
char * | sepgsql_get_label (Oid classId, Oid objectId, int32 subId) |
void | sepgsql_object_relabel (const ObjectAddress *object, const char *seclabel) |
PG_FUNCTION_INFO_V1 (sepgsql_getcon) | |
Datum | sepgsql_getcon (PG_FUNCTION_ARGS) |
PG_FUNCTION_INFO_V1 (sepgsql_setcon) | |
Datum | sepgsql_setcon (PG_FUNCTION_ARGS) |
PG_FUNCTION_INFO_V1 (sepgsql_mcstrans_in) | |
Datum | sepgsql_mcstrans_in (PG_FUNCTION_ARGS) |
PG_FUNCTION_INFO_V1 (sepgsql_mcstrans_out) | |
Datum | sepgsql_mcstrans_out (PG_FUNCTION_ARGS) |
static char * | quote_object_name (const char *src1, const char *src2, const char *src3, const char *src4) |
static void | exec_object_restorecon (struct selabel_handle *sehnd, Oid catalogId) |
PG_FUNCTION_INFO_V1 (sepgsql_restorecon) | |
Datum | sepgsql_restorecon (PG_FUNCTION_ARGS) |
Variables | |
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 |
static char * | client_label_peer = NULL |
static List * | client_label_pending = NIL |
static char * | client_label_committed = NULL |
static char * | client_label_func = NULL |
static void exec_object_restorecon | ( | struct selabel_handle * | sehnd, | |
Oid | catalogId | |||
) | [static] |
Definition at line 714 of file label.c.
References AccessShareLock, AttributeRelationId, DatabaseRelationId, elog, ereport, errcode(), errmsg(), ERROR, get_database_name(), get_namespace_name(), get_rel_name(), get_rel_namespace(), get_rel_relkind(), GETSTRUCT, heap_close, heap_open(), HeapTupleGetOid, HeapTupleIsValid, InvalidOid, MyDatabaseId, NamespaceRelationId, NameStr, NoLock, NULL, pfree(), PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, ProcedureRelationId, quote_object_name(), RelationRelationId, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW, SEPGSQL_LABEL_TAG, sepgsql_object_relabel(), SetSecurityLabel(), SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), and WARNING.
Referenced by sepgsql_restorecon().
{ Relation rel; SysScanDesc sscan; HeapTuple tuple; char *database_name = get_database_name(MyDatabaseId); char *namespace_name; Oid namespace_id; char *relation_name; /* * Open the target catalog. We don't want to allow writable accesses by * other session during initial labeling. */ rel = heap_open(catalogId, AccessShareLock); sscan = systable_beginscan(rel, InvalidOid, false, SnapshotNow, 0, NULL); while (HeapTupleIsValid(tuple = systable_getnext(sscan))) { Form_pg_database datForm; Form_pg_namespace nspForm; Form_pg_class relForm; Form_pg_attribute attForm; Form_pg_proc proForm; char *objname; int objtype = 1234; ObjectAddress object; security_context_t context; /* * The way to determine object name depends on object classes. So, any * branches set up `objtype', `objname' and `object' here. */ switch (catalogId) { case DatabaseRelationId: datForm = (Form_pg_database) GETSTRUCT(tuple); objtype = SELABEL_DB_DATABASE; objname = quote_object_name(NameStr(datForm->datname), NULL, NULL, NULL); object.classId = DatabaseRelationId; object.objectId = HeapTupleGetOid(tuple); object.objectSubId = 0; break; case NamespaceRelationId: nspForm = (Form_pg_namespace) GETSTRUCT(tuple); objtype = SELABEL_DB_SCHEMA; objname = quote_object_name(database_name, NameStr(nspForm->nspname), NULL, NULL); object.classId = NamespaceRelationId; object.objectId = HeapTupleGetOid(tuple); object.objectSubId = 0; break; case RelationRelationId: relForm = (Form_pg_class) GETSTRUCT(tuple); if (relForm->relkind == RELKIND_RELATION) objtype = SELABEL_DB_TABLE; else if (relForm->relkind == RELKIND_SEQUENCE) objtype = SELABEL_DB_SEQUENCE; else if (relForm->relkind == RELKIND_VIEW) objtype = SELABEL_DB_VIEW; else continue; /* no need to assign security label */ namespace_name = get_namespace_name(relForm->relnamespace); objname = quote_object_name(database_name, namespace_name, NameStr(relForm->relname), NULL); pfree(namespace_name); object.classId = RelationRelationId; object.objectId = HeapTupleGetOid(tuple); object.objectSubId = 0; break; case AttributeRelationId: attForm = (Form_pg_attribute) GETSTRUCT(tuple); if (get_rel_relkind(attForm->attrelid) != RELKIND_RELATION) continue; /* no need to assign security label */ objtype = SELABEL_DB_COLUMN; namespace_id = get_rel_namespace(attForm->attrelid); namespace_name = get_namespace_name(namespace_id); relation_name = get_rel_name(attForm->attrelid); objname = quote_object_name(database_name, namespace_name, relation_name, NameStr(attForm->attname)); pfree(namespace_name); pfree(relation_name); object.classId = RelationRelationId; object.objectId = attForm->attrelid; object.objectSubId = attForm->attnum; break; case ProcedureRelationId: proForm = (Form_pg_proc) GETSTRUCT(tuple); objtype = SELABEL_DB_PROCEDURE; namespace_name = get_namespace_name(proForm->pronamespace); objname = quote_object_name(database_name, namespace_name, NameStr(proForm->proname), NULL); pfree(namespace_name); object.classId = ProcedureRelationId; object.objectId = HeapTupleGetOid(tuple); object.objectSubId = 0; break; default: elog(ERROR, "unexpected catalog id: %u", catalogId); objname = NULL; /* for compiler quiet */ break; } if (selabel_lookup_raw(sehnd, &context, objname, objtype) == 0) { PG_TRY(); { /* * Check SELinux permission to relabel the fetched object, * then do the actual relabeling. */ sepgsql_object_relabel(&object, context); SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, context); } PG_CATCH(); { freecon(context); PG_RE_THROW(); } PG_END_TRY(); freecon(context); } else if (errno == ENOENT) ereport(WARNING, (errmsg("SELinux: no initial label assigned for %s (type=%d), skipping", objname, objtype))); else ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SELinux: could not determine initial security label for %s (type=%d): %m", objname, objtype))); pfree(objname); } systable_endscan(sscan); heap_close(rel, NoLock); }
PG_FUNCTION_INFO_V1 | ( | sepgsql_getcon | ) |
PG_FUNCTION_INFO_V1 | ( | sepgsql_mcstrans_out | ) |
PG_FUNCTION_INFO_V1 | ( | sepgsql_restorecon | ) |
PG_FUNCTION_INFO_V1 | ( | sepgsql_setcon | ) |
PG_FUNCTION_INFO_V1 | ( | sepgsql_mcstrans_in | ) |
static char* quote_object_name | ( | const char * | src1, | |
const char * | src2, | |||
const char * | src3, | |||
const char * | src4 | |||
) | [static] |
Definition at line 667 of file label.c.
References appendStringInfo(), StringInfoData::data, initStringInfo(), pfree(), and quote_identifier().
Referenced by exec_object_restorecon().
{ StringInfoData result; const char *temp; initStringInfo(&result); if (src1) { temp = quote_identifier(src1); appendStringInfo(&result, "%s", temp); if (src1 != temp) pfree((void *) temp); } if (src2) { temp = quote_identifier(src2); appendStringInfo(&result, ".%s", temp); if (src2 != temp) pfree((void *) temp); } if (src3) { temp = quote_identifier(src3); appendStringInfo(&result, ".%s", temp); if (src3 != temp) pfree((void *) temp); } if (src4) { temp = quote_identifier(src4); appendStringInfo(&result, ".%s", temp); if (src4 != temp) pfree((void *) temp); } return result.data; }
static void sepgsql_client_auth | ( | Port * | port, | |
int | status | |||
) | [static] |
Definition at line 240 of file label.c.
References client_label_peer, ereport, errcode(), errmsg(), FATAL, next_client_auth_hook, sepgsql_get_permissive(), SEPGSQL_MODE_DEFAULT, SEPGSQL_MODE_PERMISSIVE, sepgsql_set_mode(), and STATUS_OK.
{ 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, &client_label_peer) < 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); }
static void sepgsql_fmgr_hook | ( | FmgrHookEventType | event, | |
FmgrInfo * | flinfo, | |||
Datum * | private | |||
) | [static] |
Definition at line 321 of file label.c.
References Assert, client_label_func, DatumGetPointer, elog, ERROR, FHET_ABORT, FHET_END, FHET_START, FmgrInfo::fn_mcxt, FmgrInfo::fn_oid, getObjectDescription(), MemoryContextSwitchTo(), next_fmgr_hook, NULL, palloc(), PointerGetDatum, SEPG_CLASS_DB_PROCEDURE, SEPG_CLASS_PROCESS, SEPG_DB_PROCEDURE__ENTRYPOINT, SEPG_PROCESS__TRANSITION, sepgsql_avc_check_perms(), sepgsql_avc_check_perms_label(), and sepgsql_avc_trusted_proc().
{ 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. * * Also, db_procedure:entrypoint permission should be checked * whether this procedure can perform as an entrypoint of the * trusted procedure, or not. * Note that db_procedure:execute permission shall be checked * individually. */ if (stack->new_label) { ObjectAddress object; object.classId = ProcedureRelationId; object.objectId = flinfo->fn_oid; object.objectSubId = 0; sepgsql_avc_check_perms(&object, SEPG_CLASS_DB_PROCEDURE, SEPG_DB_PROCEDURE__ENTRYPOINT, getObjectDescription(&object), true); 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_func; client_label_func = 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_func = stack->old_label; stack->old_label = NULL; } break; default: elog(ERROR, "unexpected event type: %d", (int) event); break; } }
char* sepgsql_get_client_label | ( | void | ) |
Definition at line 83 of file label.c.
References Assert, client_label_committed, client_label_func, client_label_peer, pending_label::label, llast, and NULL.
Referenced by sepgsql_attribute_post_create(), sepgsql_avc_check_perms_label(), sepgsql_avc_trusted_proc(), sepgsql_database_post_create(), sepgsql_getcon(), sepgsql_proc_post_create(), sepgsql_relation_post_create(), sepgsql_schema_post_create(), and sepgsql_set_client_label().
{ /* trusted procedure client label override */ if (client_label_func) return client_label_func; /* uncommitted sepgsql_setcon() value */ if (client_label_pending) { pending_label *plabel = llast(client_label_pending); if (plabel->label) return plabel->label; } else if (client_label_committed) return client_label_committed; /* set by sepgsql_setcon() committed */ /* default label */ Assert(client_label_peer != NULL); return client_label_peer; }
Definition at line 456 of file label.c.
References ereport, errcode(), errmsg(), ERROR, GetSecurityLabel(), label, PG_CATCH, PG_END_TRY, PG_RE_THROW, PG_TRY, pstrdup(), and SEPGSQL_LABEL_TAG.
Referenced by sepgsql_attribute_post_create(), sepgsql_database_post_create(), sepgsql_proc_post_create(), sepgsql_relation_post_create(), and sepgsql_schema_post_create().
{ ObjectAddress object; char *label; object.classId = classId; object.objectId = objectId; object.objectSubId = subId; label = GetSecurityLabel(&object, SEPGSQL_LABEL_TAG); if (!label || security_check_context_raw((security_context_t) label)) { security_context_t unlabeled; if (security_get_initial_context_raw("unlabeled", &unlabeled) < 0) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SELinux: failed to get initial security label: %m"))); PG_TRY(); { label = pstrdup(unlabeled); } PG_CATCH(); { freecon(unlabeled); PG_RE_THROW(); } PG_END_TRY(); freecon(unlabeled); } return label; }
Datum sepgsql_getcon | ( | PG_FUNCTION_ARGS | ) |
Definition at line 548 of file label.c.
References cstring_to_text(), PG_RETURN_NULL, PG_RETURN_TEXT_P, sepgsql_get_client_label(), and sepgsql_is_enabled().
{ char *client_label; if (!sepgsql_is_enabled()) PG_RETURN_NULL(); client_label = sepgsql_get_client_label(); PG_RETURN_TEXT_P(cstring_to_text(client_label)); }
void sepgsql_init_client_label | ( | void | ) |
Definition at line 415 of file label.c.
References client_label_peer, ClientAuthentication_hook, ereport, errcode(), errmsg(), ERROR, fmgr_hook, needs_fmgr_hook, next_client_auth_hook, next_fmgr_hook, next_needs_fmgr_hook, NULL, RegisterSubXactCallback(), RegisterXactCallback(), sepgsql_subxact_callback(), and sepgsql_xact_callback().
Referenced by _PG_init().
{ /* * 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_peer) < 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; /* Transaction/Sub-transaction callbacks */ RegisterXactCallback(sepgsql_xact_callback, NULL); RegisterSubXactCallback(sepgsql_subxact_callback, NULL); }
Datum sepgsql_mcstrans_in | ( | PG_FUNCTION_ARGS | ) |
Definition at line 589 of file label.c.
References cstring_to_text(), ereport, errcode(), errmsg(), ERROR, label, PG_CATCH, PG_END_TRY, PG_GETARG_TEXT_P, PG_RE_THROW, PG_RETURN_TEXT_P, PG_TRY, pstrdup(), sepgsql_is_enabled(), and text_to_cstring().
{ text *label = PG_GETARG_TEXT_P(0); char *raw_label; char *result; if (!sepgsql_is_enabled()) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("sepgsql is not enabled"))); if (selinux_trans_to_raw_context(text_to_cstring(label), &raw_label) < 0) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SELinux: could not translate security label: %m"))); PG_TRY(); { result = pstrdup(raw_label); } PG_CATCH(); { freecon(raw_label); PG_RE_THROW(); } PG_END_TRY(); freecon(raw_label); PG_RETURN_TEXT_P(cstring_to_text(result)); }
Datum sepgsql_mcstrans_out | ( | PG_FUNCTION_ARGS | ) |
Definition at line 629 of file label.c.
References cstring_to_text(), ereport, errcode(), errmsg(), ERROR, label, PG_CATCH, PG_END_TRY, PG_GETARG_TEXT_P, PG_RE_THROW, PG_RETURN_TEXT_P, PG_TRY, pstrdup(), sepgsql_is_enabled(), and text_to_cstring().
{ text *label = PG_GETARG_TEXT_P(0); char *qual_label; char *result; if (!sepgsql_is_enabled()) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("sepgsql is not currently enabled"))); if (selinux_raw_to_trans_context(text_to_cstring(label), &qual_label) < 0) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SELinux: could not translate security label: %m"))); PG_TRY(); { result = pstrdup(qual_label); } PG_CATCH(); { freecon(qual_label); PG_RE_THROW(); } PG_END_TRY(); freecon(qual_label); PG_RETURN_TEXT_P(cstring_to_text(result)); }
Definition at line 278 of file label.c.
References next_needs_fmgr_hook, NULL, SEPG_CLASS_DB_PROCEDURE, SEPG_DB_PROCEDURE__ENTRYPOINT, SEPG_DB_PROCEDURE__EXECUTE, sepgsql_avc_check_perms(), SEPGSQL_AVC_NOAUDIT, and sepgsql_avc_trusted_proc().
{ 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 | SEPG_DB_PROCEDURE__ENTRYPOINT, SEPGSQL_AVC_NOAUDIT, false)) return true; return false; }
void sepgsql_object_relabel | ( | const ObjectAddress * | object, | |
const char * | seclabel | |||
) |
Definition at line 496 of file label.c.
References ObjectAddress::classId, DatabaseRelationId, elog, ereport, errcode(), errmsg(), ERROR, NamespaceRelationId, ObjectAddress::objectId, ObjectAddress::objectSubId, ProcedureRelationId, RelationRelationId, sepgsql_attribute_relabel(), sepgsql_database_relabel(), sepgsql_proc_relabel(), sepgsql_relation_relabel(), and sepgsql_schema_relabel().
Referenced by _PG_init(), and exec_object_restorecon().
{ /* * validate format of the supplied security label, if it is security * context of selinux. */ if (seclabel && security_check_context_raw((security_context_t) seclabel) < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), errmsg("SELinux: invalid security label: \"%s\"", seclabel))); /* * Do actual permission checks for each object classes */ switch (object->classId) { case DatabaseRelationId: sepgsql_database_relabel(object->objectId, seclabel); break; case NamespaceRelationId: sepgsql_schema_relabel(object->objectId, seclabel); break; case RelationRelationId: if (object->objectSubId == 0) sepgsql_relation_relabel(object->objectId, seclabel); else sepgsql_attribute_relabel(object->objectId, object->objectSubId, seclabel); break; case ProcedureRelationId: sepgsql_proc_relabel(object->objectId, seclabel); break; default: elog(ERROR, "unsupported object type: %u", object->classId); break; } }
Datum sepgsql_restorecon | ( | PG_FUNCTION_ARGS | ) |
Definition at line 896 of file label.c.
References AttributeRelationId, DatabaseRelationId, ereport, errcode(), errmsg(), ERROR, exec_object_restorecon(), NamespaceRelationId, PG_ARGISNULL, PG_CATCH, PG_END_TRY, PG_GETARG_DATUM, PG_RE_THROW, PG_RETURN_BOOL, PG_TRY, ProcedureRelationId, RelationRelationId, sepgsql_is_enabled(), superuser(), and TextDatumGetCString.
{ struct selabel_handle *sehnd; struct selinux_opt seopts; /* * SELinux has to be enabled on the running platform. */ if (!sepgsql_is_enabled()) ereport(ERROR, (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE), errmsg("sepgsql is not currently enabled"))); /* * Check DAC permission. Only superuser can set up initial security * labels, like root-user in filesystems */ if (!superuser()) ereport(ERROR, (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE), errmsg("SELinux: must be superuser to restore initial contexts"))); /* * Open selabel_lookup(3) stuff. It provides a set of mapping between an * initial security label and object class/name due to the system setting. */ if (PG_ARGISNULL(0)) { seopts.type = SELABEL_OPT_UNUSED; seopts.value = NULL; } else { seopts.type = SELABEL_OPT_PATH; seopts.value = TextDatumGetCString(PG_GETARG_DATUM(0)); } sehnd = selabel_open(SELABEL_CTX_DB, &seopts, 1); if (!sehnd) ereport(ERROR, (errcode(ERRCODE_INTERNAL_ERROR), errmsg("SELinux: failed to initialize labeling handle: %m"))); PG_TRY(); { exec_object_restorecon(sehnd, DatabaseRelationId); exec_object_restorecon(sehnd, NamespaceRelationId); exec_object_restorecon(sehnd, RelationRelationId); exec_object_restorecon(sehnd, AttributeRelationId); exec_object_restorecon(sehnd, ProcedureRelationId); } PG_CATCH(); { selabel_close(sehnd); PG_RE_THROW(); } PG_END_TRY(); selabel_close(sehnd); PG_RETURN_BOOL(true); }
static void sepgsql_set_client_label | ( | const char * | new_label | ) | [static] |
Definition at line 114 of file label.c.
References client_label_peer, CurTransactionContext, ereport, errcode(), errmsg(), ERROR, GetCurrentSubTransactionId(), pending_label::label, lappend(), MemoryContextSwitchTo(), NULL, palloc0(), pstrdup(), SEPG_CLASS_PROCESS, SEPG_PROCESS__DYNTRANSITION, SEPG_PROCESS__SETCURRENT, sepgsql_avc_check_perms_label(), sepgsql_get_client_label(), and pending_label::subid.
Referenced by sepgsql_setcon().
{ const char *tcontext; MemoryContext oldcxt; pending_label *plabel; /* Reset to the initial client label, if NULL */ if (!new_label) tcontext = client_label_peer; else { if (security_check_context_raw((security_context_t) new_label) < 0) ereport(ERROR, (errcode(ERRCODE_INVALID_NAME), errmsg("SELinux: invalid security label: \"%s\"", new_label))); tcontext = new_label; } /* Check process:{setcurrent} permission. */ sepgsql_avc_check_perms_label(sepgsql_get_client_label(), SEPG_CLASS_PROCESS, SEPG_PROCESS__SETCURRENT, NULL, true); /* Check process:{dyntransition} permission. */ sepgsql_avc_check_perms_label(tcontext, SEPG_CLASS_PROCESS, SEPG_PROCESS__DYNTRANSITION, NULL, true); /* * Append the supplied new_label on the pending list until the current * transaction is committed. */ oldcxt = MemoryContextSwitchTo(CurTransactionContext); plabel = palloc0(sizeof(pending_label)); plabel->subid = GetCurrentSubTransactionId(); if (new_label) plabel->label = pstrdup(new_label); client_label_pending = lappend(client_label_pending, plabel); MemoryContextSwitchTo(oldcxt); }
Datum sepgsql_setcon | ( | PG_FUNCTION_ARGS | ) |
Definition at line 567 of file label.c.
References PG_ARGISNULL, PG_GETARG_DATUM, PG_RETURN_BOOL, sepgsql_set_client_label(), and TextDatumGetCString.
{ const char *new_label; if (PG_ARGISNULL(0)) new_label = NULL; else new_label = TextDatumGetCString(PG_GETARG_DATUM(0)); sepgsql_set_client_label(new_label); PG_RETURN_BOOL(true); }
static void sepgsql_subxact_callback | ( | SubXactEvent | event, | |
SubTransactionId | mySubid, | |||
SubTransactionId | parentSubid, | |||
void * | arg | |||
) | [static] |
Definition at line 207 of file label.c.
References lfirst, list_delete_cell(), list_head(), lnext, pending_label::subid, and SUBXACT_EVENT_ABORT_SUB.
Referenced by sepgsql_init_client_label().
{ ListCell *cell; ListCell *prev; ListCell *next; if (event == SUBXACT_EVENT_ABORT_SUB) { prev = NULL; for (cell = list_head(client_label_pending); cell; cell = next) { pending_label *plabel = lfirst(cell); next = lnext(cell); if (plabel->subid == mySubid) client_label_pending = list_delete_cell(client_label_pending, cell, prev); else prev = cell; } } }
static void sepgsql_xact_callback | ( | XactEvent | event, | |
void * | arg | |||
) | [static] |
Definition at line 168 of file label.c.
References client_label_committed, pending_label::label, llast, MemoryContextStrdup(), NIL, pfree(), TopMemoryContext, XACT_EVENT_ABORT, and XACT_EVENT_COMMIT.
Referenced by sepgsql_init_client_label().
{ if (event == XACT_EVENT_COMMIT) { if (client_label_pending != NIL) { pending_label *plabel = llast(client_label_pending); char *new_label; if (plabel->label) new_label = MemoryContextStrdup(TopMemoryContext, plabel->label); else new_label = NULL; if (client_label_committed) pfree(client_label_committed); client_label_committed = new_label; /* * XXX - Note that items of client_label_pending are allocated on * CurTransactionContext, thus, all acquired memory region shall * be released implicitly. */ client_label_pending = NIL; } } else if (event == XACT_EVENT_ABORT) client_label_pending = NIL; }
char* client_label_committed = NULL [static] |
Definition at line 65 of file label.c.
Referenced by sepgsql_get_client_label(), and sepgsql_xact_callback().
char* client_label_func = NULL [static] |
Definition at line 67 of file label.c.
Referenced by sepgsql_fmgr_hook(), and sepgsql_get_client_label().
char* client_label_peer = NULL [static] |
Definition at line 62 of file label.c.
Referenced by sepgsql_client_auth(), sepgsql_get_client_label(), sepgsql_init_client_label(), and sepgsql_set_client_label().
List* client_label_pending = NIL [static] |
ClientAuthentication_hook_type next_client_auth_hook = NULL [static] |
Definition at line 45 of file label.c.
Referenced by sepgsql_client_auth(), and sepgsql_init_client_label().
fmgr_hook_type next_fmgr_hook = NULL [static] |
Definition at line 47 of file label.c.
Referenced by sepgsql_fmgr_hook(), and sepgsql_init_client_label().
needs_fmgr_hook_type next_needs_fmgr_hook = NULL [static] |
Definition at line 46 of file label.c.
Referenced by sepgsql_init_client_label(), and sepgsql_needs_fmgr_hook().