PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
label.c
Go to the documentation of this file.
1/* -------------------------------------------------------------------------
2 *
3 * contrib/sepgsql/label.c
4 *
5 * Routines to support SELinux labels (security context)
6 *
7 * Copyright (c) 2010-2024, PostgreSQL Global Development Group
8 *
9 * -------------------------------------------------------------------------
10 */
11#include "postgres.h"
12
13#include <selinux/label.h>
14
15#include "access/genam.h"
16#include "access/htup_details.h"
17#include "access/table.h"
18#include "access/xact.h"
19#include "catalog/catalog.h"
20#include "catalog/dependency.h"
22#include "catalog/pg_class.h"
23#include "catalog/pg_database.h"
25#include "catalog/pg_proc.h"
26#include "commands/dbcommands.h"
27#include "commands/seclabel.h"
28#include "libpq/auth.h"
29#include "libpq/libpq-be.h"
30#include "miscadmin.h"
31#include "sepgsql.h"
32#include "utils/builtins.h"
33#include "utils/fmgroids.h"
34#include "utils/guc.h"
35#include "utils/lsyscache.h"
36#include "utils/memutils.h"
37#include "utils/rel.h"
38
39/*
40 * Saved hook entries (if stacked)
41 */
45
46/*
47 * client_label_*
48 *
49 * security label of the database client. Initially the client security label
50 * is equal to client_label_peer, and can be changed by one or more calls to
51 * sepgsql_setcon(), and also be temporarily overridden during execution of a
52 * trusted-procedure.
53 *
54 * sepgsql_setcon() is a transaction-aware operation; a (sub-)transaction
55 * rollback should also rollback the current client security label. Therefore
56 * we use the list client_label_pending of pending_label to keep track of which
57 * labels were set during the (sub-)transactions.
58 */
59static char *client_label_peer = NULL; /* set by getpeercon(3) */
60static List *client_label_pending = NIL; /* pending list being set by
61 * sepgsql_setcon() */
62static char *client_label_committed = NULL; /* set by sepgsql_setcon(), and
63 * already committed */
64static char *client_label_func = NULL; /* set by trusted procedure */
65
66typedef struct
67{
69 char *label;
71
72/*
73 * sepgsql_get_client_label
74 *
75 * Returns the current security label of the client. All code should use this
76 * routine to get the current label, instead of referring to the client_label_*
77 * variables above.
78 */
79char *
81{
82 /* trusted procedure client label override */
84 return client_label_func;
85
86 /* uncommitted sepgsql_setcon() value */
88 {
90
91 if (plabel->label)
92 return plabel->label;
93 }
95 return client_label_committed; /* set by sepgsql_setcon() committed */
96
97 /* default label */
99 return client_label_peer;
100}
101
102/*
103 * sepgsql_set_client_label
104 *
105 * This routine tries to switch the current security label of the client, and
106 * checks related permissions. The supplied new label shall be added to the
107 * client_label_pending list, then saved at transaction-commit time to ensure
108 * transaction-awareness.
109 */
110static void
111sepgsql_set_client_label(const char *new_label)
112{
113 const char *tcontext;
114 MemoryContext oldcxt;
115 pending_label *plabel;
116
117 /* Reset to the initial client label, if NULL */
118 if (!new_label)
119 tcontext = client_label_peer;
120 else
121 {
122 if (security_check_context_raw(new_label) < 0)
124 (errcode(ERRCODE_INVALID_NAME),
125 errmsg("SELinux: invalid security label: \"%s\"",
126 new_label)));
127 tcontext = new_label;
128 }
129
130 /* Check process:{setcurrent} permission. */
134 NULL,
135 true);
136 /* Check process:{dyntransition} permission. */
140 NULL,
141 true);
142
143 /*
144 * Append the supplied new_label on the pending list until the current
145 * transaction is committed.
146 */
148
149 plabel = palloc0(sizeof(pending_label));
151 if (new_label)
152 plabel->label = pstrdup(new_label);
154
155 MemoryContextSwitchTo(oldcxt);
156}
157
158/*
159 * sepgsql_xact_callback
160 *
161 * A callback routine of transaction commit/abort/prepare. Commit or abort
162 * changes in the client_label_pending list.
163 */
164static void
166{
167 if (event == XACT_EVENT_COMMIT)
168 {
170 {
172 char *new_label;
173
174 if (plabel->label)
176 plabel->label);
177 else
178 new_label = NULL;
179
182
183 client_label_committed = new_label;
184
185 /*
186 * XXX - Note that items of client_label_pending are allocated on
187 * CurTransactionContext, thus, all acquired memory region shall
188 * be released implicitly.
189 */
191 }
192 }
193 else if (event == XACT_EVENT_ABORT)
195}
196
197/*
198 * sepgsql_subxact_callback
199 *
200 * A callback routine of sub-transaction start/abort/commit. Releases all
201 * security labels that are set within the sub-transaction that is aborted.
202 */
203static void
205 SubTransactionId parentSubid, void *arg)
206{
207 ListCell *cell;
208
209 if (event == SUBXACT_EVENT_ABORT_SUB)
210 {
211 foreach(cell, client_label_pending)
212 {
213 pending_label *plabel = lfirst(cell);
214
215 if (plabel->subid == mySubid)
218 }
219 }
220}
221
222/*
223 * sepgsql_client_auth
224 *
225 * Entrypoint of the client authentication hook.
226 * It switches the client label according to getpeercon(), and the current
227 * performing mode according to the GUC setting.
228 */
229static void
231{
233 (*next_client_auth_hook) (port, status);
234
235 /*
236 * In the case when authentication failed, the supplied socket shall be
237 * closed soon, so we don't need to do anything here.
238 */
239 if (status != STATUS_OK)
240 return;
241
242 /*
243 * Getting security label of the peer process using API of libselinux.
244 */
245 if (getpeercon_raw(port->sock, &client_label_peer) < 0)
247 (errcode(ERRCODE_INTERNAL_ERROR),
248 errmsg("SELinux: unable to get peer label: %m")));
249
250 /*
251 * Switch the current performing mode from INTERNAL to either DEFAULT or
252 * PERMISSIVE.
253 */
256 else
258}
259
260/*
261 * sepgsql_needs_fmgr_hook
262 *
263 * It informs the core whether the supplied function is trusted procedure,
264 * or not. If true, sepgsql_fmgr_hook shall be invoked at start, end, and
265 * abort time of function invocation.
266 */
267static bool
269{
270 ObjectAddress object;
271
273 (*next_needs_fmgr_hook) (functionId))
274 return true;
275
276 /*
277 * SELinux needs the function to be called via security_definer wrapper,
278 * if this invocation will take a domain-transition. We call these
279 * functions as trusted-procedure, if the security policy has a rule that
280 * switches security label of the client on execution.
281 */
282 if (sepgsql_avc_trusted_proc(functionId) != NULL)
283 return true;
284
285 /*
286 * Even if not a trusted-procedure, this function should not be inlined
287 * unless the client has db_procedure:{execute} permission. Please note
288 * that it shall be actually failed later because of same reason with
289 * ACL_EXECUTE.
290 */
291 object.classId = ProcedureRelationId;
292 object.objectId = functionId;
293 object.objectSubId = 0;
294 if (!sepgsql_avc_check_perms(&object,
298 SEPGSQL_AVC_NOAUDIT, false))
299 return true;
300
301 return false;
302}
303
304/*
305 * sepgsql_fmgr_hook
306 *
307 * It switches security label of the client on execution of trusted
308 * procedures.
309 */
310static void
312 FmgrInfo *flinfo, Datum *private)
313{
314 struct
315 {
316 char *old_label;
317 char *new_label;
318 Datum next_private;
319 } *stack;
320
321 switch (event)
322 {
323 case FHET_START:
324 stack = (void *) DatumGetPointer(*private);
325 if (!stack)
326 {
327 MemoryContext oldcxt;
328
329 oldcxt = MemoryContextSwitchTo(flinfo->fn_mcxt);
330 stack = palloc(sizeof(*stack));
331 stack->old_label = NULL;
332 stack->new_label = sepgsql_avc_trusted_proc(flinfo->fn_oid);
333 stack->next_private = 0;
334
335 MemoryContextSwitchTo(oldcxt);
336
337 /*
338 * process:transition permission between old and new label,
339 * when user tries to switch security label of the client on
340 * execution of trusted procedure.
341 *
342 * Also, db_procedure:entrypoint permission should be checked
343 * whether this procedure can perform as an entrypoint of the
344 * trusted procedure, or not. Note that db_procedure:execute
345 * permission shall be checked individually.
346 */
347 if (stack->new_label)
348 {
349 ObjectAddress object;
350
351 object.classId = ProcedureRelationId;
352 object.objectId = flinfo->fn_oid;
353 object.objectSubId = 0;
357 getObjectDescription(&object, false),
358 true);
359
360 sepgsql_avc_check_perms_label(stack->new_label,
363 NULL, true);
364 }
365 *private = PointerGetDatum(stack);
366 }
367 Assert(!stack->old_label);
368 if (stack->new_label)
369 {
370 stack->old_label = client_label_func;
371 client_label_func = stack->new_label;
372 }
373 if (next_fmgr_hook)
374 (*next_fmgr_hook) (event, flinfo, &stack->next_private);
375 break;
376
377 case FHET_END:
378 case FHET_ABORT:
379 stack = (void *) DatumGetPointer(*private);
380
381 if (next_fmgr_hook)
382 (*next_fmgr_hook) (event, flinfo, &stack->next_private);
383
384 if (stack->new_label)
385 {
386 client_label_func = stack->old_label;
387 stack->old_label = NULL;
388 }
389 break;
390
391 default:
392 elog(ERROR, "unexpected event type: %d", (int) event);
393 break;
394 }
395}
396
397/*
398 * sepgsql_init_client_label
399 *
400 * Initializes the client security label and sets up related hooks for client
401 * label management.
402 */
403void
405{
406 /*
407 * Set up dummy client label.
408 *
409 * XXX - note that PostgreSQL launches background worker process like
410 * autovacuum without authentication steps. So, we initialize sepgsql_mode
411 * with SEPGSQL_MODE_INTERNAL, and client_label with the security context
412 * of server process. Later, it also launches background of user session.
413 * In this case, the process is always hooked on post-authentication, and
414 * we can initialize the sepgsql_mode and client_label correctly.
415 */
416 if (getcon_raw(&client_label_peer) < 0)
418 (errcode(ERRCODE_INTERNAL_ERROR),
419 errmsg("SELinux: failed to get server security label: %m")));
420
421 /* Client authentication hook */
424
425 /* Trusted procedure hooks */
428
431
432 /* Transaction/Sub-transaction callbacks */
435}
436
437/*
438 * sepgsql_get_label
439 *
440 * It returns a security context of the specified database object.
441 * If unlabeled or incorrectly labeled, the system "unlabeled" label
442 * shall be returned.
443 */
444char *
445sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
446{
447 ObjectAddress object;
448 char *label;
449
450 object.classId = classId;
451 object.objectId = objectId;
452 object.objectSubId = subId;
453
455 if (!label || security_check_context_raw(label))
456 {
457 char *unlabeled;
458
459 if (security_get_initial_context_raw("unlabeled", &unlabeled) < 0)
461 (errcode(ERRCODE_INTERNAL_ERROR),
462 errmsg("SELinux: failed to get initial security label: %m")));
463 PG_TRY();
464 {
465 label = pstrdup(unlabeled);
466 }
467 PG_FINALLY();
468 {
469 freecon(unlabeled);
470 }
471 PG_END_TRY();
472 }
473 return label;
474}
475
476/*
477 * sepgsql_object_relabel
478 *
479 * An entrypoint of SECURITY LABEL statement
480 */
481void
482sepgsql_object_relabel(const ObjectAddress *object, const char *seclabel)
483{
484 /*
485 * validate format of the supplied security label, if it is security
486 * context of selinux.
487 */
488 if (seclabel &&
489 security_check_context_raw(seclabel) < 0)
491 (errcode(ERRCODE_INVALID_NAME),
492 errmsg("SELinux: invalid security label: \"%s\"", seclabel)));
493
494 /*
495 * Do actual permission checks for each object classes
496 */
497 switch (object->classId)
498 {
499 case DatabaseRelationId:
500 sepgsql_database_relabel(object->objectId, seclabel);
501 break;
502
503 case NamespaceRelationId:
504 sepgsql_schema_relabel(object->objectId, seclabel);
505 break;
506
507 case RelationRelationId:
508 if (object->objectSubId == 0)
510 seclabel);
511 else
513 object->objectSubId,
514 seclabel);
515 break;
516
517 case ProcedureRelationId:
518 sepgsql_proc_relabel(object->objectId, seclabel);
519 break;
520
521 default:
523 (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
524 errmsg("sepgsql provider does not support labels on %s",
525 getObjectTypeDescription(object, false))));
526 break;
527 }
528}
529
530/*
531 * TEXT sepgsql_getcon(VOID)
532 *
533 * It returns the security label of the client.
534 */
536Datum
538{
539 char *client_label;
540
541 if (!sepgsql_is_enabled())
543
544 client_label = sepgsql_get_client_label();
545
546 PG_RETURN_TEXT_P(cstring_to_text(client_label));
547}
548
549/*
550 * BOOL sepgsql_setcon(TEXT)
551 *
552 * It switches the security label of the client.
553 */
555Datum
557{
558 const char *new_label;
559
560 if (PG_ARGISNULL(0))
561 new_label = NULL;
562 else
563 new_label = TextDatumGetCString(PG_GETARG_DATUM(0));
564
565 sepgsql_set_client_label(new_label);
566
567 PG_RETURN_BOOL(true);
568}
569
570/*
571 * TEXT sepgsql_mcstrans_in(TEXT)
572 *
573 * It translate the given qualified MLS/MCS range into raw format
574 * when mcstrans daemon is working.
575 */
577Datum
579{
581 char *raw_label;
582 char *result;
583
584 if (!sepgsql_is_enabled())
586 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
587 errmsg("sepgsql is not enabled")));
588
589 if (selinux_trans_to_raw_context(text_to_cstring(label),
590 &raw_label) < 0)
592 (errcode(ERRCODE_INTERNAL_ERROR),
593 errmsg("SELinux: could not translate security label: %m")));
594
595 PG_TRY();
596 {
597 result = pstrdup(raw_label);
598 }
599 PG_FINALLY();
600 {
601 freecon(raw_label);
602 }
603 PG_END_TRY();
604
606}
607
608/*
609 * TEXT sepgsql_mcstrans_out(TEXT)
610 *
611 * It translate the given raw MLS/MCS range into qualified format
612 * when mcstrans daemon is working.
613 */
615Datum
617{
619 char *qual_label;
620 char *result;
621
622 if (!sepgsql_is_enabled())
624 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
625 errmsg("sepgsql is not currently enabled")));
626
627 if (selinux_raw_to_trans_context(text_to_cstring(label),
628 &qual_label) < 0)
630 (errcode(ERRCODE_INTERNAL_ERROR),
631 errmsg("SELinux: could not translate security label: %m")));
632
633 PG_TRY();
634 {
635 result = pstrdup(qual_label);
636 }
637 PG_FINALLY();
638 {
639 freecon(qual_label);
640 }
641 PG_END_TRY();
642
644}
645
646/*
647 * quote_object_name
648 *
649 * Concatenate as many of the given strings as aren't NULL, with dots between.
650 * Quote any of the strings that wouldn't be valid identifiers otherwise.
651 */
652static char *
653quote_object_name(const char *src1, const char *src2,
654 const char *src3, const char *src4)
655{
656 StringInfoData result;
657
658 initStringInfo(&result);
659 if (src1)
661 if (src2)
662 appendStringInfo(&result, ".%s", quote_identifier(src2));
663 if (src3)
664 appendStringInfo(&result, ".%s", quote_identifier(src3));
665 if (src4)
666 appendStringInfo(&result, ".%s", quote_identifier(src4));
667 return result.data;
668}
669
670/*
671 * exec_object_restorecon
672 *
673 * This routine is a helper called by sepgsql_restorecon; it set up
674 * initial security labels of database objects within the supplied
675 * catalog OID.
676 */
677static void
678exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
679{
680 Relation rel;
681 SysScanDesc sscan;
682 HeapTuple tuple;
683 char *database_name = get_database_name(MyDatabaseId);
684 char *namespace_name;
685 Oid namespace_id;
686 char *relation_name;
687
688 /*
689 * Open the target catalog. We don't want to allow writable accesses by
690 * other session during initial labeling.
691 */
692 rel = table_open(catalogId, AccessShareLock);
693
694 sscan = systable_beginscan(rel, InvalidOid, false,
695 NULL, 0, NULL);
696 while (HeapTupleIsValid(tuple = systable_getnext(sscan)))
697 {
698 Form_pg_database datForm;
699 Form_pg_namespace nspForm;
700 Form_pg_class relForm;
701 Form_pg_attribute attForm;
702 Form_pg_proc proForm;
703 char *objname;
704 int objtype = 1234;
705 ObjectAddress object;
706 char *context;
707
708 /*
709 * The way to determine object name depends on object classes. So, any
710 * branches set up `objtype', `objname' and `object' here.
711 */
712 switch (catalogId)
713 {
714 case DatabaseRelationId:
715 datForm = (Form_pg_database) GETSTRUCT(tuple);
716
717 objtype = SELABEL_DB_DATABASE;
718
719 objname = quote_object_name(NameStr(datForm->datname),
720 NULL, NULL, NULL);
721
722 object.classId = DatabaseRelationId;
723 object.objectId = datForm->oid;
724 object.objectSubId = 0;
725 break;
726
727 case NamespaceRelationId:
728 nspForm = (Form_pg_namespace) GETSTRUCT(tuple);
729
730 objtype = SELABEL_DB_SCHEMA;
731
732 objname = quote_object_name(database_name,
733 NameStr(nspForm->nspname),
734 NULL, NULL);
735
736 object.classId = NamespaceRelationId;
737 object.objectId = nspForm->oid;
738 object.objectSubId = 0;
739 break;
740
741 case RelationRelationId:
742 relForm = (Form_pg_class) GETSTRUCT(tuple);
743
744 if (relForm->relkind == RELKIND_RELATION ||
745 relForm->relkind == RELKIND_PARTITIONED_TABLE)
746 objtype = SELABEL_DB_TABLE;
747 else if (relForm->relkind == RELKIND_SEQUENCE)
748 objtype = SELABEL_DB_SEQUENCE;
749 else if (relForm->relkind == RELKIND_VIEW)
750 objtype = SELABEL_DB_VIEW;
751 else
752 continue; /* no need to assign security label */
753
754 namespace_name = get_namespace_name(relForm->relnamespace);
755 objname = quote_object_name(database_name,
756 namespace_name,
757 NameStr(relForm->relname),
758 NULL);
759 pfree(namespace_name);
760
761 object.classId = RelationRelationId;
762 object.objectId = relForm->oid;
763 object.objectSubId = 0;
764 break;
765
766 case AttributeRelationId:
767 attForm = (Form_pg_attribute) GETSTRUCT(tuple);
768
769 if (get_rel_relkind(attForm->attrelid) != RELKIND_RELATION &&
770 get_rel_relkind(attForm->attrelid) != RELKIND_PARTITIONED_TABLE)
771 continue; /* no need to assign security label */
772
773 objtype = SELABEL_DB_COLUMN;
774
775 namespace_id = get_rel_namespace(attForm->attrelid);
776 namespace_name = get_namespace_name(namespace_id);
777 relation_name = get_rel_name(attForm->attrelid);
778 objname = quote_object_name(database_name,
779 namespace_name,
780 relation_name,
781 NameStr(attForm->attname));
782 pfree(namespace_name);
783 pfree(relation_name);
784
785 object.classId = RelationRelationId;
786 object.objectId = attForm->attrelid;
787 object.objectSubId = attForm->attnum;
788 break;
789
790 case ProcedureRelationId:
791 proForm = (Form_pg_proc) GETSTRUCT(tuple);
792
793 objtype = SELABEL_DB_PROCEDURE;
794
795 namespace_name = get_namespace_name(proForm->pronamespace);
796 objname = quote_object_name(database_name,
797 namespace_name,
798 NameStr(proForm->proname),
799 NULL);
800 pfree(namespace_name);
801
802 object.classId = ProcedureRelationId;
803 object.objectId = proForm->oid;
804 object.objectSubId = 0;
805 break;
806
807 default:
808 elog(ERROR, "unexpected catalog id: %u", catalogId);
809 objname = NULL; /* for compiler quiet */
810 break;
811 }
812
813 if (selabel_lookup_raw(sehnd, &context, objname, objtype) == 0)
814 {
815 PG_TRY();
816 {
817 /*
818 * Check SELinux permission to relabel the fetched object,
819 * then do the actual relabeling.
820 */
822
824 }
825 PG_FINALLY();
826 {
827 freecon(context);
828 }
829 PG_END_TRY();
830 }
831 else if (errno == ENOENT)
833 (errmsg("SELinux: no initial label assigned for %s (type=%d), skipping",
834 objname, objtype)));
835 else
837 (errcode(ERRCODE_INTERNAL_ERROR),
838 errmsg("SELinux: could not determine initial security label for %s (type=%d): %m", objname, objtype)));
839
840 pfree(objname);
841 }
842 systable_endscan(sscan);
843
844 table_close(rel, NoLock);
845}
846
847/*
848 * BOOL sepgsql_restorecon(TEXT specfile)
849 *
850 * This function tries to assign initial security labels on all the object
851 * within the current database, according to the system setting.
852 * It is typically invoked by sepgsql-install script just after initdb, to
853 * assign initial security labels.
854 *
855 * If @specfile is not NULL, it uses explicitly specified specfile, instead
856 * of the system default.
857 */
859Datum
861{
862 struct selabel_handle *sehnd;
863 struct selinux_opt seopts;
864
865 /*
866 * SELinux has to be enabled on the running platform.
867 */
868 if (!sepgsql_is_enabled())
870 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
871 errmsg("sepgsql is not currently enabled")));
872
873 /*
874 * Check DAC permission. Only superuser can set up initial security
875 * labels, like root-user in filesystems
876 */
877 if (!superuser())
879 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
880 errmsg("SELinux: must be superuser to restore initial contexts")));
881
882 /*
883 * Open selabel_lookup(3) stuff. It provides a set of mapping between an
884 * initial security label and object class/name due to the system setting.
885 */
886 if (PG_ARGISNULL(0))
887 {
888 seopts.type = SELABEL_OPT_UNUSED;
889 seopts.value = NULL;
890 }
891 else
892 {
893 seopts.type = SELABEL_OPT_PATH;
894 seopts.value = TextDatumGetCString(PG_GETARG_DATUM(0));
895 }
896 sehnd = selabel_open(SELABEL_CTX_DB, &seopts, 1);
897 if (!sehnd)
899 (errcode(ERRCODE_INTERNAL_ERROR),
900 errmsg("SELinux: failed to initialize labeling handle: %m")));
901 PG_TRY();
902 {
903 exec_object_restorecon(sehnd, DatabaseRelationId);
904 exec_object_restorecon(sehnd, NamespaceRelationId);
905 exec_object_restorecon(sehnd, RelationRelationId);
906 exec_object_restorecon(sehnd, AttributeRelationId);
907 exec_object_restorecon(sehnd, ProcedureRelationId);
908 }
909 PG_FINALLY();
910 {
911 selabel_close(sehnd);
912 }
913 PG_END_TRY();
914
915 PG_RETURN_BOOL(true);
916}
ClientAuthentication_hook_type ClientAuthentication_hook
Definition: auth.c:230
void(* ClientAuthentication_hook_type)(Port *, int)
Definition: auth.h:28
#define TextDatumGetCString(d)
Definition: builtins.h:98
#define NameStr(name)
Definition: c.h:700
#define STATUS_OK
Definition: c.h:1123
uint32 SubTransactionId
Definition: c.h:610
#define Assert(condition)
Definition: c.h:812
int32_t int32
Definition: c.h:481
void sepgsql_proc_relabel(Oid functionId, const char *seclabel)
Definition: proc.c:198
void sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum, const char *seclabel)
Definition: relation.c:165
void sepgsql_relation_relabel(Oid relOid, const char *seclabel)
Definition: relation.c:564
void sepgsql_database_relabel(Oid databaseId, const char *seclabel)
Definition: database.c:187
char * get_database_name(Oid dbid)
Definition: dbcommands.c:3187
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define FATAL
Definition: elog.h:41
#define PG_TRY(...)
Definition: elog.h:371
#define WARNING
Definition: elog.h:36
#define PG_END_TRY(...)
Definition: elog.h:396
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
#define PG_FINALLY(...)
Definition: elog.h:388
#define ereport(elevel,...)
Definition: elog.h:149
PGDLLIMPORT needs_fmgr_hook_type needs_fmgr_hook
Definition: fmgr.c:39
PGDLLIMPORT fmgr_hook_type fmgr_hook
Definition: fmgr.c:40
#define PG_GETARG_TEXT_PP(n)
Definition: fmgr.h:309
bool(* needs_fmgr_hook_type)(Oid fn_oid)
Definition: fmgr.h:788
#define PG_ARGISNULL(n)
Definition: fmgr.h:209
#define PG_GETARG_DATUM(n)
Definition: fmgr.h:268
#define PG_RETURN_NULL()
Definition: fmgr.h:345
FmgrHookEventType
Definition: fmgr.h:782
@ FHET_END
Definition: fmgr.h:784
@ FHET_ABORT
Definition: fmgr.h:785
@ FHET_START
Definition: fmgr.h:783
#define PG_RETURN_TEXT_P(x)
Definition: fmgr.h:372
void(* fmgr_hook_type)(FmgrHookEventType event, FmgrInfo *flinfo, Datum *arg)
Definition: fmgr.h:790
#define PG_FUNCTION_ARGS
Definition: fmgr.h:193
#define PG_RETURN_BOOL(x)
Definition: fmgr.h:359
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:606
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:513
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
Oid MyDatabaseId
Definition: globals.c:93
bool sepgsql_get_permissive(void)
Definition: hooks.c:63
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
Datum sepgsql_getcon(PG_FUNCTION_ARGS)
Definition: label.c:537
static fmgr_hook_type next_fmgr_hook
Definition: label.c:44
static void sepgsql_fmgr_hook(FmgrHookEventType event, FmgrInfo *flinfo, Datum *private)
Definition: label.c:311
void sepgsql_init_client_label(void)
Definition: label.c:404
static char * client_label_committed
Definition: label.c:62
static needs_fmgr_hook_type next_needs_fmgr_hook
Definition: label.c:43
static char * quote_object_name(const char *src1, const char *src2, const char *src3, const char *src4)
Definition: label.c:653
Datum sepgsql_mcstrans_out(PG_FUNCTION_ARGS)
Definition: label.c:616
static void exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
Definition: label.c:678
PG_FUNCTION_INFO_V1(sepgsql_getcon)
static char * client_label_peer
Definition: label.c:59
static List * client_label_pending
Definition: label.c:60
char * sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
Definition: label.c:445
void sepgsql_object_relabel(const ObjectAddress *object, const char *seclabel)
Definition: label.c:482
Datum sepgsql_restorecon(PG_FUNCTION_ARGS)
Definition: label.c:860
static void sepgsql_subxact_callback(SubXactEvent event, SubTransactionId mySubid, SubTransactionId parentSubid, void *arg)
Definition: label.c:204
static void sepgsql_client_auth(Port *port, int status)
Definition: label.c:230
static char * client_label_func
Definition: label.c:64
char * sepgsql_get_client_label(void)
Definition: label.c:80
static void sepgsql_xact_callback(XactEvent event, void *arg)
Definition: label.c:165
Datum sepgsql_setcon(PG_FUNCTION_ARGS)
Definition: label.c:556
static ClientAuthentication_hook_type next_client_auth_hook
Definition: label.c:42
Datum sepgsql_mcstrans_in(PG_FUNCTION_ARGS)
Definition: label.c:578
static void sepgsql_set_client_label(const char *new_label)
Definition: label.c:111
static bool sepgsql_needs_fmgr_hook(Oid functionId)
Definition: label.c:268
List * lappend(List *list, void *datum)
Definition: list.c:339
#define NoLock
Definition: lockdefs.h:34
#define AccessShareLock
Definition: lockdefs.h:36
char * get_rel_name(Oid relid)
Definition: lsyscache.c:1928
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:2003
Oid get_rel_namespace(Oid relid)
Definition: lsyscache.c:1952
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3366
char * MemoryContextStrdup(MemoryContext context, const char *string)
Definition: mcxt.c:1683
char * pstrdup(const char *in)
Definition: mcxt.c:1696
void pfree(void *pointer)
Definition: mcxt.c:1521
void * palloc0(Size size)
Definition: mcxt.c:1347
MemoryContext TopMemoryContext
Definition: mcxt.c:149
void * palloc(Size size)
Definition: mcxt.c:1317
MemoryContext CurTransactionContext
Definition: mcxt.c:155
char * getObjectTypeDescription(const ObjectAddress *object, bool missing_ok)
char * getObjectDescription(const ObjectAddress *object, bool missing_ok)
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
void * arg
static char * label
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
FormData_pg_database * Form_pg_database
Definition: pg_database.h:96
#define lfirst(lc)
Definition: pg_list.h:172
#define llast(l)
Definition: pg_list.h:198
#define NIL
Definition: pg_list.h:68
#define foreach_delete_current(lst, var_or_cell)
Definition: pg_list.h:391
FormData_pg_namespace * Form_pg_namespace
Definition: pg_namespace.h:52
FormData_pg_proc * Form_pg_proc
Definition: pg_proc.h:136
static int port
Definition: pg_regress.c:115
static Datum PointerGetDatum(const void *X)
Definition: postgres.h:322
uintptr_t Datum
Definition: postgres.h:64
static Pointer DatumGetPointer(Datum X)
Definition: postgres.h:312
#define InvalidOid
Definition: postgres_ext.h:36
unsigned int Oid
Definition: postgres_ext.h:31
tree context
Definition: radixtree.h:1837
MemoryContextSwitchTo(old_ctx)
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:12870
void sepgsql_schema_relabel(Oid namespaceId, const char *seclabel)
Definition: schema.c:142
void SetSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition: seclabel.c:404
char * GetSecurityLabel(const ObjectAddress *object, const char *provider)
Definition: seclabel.c:272
int sepgsql_set_mode(int new_mode)
Definition: selinux.c:634
bool sepgsql_is_enabled(void)
Definition: selinux.c:616
char * sepgsql_avc_trusted_proc(Oid functionId)
Definition: uavc.c:445
bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:337
#define SEPG_DB_PROCEDURE__EXECUTE
Definition: sepgsql.h:166
#define SEPG_PROCESS__SETCURRENT
Definition: sepgsql.h:61
#define SEPG_PROCESS__TRANSITION
Definition: sepgsql.h:59
#define SEPG_PROCESS__DYNTRANSITION
Definition: sepgsql.h:60
#define SEPG_DB_PROCEDURE__ENTRYPOINT
Definition: sepgsql.h:167
#define SEPG_CLASS_DB_PROCEDURE
Definition: sepgsql.h:48
#define SEPGSQL_AVC_NOAUDIT
Definition: sepgsql.h:250
#define SEPGSQL_LABEL_TAG
Definition: sepgsql.h:23
#define SEPGSQL_MODE_DEFAULT
Definition: sepgsql.h:28
#define SEPG_CLASS_PROCESS
Definition: sepgsql.h:36
#define SEPGSQL_MODE_PERMISSIVE
Definition: sepgsql.h:29
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:420
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:94
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:179
void initStringInfo(StringInfo str)
Definition: stringinfo.c:56
Definition: fmgr.h:57
MemoryContext fn_mcxt
Definition: fmgr.h:65
Oid fn_oid
Definition: fmgr.h:59
Definition: pg_list.h:54
Definition: libpq-be.h:133
SubTransactionId subid
Definition: label.c:68
char * label
Definition: label.c:69
Definition: c.h:641
bool superuser(void)
Definition: superuser.c:46
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40
text * cstring_to_text(const char *s)
Definition: varlena.c:184
char * text_to_cstring(const text *t)
Definition: varlena.c:217
SubTransactionId GetCurrentSubTransactionId(void)
Definition: xact.c:790
void RegisterXactCallback(XactCallback callback, void *arg)
Definition: xact.c:3796
void RegisterSubXactCallback(SubXactCallback callback, void *arg)
Definition: xact.c:3856
SubXactEvent
Definition: xact.h:141
@ SUBXACT_EVENT_ABORT_SUB
Definition: xact.h:144
XactEvent
Definition: xact.h:127
@ XACT_EVENT_COMMIT
Definition: xact.h:128
@ XACT_EVENT_ABORT
Definition: xact.h:130