PostgreSQL Source Code  git master
label.c File Reference
#include "postgres.h"
#include <selinux/label.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 dependency graph for label.c:

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 Listclient_label_pending = NIL
 
static char * client_label_committed = NULL
 
static char * client_label_func = NULL
 

Function Documentation

◆ exec_object_restorecon()

static void exec_object_restorecon ( struct selabel_handle *  sehnd,
Oid  catalogId 
)
static

Definition at line 716 of file label.c.

References AccessShareLock, 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, NameStr, NoLock, pfree(), PG_CATCH, PG_END_TRY, PG_FUNCTION_INFO_V1(), PG_RE_THROW, PG_TRY, quote_object_name(), SEPGSQL_LABEL_TAG, sepgsql_object_relabel(), sepgsql_restorecon(), SetSecurityLabel(), systable_beginscan(), systable_endscan(), systable_getnext(), and WARNING.

Referenced by sepgsql_restorecon().

717 {
718  Relation rel;
719  SysScanDesc sscan;
720  HeapTuple tuple;
721  char *database_name = get_database_name(MyDatabaseId);
722  char *namespace_name;
723  Oid namespace_id;
724  char *relation_name;
725 
726  /*
727  * Open the target catalog. We don't want to allow writable accesses by
728  * other session during initial labeling.
729  */
730  rel = heap_open(catalogId, AccessShareLock);
731 
732  sscan = systable_beginscan(rel, InvalidOid, false,
733  NULL, 0, NULL);
734  while (HeapTupleIsValid(tuple = systable_getnext(sscan)))
735  {
736  Form_pg_database datForm;
737  Form_pg_namespace nspForm;
738  Form_pg_class relForm;
739  Form_pg_attribute attForm;
740  Form_pg_proc proForm;
741  char *objname;
742  int objtype = 1234;
743  ObjectAddress object;
744  security_context_t context;
745 
746  /*
747  * The way to determine object name depends on object classes. So, any
748  * branches set up `objtype', `objname' and `object' here.
749  */
750  switch (catalogId)
751  {
752  case DatabaseRelationId:
753  datForm = (Form_pg_database) GETSTRUCT(tuple);
754 
755  objtype = SELABEL_DB_DATABASE;
756 
757  objname = quote_object_name(NameStr(datForm->datname),
758  NULL, NULL, NULL);
759 
760  object.classId = DatabaseRelationId;
761  object.objectId = HeapTupleGetOid(tuple);
762  object.objectSubId = 0;
763  break;
764 
765  case NamespaceRelationId:
766  nspForm = (Form_pg_namespace) GETSTRUCT(tuple);
767 
768  objtype = SELABEL_DB_SCHEMA;
769 
770  objname = quote_object_name(database_name,
771  NameStr(nspForm->nspname),
772  NULL, NULL);
773 
774  object.classId = NamespaceRelationId;
775  object.objectId = HeapTupleGetOid(tuple);
776  object.objectSubId = 0;
777  break;
778 
779  case RelationRelationId:
780  relForm = (Form_pg_class) GETSTRUCT(tuple);
781 
782  if (relForm->relkind == RELKIND_RELATION ||
783  relForm->relkind == RELKIND_PARTITIONED_TABLE)
784  objtype = SELABEL_DB_TABLE;
785  else if (relForm->relkind == RELKIND_SEQUENCE)
786  objtype = SELABEL_DB_SEQUENCE;
787  else if (relForm->relkind == RELKIND_VIEW)
788  objtype = SELABEL_DB_VIEW;
789  else
790  continue; /* no need to assign security label */
791 
792  namespace_name = get_namespace_name(relForm->relnamespace);
793  objname = quote_object_name(database_name,
794  namespace_name,
795  NameStr(relForm->relname),
796  NULL);
797  pfree(namespace_name);
798 
799  object.classId = RelationRelationId;
800  object.objectId = HeapTupleGetOid(tuple);
801  object.objectSubId = 0;
802  break;
803 
804  case AttributeRelationId:
805  attForm = (Form_pg_attribute) GETSTRUCT(tuple);
806 
807  if (get_rel_relkind(attForm->attrelid) != RELKIND_RELATION &&
808  get_rel_relkind(attForm->attrelid) != RELKIND_PARTITIONED_TABLE)
809  continue; /* no need to assign security label */
810 
811  objtype = SELABEL_DB_COLUMN;
812 
813  namespace_id = get_rel_namespace(attForm->attrelid);
814  namespace_name = get_namespace_name(namespace_id);
815  relation_name = get_rel_name(attForm->attrelid);
816  objname = quote_object_name(database_name,
817  namespace_name,
818  relation_name,
819  NameStr(attForm->attname));
820  pfree(namespace_name);
821  pfree(relation_name);
822 
823  object.classId = RelationRelationId;
824  object.objectId = attForm->attrelid;
825  object.objectSubId = attForm->attnum;
826  break;
827 
828  case ProcedureRelationId:
829  proForm = (Form_pg_proc) GETSTRUCT(tuple);
830 
831  objtype = SELABEL_DB_PROCEDURE;
832 
833  namespace_name = get_namespace_name(proForm->pronamespace);
834  objname = quote_object_name(database_name,
835  namespace_name,
836  NameStr(proForm->proname),
837  NULL);
838  pfree(namespace_name);
839 
840  object.classId = ProcedureRelationId;
841  object.objectId = HeapTupleGetOid(tuple);
842  object.objectSubId = 0;
843  break;
844 
845  default:
846  elog(ERROR, "unexpected catalog id: %u", catalogId);
847  objname = NULL; /* for compiler quiet */
848  break;
849  }
850 
851  if (selabel_lookup_raw(sehnd, &context, objname, objtype) == 0)
852  {
853  PG_TRY();
854  {
855  /*
856  * Check SELinux permission to relabel the fetched object,
857  * then do the actual relabeling.
858  */
859  sepgsql_object_relabel(&object, context);
860 
861  SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, context);
862  }
863  PG_CATCH();
864  {
865  freecon(context);
866  PG_RE_THROW();
867  }
868  PG_END_TRY();
869  freecon(context);
870  }
871  else if (errno == ENOENT)
873  (errmsg("SELinux: no initial label assigned for %s (type=%d), skipping",
874  objname, objtype)));
875  else
876  ereport(ERROR,
877  (errcode(ERRCODE_INTERNAL_ERROR),
878  errmsg("SELinux: could not determine initial security label for %s (type=%d): %m", objname, objtype)));
879 
880  pfree(objname);
881  }
882  systable_endscan(sscan);
883 
884  heap_close(rel, NoLock);
885 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:502
#define GETSTRUCT(TUP)
Definition: htup_details.h:668
FormData_pg_namespace * Form_pg_namespace
Definition: pg_namespace.h:49
void SetSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition: seclabel.c:327
FormData_pg_database * Form_pg_database
Definition: pg_database.h:54
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1805
Oid get_rel_namespace(Oid relid)
Definition: lsyscache.c:1754
#define AccessShareLock
Definition: lockdefs.h:36
int errcode(int sqlerrcode)
Definition: elog.c:575
#define heap_close(r, l)
Definition: heapam.h:97
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:331
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:419
static char * quote_object_name(const char *src1, const char *src2, const char *src3, const char *src4)
Definition: label.c:669
void pfree(void *pointer)
Definition: mcxt.c:1031
#define ERROR
Definition: elog.h:43
char * get_database_name(Oid dbid)
Definition: dbcommands.c:2056
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3051
#define NoLock
Definition: lockdefs.h:34
#define SEPGSQL_LABEL_TAG
Definition: sepgsql.h:23
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:197
#define ereport(elevel, rest)
Definition: elog.h:122
#define WARNING
Definition: elog.h:40
Oid MyDatabaseId
Definition: globals.c:84
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1294
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:132
#define InvalidOid
Definition: postgres_ext.h:36
#define PG_CATCH()
Definition: elog.h:293
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define PG_RE_THROW()
Definition: elog.h:314
FormData_pg_class * Form_pg_class
Definition: pg_class.h:93
void sepgsql_object_relabel(const ObjectAddress *object, const char *seclabel)
Definition: label.c:495
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define NameStr(name)
Definition: c.h:576
#define elog
Definition: elog.h:219
#define HeapTupleGetOid(tuple)
Definition: htup_details.h:707
#define PG_TRY()
Definition: elog.h:284
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1730
#define PG_END_TRY()
Definition: elog.h:300

◆ PG_FUNCTION_INFO_V1() [1/5]

◆ PG_FUNCTION_INFO_V1() [2/5]

PG_FUNCTION_INFO_V1 ( sepgsql_setcon  )

◆ PG_FUNCTION_INFO_V1() [3/5]

PG_FUNCTION_INFO_V1 ( sepgsql_mcstrans_in  )

◆ PG_FUNCTION_INFO_V1() [4/5]

PG_FUNCTION_INFO_V1 ( sepgsql_mcstrans_out  )

◆ PG_FUNCTION_INFO_V1() [5/5]

PG_FUNCTION_INFO_V1 ( sepgsql_restorecon  )

◆ quote_object_name()

static char* quote_object_name ( const char *  src1,
const char *  src2,
const char *  src3,
const char *  src4 
)
static

Definition at line 669 of file label.c.

References appendStringInfo(), StringInfoData::data, initStringInfo(), pfree(), and quote_identifier().

Referenced by exec_object_restorecon().

671 {
672  StringInfoData result;
673  const char *temp;
674 
675  initStringInfo(&result);
676 
677  if (src1)
678  {
679  temp = quote_identifier(src1);
680  appendStringInfo(&result, "%s", temp);
681  if (src1 != temp)
682  pfree((void *) temp);
683  }
684  if (src2)
685  {
686  temp = quote_identifier(src2);
687  appendStringInfo(&result, ".%s", temp);
688  if (src2 != temp)
689  pfree((void *) temp);
690  }
691  if (src3)
692  {
693  temp = quote_identifier(src3);
694  appendStringInfo(&result, ".%s", temp);
695  if (src3 != temp)
696  pfree((void *) temp);
697  }
698  if (src4)
699  {
700  temp = quote_identifier(src4);
701  appendStringInfo(&result, ".%s", temp);
702  if (src4 != temp)
703  pfree((void *) temp);
704  }
705  return result.data;
706 }
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10488
void pfree(void *pointer)
Definition: mcxt.c:1031
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46

◆ sepgsql_client_auth()

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, port, sepgsql_get_permissive(), SEPGSQL_MODE_DEFAULT, SEPGSQL_MODE_PERMISSIVE, sepgsql_set_mode(), status(), and STATUS_OK.

Referenced by sepgsql_init_client_label().

241 {
243  (*next_client_auth_hook) (port, status);
244 
245  /*
246  * In the case when authentication failed, the supplied socket shall be
247  * closed soon, so we don't need to do anything here.
248  */
249  if (status != STATUS_OK)
250  return;
251 
252  /*
253  * Getting security label of the peer process using API of libselinux.
254  */
255  if (getpeercon_raw(port->sock, &client_label_peer) < 0)
256  ereport(FATAL,
257  (errcode(ERRCODE_INTERNAL_ERROR),
258  errmsg("SELinux: unable to get peer label: %m")));
259 
260  /*
261  * Switch the current performing mode from INTERNAL to either DEFAULT or
262  * PERMISSIVE.
263  */
266  else
268 }
int errcode(int sqlerrcode)
Definition: elog.c:575
static ClientAuthentication_hook_type next_client_auth_hook
Definition: label.c:45
#define FATAL
Definition: elog.h:52
int sepgsql_set_mode(int new_mode)
Definition: selinux.c:631
#define ereport(elevel, rest)
Definition: elog.h:122
#define STATUS_OK
Definition: c.h:1008
static int port
Definition: pg_regress.c:90
#define SEPGSQL_MODE_DEFAULT
Definition: sepgsql.h:28
#define SEPGSQL_MODE_PERMISSIVE
Definition: sepgsql.h:29
static char * client_label_peer
Definition: label.c:62
bool sepgsql_get_permissive(void)
Definition: hooks.c:65
int errmsg(const char *fmt,...)
Definition: elog.c:797
static void static void status(const char *fmt,...) pg_attribute_printf(1
Definition: pg_regress.c:225

◆ sepgsql_fmgr_hook()

static void sepgsql_fmgr_hook ( FmgrHookEventType  event,
FmgrInfo flinfo,
Datum private 
)
static

Definition at line 321 of file label.c.

References Assert, ObjectAddress::classId, client_label_func, DatumGetPointer, elog, ERROR, FHET_ABORT, FHET_END, FHET_START, FmgrInfo::fn_mcxt, FmgrInfo::fn_oid, getObjectDescription(), MemoryContextSwitchTo(), next_fmgr_hook, 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().

Referenced by sepgsql_init_client_label().

323 {
324  struct
325  {
326  char *old_label;
327  char *new_label;
328  Datum next_private;
329  } *stack;
330 
331  switch (event)
332  {
333  case FHET_START:
334  stack = (void *) DatumGetPointer(*private);
335  if (!stack)
336  {
337  MemoryContext oldcxt;
338 
339  oldcxt = MemoryContextSwitchTo(flinfo->fn_mcxt);
340  stack = palloc(sizeof(*stack));
341  stack->old_label = NULL;
342  stack->new_label = sepgsql_avc_trusted_proc(flinfo->fn_oid);
343  stack->next_private = 0;
344 
345  MemoryContextSwitchTo(oldcxt);
346 
347  /*
348  * process:transition permission between old and new label,
349  * when user tries to switch security label of the client on
350  * execution of trusted procedure.
351  *
352  * Also, db_procedure:entrypoint permission should be checked
353  * whether this procedure can perform as an entrypoint of the
354  * trusted procedure, or not. Note that db_procedure:execute
355  * permission shall be checked individually.
356  */
357  if (stack->new_label)
358  {
359  ObjectAddress object;
360 
361  object.classId = ProcedureRelationId;
362  object.objectId = flinfo->fn_oid;
363  object.objectSubId = 0;
364  sepgsql_avc_check_perms(&object,
367  getObjectDescription(&object),
368  true);
369 
370  sepgsql_avc_check_perms_label(stack->new_label,
373  NULL, true);
374  }
375  *private = PointerGetDatum(stack);
376  }
377  Assert(!stack->old_label);
378  if (stack->new_label)
379  {
380  stack->old_label = client_label_func;
381  client_label_func = stack->new_label;
382  }
383  if (next_fmgr_hook)
384  (*next_fmgr_hook) (event, flinfo, &stack->next_private);
385  break;
386 
387  case FHET_END:
388  case FHET_ABORT:
389  stack = (void *) DatumGetPointer(*private);
390 
391  if (next_fmgr_hook)
392  (*next_fmgr_hook) (event, flinfo, &stack->next_private);
393 
394  if (stack->new_label)
395  {
396  client_label_func = stack->old_label;
397  stack->old_label = NULL;
398  }
399  break;
400 
401  default:
402  elog(ERROR, "unexpected event type: %d", (int) event);
403  break;
404  }
405 }
bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:346
static char * client_label_func
Definition: label.c:67
MemoryContext fn_mcxt
Definition: fmgr.h:65
#define PointerGetDatum(X)
Definition: postgres.h:541
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:428
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
#define SEPG_PROCESS__TRANSITION
Definition: sepgsql.h:59
char * getObjectDescription(const ObjectAddress *object)
#define SEPG_CLASS_PROCESS
Definition: sepgsql.h:36
#define ERROR
Definition: elog.h:43
char * sepgsql_avc_trusted_proc(Oid functionId)
Definition: uavc.c:453
#define SEPG_CLASS_DB_PROCEDURE
Definition: sepgsql.h:48
Definition: fmgr.h:723
uintptr_t Datum
Definition: postgres.h:367
Oid fn_oid
Definition: fmgr.h:59
#define SEPG_DB_PROCEDURE__ENTRYPOINT
Definition: sepgsql.h:166
#define Assert(condition)
Definition: c.h:699
#define DatumGetPointer(X)
Definition: postgres.h:534
void * palloc(Size size)
Definition: mcxt.c:924
#define elog
Definition: elog.h:219
static fmgr_hook_type next_fmgr_hook
Definition: label.c:47

◆ sepgsql_get_client_label()

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, and llast.

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().

84 {
85  /* trusted procedure client label override */
87  return client_label_func;
88 
89  /* uncommitted sepgsql_setcon() value */
91  {
93 
94  if (plabel->label)
95  return plabel->label;
96  }
97  else if (client_label_committed)
98  return client_label_committed; /* set by sepgsql_setcon() committed */
99 
100  /* default label */
101  Assert(client_label_peer != NULL);
102  return client_label_peer;
103 }
static char * client_label_func
Definition: label.c:67
static char * client_label_committed
Definition: label.c:65
#define llast(l)
Definition: pg_list.h:131
char * label
Definition: label.c:72
static List * client_label_pending
Definition: label.c:63
#define Assert(condition)
Definition: c.h:699
static char * client_label_peer
Definition: label.c:62

◆ sepgsql_get_label()

char* sepgsql_get_label ( Oid  classId,
Oid  objectId,
int32  subId 
)

Definition at line 455 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().

456 {
457  ObjectAddress object;
458  char *label;
459 
460  object.classId = classId;
461  object.objectId = objectId;
462  object.objectSubId = subId;
463 
464  label = GetSecurityLabel(&object, SEPGSQL_LABEL_TAG);
465  if (!label || security_check_context_raw((security_context_t) label))
466  {
467  security_context_t unlabeled;
468 
469  if (security_get_initial_context_raw("unlabeled", &unlabeled) < 0)
470  ereport(ERROR,
471  (errcode(ERRCODE_INTERNAL_ERROR),
472  errmsg("SELinux: failed to get initial security label: %m")));
473  PG_TRY();
474  {
475  label = pstrdup(unlabeled);
476  }
477  PG_CATCH();
478  {
479  freecon(unlabeled);
480  PG_RE_THROW();
481  }
482  PG_END_TRY();
483 
484  freecon(unlabeled);
485  }
486  return label;
487 }
char * pstrdup(const char *in)
Definition: mcxt.c:1161
int errcode(int sqlerrcode)
Definition: elog.c:575
#define ERROR
Definition: elog.h:43
char * GetSecurityLabel(const ObjectAddress *object, const char *provider)
Definition: seclabel.c:195
#define SEPGSQL_LABEL_TAG
Definition: sepgsql.h:23
#define ereport(elevel, rest)
Definition: elog.h:122
static char * label
Definition: pg_basebackup.c:84
#define PG_CATCH()
Definition: elog.h:293
#define PG_RE_THROW()
Definition: elog.h:314
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300

◆ sepgsql_getcon()

Datum sepgsql_getcon ( PG_FUNCTION_ARGS  )

Definition at line 550 of file label.c.

References cstring_to_text(), PG_FUNCTION_INFO_V1(), PG_RETURN_NULL, PG_RETURN_TEXT_P, sepgsql_get_client_label(), sepgsql_is_enabled(), and sepgsql_setcon().

Referenced by sepgsql_object_relabel().

551 {
552  char *client_label;
553 
554  if (!sepgsql_is_enabled())
555  PG_RETURN_NULL();
556 
557  client_label = sepgsql_get_client_label();
558 
559  PG_RETURN_TEXT_P(cstring_to_text(client_label));
560 }
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:336
bool sepgsql_is_enabled(void)
Definition: selinux.c:613
text * cstring_to_text(const char *s)
Definition: varlena.c:149
char * sepgsql_get_client_label(void)
Definition: label.c:83
#define PG_RETURN_NULL()
Definition: fmgr.h:310

◆ sepgsql_init_client_label()

void sepgsql_init_client_label ( void  )

Definition at line 414 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, RegisterSubXactCallback(), RegisterXactCallback(), sepgsql_client_auth(), sepgsql_fmgr_hook(), sepgsql_needs_fmgr_hook(), sepgsql_subxact_callback(), and sepgsql_xact_callback().

Referenced by _PG_init().

415 {
416  /*
417  * Set up dummy client label.
418  *
419  * XXX - note that PostgreSQL launches background worker process like
420  * autovacuum without authentication steps. So, we initialize sepgsql_mode
421  * with SEPGSQL_MODE_INTERNAL, and client_label with the security context
422  * of server process. Later, it also launches background of user session.
423  * In this case, the process is always hooked on post-authentication, and
424  * we can initialize the sepgsql_mode and client_label correctly.
425  */
426  if (getcon_raw(&client_label_peer) < 0)
427  ereport(ERROR,
428  (errcode(ERRCODE_INTERNAL_ERROR),
429  errmsg("SELinux: failed to get server security label: %m")));
430 
431  /* Client authentication hook */
434 
435  /* Trusted procedure hooks */
438 
441 
442  /* Transaction/Sub-transaction callbacks */
445 }
int errcode(int sqlerrcode)
Definition: elog.c:575
static void sepgsql_xact_callback(XactEvent event, void *arg)
Definition: label.c:168
static ClientAuthentication_hook_type next_client_auth_hook
Definition: label.c:45
static bool sepgsql_needs_fmgr_hook(Oid functionId)
Definition: label.c:278
#define ERROR
Definition: elog.h:43
ClientAuthentication_hook_type ClientAuthentication_hook
Definition: auth.c:243
#define ereport(elevel, rest)
Definition: elog.h:122
static void sepgsql_client_auth(Port *port, int status)
Definition: label.c:240
static needs_fmgr_hook_type next_needs_fmgr_hook
Definition: label.c:46
void RegisterSubXactCallback(SubXactCallback callback, void *arg)
Definition: xact.c:3357
PGDLLIMPORT fmgr_hook_type fmgr_hook
Definition: fmgr.c:37
PGDLLIMPORT needs_fmgr_hook_type needs_fmgr_hook
Definition: fmgr.c:36
static void sepgsql_subxact_callback(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
Definition: label.c:207
void RegisterXactCallback(XactCallback callback, void *arg)
Definition: xact.c:3302
static char * client_label_peer
Definition: label.c:62
static void sepgsql_fmgr_hook(FmgrHookEventType event, FmgrInfo *flinfo, Datum *private)
Definition: label.c:321
int errmsg(const char *fmt,...)
Definition: elog.c:797
static fmgr_hook_type next_fmgr_hook
Definition: label.c:47

◆ sepgsql_mcstrans_in()

Datum sepgsql_mcstrans_in ( PG_FUNCTION_ARGS  )

Definition at line 591 of file label.c.

References cstring_to_text(), ereport, errcode(), errmsg(), ERROR, label, PG_CATCH, PG_END_TRY, PG_FUNCTION_INFO_V1(), PG_GETARG_TEXT_PP, PG_RE_THROW, PG_RETURN_TEXT_P, PG_TRY, pstrdup(), sepgsql_is_enabled(), sepgsql_mcstrans_out(), and text_to_cstring().

Referenced by sepgsql_setcon().

592 {
594  char *raw_label;
595  char *result;
596 
597  if (!sepgsql_is_enabled())
598  ereport(ERROR,
599  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
600  errmsg("sepgsql is not enabled")));
601 
602  if (selinux_trans_to_raw_context(text_to_cstring(label),
603  &raw_label) < 0)
604  ereport(ERROR,
605  (errcode(ERRCODE_INTERNAL_ERROR),
606  errmsg("SELinux: could not translate security label: %m")));
607 
608  PG_TRY();
609  {
610  result = pstrdup(raw_label);
611  }
612  PG_CATCH();
613  {
614  freecon(raw_label);
615  PG_RE_THROW();
616  }
617  PG_END_TRY();
618  freecon(raw_label);
619 
621 }
char * pstrdup(const char *in)
Definition: mcxt.c:1161
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:278
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static char * label
Definition: pg_basebackup.c:84
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:336
#define PG_CATCH()
Definition: elog.h:293
bool sepgsql_is_enabled(void)
Definition: selinux.c:613
text * cstring_to_text(const char *s)
Definition: varlena.c:149
#define PG_RE_THROW()
Definition: elog.h:314
char * text_to_cstring(const text *t)
Definition: varlena.c:182
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:516
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300

◆ sepgsql_mcstrans_out()

Datum sepgsql_mcstrans_out ( PG_FUNCTION_ARGS  )

Definition at line 631 of file label.c.

References cstring_to_text(), ereport, errcode(), errmsg(), ERROR, label, PG_CATCH, PG_END_TRY, PG_GETARG_TEXT_PP, PG_RE_THROW, PG_RETURN_TEXT_P, PG_TRY, pstrdup(), sepgsql_is_enabled(), and text_to_cstring().

Referenced by sepgsql_mcstrans_in().

632 {
634  char *qual_label;
635  char *result;
636 
637  if (!sepgsql_is_enabled())
638  ereport(ERROR,
639  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
640  errmsg("sepgsql is not currently enabled")));
641 
642  if (selinux_raw_to_trans_context(text_to_cstring(label),
643  &qual_label) < 0)
644  ereport(ERROR,
645  (errcode(ERRCODE_INTERNAL_ERROR),
646  errmsg("SELinux: could not translate security label: %m")));
647 
648  PG_TRY();
649  {
650  result = pstrdup(qual_label);
651  }
652  PG_CATCH();
653  {
654  freecon(qual_label);
655  PG_RE_THROW();
656  }
657  PG_END_TRY();
658  freecon(qual_label);
659 
661 }
char * pstrdup(const char *in)
Definition: mcxt.c:1161
int errcode(int sqlerrcode)
Definition: elog.c:575
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:278
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
static char * label
Definition: pg_basebackup.c:84
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:336
#define PG_CATCH()
Definition: elog.h:293
bool sepgsql_is_enabled(void)
Definition: selinux.c:613
text * cstring_to_text(const char *s)
Definition: varlena.c:149
#define PG_RE_THROW()
Definition: elog.h:314
char * text_to_cstring(const text *t)
Definition: varlena.c:182
int errmsg(const char *fmt,...)
Definition: elog.c:797
Definition: c.h:516
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300

◆ sepgsql_needs_fmgr_hook()

static bool sepgsql_needs_fmgr_hook ( Oid  functionId)
static

Definition at line 278 of file label.c.

References ObjectAddress::classId, next_needs_fmgr_hook, SEPG_CLASS_DB_PROCEDURE, SEPG_DB_PROCEDURE__ENTRYPOINT, SEPG_DB_PROCEDURE__EXECUTE, sepgsql_avc_check_perms(), SEPGSQL_AVC_NOAUDIT, and sepgsql_avc_trusted_proc().

Referenced by sepgsql_init_client_label().

279 {
280  ObjectAddress object;
281 
282  if (next_needs_fmgr_hook &&
283  (*next_needs_fmgr_hook) (functionId))
284  return true;
285 
286  /*
287  * SELinux needs the function to be called via security_definer wrapper,
288  * if this invocation will take a domain-transition. We call these
289  * functions as trusted-procedure, if the security policy has a rule that
290  * switches security label of the client on execution.
291  */
292  if (sepgsql_avc_trusted_proc(functionId) != NULL)
293  return true;
294 
295  /*
296  * Even if not a trusted-procedure, this function should not be inlined
297  * unless the client has db_procedure:{execute} permission. Please note
298  * that it shall be actually failed later because of same reason with
299  * ACL_EXECUTE.
300  */
301  object.classId = ProcedureRelationId;
302  object.objectId = functionId;
303  object.objectSubId = 0;
304  if (!sepgsql_avc_check_perms(&object,
308  SEPGSQL_AVC_NOAUDIT, false))
309  return true;
310 
311  return false;
312 }
#define SEPG_DB_PROCEDURE__EXECUTE
Definition: sepgsql.h:165
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:428
#define SEPGSQL_AVC_NOAUDIT
Definition: sepgsql.h:255
char * sepgsql_avc_trusted_proc(Oid functionId)
Definition: uavc.c:453
#define SEPG_CLASS_DB_PROCEDURE
Definition: sepgsql.h:48
static needs_fmgr_hook_type next_needs_fmgr_hook
Definition: label.c:46
#define SEPG_DB_PROCEDURE__ENTRYPOINT
Definition: sepgsql.h:166

◆ sepgsql_object_relabel()

void sepgsql_object_relabel ( const ObjectAddress object,
const char *  seclabel 
)

Definition at line 495 of file label.c.

References ObjectAddress::classId, ereport, errcode(), errmsg(), ERROR, getObjectTypeDescription(), ObjectAddress::objectId, ObjectAddress::objectSubId, PG_FUNCTION_INFO_V1(), sepgsql_attribute_relabel(), sepgsql_database_relabel(), sepgsql_getcon(), sepgsql_proc_relabel(), sepgsql_relation_relabel(), and sepgsql_schema_relabel().

Referenced by _PG_init(), and exec_object_restorecon().

496 {
497  /*
498  * validate format of the supplied security label, if it is security
499  * context of selinux.
500  */
501  if (seclabel &&
502  security_check_context_raw((security_context_t) seclabel) < 0)
503  ereport(ERROR,
504  (errcode(ERRCODE_INVALID_NAME),
505  errmsg("SELinux: invalid security label: \"%s\"", seclabel)));
506 
507  /*
508  * Do actual permission checks for each object classes
509  */
510  switch (object->classId)
511  {
512  case DatabaseRelationId:
513  sepgsql_database_relabel(object->objectId, seclabel);
514  break;
515 
516  case NamespaceRelationId:
517  sepgsql_schema_relabel(object->objectId, seclabel);
518  break;
519 
520  case RelationRelationId:
521  if (object->objectSubId == 0)
523  seclabel);
524  else
526  object->objectSubId,
527  seclabel);
528  break;
529 
530  case ProcedureRelationId:
531  sepgsql_proc_relabel(object->objectId, seclabel);
532  break;
533 
534  default:
535  ereport(ERROR,
536  (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
537  errmsg("sepgsql provider does not support labels on %s",
538  getObjectTypeDescription(object))));
539  break;
540  }
541 }
void sepgsql_schema_relabel(Oid namespaceId, const char *seclabel)
Definition: schema.c:144
char * getObjectTypeDescription(const ObjectAddress *object)
int errcode(int sqlerrcode)
Definition: elog.c:575
void sepgsql_database_relabel(Oid databaseId, const char *seclabel)
Definition: database.c:188
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
void sepgsql_relation_relabel(Oid relOid, const char *seclabel)
Definition: relation.c:526
void sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum, const char *seclabel)
Definition: relation.c:167
void sepgsql_proc_relabel(Oid functionId, const char *seclabel)
Definition: proc.c:200
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ sepgsql_restorecon()

Datum sepgsql_restorecon ( PG_FUNCTION_ARGS  )

Definition at line 900 of file label.c.

References ereport, errcode(), errmsg(), ERROR, exec_object_restorecon(), PG_ARGISNULL, PG_CATCH, PG_END_TRY, PG_GETARG_DATUM, PG_RE_THROW, PG_RETURN_BOOL, PG_TRY, sepgsql_is_enabled(), superuser(), and TextDatumGetCString.

Referenced by exec_object_restorecon().

901 {
902  struct selabel_handle *sehnd;
903  struct selinux_opt seopts;
904 
905  /*
906  * SELinux has to be enabled on the running platform.
907  */
908  if (!sepgsql_is_enabled())
909  ereport(ERROR,
910  (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
911  errmsg("sepgsql is not currently enabled")));
912 
913  /*
914  * Check DAC permission. Only superuser can set up initial security
915  * labels, like root-user in filesystems
916  */
917  if (!superuser())
918  ereport(ERROR,
919  (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
920  errmsg("SELinux: must be superuser to restore initial contexts")));
921 
922  /*
923  * Open selabel_lookup(3) stuff. It provides a set of mapping between an
924  * initial security label and object class/name due to the system setting.
925  */
926  if (PG_ARGISNULL(0))
927  {
928  seopts.type = SELABEL_OPT_UNUSED;
929  seopts.value = NULL;
930  }
931  else
932  {
933  seopts.type = SELABEL_OPT_PATH;
934  seopts.value = TextDatumGetCString(PG_GETARG_DATUM(0));
935  }
936  sehnd = selabel_open(SELABEL_CTX_DB, &seopts, 1);
937  if (!sehnd)
938  ereport(ERROR,
939  (errcode(ERRCODE_INTERNAL_ERROR),
940  errmsg("SELinux: failed to initialize labeling handle: %m")));
941  PG_TRY();
942  {
943  exec_object_restorecon(sehnd, DatabaseRelationId);
944  exec_object_restorecon(sehnd, NamespaceRelationId);
945  exec_object_restorecon(sehnd, RelationRelationId);
946  exec_object_restorecon(sehnd, AttributeRelationId);
947  exec_object_restorecon(sehnd, ProcedureRelationId);
948  }
949  PG_CATCH();
950  {
951  selabel_close(sehnd);
952  PG_RE_THROW();
953  }
954  PG_END_TRY();
955 
956  selabel_close(sehnd);
957 
958  PG_RETURN_BOOL(true);
959 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:238
static void exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
Definition: label.c:716
int errcode(int sqlerrcode)
Definition: elog.c:575
bool superuser(void)
Definition: superuser.c:47
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
#define TextDatumGetCString(d)
Definition: builtins.h:96
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
#define PG_CATCH()
Definition: elog.h:293
bool sepgsql_is_enabled(void)
Definition: selinux.c:613
#define PG_ARGISNULL(n)
Definition: fmgr.h:179
#define PG_RE_THROW()
Definition: elog.h:314
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define PG_TRY()
Definition: elog.h:284
#define PG_END_TRY()
Definition: elog.h:300

◆ sepgsql_set_client_label()

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(), 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().

115 {
116  const char *tcontext;
117  MemoryContext oldcxt;
118  pending_label *plabel;
119 
120  /* Reset to the initial client label, if NULL */
121  if (!new_label)
122  tcontext = client_label_peer;
123  else
124  {
125  if (security_check_context_raw((security_context_t) new_label) < 0)
126  ereport(ERROR,
127  (errcode(ERRCODE_INVALID_NAME),
128  errmsg("SELinux: invalid security label: \"%s\"",
129  new_label)));
130  tcontext = new_label;
131  }
132 
133  /* Check process:{setcurrent} permission. */
137  NULL,
138  true);
139  /* Check process:{dyntransition} permission. */
143  NULL,
144  true);
145 
146  /*
147  * Append the supplied new_label on the pending list until the current
148  * transaction is committed.
149  */
151 
152  plabel = palloc0(sizeof(pending_label));
153  plabel->subid = GetCurrentSubTransactionId();
154  if (new_label)
155  plabel->label = pstrdup(new_label);
157 
158  MemoryContextSwitchTo(oldcxt);
159 }
bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:346
#define SEPG_PROCESS__DYNTRANSITION
Definition: sepgsql.h:60
char * pstrdup(const char *in)
Definition: mcxt.c:1161
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition: palloc.h:109
MemoryContext CurTransactionContext
Definition: mcxt.c:50
int errcode(int sqlerrcode)
Definition: elog.c:575
#define SEPG_CLASS_PROCESS
Definition: sepgsql.h:36
#define ERROR
Definition: elog.h:43
#define ereport(elevel, rest)
Definition: elog.h:122
List * lappend(List *list, void *datum)
Definition: list.c:128
char * label
Definition: label.c:72
void * palloc0(Size size)
Definition: mcxt.c:955
static List * client_label_pending
Definition: label.c:63
SubTransactionId subid
Definition: label.c:71
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:641
static char * client_label_peer
Definition: label.c:62
char * sepgsql_get_client_label(void)
Definition: label.c:83
#define SEPG_PROCESS__SETCURRENT
Definition: sepgsql.h:61
int errmsg(const char *fmt,...)
Definition: elog.c:797

◆ sepgsql_setcon()

Datum sepgsql_setcon ( PG_FUNCTION_ARGS  )

Definition at line 569 of file label.c.

References PG_ARGISNULL, PG_FUNCTION_INFO_V1(), PG_GETARG_DATUM, PG_RETURN_BOOL, sepgsql_mcstrans_in(), sepgsql_set_client_label(), and TextDatumGetCString.

Referenced by sepgsql_getcon().

570 {
571  const char *new_label;
572 
573  if (PG_ARGISNULL(0))
574  new_label = NULL;
575  else
576  new_label = TextDatumGetCString(PG_GETARG_DATUM(0));
577 
578  sepgsql_set_client_label(new_label);
579 
580  PG_RETURN_BOOL(true);
581 }
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:238
#define TextDatumGetCString(d)
Definition: builtins.h:96
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:324
#define PG_ARGISNULL(n)
Definition: fmgr.h:179
static void sepgsql_set_client_label(const char *new_label)
Definition: label.c:114

◆ sepgsql_subxact_callback()

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, next, pending_label::subid, and SUBXACT_EVENT_ABORT_SUB.

Referenced by sepgsql_init_client_label().

209 {
210  ListCell *cell;
211  ListCell *prev;
212  ListCell *next;
213 
214  if (event == SUBXACT_EVENT_ABORT_SUB)
215  {
216  prev = NULL;
217  for (cell = list_head(client_label_pending); cell; cell = next)
218  {
219  pending_label *plabel = lfirst(cell);
220 
221  next = lnext(cell);
222 
223  if (plabel->subid == mySubid)
225  = list_delete_cell(client_label_pending, cell, prev);
226  else
227  prev = cell;
228  }
229  }
230 }
static int32 next
Definition: blutils.c:211
static ListCell * list_head(const List *l)
Definition: pg_list.h:77
#define lnext(lc)
Definition: pg_list.h:105
List * list_delete_cell(List *list, ListCell *cell, ListCell *prev)
Definition: list.c:528
static List * client_label_pending
Definition: label.c:63
SubTransactionId subid
Definition: label.c:71
#define lfirst(lc)
Definition: pg_list.h:106

◆ sepgsql_xact_callback()

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().

169 {
170  if (event == XACT_EVENT_COMMIT)
171  {
172  if (client_label_pending != NIL)
173  {
175  char *new_label;
176 
177  if (plabel->label)
179  plabel->label);
180  else
181  new_label = NULL;
182 
185 
186  client_label_committed = new_label;
187 
188  /*
189  * XXX - Note that items of client_label_pending are allocated on
190  * CurTransactionContext, thus, all acquired memory region shall
191  * be released implicitly.
192  */
194  }
195  }
196  else if (event == XACT_EVENT_ABORT)
198 }
#define NIL
Definition: pg_list.h:69
static char * client_label_committed
Definition: label.c:65
#define llast(l)
Definition: pg_list.h:131
void pfree(void *pointer)
Definition: mcxt.c:1031
MemoryContext TopMemoryContext
Definition: mcxt.c:44
char * label
Definition: label.c:72
static List * client_label_pending
Definition: label.c:63
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1148

Variable Documentation

◆ client_label_committed

char* client_label_committed = NULL
static

Definition at line 65 of file label.c.

Referenced by sepgsql_get_client_label(), and sepgsql_xact_callback().

◆ client_label_func

char* client_label_func = NULL
static

Definition at line 67 of file label.c.

Referenced by sepgsql_fmgr_hook(), and sepgsql_get_client_label().

◆ client_label_peer

char* client_label_peer = NULL
static

◆ client_label_pending

List* client_label_pending = NIL
static

Definition at line 63 of file label.c.

◆ next_client_auth_hook

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().

◆ next_fmgr_hook

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().

◆ next_needs_fmgr_hook

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().