00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011 #include "postgres.h"
00012
00013 #include "access/heapam.h"
00014 #include "access/htup_details.h"
00015 #include "access/genam.h"
00016 #include "access/xact.h"
00017 #include "catalog/catalog.h"
00018 #include "catalog/dependency.h"
00019 #include "catalog/indexing.h"
00020 #include "catalog/pg_attribute.h"
00021 #include "catalog/pg_class.h"
00022 #include "catalog/pg_database.h"
00023 #include "catalog/pg_namespace.h"
00024 #include "catalog/pg_proc.h"
00025 #include "commands/dbcommands.h"
00026 #include "commands/seclabel.h"
00027 #include "libpq/auth.h"
00028 #include "libpq/libpq-be.h"
00029 #include "miscadmin.h"
00030 #include "utils/builtins.h"
00031 #include "utils/fmgroids.h"
00032 #include "utils/guc.h"
00033 #include "utils/lsyscache.h"
00034 #include "utils/memutils.h"
00035 #include "utils/rel.h"
00036 #include "utils/tqual.h"
00037
00038 #include "sepgsql.h"
00039
00040 #include <selinux/label.h>
00041
00042
00043
00044
00045 static ClientAuthentication_hook_type next_client_auth_hook = NULL;
00046 static needs_fmgr_hook_type next_needs_fmgr_hook = NULL;
00047 static fmgr_hook_type next_fmgr_hook = NULL;
00048
00049
00050
00051
00052
00053
00054
00055
00056
00057
00058
00059
00060
00061
00062 static char *client_label_peer = NULL;
00063 static List *client_label_pending = NIL;
00064
00065 static char *client_label_committed = NULL;
00066
00067 static char *client_label_func = NULL;
00068
00069 typedef struct
00070 {
00071 SubTransactionId subid;
00072 char *label;
00073 } pending_label;
00074
00075
00076
00077
00078
00079
00080
00081
00082 char *
00083 sepgsql_get_client_label(void)
00084 {
00085
00086 if (client_label_func)
00087 return client_label_func;
00088
00089
00090 if (client_label_pending)
00091 {
00092 pending_label *plabel = llast(client_label_pending);
00093
00094 if (plabel->label)
00095 return plabel->label;
00096 }
00097 else if (client_label_committed)
00098 return client_label_committed;
00099
00100
00101 Assert(client_label_peer != NULL);
00102 return client_label_peer;
00103 }
00104
00105
00106
00107
00108
00109
00110
00111
00112
00113 static void
00114 sepgsql_set_client_label(const char *new_label)
00115 {
00116 const char *tcontext;
00117 MemoryContext oldcxt;
00118 pending_label *plabel;
00119
00120
00121 if (!new_label)
00122 tcontext = client_label_peer;
00123 else
00124 {
00125 if (security_check_context_raw((security_context_t) new_label) < 0)
00126 ereport(ERROR,
00127 (errcode(ERRCODE_INVALID_NAME),
00128 errmsg("SELinux: invalid security label: \"%s\"",
00129 new_label)));
00130 tcontext = new_label;
00131 }
00132
00133
00134 sepgsql_avc_check_perms_label(sepgsql_get_client_label(),
00135 SEPG_CLASS_PROCESS,
00136 SEPG_PROCESS__SETCURRENT,
00137 NULL,
00138 true);
00139
00140 sepgsql_avc_check_perms_label(tcontext,
00141 SEPG_CLASS_PROCESS,
00142 SEPG_PROCESS__DYNTRANSITION,
00143 NULL,
00144 true);
00145
00146
00147
00148
00149
00150 oldcxt = MemoryContextSwitchTo(CurTransactionContext);
00151
00152 plabel = palloc0(sizeof(pending_label));
00153 plabel->subid = GetCurrentSubTransactionId();
00154 if (new_label)
00155 plabel->label = pstrdup(new_label);
00156 client_label_pending = lappend(client_label_pending, plabel);
00157
00158 MemoryContextSwitchTo(oldcxt);
00159 }
00160
00161
00162
00163
00164
00165
00166
00167 static void
00168 sepgsql_xact_callback(XactEvent event, void *arg)
00169 {
00170 if (event == XACT_EVENT_COMMIT)
00171 {
00172 if (client_label_pending != NIL)
00173 {
00174 pending_label *plabel = llast(client_label_pending);
00175 char *new_label;
00176
00177 if (plabel->label)
00178 new_label = MemoryContextStrdup(TopMemoryContext,
00179 plabel->label);
00180 else
00181 new_label = NULL;
00182
00183 if (client_label_committed)
00184 pfree(client_label_committed);
00185
00186 client_label_committed = new_label;
00187
00188
00189
00190
00191
00192
00193 client_label_pending = NIL;
00194 }
00195 }
00196 else if (event == XACT_EVENT_ABORT)
00197 client_label_pending = NIL;
00198 }
00199
00200
00201
00202
00203
00204
00205
00206 static void
00207 sepgsql_subxact_callback(SubXactEvent event, SubTransactionId mySubid,
00208 SubTransactionId parentSubid, void *arg)
00209 {
00210 ListCell *cell;
00211 ListCell *prev;
00212 ListCell *next;
00213
00214 if (event == SUBXACT_EVENT_ABORT_SUB)
00215 {
00216 prev = NULL;
00217 for (cell = list_head(client_label_pending); cell; cell = next)
00218 {
00219 pending_label *plabel = lfirst(cell);
00220
00221 next = lnext(cell);
00222
00223 if (plabel->subid == mySubid)
00224 client_label_pending
00225 = list_delete_cell(client_label_pending, cell, prev);
00226 else
00227 prev = cell;
00228 }
00229 }
00230 }
00231
00232
00233
00234
00235
00236
00237
00238
00239 static void
00240 sepgsql_client_auth(Port *port, int status)
00241 {
00242 if (next_client_auth_hook)
00243 (*next_client_auth_hook) (port, status);
00244
00245
00246
00247
00248
00249 if (status != STATUS_OK)
00250 return;
00251
00252
00253
00254
00255 if (getpeercon_raw(port->sock, &client_label_peer) < 0)
00256 ereport(FATAL,
00257 (errcode(ERRCODE_INTERNAL_ERROR),
00258 errmsg("SELinux: unable to get peer label: %m")));
00259
00260
00261
00262
00263
00264 if (sepgsql_get_permissive())
00265 sepgsql_set_mode(SEPGSQL_MODE_PERMISSIVE);
00266 else
00267 sepgsql_set_mode(SEPGSQL_MODE_DEFAULT);
00268 }
00269
00270
00271
00272
00273
00274
00275
00276
00277 static bool
00278 sepgsql_needs_fmgr_hook(Oid functionId)
00279 {
00280 ObjectAddress object;
00281
00282 if (next_needs_fmgr_hook &&
00283 (*next_needs_fmgr_hook) (functionId))
00284 return true;
00285
00286
00287
00288
00289
00290
00291
00292 if (sepgsql_avc_trusted_proc(functionId) != NULL)
00293 return true;
00294
00295
00296
00297
00298
00299
00300
00301 object.classId = ProcedureRelationId;
00302 object.objectId = functionId;
00303 object.objectSubId = 0;
00304 if (!sepgsql_avc_check_perms(&object,
00305 SEPG_CLASS_DB_PROCEDURE,
00306 SEPG_DB_PROCEDURE__EXECUTE |
00307 SEPG_DB_PROCEDURE__ENTRYPOINT,
00308 SEPGSQL_AVC_NOAUDIT, false))
00309 return true;
00310
00311 return false;
00312 }
00313
00314
00315
00316
00317
00318
00319
00320 static void
00321 sepgsql_fmgr_hook(FmgrHookEventType event,
00322 FmgrInfo *flinfo, Datum *private)
00323 {
00324 struct
00325 {
00326 char *old_label;
00327 char *new_label;
00328 Datum next_private;
00329 } *stack;
00330
00331 switch (event)
00332 {
00333 case FHET_START:
00334 stack = (void *) DatumGetPointer(*private);
00335 if (!stack)
00336 {
00337 MemoryContext oldcxt;
00338
00339 oldcxt = MemoryContextSwitchTo(flinfo->fn_mcxt);
00340 stack = palloc(sizeof(*stack));
00341 stack->old_label = NULL;
00342 stack->new_label = sepgsql_avc_trusted_proc(flinfo->fn_oid);
00343 stack->next_private = 0;
00344
00345 MemoryContextSwitchTo(oldcxt);
00346
00347
00348
00349
00350
00351
00352
00353
00354
00355
00356
00357
00358 if (stack->new_label)
00359 {
00360 ObjectAddress object;
00361
00362 object.classId = ProcedureRelationId;
00363 object.objectId = flinfo->fn_oid;
00364 object.objectSubId = 0;
00365 sepgsql_avc_check_perms(&object,
00366 SEPG_CLASS_DB_PROCEDURE,
00367 SEPG_DB_PROCEDURE__ENTRYPOINT,
00368 getObjectDescription(&object),
00369 true);
00370
00371 sepgsql_avc_check_perms_label(stack->new_label,
00372 SEPG_CLASS_PROCESS,
00373 SEPG_PROCESS__TRANSITION,
00374 NULL, true);
00375 }
00376 *private = PointerGetDatum(stack);
00377 }
00378 Assert(!stack->old_label);
00379 if (stack->new_label)
00380 {
00381 stack->old_label = client_label_func;
00382 client_label_func = stack->new_label;
00383 }
00384 if (next_fmgr_hook)
00385 (*next_fmgr_hook) (event, flinfo, &stack->next_private);
00386 break;
00387
00388 case FHET_END:
00389 case FHET_ABORT:
00390 stack = (void *) DatumGetPointer(*private);
00391
00392 if (next_fmgr_hook)
00393 (*next_fmgr_hook) (event, flinfo, &stack->next_private);
00394
00395 if (stack->new_label)
00396 {
00397 client_label_func = stack->old_label;
00398 stack->old_label = NULL;
00399 }
00400 break;
00401
00402 default:
00403 elog(ERROR, "unexpected event type: %d", (int) event);
00404 break;
00405 }
00406 }
00407
00408
00409
00410
00411
00412
00413
00414 void
00415 sepgsql_init_client_label(void)
00416 {
00417
00418
00419
00420
00421
00422
00423
00424
00425
00426
00427 if (getcon_raw(&client_label_peer) < 0)
00428 ereport(ERROR,
00429 (errcode(ERRCODE_INTERNAL_ERROR),
00430 errmsg("SELinux: failed to get server security label: %m")));
00431
00432
00433 next_client_auth_hook = ClientAuthentication_hook;
00434 ClientAuthentication_hook = sepgsql_client_auth;
00435
00436
00437 next_needs_fmgr_hook = needs_fmgr_hook;
00438 needs_fmgr_hook = sepgsql_needs_fmgr_hook;
00439
00440 next_fmgr_hook = fmgr_hook;
00441 fmgr_hook = sepgsql_fmgr_hook;
00442
00443
00444 RegisterXactCallback(sepgsql_xact_callback, NULL);
00445 RegisterSubXactCallback(sepgsql_subxact_callback, NULL);
00446 }
00447
00448
00449
00450
00451
00452
00453
00454
00455 char *
00456 sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
00457 {
00458 ObjectAddress object;
00459 char *label;
00460
00461 object.classId = classId;
00462 object.objectId = objectId;
00463 object.objectSubId = subId;
00464
00465 label = GetSecurityLabel(&object, SEPGSQL_LABEL_TAG);
00466 if (!label || security_check_context_raw((security_context_t) label))
00467 {
00468 security_context_t unlabeled;
00469
00470 if (security_get_initial_context_raw("unlabeled", &unlabeled) < 0)
00471 ereport(ERROR,
00472 (errcode(ERRCODE_INTERNAL_ERROR),
00473 errmsg("SELinux: failed to get initial security label: %m")));
00474 PG_TRY();
00475 {
00476 label = pstrdup(unlabeled);
00477 }
00478 PG_CATCH();
00479 {
00480 freecon(unlabeled);
00481 PG_RE_THROW();
00482 }
00483 PG_END_TRY();
00484
00485 freecon(unlabeled);
00486 }
00487 return label;
00488 }
00489
00490
00491
00492
00493
00494
00495 void
00496 sepgsql_object_relabel(const ObjectAddress *object, const char *seclabel)
00497 {
00498
00499
00500
00501
00502 if (seclabel &&
00503 security_check_context_raw((security_context_t) seclabel) < 0)
00504 ereport(ERROR,
00505 (errcode(ERRCODE_INVALID_NAME),
00506 errmsg("SELinux: invalid security label: \"%s\"", seclabel)));
00507
00508
00509
00510
00511 switch (object->classId)
00512 {
00513 case DatabaseRelationId:
00514 sepgsql_database_relabel(object->objectId, seclabel);
00515 break;
00516
00517 case NamespaceRelationId:
00518 sepgsql_schema_relabel(object->objectId, seclabel);
00519 break;
00520
00521 case RelationRelationId:
00522 if (object->objectSubId == 0)
00523 sepgsql_relation_relabel(object->objectId,
00524 seclabel);
00525 else
00526 sepgsql_attribute_relabel(object->objectId,
00527 object->objectSubId,
00528 seclabel);
00529 break;
00530
00531 case ProcedureRelationId:
00532 sepgsql_proc_relabel(object->objectId, seclabel);
00533 break;
00534
00535 default:
00536 elog(ERROR, "unsupported object type: %u", object->classId);
00537 break;
00538 }
00539 }
00540
00541
00542
00543
00544
00545
00546 PG_FUNCTION_INFO_V1(sepgsql_getcon);
00547 Datum
00548 sepgsql_getcon(PG_FUNCTION_ARGS)
00549 {
00550 char *client_label;
00551
00552 if (!sepgsql_is_enabled())
00553 PG_RETURN_NULL();
00554
00555 client_label = sepgsql_get_client_label();
00556
00557 PG_RETURN_TEXT_P(cstring_to_text(client_label));
00558 }
00559
00560
00561
00562
00563
00564
00565 PG_FUNCTION_INFO_V1(sepgsql_setcon);
00566 Datum
00567 sepgsql_setcon(PG_FUNCTION_ARGS)
00568 {
00569 const char *new_label;
00570
00571 if (PG_ARGISNULL(0))
00572 new_label = NULL;
00573 else
00574 new_label = TextDatumGetCString(PG_GETARG_DATUM(0));
00575
00576 sepgsql_set_client_label(new_label);
00577
00578 PG_RETURN_BOOL(true);
00579 }
00580
00581
00582
00583
00584
00585
00586
00587 PG_FUNCTION_INFO_V1(sepgsql_mcstrans_in);
00588 Datum
00589 sepgsql_mcstrans_in(PG_FUNCTION_ARGS)
00590 {
00591 text *label = PG_GETARG_TEXT_P(0);
00592 char *raw_label;
00593 char *result;
00594
00595 if (!sepgsql_is_enabled())
00596 ereport(ERROR,
00597 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
00598 errmsg("sepgsql is not enabled")));
00599
00600 if (selinux_trans_to_raw_context(text_to_cstring(label),
00601 &raw_label) < 0)
00602 ereport(ERROR,
00603 (errcode(ERRCODE_INTERNAL_ERROR),
00604 errmsg("SELinux: could not translate security label: %m")));
00605
00606 PG_TRY();
00607 {
00608 result = pstrdup(raw_label);
00609 }
00610 PG_CATCH();
00611 {
00612 freecon(raw_label);
00613 PG_RE_THROW();
00614 }
00615 PG_END_TRY();
00616 freecon(raw_label);
00617
00618 PG_RETURN_TEXT_P(cstring_to_text(result));
00619 }
00620
00621
00622
00623
00624
00625
00626
00627 PG_FUNCTION_INFO_V1(sepgsql_mcstrans_out);
00628 Datum
00629 sepgsql_mcstrans_out(PG_FUNCTION_ARGS)
00630 {
00631 text *label = PG_GETARG_TEXT_P(0);
00632 char *qual_label;
00633 char *result;
00634
00635 if (!sepgsql_is_enabled())
00636 ereport(ERROR,
00637 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
00638 errmsg("sepgsql is not currently enabled")));
00639
00640 if (selinux_raw_to_trans_context(text_to_cstring(label),
00641 &qual_label) < 0)
00642 ereport(ERROR,
00643 (errcode(ERRCODE_INTERNAL_ERROR),
00644 errmsg("SELinux: could not translate security label: %m")));
00645
00646 PG_TRY();
00647 {
00648 result = pstrdup(qual_label);
00649 }
00650 PG_CATCH();
00651 {
00652 freecon(qual_label);
00653 PG_RE_THROW();
00654 }
00655 PG_END_TRY();
00656 freecon(qual_label);
00657
00658 PG_RETURN_TEXT_P(cstring_to_text(result));
00659 }
00660
00661
00662
00663
00664
00665
00666 static char *
00667 quote_object_name(const char *src1, const char *src2,
00668 const char *src3, const char *src4)
00669 {
00670 StringInfoData result;
00671 const char *temp;
00672
00673 initStringInfo(&result);
00674
00675 if (src1)
00676 {
00677 temp = quote_identifier(src1);
00678 appendStringInfo(&result, "%s", temp);
00679 if (src1 != temp)
00680 pfree((void *) temp);
00681 }
00682 if (src2)
00683 {
00684 temp = quote_identifier(src2);
00685 appendStringInfo(&result, ".%s", temp);
00686 if (src2 != temp)
00687 pfree((void *) temp);
00688 }
00689 if (src3)
00690 {
00691 temp = quote_identifier(src3);
00692 appendStringInfo(&result, ".%s", temp);
00693 if (src3 != temp)
00694 pfree((void *) temp);
00695 }
00696 if (src4)
00697 {
00698 temp = quote_identifier(src4);
00699 appendStringInfo(&result, ".%s", temp);
00700 if (src4 != temp)
00701 pfree((void *) temp);
00702 }
00703 return result.data;
00704 }
00705
00706
00707
00708
00709
00710
00711
00712
00713 static void
00714 exec_object_restorecon(struct selabel_handle * sehnd, Oid catalogId)
00715 {
00716 Relation rel;
00717 SysScanDesc sscan;
00718 HeapTuple tuple;
00719 char *database_name = get_database_name(MyDatabaseId);
00720 char *namespace_name;
00721 Oid namespace_id;
00722 char *relation_name;
00723
00724
00725
00726
00727
00728 rel = heap_open(catalogId, AccessShareLock);
00729
00730 sscan = systable_beginscan(rel, InvalidOid, false,
00731 SnapshotNow, 0, NULL);
00732 while (HeapTupleIsValid(tuple = systable_getnext(sscan)))
00733 {
00734 Form_pg_database datForm;
00735 Form_pg_namespace nspForm;
00736 Form_pg_class relForm;
00737 Form_pg_attribute attForm;
00738 Form_pg_proc proForm;
00739 char *objname;
00740 int objtype = 1234;
00741 ObjectAddress object;
00742 security_context_t context;
00743
00744
00745
00746
00747
00748 switch (catalogId)
00749 {
00750 case DatabaseRelationId:
00751 datForm = (Form_pg_database) GETSTRUCT(tuple);
00752
00753 objtype = SELABEL_DB_DATABASE;
00754
00755 objname = quote_object_name(NameStr(datForm->datname),
00756 NULL, NULL, NULL);
00757
00758 object.classId = DatabaseRelationId;
00759 object.objectId = HeapTupleGetOid(tuple);
00760 object.objectSubId = 0;
00761 break;
00762
00763 case NamespaceRelationId:
00764 nspForm = (Form_pg_namespace) GETSTRUCT(tuple);
00765
00766 objtype = SELABEL_DB_SCHEMA;
00767
00768 objname = quote_object_name(database_name,
00769 NameStr(nspForm->nspname),
00770 NULL, NULL);
00771
00772 object.classId = NamespaceRelationId;
00773 object.objectId = HeapTupleGetOid(tuple);
00774 object.objectSubId = 0;
00775 break;
00776
00777 case RelationRelationId:
00778 relForm = (Form_pg_class) GETSTRUCT(tuple);
00779
00780 if (relForm->relkind == RELKIND_RELATION)
00781 objtype = SELABEL_DB_TABLE;
00782 else if (relForm->relkind == RELKIND_SEQUENCE)
00783 objtype = SELABEL_DB_SEQUENCE;
00784 else if (relForm->relkind == RELKIND_VIEW)
00785 objtype = SELABEL_DB_VIEW;
00786 else
00787 continue;
00788
00789 namespace_name = get_namespace_name(relForm->relnamespace);
00790 objname = quote_object_name(database_name,
00791 namespace_name,
00792 NameStr(relForm->relname),
00793 NULL);
00794 pfree(namespace_name);
00795
00796 object.classId = RelationRelationId;
00797 object.objectId = HeapTupleGetOid(tuple);
00798 object.objectSubId = 0;
00799 break;
00800
00801 case AttributeRelationId:
00802 attForm = (Form_pg_attribute) GETSTRUCT(tuple);
00803
00804 if (get_rel_relkind(attForm->attrelid) != RELKIND_RELATION)
00805 continue;
00806
00807 objtype = SELABEL_DB_COLUMN;
00808
00809 namespace_id = get_rel_namespace(attForm->attrelid);
00810 namespace_name = get_namespace_name(namespace_id);
00811 relation_name = get_rel_name(attForm->attrelid);
00812 objname = quote_object_name(database_name,
00813 namespace_name,
00814 relation_name,
00815 NameStr(attForm->attname));
00816 pfree(namespace_name);
00817 pfree(relation_name);
00818
00819 object.classId = RelationRelationId;
00820 object.objectId = attForm->attrelid;
00821 object.objectSubId = attForm->attnum;
00822 break;
00823
00824 case ProcedureRelationId:
00825 proForm = (Form_pg_proc) GETSTRUCT(tuple);
00826
00827 objtype = SELABEL_DB_PROCEDURE;
00828
00829 namespace_name = get_namespace_name(proForm->pronamespace);
00830 objname = quote_object_name(database_name,
00831 namespace_name,
00832 NameStr(proForm->proname),
00833 NULL);
00834 pfree(namespace_name);
00835
00836 object.classId = ProcedureRelationId;
00837 object.objectId = HeapTupleGetOid(tuple);
00838 object.objectSubId = 0;
00839 break;
00840
00841 default:
00842 elog(ERROR, "unexpected catalog id: %u", catalogId);
00843 objname = NULL;
00844 break;
00845 }
00846
00847 if (selabel_lookup_raw(sehnd, &context, objname, objtype) == 0)
00848 {
00849 PG_TRY();
00850 {
00851
00852
00853
00854
00855 sepgsql_object_relabel(&object, context);
00856
00857 SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, context);
00858 }
00859 PG_CATCH();
00860 {
00861 freecon(context);
00862 PG_RE_THROW();
00863 }
00864 PG_END_TRY();
00865 freecon(context);
00866 }
00867 else if (errno == ENOENT)
00868 ereport(WARNING,
00869 (errmsg("SELinux: no initial label assigned for %s (type=%d), skipping",
00870 objname, objtype)));
00871 else
00872 ereport(ERROR,
00873 (errcode(ERRCODE_INTERNAL_ERROR),
00874 errmsg("SELinux: could not determine initial security label for %s (type=%d): %m", objname, objtype)));
00875
00876 pfree(objname);
00877 }
00878 systable_endscan(sscan);
00879
00880 heap_close(rel, NoLock);
00881 }
00882
00883
00884
00885
00886
00887
00888
00889
00890
00891
00892
00893
00894 PG_FUNCTION_INFO_V1(sepgsql_restorecon);
00895 Datum
00896 sepgsql_restorecon(PG_FUNCTION_ARGS)
00897 {
00898 struct selabel_handle *sehnd;
00899 struct selinux_opt seopts;
00900
00901
00902
00903
00904 if (!sepgsql_is_enabled())
00905 ereport(ERROR,
00906 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
00907 errmsg("sepgsql is not currently enabled")));
00908
00909
00910
00911
00912
00913 if (!superuser())
00914 ereport(ERROR,
00915 (errcode(ERRCODE_INSUFFICIENT_PRIVILEGE),
00916 errmsg("SELinux: must be superuser to restore initial contexts")));
00917
00918
00919
00920
00921
00922 if (PG_ARGISNULL(0))
00923 {
00924 seopts.type = SELABEL_OPT_UNUSED;
00925 seopts.value = NULL;
00926 }
00927 else
00928 {
00929 seopts.type = SELABEL_OPT_PATH;
00930 seopts.value = TextDatumGetCString(PG_GETARG_DATUM(0));
00931 }
00932 sehnd = selabel_open(SELABEL_CTX_DB, &seopts, 1);
00933 if (!sehnd)
00934 ereport(ERROR,
00935 (errcode(ERRCODE_INTERNAL_ERROR),
00936 errmsg("SELinux: failed to initialize labeling handle: %m")));
00937 PG_TRY();
00938 {
00939 exec_object_restorecon(sehnd, DatabaseRelationId);
00940 exec_object_restorecon(sehnd, NamespaceRelationId);
00941 exec_object_restorecon(sehnd, RelationRelationId);
00942 exec_object_restorecon(sehnd, AttributeRelationId);
00943 exec_object_restorecon(sehnd, ProcedureRelationId);
00944 }
00945 PG_CATCH();
00946 {
00947 selabel_close(sehnd);
00948 PG_RE_THROW();
00949 }
00950 PG_END_TRY();
00951
00952 selabel_close(sehnd);
00953
00954 PG_RETURN_BOOL(true);
00955 }