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

Generated by: LCOV version 2.4-beta