LCOV - differential code coverage report
Current view: top level - contrib/sepgsql - label.c (source / functions) Coverage Total Hit UBC
Current: Differential Code Coverage 16@8cea358b128 vs 17@8cea358b128 Lines: 0.0 % 317 0 317
Current Date: 2024-04-14 14:21:10 Functions: 0.0 % 22 0 22
Baseline: 16@8cea358b128 Branches: 0.0 % 194 0 194
Baseline Date: 2024-04-14 14:21:09 Line coverage date bins:
Legend: Lines: hit not hit | Branches: + taken - not taken # not executed (240..) days: 0.0 % 317 0 317
Function coverage date bins:
(240..) days: 0.0 % 22 0 22
Branch coverage date bins:
(240..) days: 0.0 % 194 0 194

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  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"
                                 21                 :                : #include "catalog/pg_attribute.h"
                                 22                 :                : #include "catalog/pg_class.h"
                                 23                 :                : #include "catalog/pg_database.h"
                                 24                 :                : #include "catalog/pg_namespace.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                 :                :  */
                                 42                 :                : static ClientAuthentication_hook_type next_client_auth_hook = NULL;
                                 43                 :                : static needs_fmgr_hook_type next_needs_fmgr_hook = NULL;
                                 44                 :                : static fmgr_hook_type next_fmgr_hook = NULL;
                                 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                 :                :  */
                                 59                 :                : static char *client_label_peer = NULL;  /* set by getpeercon(3) */
                                 60                 :                : static List *client_label_pending = NIL;    /* pending list being set by
                                 61                 :                :                                              * sepgsql_setcon() */
                                 62                 :                : static char *client_label_committed = NULL; /* set by sepgsql_setcon(), and
                                 63                 :                :                                              * already committed */
                                 64                 :                : static char *client_label_func = NULL;  /* set by trusted procedure */
                                 65                 :                : 
                                 66                 :                : typedef struct
                                 67                 :                : {
                                 68                 :                :     SubTransactionId subid;
                                 69                 :                :     char       *label;
                                 70                 :                : }           pending_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                 :                :  */
                                 79                 :                : char *
 4830 rhaas@postgresql.org       80                 :UBC           0 : sepgsql_get_client_label(void)
                                 81                 :                : {
                                 82                 :                :     /* trusted procedure client label override */
 4413                            83         [ #  # ]:              0 :     if (client_label_func)
                                 84                 :              0 :         return client_label_func;
                                 85                 :                : 
                                 86                 :                :     /* uncommitted sepgsql_setcon() value */
                                 87         [ #  # ]:              0 :     if (client_label_pending)
                                 88                 :                :     {
 4326 bruce@momjian.us           89                 :              0 :         pending_label *plabel = llast(client_label_pending);
                                 90                 :                : 
 4413 rhaas@postgresql.org       91         [ #  # ]:              0 :         if (plabel->label)
                                 92                 :              0 :             return plabel->label;
                                 93                 :                :     }
                                 94         [ #  # ]:              0 :     else if (client_label_committed)
                                 95                 :              0 :         return client_label_committed;  /* set by sepgsql_setcon() committed */
                                 96                 :                : 
                                 97                 :                :     /* default label */
                                 98         [ #  # ]:              0 :     Assert(client_label_peer != NULL);
                                 99                 :              0 :     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                 :                :  */
                                110                 :                : static void
                                111                 :              0 : sepgsql_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         [ #  # ]:              0 :     if (!new_label)
                                119                 :              0 :         tcontext = client_label_peer;
                                120                 :                :     else
                                121                 :                :     {
 1339 michael@paquier.xyz       122         [ #  # ]:              0 :         if (security_check_context_raw(new_label) < 0)
 4413 rhaas@postgresql.org      123         [ #  # ]:              0 :             ereport(ERROR,
                                124                 :                :                     (errcode(ERRCODE_INVALID_NAME),
                                125                 :                :                      errmsg("SELinux: invalid security label: \"%s\"",
                                126                 :                :                             new_label)));
                                127                 :              0 :         tcontext = new_label;
                                128                 :                :     }
                                129                 :                : 
                                130                 :                :     /* Check process:{setcurrent} permission. */
                                131                 :              0 :     sepgsql_avc_check_perms_label(sepgsql_get_client_label(),
                                132                 :                :                                   SEPG_CLASS_PROCESS,
                                133                 :                :                                   SEPG_PROCESS__SETCURRENT,
                                134                 :                :                                   NULL,
                                135                 :                :                                   true);
                                136                 :                :     /* Check process:{dyntransition} permission. */
                                137                 :              0 :     sepgsql_avc_check_perms_label(tcontext,
                                138                 :                :                                   SEPG_CLASS_PROCESS,
                                139                 :                :                                   SEPG_PROCESS__DYNTRANSITION,
                                140                 :                :                                   NULL,
                                141                 :                :                                   true);
                                142                 :                : 
                                143                 :                :     /*
                                144                 :                :      * Append the supplied new_label on the pending list until the current
                                145                 :                :      * transaction is committed.
                                146                 :                :      */
                                147                 :              0 :     oldcxt = MemoryContextSwitchTo(CurTransactionContext);
                                148                 :                : 
                                149                 :              0 :     plabel = palloc0(sizeof(pending_label));
                                150                 :              0 :     plabel->subid = GetCurrentSubTransactionId();
                                151         [ #  # ]:              0 :     if (new_label)
                                152                 :              0 :         plabel->label = pstrdup(new_label);
                                153                 :              0 :     client_label_pending = lappend(client_label_pending, plabel);
                                154                 :                : 
                                155                 :              0 :     MemoryContextSwitchTo(oldcxt);
                                156                 :              0 : }
                                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                 :                :  */
                                164                 :                : static void
                                165                 :              0 : sepgsql_xact_callback(XactEvent event, void *arg)
                                166                 :                : {
                                167         [ #  # ]:              0 :     if (event == XACT_EVENT_COMMIT)
                                168                 :                :     {
                                169         [ #  # ]:              0 :         if (client_label_pending != NIL)
                                170                 :                :         {
 4326 bruce@momjian.us          171                 :              0 :             pending_label *plabel = llast(client_label_pending);
                                172                 :                :             char       *new_label;
                                173                 :                : 
 4413 rhaas@postgresql.org      174         [ #  # ]:              0 :             if (plabel->label)
                                175                 :              0 :                 new_label = MemoryContextStrdup(TopMemoryContext,
                                176                 :              0 :                                                 plabel->label);
                                177                 :                :             else
                                178                 :              0 :                 new_label = NULL;
                                179                 :                : 
                                180         [ #  # ]:              0 :             if (client_label_committed)
                                181                 :              0 :                 pfree(client_label_committed);
                                182                 :                : 
                                183                 :              0 :             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                 :                :              */
                                190                 :              0 :             client_label_pending = NIL;
                                191                 :                :         }
                                192                 :                :     }
                                193         [ #  # ]:              0 :     else if (event == XACT_EVENT_ABORT)
                                194                 :              0 :         client_label_pending = NIL;
                                195                 :              0 : }
                                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                 :                :  */
                                203                 :                : static void
                                204                 :              0 : sepgsql_subxact_callback(SubXactEvent event, SubTransactionId mySubid,
                                205                 :                :                          SubTransactionId parentSubid, void *arg)
                                206                 :                : {
                                207                 :                :     ListCell   *cell;
                                208                 :                : 
                                209         [ #  # ]:              0 :     if (event == SUBXACT_EVENT_ABORT_SUB)
                                210                 :                :     {
 1735 tgl@sss.pgh.pa.us         211   [ #  #  #  #  :              0 :         foreach(cell, client_label_pending)
                                              #  # ]
                                212                 :                :         {
 4326 bruce@momjian.us          213                 :              0 :             pending_label *plabel = lfirst(cell);
                                214                 :                : 
 4413 rhaas@postgresql.org      215         [ #  # ]:              0 :             if (plabel->subid == mySubid)
                                216                 :                :                 client_label_pending
 1735 tgl@sss.pgh.pa.us         217                 :              0 :                     = foreach_delete_current(client_label_pending, cell);
                                218                 :                :         }
                                219                 :                :     }
 4830 rhaas@postgresql.org      220                 :              0 : }
                                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                 :                :  */
                                229                 :                : static void
 4442                           230                 :              0 : sepgsql_client_auth(Port *port, int status)
                                231                 :                : {
                                232         [ #  # ]:              0 :     if (next_client_auth_hook)
                                233                 :              0 :         (*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         [ #  # ]:              0 :     if (status != STATUS_OK)
                                240                 :              0 :         return;
                                241                 :                : 
                                242                 :                :     /*
                                243                 :                :      * Getting security label of the peer process using API of libselinux.
                                244                 :                :      */
 4413                           245         [ #  # ]:              0 :     if (getpeercon_raw(port->sock, &client_label_peer) < 0)
 4442                           246         [ #  # ]:              0 :         ereport(FATAL,
                                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                 :                :      */
                                254         [ #  # ]:              0 :     if (sepgsql_get_permissive())
                                255                 :              0 :         sepgsql_set_mode(SEPGSQL_MODE_PERMISSIVE);
                                256                 :                :     else
                                257                 :              0 :         sepgsql_set_mode(SEPGSQL_MODE_DEFAULT);
                                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                 :                :  */
                                267                 :                : static bool
                                268                 :              0 : sepgsql_needs_fmgr_hook(Oid functionId)
                                269                 :                : {
                                270                 :                :     ObjectAddress object;
                                271                 :                : 
                                272   [ #  #  #  # ]:              0 :     if (next_needs_fmgr_hook &&
                                273                 :              0 :         (*next_needs_fmgr_hook) (functionId))
                                274                 :              0 :         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         [ #  # ]:              0 :     if (sepgsql_avc_trusted_proc(functionId) != NULL)
                                283                 :              0 :         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                 :              0 :     object.classId = ProcedureRelationId;
                                292                 :              0 :     object.objectId = functionId;
                                293                 :              0 :     object.objectSubId = 0;
                                294         [ #  # ]:              0 :     if (!sepgsql_avc_check_perms(&object,
                                295                 :                :                                  SEPG_CLASS_DB_PROCEDURE,
                                296                 :                :                                  SEPG_DB_PROCEDURE__EXECUTE |
                                297                 :                :                                  SEPG_DB_PROCEDURE__ENTRYPOINT,
                                298                 :                :                                  SEPGSQL_AVC_NOAUDIT, false))
                                299                 :              0 :         return true;
                                300                 :                : 
                                301                 :              0 :     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                 :                :  */
                                310                 :                : static void
                                311                 :              0 : sepgsql_fmgr_hook(FmgrHookEventType event,
                                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      [ #  #  # ]:              0 :     switch (event)
                                322                 :                :     {
                                323                 :              0 :         case FHET_START:
                                324                 :              0 :             stack = (void *) DatumGetPointer(*private);
                                325         [ #  # ]:              0 :             if (!stack)
                                326                 :                :             {
                                327                 :                :                 MemoryContext oldcxt;
                                328                 :                : 
                                329                 :              0 :                 oldcxt = MemoryContextSwitchTo(flinfo->fn_mcxt);
                                330                 :              0 :                 stack = palloc(sizeof(*stack));
                                331                 :              0 :                 stack->old_label = NULL;
                                332                 :              0 :                 stack->new_label = sepgsql_avc_trusted_proc(flinfo->fn_oid);
                                333                 :              0 :                 stack->next_private = 0;
                                334                 :                : 
                                335                 :              0 :                 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         [ #  # ]:              0 :                 if (stack->new_label)
                                348                 :                :                 {
                                349                 :                :                     ObjectAddress object;
                                350                 :                : 
 4020                           351                 :              0 :                     object.classId = ProcedureRelationId;
                                352                 :              0 :                     object.objectId = flinfo->fn_oid;
                                353                 :              0 :                     object.objectSubId = 0;
                                354                 :              0 :                     sepgsql_avc_check_perms(&object,
                                355                 :                :                                             SEPG_CLASS_DB_PROCEDURE,
                                356                 :                :                                             SEPG_DB_PROCEDURE__ENTRYPOINT,
 1369 michael@paquier.xyz       357                 :              0 :                                             getObjectDescription(&object, false),
                                358                 :                :                                             true);
                                359                 :                : 
 4442 rhaas@postgresql.org      360                 :              0 :                     sepgsql_avc_check_perms_label(stack->new_label,
                                361                 :                :                                                   SEPG_CLASS_PROCESS,
                                362                 :                :                                                   SEPG_PROCESS__TRANSITION,
                                363                 :                :                                                   NULL, true);
                                364                 :                :                 }
                                365                 :              0 :                 *private = PointerGetDatum(stack);
                                366                 :                :             }
                                367         [ #  # ]:              0 :             Assert(!stack->old_label);
                                368         [ #  # ]:              0 :             if (stack->new_label)
                                369                 :                :             {
 4413                           370                 :              0 :                 stack->old_label = client_label_func;
                                371                 :              0 :                 client_label_func = stack->new_label;
                                372                 :                :             }
 4442                           373         [ #  # ]:              0 :             if (next_fmgr_hook)
                                374                 :              0 :                 (*next_fmgr_hook) (event, flinfo, &stack->next_private);
                                375                 :              0 :             break;
                                376                 :                : 
                                377                 :              0 :         case FHET_END:
                                378                 :                :         case FHET_ABORT:
                                379                 :              0 :             stack = (void *) DatumGetPointer(*private);
                                380                 :                : 
                                381         [ #  # ]:              0 :             if (next_fmgr_hook)
                                382                 :              0 :                 (*next_fmgr_hook) (event, flinfo, &stack->next_private);
                                383                 :                : 
                                384         [ #  # ]:              0 :             if (stack->new_label)
                                385                 :                :             {
 4413                           386                 :              0 :                 client_label_func = stack->old_label;
 4442                           387                 :              0 :                 stack->old_label = NULL;
                                388                 :                :             }
                                389                 :              0 :             break;
                                390                 :                : 
                                391                 :              0 :         default:
                                392         [ #  # ]:              0 :             elog(ERROR, "unexpected event type: %d", (int) event);
                                393                 :                :             break;
                                394                 :                :     }
                                395                 :              0 : }
                                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                 :                :  */
                                403                 :                : void
                                404                 :              0 : sepgsql_init_client_label(void)
                                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                 :                :      */
 4413                           416         [ #  # ]:              0 :     if (getcon_raw(&client_label_peer) < 0)
 4442                           417         [ #  # ]:              0 :         ereport(ERROR,
                                418                 :                :                 (errcode(ERRCODE_INTERNAL_ERROR),
                                419                 :                :                  errmsg("SELinux: failed to get server security label: %m")));
                                420                 :                : 
                                421                 :                :     /* Client authentication hook */
                                422                 :              0 :     next_client_auth_hook = ClientAuthentication_hook;
                                423                 :              0 :     ClientAuthentication_hook = sepgsql_client_auth;
                                424                 :                : 
                                425                 :                :     /* Trusted procedure hooks */
                                426                 :              0 :     next_needs_fmgr_hook = needs_fmgr_hook;
                                427                 :              0 :     needs_fmgr_hook = sepgsql_needs_fmgr_hook;
                                428                 :                : 
                                429                 :              0 :     next_fmgr_hook = fmgr_hook;
                                430                 :              0 :     fmgr_hook = sepgsql_fmgr_hook;
                                431                 :                : 
                                432                 :                :     /* Transaction/Sub-transaction callbacks */
 4413                           433                 :              0 :     RegisterXactCallback(sepgsql_xact_callback, NULL);
                                434                 :              0 :     RegisterSubXactCallback(sepgsql_subxact_callback, NULL);
 4830                           435                 :              0 : }
                                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                 :                :  */
                                444                 :                : char *
                                445                 :              0 : sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
                                446                 :                : {
                                447                 :                :     ObjectAddress object;
                                448                 :                :     char       *label;
                                449                 :                : 
 4753 bruce@momjian.us          450                 :              0 :     object.classId = classId;
                                451                 :              0 :     object.objectId = objectId;
                                452                 :              0 :     object.objectSubId = subId;
                                453                 :                : 
 4830 rhaas@postgresql.org      454                 :              0 :     label = GetSecurityLabel(&object, SEPGSQL_LABEL_TAG);
 1339 michael@paquier.xyz       455   [ #  #  #  # ]:              0 :     if (!label || security_check_context_raw(label))
                                456                 :                :     {
                                457                 :                :         char       *unlabeled;
                                458                 :                : 
 4830 rhaas@postgresql.org      459         [ #  # ]:              0 :         if (security_get_initial_context_raw("unlabeled", &unlabeled) < 0)
                                460         [ #  # ]:              0 :             ereport(ERROR,
                                461                 :                :                     (errcode(ERRCODE_INTERNAL_ERROR),
                                462                 :                :                      errmsg("SELinux: failed to get initial security label: %m")));
                                463         [ #  # ]:              0 :         PG_TRY();
                                464                 :                :         {
                                465                 :              0 :             label = pstrdup(unlabeled);
                                466                 :                :         }
 1626 peter@eisentraut.org      467                 :              0 :         PG_FINALLY();
                                468                 :                :         {
 4830 rhaas@postgresql.org      469                 :              0 :             freecon(unlabeled);
                                470                 :                :         }
                                471         [ #  # ]:              0 :         PG_END_TRY();
                                472                 :                :     }
                                473                 :              0 :     return label;
                                474                 :                : }
                                475                 :                : 
                                476                 :                : /*
                                477                 :                :  * sepgsql_object_relabel
                                478                 :                :  *
                                479                 :                :  * An entrypoint of SECURITY LABEL statement
                                480                 :                :  */
                                481                 :                : void
                                482                 :              0 : sepgsql_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   [ #  #  #  # ]:              0 :     if (seclabel &&
 1339 michael@paquier.xyz       489                 :              0 :         security_check_context_raw(seclabel) < 0)
 4830 rhaas@postgresql.org      490         [ #  # ]:              0 :         ereport(ERROR,
                                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   [ #  #  #  #  :              0 :     switch (object->classId)
                                                 # ]
                                498                 :                :     {
 4587                           499                 :              0 :         case DatabaseRelationId:
                                500                 :              0 :             sepgsql_database_relabel(object->objectId, seclabel);
                                501                 :              0 :             break;
                                502                 :                : 
 4830                           503                 :              0 :         case NamespaceRelationId:
 4753 bruce@momjian.us          504                 :              0 :             sepgsql_schema_relabel(object->objectId, seclabel);
 4830 rhaas@postgresql.org      505                 :              0 :             break;
                                506                 :                : 
                                507                 :              0 :         case RelationRelationId:
                                508         [ #  # ]:              0 :             if (object->objectSubId == 0)
                                509                 :              0 :                 sepgsql_relation_relabel(object->objectId,
                                510                 :                :                                          seclabel);
                                511                 :                :             else
                                512                 :              0 :                 sepgsql_attribute_relabel(object->objectId,
                                513                 :              0 :                                           object->objectSubId,
                                514                 :                :                                           seclabel);
                                515                 :              0 :             break;
                                516                 :                : 
                                517                 :              0 :         case ProcedureRelationId:
                                518                 :              0 :             sepgsql_proc_relabel(object->objectId, seclabel);
                                519                 :              0 :             break;
                                520                 :                : 
                                521                 :              0 :         default:
 3322                           522         [ #  # ]:              0 :             ereport(ERROR,
                                523                 :                :                     (errcode(ERRCODE_FEATURE_NOT_SUPPORTED),
                                524                 :                :                      errmsg("sepgsql provider does not support labels on %s",
                                525                 :                :                             getObjectTypeDescription(object, false))));
                                526                 :                :             break;
                                527                 :                :     }
 4830                           528                 :              0 : }
                                529                 :                : 
                                530                 :                : /*
                                531                 :                :  * TEXT sepgsql_getcon(VOID)
                                532                 :                :  *
                                533                 :                :  * It returns the security label of the client.
                                534                 :                :  */
                                535                 :              0 : PG_FUNCTION_INFO_V1(sepgsql_getcon);
                                536                 :                : Datum
                                537                 :              0 : sepgsql_getcon(PG_FUNCTION_ARGS)
                                538                 :                : {
                                539                 :                :     char       *client_label;
                                540                 :                : 
                                541         [ #  # ]:              0 :     if (!sepgsql_is_enabled())
                                542                 :              0 :         PG_RETURN_NULL();
                                543                 :                : 
                                544                 :              0 :     client_label = sepgsql_get_client_label();
                                545                 :                : 
                                546                 :              0 :     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                 :                :  */
 4413                           554                 :              0 : PG_FUNCTION_INFO_V1(sepgsql_setcon);
                                555                 :                : Datum
                                556                 :              0 : sepgsql_setcon(PG_FUNCTION_ARGS)
                                557                 :                : {
                                558                 :                :     const char *new_label;
                                559                 :                : 
                                560         [ #  # ]:              0 :     if (PG_ARGISNULL(0))
                                561                 :              0 :         new_label = NULL;
                                562                 :                :     else
                                563                 :              0 :         new_label = TextDatumGetCString(PG_GETARG_DATUM(0));
                                564                 :                : 
                                565                 :              0 :     sepgsql_set_client_label(new_label);
                                566                 :                : 
                                567                 :              0 :     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                 :                :  */
 4830                           576                 :              0 : PG_FUNCTION_INFO_V1(sepgsql_mcstrans_in);
                                577                 :                : Datum
                                578                 :              0 : sepgsql_mcstrans_in(PG_FUNCTION_ARGS)
                                579                 :                : {
 2590 noah@leadboat.com         580                 :              0 :     text       *label = PG_GETARG_TEXT_PP(0);
                                581                 :                :     char       *raw_label;
                                582                 :                :     char       *result;
                                583                 :                : 
 4830 rhaas@postgresql.org      584         [ #  # ]:              0 :     if (!sepgsql_is_enabled())
                                585         [ #  # ]:              0 :         ereport(ERROR,
                                586                 :                :                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
                                587                 :                :                  errmsg("sepgsql is not enabled")));
                                588                 :                : 
                                589         [ #  # ]:              0 :     if (selinux_trans_to_raw_context(text_to_cstring(label),
                                590                 :                :                                      &raw_label) < 0)
                                591         [ #  # ]:              0 :         ereport(ERROR,
                                592                 :                :                 (errcode(ERRCODE_INTERNAL_ERROR),
                                593                 :                :                  errmsg("SELinux: could not translate security label: %m")));
                                594                 :                : 
                                595         [ #  # ]:              0 :     PG_TRY();
                                596                 :                :     {
                                597                 :              0 :         result = pstrdup(raw_label);
                                598                 :                :     }
 1626 peter@eisentraut.org      599                 :              0 :     PG_FINALLY();
                                600                 :                :     {
 4830 rhaas@postgresql.org      601                 :              0 :         freecon(raw_label);
                                602                 :                :     }
                                603         [ #  # ]:              0 :     PG_END_TRY();
                                604                 :                : 
                                605                 :              0 :     PG_RETURN_TEXT_P(cstring_to_text(result));
                                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                 :                :  */
                                614                 :              0 : PG_FUNCTION_INFO_V1(sepgsql_mcstrans_out);
                                615                 :                : Datum
                                616                 :              0 : sepgsql_mcstrans_out(PG_FUNCTION_ARGS)
                                617                 :                : {
 2590 noah@leadboat.com         618                 :              0 :     text       *label = PG_GETARG_TEXT_PP(0);
                                619                 :                :     char       *qual_label;
                                620                 :                :     char       *result;
                                621                 :                : 
 4830 rhaas@postgresql.org      622         [ #  # ]:              0 :     if (!sepgsql_is_enabled())
                                623         [ #  # ]:              0 :         ereport(ERROR,
                                624                 :                :                 (errcode(ERRCODE_OBJECT_NOT_IN_PREREQUISITE_STATE),
                                625                 :                :                  errmsg("sepgsql is not currently enabled")));
                                626                 :                : 
                                627         [ #  # ]:              0 :     if (selinux_raw_to_trans_context(text_to_cstring(label),
                                628                 :                :                                      &qual_label) < 0)
                                629         [ #  # ]:              0 :         ereport(ERROR,
                                630                 :                :                 (errcode(ERRCODE_INTERNAL_ERROR),
                                631                 :                :                  errmsg("SELinux: could not translate security label: %m")));
                                632                 :                : 
                                633         [ #  # ]:              0 :     PG_TRY();
                                634                 :                :     {
                                635                 :              0 :         result = pstrdup(qual_label);
                                636                 :                :     }
 1626 peter@eisentraut.org      637                 :              0 :     PG_FINALLY();
                                638                 :                :     {
 4830 rhaas@postgresql.org      639                 :              0 :         freecon(qual_label);
                                640                 :                :     }
                                641         [ #  # ]:              0 :     PG_END_TRY();
                                642                 :                : 
                                643                 :              0 :     PG_RETURN_TEXT_P(cstring_to_text(result));
                                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                 :                :  */
                                652                 :                : static char *
 4820                           653                 :              0 : quote_object_name(const char *src1, const char *src2,
                                654                 :                :                   const char *src3, const char *src4)
                                655                 :                : {
                                656                 :                :     StringInfoData result;
                                657                 :                : 
                                658                 :              0 :     initStringInfo(&result);
                                659         [ #  # ]:              0 :     if (src1)
  596 tgl@sss.pgh.pa.us         660                 :              0 :         appendStringInfoString(&result, quote_identifier(src1));
 4820 rhaas@postgresql.org      661         [ #  # ]:              0 :     if (src2)
  596 tgl@sss.pgh.pa.us         662                 :              0 :         appendStringInfo(&result, ".%s", quote_identifier(src2));
 4820 rhaas@postgresql.org      663         [ #  # ]:              0 :     if (src3)
  596 tgl@sss.pgh.pa.us         664                 :              0 :         appendStringInfo(&result, ".%s", quote_identifier(src3));
 4820 rhaas@postgresql.org      665         [ #  # ]:              0 :     if (src4)
  596 tgl@sss.pgh.pa.us         666                 :              0 :         appendStringInfo(&result, ".%s", quote_identifier(src4));
 4820 rhaas@postgresql.org      667                 :              0 :     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                 :                :  */
                                677                 :                : static void
 2489 tgl@sss.pgh.pa.us         678                 :              0 : exec_object_restorecon(struct selabel_handle *sehnd, Oid catalogId)
                                679                 :                : {
                                680                 :                :     Relation    rel;
                                681                 :                :     SysScanDesc sscan;
                                682                 :                :     HeapTuple   tuple;
 4753 bruce@momjian.us          683                 :              0 :     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                 :                :      */
 1910 andres@anarazel.de        692                 :              0 :     rel = table_open(catalogId, AccessShareLock);
                                693                 :                : 
 4830 rhaas@postgresql.org      694                 :              0 :     sscan = systable_beginscan(rel, InvalidOid, false,
                                695                 :                :                                NULL, 0, NULL);
                                696         [ #  # ]:              0 :     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;
 4753 bruce@momjian.us          704                 :              0 :         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                 :                :          */
 4830 rhaas@postgresql.org      712   [ #  #  #  #  :              0 :         switch (catalogId)
                                              #  # ]
                                713                 :                :         {
 4587                           714                 :              0 :             case DatabaseRelationId:
                                715                 :              0 :                 datForm = (Form_pg_database) GETSTRUCT(tuple);
                                716                 :                : 
                                717                 :              0 :                 objtype = SELABEL_DB_DATABASE;
                                718                 :                : 
                                719                 :              0 :                 objname = quote_object_name(NameStr(datForm->datname),
                                720                 :                :                                             NULL, NULL, NULL);
                                721                 :                : 
                                722                 :              0 :                 object.classId = DatabaseRelationId;
 1972 andres@anarazel.de        723                 :              0 :                 object.objectId = datForm->oid;
 4587 rhaas@postgresql.org      724                 :              0 :                 object.objectSubId = 0;
                                725                 :              0 :                 break;
                                726                 :                : 
 4830                           727                 :              0 :             case NamespaceRelationId:
                                728                 :              0 :                 nspForm = (Form_pg_namespace) GETSTRUCT(tuple);
                                729                 :                : 
                                730                 :              0 :                 objtype = SELABEL_DB_SCHEMA;
                                731                 :                : 
 4820                           732                 :              0 :                 objname = quote_object_name(database_name,
                                733                 :              0 :                                             NameStr(nspForm->nspname),
                                734                 :                :                                             NULL, NULL);
                                735                 :                : 
 4830                           736                 :              0 :                 object.classId = NamespaceRelationId;
 1972 andres@anarazel.de        737                 :              0 :                 object.objectId = nspForm->oid;
 4830 rhaas@postgresql.org      738                 :              0 :                 object.objectSubId = 0;
                                739                 :              0 :                 break;
                                740                 :                : 
                                741                 :              0 :             case RelationRelationId:
                                742                 :              0 :                 relForm = (Form_pg_class) GETSTRUCT(tuple);
                                743                 :                : 
 2562 mail@joeconway.com        744         [ #  # ]:              0 :                 if (relForm->relkind == RELKIND_RELATION ||
                                745         [ #  # ]:              0 :                     relForm->relkind == RELKIND_PARTITIONED_TABLE)
 4830 rhaas@postgresql.org      746                 :              0 :                     objtype = SELABEL_DB_TABLE;
                                747         [ #  # ]:              0 :                 else if (relForm->relkind == RELKIND_SEQUENCE)
                                748                 :              0 :                     objtype = SELABEL_DB_SEQUENCE;
                                749         [ #  # ]:              0 :                 else if (relForm->relkind == RELKIND_VIEW)
                                750                 :              0 :                     objtype = SELABEL_DB_VIEW;
                                751                 :                :                 else
                                752                 :              0 :                     continue;   /* no need to assign security label */
                                753                 :                : 
                                754                 :              0 :                 namespace_name = get_namespace_name(relForm->relnamespace);
 4820                           755                 :              0 :                 objname = quote_object_name(database_name,
                                756                 :                :                                             namespace_name,
                                757                 :              0 :                                             NameStr(relForm->relname),
                                758                 :                :                                             NULL);
 4830                           759                 :              0 :                 pfree(namespace_name);
                                760                 :                : 
                                761                 :              0 :                 object.classId = RelationRelationId;
 1972 andres@anarazel.de        762                 :              0 :                 object.objectId = relForm->oid;
 4830 rhaas@postgresql.org      763                 :              0 :                 object.objectSubId = 0;
                                764                 :              0 :                 break;
                                765                 :                : 
                                766                 :              0 :             case AttributeRelationId:
                                767                 :              0 :                 attForm = (Form_pg_attribute) GETSTRUCT(tuple);
                                768                 :                : 
 2562 mail@joeconway.com        769         [ #  # ]:              0 :                 if (get_rel_relkind(attForm->attrelid) != RELKIND_RELATION &&
                                770         [ #  # ]:              0 :                     get_rel_relkind(attForm->attrelid) != RELKIND_PARTITIONED_TABLE)
 4830 rhaas@postgresql.org      771                 :              0 :                     continue;   /* no need to assign security label */
                                772                 :                : 
                                773                 :              0 :                 objtype = SELABEL_DB_COLUMN;
                                774                 :                : 
                                775                 :              0 :                 namespace_id = get_rel_namespace(attForm->attrelid);
                                776                 :              0 :                 namespace_name = get_namespace_name(namespace_id);
                                777                 :              0 :                 relation_name = get_rel_name(attForm->attrelid);
 4820                           778                 :              0 :                 objname = quote_object_name(database_name,
                                779                 :                :                                             namespace_name,
                                780                 :                :                                             relation_name,
                                781                 :              0 :                                             NameStr(attForm->attname));
 4830                           782                 :              0 :                 pfree(namespace_name);
 4820                           783                 :              0 :                 pfree(relation_name);
                                784                 :                : 
 4830                           785                 :              0 :                 object.classId = RelationRelationId;
                                786                 :              0 :                 object.objectId = attForm->attrelid;
                                787                 :              0 :                 object.objectSubId = attForm->attnum;
                                788                 :              0 :                 break;
                                789                 :                : 
                                790                 :              0 :             case ProcedureRelationId:
                                791                 :              0 :                 proForm = (Form_pg_proc) GETSTRUCT(tuple);
                                792                 :                : 
                                793                 :              0 :                 objtype = SELABEL_DB_PROCEDURE;
                                794                 :                : 
                                795                 :              0 :                 namespace_name = get_namespace_name(proForm->pronamespace);
 4820                           796                 :              0 :                 objname = quote_object_name(database_name,
                                797                 :                :                                             namespace_name,
                                798                 :              0 :                                             NameStr(proForm->proname),
                                799                 :                :                                             NULL);
 4830                           800                 :              0 :                 pfree(namespace_name);
                                801                 :                : 
                                802                 :              0 :                 object.classId = ProcedureRelationId;
 1972 andres@anarazel.de        803                 :              0 :                 object.objectId = proForm->oid;
 4830 rhaas@postgresql.org      804                 :              0 :                 object.objectSubId = 0;
                                805                 :              0 :                 break;
                                806                 :                : 
                                807                 :              0 :             default:
                                808         [ #  # ]:              0 :                 elog(ERROR, "unexpected catalog id: %u", catalogId);
                                809                 :                :                 objname = NULL; /* for compiler quiet */
                                810                 :                :                 break;
                                811                 :                :         }
                                812                 :                : 
                                813         [ #  # ]:              0 :         if (selabel_lookup_raw(sehnd, &context, objname, objtype) == 0)
                                814                 :                :         {
                                815         [ #  # ]:              0 :             PG_TRY();
                                816                 :                :             {
                                817                 :                :                 /*
                                818                 :                :                  * Check SELinux permission to relabel the fetched object,
                                819                 :                :                  * then do the actual relabeling.
                                820                 :                :                  */
                                821                 :              0 :                 sepgsql_object_relabel(&object, context);
                                822                 :                : 
                                823                 :              0 :                 SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, context);
                                824                 :                :             }
 1626 peter@eisentraut.org      825                 :              0 :             PG_FINALLY();
                                826                 :                :             {
 4830 rhaas@postgresql.org      827                 :              0 :                 freecon(context);
                                828                 :                :             }
                                829         [ #  # ]:              0 :             PG_END_TRY();
                                830                 :                :         }
                                831         [ #  # ]:              0 :         else if (errno == ENOENT)
                                832         [ #  # ]:              0 :             ereport(WARNING,
                                833                 :                :                     (errmsg("SELinux: no initial label assigned for %s (type=%d), skipping",
                                834                 :                :                             objname, objtype)));
                                835                 :                :         else
                                836         [ #  # ]:              0 :             ereport(ERROR,
                                837                 :                :                     (errcode(ERRCODE_INTERNAL_ERROR),
                                838                 :                :                      errmsg("SELinux: could not determine initial security label for %s (type=%d): %m", objname, objtype)));
                                839                 :                : 
 4820                           840                 :              0 :         pfree(objname);
                                841                 :                :     }
 4830                           842                 :              0 :     systable_endscan(sscan);
                                843                 :                : 
 1910 andres@anarazel.de        844                 :              0 :     table_close(rel, NoLock);
 4830 rhaas@postgresql.org      845                 :              0 : }
                                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                 :                :  */
                                858                 :              0 : PG_FUNCTION_INFO_V1(sepgsql_restorecon);
                                859                 :                : Datum
                                860                 :              0 : sepgsql_restorecon(PG_FUNCTION_ARGS)
                                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         [ #  # ]:              0 :     if (!sepgsql_is_enabled())
                                869         [ #  # ]:              0 :         ereport(ERROR,
                                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         [ #  # ]:              0 :     if (!superuser())
                                878         [ #  # ]:              0 :         ereport(ERROR,
                                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         [ #  # ]:              0 :     if (PG_ARGISNULL(0))
                                887                 :                :     {
                                888                 :              0 :         seopts.type = SELABEL_OPT_UNUSED;
                                889                 :              0 :         seopts.value = NULL;
                                890                 :                :     }
                                891                 :                :     else
                                892                 :                :     {
                                893                 :              0 :         seopts.type = SELABEL_OPT_PATH;
                                894                 :              0 :         seopts.value = TextDatumGetCString(PG_GETARG_DATUM(0));
                                895                 :                :     }
                                896                 :              0 :     sehnd = selabel_open(SELABEL_CTX_DB, &seopts, 1);
                                897         [ #  # ]:              0 :     if (!sehnd)
                                898         [ #  # ]:              0 :         ereport(ERROR,
                                899                 :                :                 (errcode(ERRCODE_INTERNAL_ERROR),
                                900                 :                :                  errmsg("SELinux: failed to initialize labeling handle: %m")));
                                901         [ #  # ]:              0 :     PG_TRY();
                                902                 :                :     {
 4587                           903                 :              0 :         exec_object_restorecon(sehnd, DatabaseRelationId);
 4830                           904                 :              0 :         exec_object_restorecon(sehnd, NamespaceRelationId);
                                905                 :              0 :         exec_object_restorecon(sehnd, RelationRelationId);
                                906                 :              0 :         exec_object_restorecon(sehnd, AttributeRelationId);
                                907                 :              0 :         exec_object_restorecon(sehnd, ProcedureRelationId);
                                908                 :                :     }
 1626 peter@eisentraut.org      909                 :              0 :     PG_FINALLY();
                                910                 :                :     {
 4830 rhaas@postgresql.org      911                 :              0 :         selabel_close(sehnd);
                                912                 :                :     }
 4753 bruce@momjian.us          913         [ #  # ]:              0 :     PG_END_TRY();
                                914                 :                : 
 4830 rhaas@postgresql.org      915                 :              0 :     PG_RETURN_BOOL(true);
                                916                 :                : }
        

Generated by: LCOV version 2.1-beta2-3-g6141622