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

 Age         Owner                    Branch data    TLA  Line data    Source code
                                  1                 :                : /* -------------------------------------------------------------------------
                                  2                 :                :  *
                                  3                 :                :  * contrib/sepgsql/relation.c
                                  4                 :                :  *
                                  5                 :                :  * Routines corresponding to relation/attribute objects
                                  6                 :                :  *
                                  7                 :                :  * Copyright (c) 2010-2024, PostgreSQL Global Development Group
                                  8                 :                :  *
                                  9                 :                :  * -------------------------------------------------------------------------
                                 10                 :                :  */
                                 11                 :                : #include "postgres.h"
                                 12                 :                : 
                                 13                 :                : #include "access/genam.h"
                                 14                 :                : #include "access/htup_details.h"
                                 15                 :                : #include "access/sysattr.h"
                                 16                 :                : #include "access/table.h"
                                 17                 :                : #include "catalog/dependency.h"
                                 18                 :                : #include "catalog/pg_attribute.h"
                                 19                 :                : #include "catalog/pg_class.h"
                                 20                 :                : #include "catalog/pg_namespace.h"
                                 21                 :                : #include "commands/seclabel.h"
                                 22                 :                : #include "lib/stringinfo.h"
                                 23                 :                : #include "sepgsql.h"
                                 24                 :                : #include "utils/builtins.h"
                                 25                 :                : #include "utils/catcache.h"
                                 26                 :                : #include "utils/fmgroids.h"
                                 27                 :                : #include "utils/lsyscache.h"
                                 28                 :                : #include "utils/rel.h"
                                 29                 :                : #include "utils/snapmgr.h"
                                 30                 :                : #include "utils/syscache.h"
                                 31                 :                : 
                                 32                 :                : static void sepgsql_index_modify(Oid indexOid);
                                 33                 :                : 
                                 34                 :                : /*
                                 35                 :                :  * sepgsql_attribute_post_create
                                 36                 :                :  *
                                 37                 :                :  * This routine assigns a default security label on a newly defined
                                 38                 :                :  * column, using ALTER TABLE ... ADD COLUMN.
                                 39                 :                :  * Note that this routine is not invoked in the case of CREATE TABLE,
                                 40                 :                :  * although it also defines columns in addition to table.
                                 41                 :                :  */
                                 42                 :                : void
 4830 rhaas@postgresql.org       43                 :UBC           0 : sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum)
                                 44                 :                : {
                                 45                 :                :     Relation    rel;
                                 46                 :                :     ScanKeyData skey[2];
                                 47                 :                :     SysScanDesc sscan;
                                 48                 :                :     HeapTuple   tuple;
                                 49                 :                :     char       *scontext;
                                 50                 :                :     char       *tcontext;
                                 51                 :                :     char       *ncontext;
                                 52                 :                :     ObjectAddress object;
                                 53                 :                :     Form_pg_attribute attForm;
                                 54                 :                :     StringInfoData audit_name;
 2562 mail@joeconway.com         55                 :              0 :     char        relkind = get_rel_relkind(relOid);
                                 56                 :                : 
                                 57                 :                :     /*
                                 58                 :                :      * Only attributes within regular relations or partition relations have
                                 59                 :                :      * individual security labels.
                                 60                 :                :      */
                                 61   [ #  #  #  # ]:              0 :     if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
 4830 rhaas@postgresql.org       62                 :              0 :         return;
                                 63                 :                : 
                                 64                 :                :     /*
                                 65                 :                :      * Compute a default security label of the new column underlying the
                                 66                 :                :      * specified relation, and check permission to create it.
                                 67                 :                :      */
 1910 andres@anarazel.de         68                 :              0 :     rel = table_open(AttributeRelationId, AccessShareLock);
                                 69                 :                : 
 4498 rhaas@postgresql.org       70                 :              0 :     ScanKeyInit(&skey[0],
                                 71                 :                :                 Anum_pg_attribute_attrelid,
                                 72                 :                :                 BTEqualStrategyNumber, F_OIDEQ,
                                 73                 :                :                 ObjectIdGetDatum(relOid));
                                 74                 :              0 :     ScanKeyInit(&skey[1],
                                 75                 :                :                 Anum_pg_attribute_attnum,
                                 76                 :                :                 BTEqualStrategyNumber, F_INT2EQ,
                                 77                 :                :                 Int16GetDatum(attnum));
                                 78                 :                : 
                                 79                 :              0 :     sscan = systable_beginscan(rel, AttributeRelidNumIndexId, true,
                                 80                 :                :                                SnapshotSelf, 2, &skey[0]);
                                 81                 :                : 
                                 82                 :              0 :     tuple = systable_getnext(sscan);
                                 83         [ #  # ]:              0 :     if (!HeapTupleIsValid(tuple))
 2506 tgl@sss.pgh.pa.us          84         [ #  # ]:              0 :         elog(ERROR, "could not find tuple for column %d of relation %u",
                                 85                 :                :              attnum, relOid);
                                 86                 :                : 
 4498 rhaas@postgresql.org       87                 :              0 :     attForm = (Form_pg_attribute) GETSTRUCT(tuple);
                                 88                 :                : 
 4830                            89                 :              0 :     scontext = sepgsql_get_client_label();
                                 90                 :              0 :     tcontext = sepgsql_get_label(RelationRelationId, relOid, 0);
                                 91                 :              0 :     ncontext = sepgsql_compute_create(scontext, tcontext,
                                 92                 :                :                                       SEPG_CLASS_DB_COLUMN,
 4035                            93                 :              0 :                                       NameStr(attForm->attname));
                                 94                 :                : 
                                 95                 :                :     /*
                                 96                 :                :      * check db_column:{create} permission
                                 97                 :                :      */
 4020                            98                 :              0 :     object.classId = RelationRelationId;
                                 99                 :              0 :     object.objectId = relOid;
                                100                 :              0 :     object.objectSubId = 0;
                                101                 :                : 
                                102                 :              0 :     initStringInfo(&audit_name);
                                103                 :              0 :     appendStringInfo(&audit_name, "%s.%s",
                                104                 :                :                      getObjectIdentity(&object, false),
                                105                 :              0 :                      quote_identifier(NameStr(attForm->attname)));
 4498                           106                 :              0 :     sepgsql_avc_check_perms_label(ncontext,
                                107                 :                :                                   SEPG_CLASS_DB_COLUMN,
                                108                 :                :                                   SEPG_DB_COLUMN__CREATE,
 4020                           109                 :              0 :                                   audit_name.data,
                                110                 :                :                                   true);
                                111                 :                : 
                                112                 :                :     /*
                                113                 :                :      * Assign the default security label on a new procedure
                                114                 :                :      */
 4830                           115                 :              0 :     object.classId = RelationRelationId;
                                116                 :              0 :     object.objectId = relOid;
                                117                 :              0 :     object.objectSubId = attnum;
                                118                 :              0 :     SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
                                119                 :                : 
 4498                           120                 :              0 :     systable_endscan(sscan);
 1910 andres@anarazel.de        121                 :              0 :     table_close(rel, AccessShareLock);
                                122                 :                : 
 4830 rhaas@postgresql.org      123                 :              0 :     pfree(tcontext);
                                124                 :              0 :     pfree(ncontext);
                                125                 :                : }
                                126                 :                : 
                                127                 :                : /*
                                128                 :                :  * sepgsql_attribute_drop
                                129                 :                :  *
                                130                 :                :  * It checks privileges to drop the supplied column.
                                131                 :                :  */
                                132                 :                : void
 4419                           133                 :              0 : sepgsql_attribute_drop(Oid relOid, AttrNumber attnum)
                                134                 :                : {
                                135                 :                :     ObjectAddress object;
                                136                 :                :     char       *audit_name;
 2562 mail@joeconway.com        137                 :              0 :     char        relkind = get_rel_relkind(relOid);
                                138                 :                : 
                                139   [ #  #  #  # ]:              0 :     if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
 4419 rhaas@postgresql.org      140                 :              0 :         return;
                                141                 :                : 
                                142                 :                :     /*
                                143                 :                :      * check db_column:{drop} permission
                                144                 :                :      */
                                145                 :              0 :     object.classId = RelationRelationId;
                                146                 :              0 :     object.objectId = relOid;
                                147                 :              0 :     object.objectSubId = attnum;
 1369 michael@paquier.xyz       148                 :              0 :     audit_name = getObjectIdentity(&object, false);
                                149                 :                : 
 4419 rhaas@postgresql.org      150                 :              0 :     sepgsql_avc_check_perms(&object,
                                151                 :                :                             SEPG_CLASS_DB_COLUMN,
                                152                 :                :                             SEPG_DB_COLUMN__DROP,
                                153                 :                :                             audit_name,
                                154                 :                :                             true);
                                155                 :              0 :     pfree(audit_name);
                                156                 :                : }
                                157                 :                : 
                                158                 :                : /*
                                159                 :                :  * sepgsql_attribute_relabel
                                160                 :                :  *
                                161                 :                :  * It checks privileges to relabel the supplied column
                                162                 :                :  * by the `seclabel'.
                                163                 :                :  */
                                164                 :                : void
 4830                           165                 :              0 : sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
                                166                 :                :                           const char *seclabel)
                                167                 :                : {
                                168                 :                :     ObjectAddress object;
                                169                 :                :     char       *audit_name;
 2562 mail@joeconway.com        170                 :              0 :     char        relkind = get_rel_relkind(relOid);
                                171                 :                : 
                                172   [ #  #  #  # ]:              0 :     if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
 4830 rhaas@postgresql.org      173         [ #  # ]:              0 :         ereport(ERROR,
                                174                 :                :                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
                                175                 :                :                  errmsg("cannot set security label on non-regular columns")));
                                176                 :                : 
 4820                           177                 :              0 :     object.classId = RelationRelationId;
                                178                 :              0 :     object.objectId = relOid;
                                179                 :              0 :     object.objectSubId = attnum;
 1369 michael@paquier.xyz       180                 :              0 :     audit_name = getObjectIdentity(&object, false);
                                181                 :                : 
                                182                 :                :     /*
                                183                 :                :      * check db_column:{setattr relabelfrom} permission
                                184                 :                :      */
 4609 rhaas@postgresql.org      185                 :              0 :     sepgsql_avc_check_perms(&object,
                                186                 :                :                             SEPG_CLASS_DB_COLUMN,
                                187                 :                :                             SEPG_DB_COLUMN__SETATTR |
                                188                 :                :                             SEPG_DB_COLUMN__RELABELFROM,
                                189                 :                :                             audit_name,
                                190                 :                :                             true);
                                191                 :                : 
                                192                 :                :     /*
                                193                 :                :      * check db_column:{relabelto} permission
                                194                 :                :      */
                                195                 :              0 :     sepgsql_avc_check_perms_label(seclabel,
                                196                 :                :                                   SEPG_CLASS_DB_COLUMN,
                                197                 :                :                                   SEPG_DB_PROCEDURE__RELABELTO,
                                198                 :                :                                   audit_name,
                                199                 :                :                                   true);
 4820                           200                 :              0 :     pfree(audit_name);
 4830                           201                 :              0 : }
                                202                 :                : 
                                203                 :                : /*
                                204                 :                :  * sepgsql_attribute_setattr
                                205                 :                :  *
                                206                 :                :  * It checks privileges to alter the supplied column.
                                207                 :                :  */
                                208                 :                : void
 4036                           209                 :              0 : sepgsql_attribute_setattr(Oid relOid, AttrNumber attnum)
                                210                 :                : {
                                211                 :                :     ObjectAddress object;
                                212                 :                :     char       *audit_name;
 2562 mail@joeconway.com        213                 :              0 :     char        relkind = get_rel_relkind(relOid);
                                214                 :                : 
                                215   [ #  #  #  # ]:              0 :     if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
 4036 rhaas@postgresql.org      216                 :              0 :         return;
                                217                 :                : 
                                218                 :                :     /*
                                219                 :                :      * check db_column:{setattr} permission
                                220                 :                :      */
                                221                 :              0 :     object.classId = RelationRelationId;
                                222                 :              0 :     object.objectId = relOid;
                                223                 :              0 :     object.objectSubId = attnum;
 1369 michael@paquier.xyz       224                 :              0 :     audit_name = getObjectIdentity(&object, false);
                                225                 :                : 
 4036 rhaas@postgresql.org      226                 :              0 :     sepgsql_avc_check_perms(&object,
                                227                 :                :                             SEPG_CLASS_DB_COLUMN,
                                228                 :                :                             SEPG_DB_COLUMN__SETATTR,
                                229                 :                :                             audit_name,
                                230                 :                :                             true);
                                231                 :              0 :     pfree(audit_name);
                                232                 :                : }
                                233                 :                : 
                                234                 :                : /*
                                235                 :                :  * sepgsql_relation_post_create
                                236                 :                :  *
                                237                 :                :  * The post creation hook of relation/attribute
                                238                 :                :  */
                                239                 :                : void
 4830                           240                 :              0 : sepgsql_relation_post_create(Oid relOid)
                                241                 :                : {
                                242                 :                :     Relation    rel;
                                243                 :                :     ScanKeyData skey;
                                244                 :                :     SysScanDesc sscan;
                                245                 :                :     HeapTuple   tuple;
                                246                 :                :     Form_pg_class classForm;
                                247                 :                :     ObjectAddress object;
                                248                 :                :     uint16_t    tclass;
                                249                 :                :     char       *scontext;       /* subject */
                                250                 :                :     char       *tcontext;       /* schema */
                                251                 :                :     char       *rcontext;       /* relation */
                                252                 :                :     char       *ccontext;       /* column */
                                253                 :                :     char       *nsp_name;
                                254                 :                :     StringInfoData audit_name;
                                255                 :                : 
                                256                 :                :     /*
                                257                 :                :      * Fetch catalog record of the new relation. Because pg_class entry is not
                                258                 :                :      * visible right now, we need to scan the catalog using SnapshotSelf.
                                259                 :                :      */
 1910 andres@anarazel.de        260                 :              0 :     rel = table_open(RelationRelationId, AccessShareLock);
                                261                 :                : 
 4830 rhaas@postgresql.org      262                 :              0 :     ScanKeyInit(&skey,
                                263                 :                :                 Anum_pg_class_oid,
                                264                 :                :                 BTEqualStrategyNumber, F_OIDEQ,
                                265                 :                :                 ObjectIdGetDatum(relOid));
                                266                 :                : 
                                267                 :              0 :     sscan = systable_beginscan(rel, ClassOidIndexId, true,
                                268                 :                :                                SnapshotSelf, 1, &skey);
                                269                 :                : 
                                270                 :              0 :     tuple = systable_getnext(sscan);
                                271         [ #  # ]:              0 :     if (!HeapTupleIsValid(tuple))
 2506 tgl@sss.pgh.pa.us         272         [ #  # ]:              0 :         elog(ERROR, "could not find tuple for relation %u", relOid);
                                273                 :                : 
 4830 rhaas@postgresql.org      274                 :              0 :     classForm = (Form_pg_class) GETSTRUCT(tuple);
                                275                 :                : 
                                276                 :                :     /* ignore indexes on toast tables */
 4191 alvherre@alvh.no-ip.      277         [ #  # ]:              0 :     if (classForm->relkind == RELKIND_INDEX &&
                                278         [ #  # ]:              0 :         classForm->relnamespace == PG_TOAST_NAMESPACE)
                                279                 :              0 :         goto out;
                                280                 :                : 
                                281                 :                :     /*
                                282                 :                :      * check db_schema:{add_name} permission of the namespace
                                283                 :                :      */
                                284                 :              0 :     object.classId = NamespaceRelationId;
                                285                 :              0 :     object.objectId = classForm->relnamespace;
                                286                 :              0 :     object.objectSubId = 0;
                                287                 :              0 :     sepgsql_avc_check_perms(&object,
                                288                 :                :                             SEPG_CLASS_DB_SCHEMA,
                                289                 :                :                             SEPG_DB_SCHEMA__ADD_NAME,
 1369 michael@paquier.xyz       290                 :              0 :                             getObjectIdentity(&object, false),
                                291                 :                :                             true);
                                292                 :                : 
 4498 rhaas@postgresql.org      293   [ #  #  #  #  :              0 :     switch (classForm->relkind)
                                                 # ]
                                294                 :                :     {
                                295                 :              0 :         case RELKIND_RELATION:
                                296                 :                :         case RELKIND_PARTITIONED_TABLE:
                                297                 :              0 :             tclass = SEPG_CLASS_DB_TABLE;
                                298                 :              0 :             break;
                                299                 :              0 :         case RELKIND_SEQUENCE:
                                300                 :              0 :             tclass = SEPG_CLASS_DB_SEQUENCE;
                                301                 :              0 :             break;
                                302                 :              0 :         case RELKIND_VIEW:
                                303                 :              0 :             tclass = SEPG_CLASS_DB_VIEW;
                                304                 :              0 :             break;
 4191 alvherre@alvh.no-ip.      305                 :              0 :         case RELKIND_INDEX:
                                306                 :                :             /* deal with indexes specially; no need for tclass */
                                307                 :              0 :             sepgsql_index_modify(relOid);
                                308                 :              0 :             goto out;
 4498 rhaas@postgresql.org      309                 :              0 :         default:
                                310                 :                :             /* ignore other relkinds */
                                311                 :              0 :             goto out;
                                312                 :                :     }
                                313                 :                : 
                                314                 :                :     /*
                                315                 :                :      * Compute a default security label when we create a new relation object
                                316                 :                :      * under the specified namespace.
                                317                 :                :      */
 4830                           318                 :              0 :     scontext = sepgsql_get_client_label();
                                319                 :              0 :     tcontext = sepgsql_get_label(NamespaceRelationId,
                                320                 :                :                                  classForm->relnamespace, 0);
 4035                           321                 :              0 :     rcontext = sepgsql_compute_create(scontext, tcontext, tclass,
                                322                 :              0 :                                       NameStr(classForm->relname));
                                323                 :                : 
                                324                 :                :     /*
                                325                 :                :      * check db_xxx:{create} permission
                                326                 :                :      */
 4020                           327                 :              0 :     nsp_name = get_namespace_name(classForm->relnamespace);
                                328                 :              0 :     initStringInfo(&audit_name);
                                329                 :              0 :     appendStringInfo(&audit_name, "%s.%s",
                                330                 :                :                      quote_identifier(nsp_name),
                                331                 :              0 :                      quote_identifier(NameStr(classForm->relname)));
 4498                           332                 :              0 :     sepgsql_avc_check_perms_label(rcontext,
                                333                 :                :                                   tclass,
                                334                 :                :                                   SEPG_DB_DATABASE__CREATE,
 4020                           335                 :              0 :                                   audit_name.data,
                                336                 :                :                                   true);
                                337                 :                : 
                                338                 :                :     /*
                                339                 :                :      * Assign the default security label on the new regular or partitioned
                                340                 :                :      * relation.
                                341                 :                :      */
 4830                           342                 :              0 :     object.classId = RelationRelationId;
                                343                 :              0 :     object.objectId = relOid;
                                344                 :              0 :     object.objectSubId = 0;
                                345                 :              0 :     SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, rcontext);
                                346                 :                : 
                                347                 :                :     /*
                                348                 :                :      * We also assign a default security label on columns of a new table.
                                349                 :                :      */
 2562 mail@joeconway.com        350         [ #  # ]:              0 :     if (classForm->relkind == RELKIND_RELATION ||
                                351         [ #  # ]:              0 :         classForm->relkind == RELKIND_PARTITIONED_TABLE)
                                352                 :                :     {
                                353                 :                :         Relation    arel;
                                354                 :                :         ScanKeyData akey;
                                355                 :                :         SysScanDesc ascan;
                                356                 :                :         HeapTuple   atup;
                                357                 :                :         Form_pg_attribute attForm;
                                358                 :                : 
 1910 andres@anarazel.de        359                 :              0 :         arel = table_open(AttributeRelationId, AccessShareLock);
                                360                 :                : 
 4498 rhaas@postgresql.org      361                 :              0 :         ScanKeyInit(&akey,
                                362                 :                :                     Anum_pg_attribute_attrelid,
                                363                 :                :                     BTEqualStrategyNumber, F_OIDEQ,
                                364                 :                :                     ObjectIdGetDatum(relOid));
                                365                 :                : 
                                366                 :              0 :         ascan = systable_beginscan(arel, AttributeRelidNumIndexId, true,
                                367                 :                :                                    SnapshotSelf, 1, &akey);
                                368                 :                : 
                                369         [ #  # ]:              0 :         while (HeapTupleIsValid(atup = systable_getnext(ascan)))
                                370                 :                :         {
                                371                 :              0 :             attForm = (Form_pg_attribute) GETSTRUCT(atup);
                                372                 :                : 
 4020                           373                 :              0 :             resetStringInfo(&audit_name);
                                374                 :              0 :             appendStringInfo(&audit_name, "%s.%s.%s",
                                375                 :                :                              quote_identifier(nsp_name),
                                376                 :              0 :                              quote_identifier(NameStr(classForm->relname)),
                                377                 :              0 :                              quote_identifier(NameStr(attForm->attname)));
                                378                 :                : 
 4498                           379                 :              0 :             ccontext = sepgsql_compute_create(scontext,
                                380                 :                :                                               rcontext,
                                381                 :                :                                               SEPG_CLASS_DB_COLUMN,
 4035                           382                 :              0 :                                               NameStr(attForm->attname));
                                383                 :                : 
                                384                 :                :             /*
                                385                 :                :              * check db_column:{create} permission
                                386                 :                :              */
 4498                           387                 :              0 :             sepgsql_avc_check_perms_label(ccontext,
                                388                 :                :                                           SEPG_CLASS_DB_COLUMN,
                                389                 :                :                                           SEPG_DB_COLUMN__CREATE,
 4020                           390                 :              0 :                                           audit_name.data,
                                391                 :                :                                           true);
                                392                 :                : 
 4830                           393                 :              0 :             object.classId = RelationRelationId;
                                394                 :              0 :             object.objectId = relOid;
 4498                           395                 :              0 :             object.objectSubId = attForm->attnum;
 4830                           396                 :              0 :             SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ccontext);
                                397                 :                : 
 4498                           398                 :              0 :             pfree(ccontext);
                                399                 :                :         }
                                400                 :              0 :         systable_endscan(ascan);
 1910 andres@anarazel.de        401                 :              0 :         table_close(arel, AccessShareLock);
                                402                 :                :     }
 4830 rhaas@postgresql.org      403                 :              0 :     pfree(rcontext);
                                404                 :                : 
                                405                 :              0 : out:
                                406                 :              0 :     systable_endscan(sscan);
 1910 andres@anarazel.de        407                 :              0 :     table_close(rel, AccessShareLock);
 4830 rhaas@postgresql.org      408                 :              0 : }
                                409                 :                : 
                                410                 :                : /*
                                411                 :                :  * sepgsql_relation_drop
                                412                 :                :  *
                                413                 :                :  * It checks privileges to drop the supplied relation.
                                414                 :                :  */
                                415                 :                : void
 4419                           416                 :              0 : sepgsql_relation_drop(Oid relOid)
                                417                 :                : {
                                418                 :                :     ObjectAddress object;
                                419                 :                :     char       *audit_name;
 2565 mail@joeconway.com        420                 :              0 :     uint16_t    tclass = 0;
 2562                           421                 :              0 :     char        relkind = get_rel_relkind(relOid);
                                422                 :                : 
 4191 alvherre@alvh.no-ip.      423   [ #  #  #  #  :              0 :     switch (relkind)
                                                 # ]
                                424                 :                :     {
                                425                 :              0 :         case RELKIND_RELATION:
                                426                 :                :         case RELKIND_PARTITIONED_TABLE:
                                427                 :              0 :             tclass = SEPG_CLASS_DB_TABLE;
                                428                 :              0 :             break;
                                429                 :              0 :         case RELKIND_SEQUENCE:
                                430                 :              0 :             tclass = SEPG_CLASS_DB_SEQUENCE;
                                431                 :              0 :             break;
                                432                 :              0 :         case RELKIND_VIEW:
                                433                 :              0 :             tclass = SEPG_CLASS_DB_VIEW;
                                434                 :              0 :             break;
                                435                 :              0 :         case RELKIND_INDEX:
                                436                 :                :             /* ignore indexes on toast tables */
                                437         [ #  # ]:              0 :             if (get_rel_namespace(relOid) == PG_TOAST_NAMESPACE)
                                438                 :              0 :                 return;
                                439                 :                :             /* other indexes are handled specially below; no need for tclass */
                                440                 :              0 :             break;
                                441                 :              0 :         default:
                                442                 :                :             /* ignore other relkinds */
                                443                 :              0 :             return;
                                444                 :                :     }
                                445                 :                : 
                                446                 :                :     /*
                                447                 :                :      * check db_schema:{remove_name} permission
                                448                 :                :      */
 4419 rhaas@postgresql.org      449                 :              0 :     object.classId = NamespaceRelationId;
                                450                 :              0 :     object.objectId = get_rel_namespace(relOid);
                                451                 :              0 :     object.objectSubId = 0;
 1369 michael@paquier.xyz       452                 :              0 :     audit_name = getObjectIdentity(&object, false);
                                453                 :                : 
 4419 rhaas@postgresql.org      454                 :              0 :     sepgsql_avc_check_perms(&object,
                                455                 :                :                             SEPG_CLASS_DB_SCHEMA,
                                456                 :                :                             SEPG_DB_SCHEMA__REMOVE_NAME,
                                457                 :                :                             audit_name,
                                458                 :                :                             true);
                                459                 :              0 :     pfree(audit_name);
                                460                 :                : 
                                461                 :                :     /* deal with indexes specially */
 4191 alvherre@alvh.no-ip.      462         [ #  # ]:              0 :     if (relkind == RELKIND_INDEX)
                                463                 :                :     {
                                464                 :              0 :         sepgsql_index_modify(relOid);
                                465                 :              0 :         return;
                                466                 :                :     }
                                467                 :                : 
                                468                 :                :     /*
                                469                 :                :      * check db_table/sequence/view:{drop} permission
                                470                 :                :      */
 4419 rhaas@postgresql.org      471                 :              0 :     object.classId = RelationRelationId;
                                472                 :              0 :     object.objectId = relOid;
                                473                 :              0 :     object.objectSubId = 0;
 1369 michael@paquier.xyz       474                 :              0 :     audit_name = getObjectIdentity(&object, false);
                                475                 :                : 
 4419 rhaas@postgresql.org      476                 :              0 :     sepgsql_avc_check_perms(&object,
                                477                 :                :                             tclass,
                                478                 :                :                             SEPG_DB_TABLE__DROP,
                                479                 :                :                             audit_name,
                                480                 :                :                             true);
                                481                 :              0 :     pfree(audit_name);
                                482                 :                : 
                                483                 :                :     /*
                                484                 :                :      * check db_column:{drop} permission
                                485                 :                :      */
 2562 mail@joeconway.com        486   [ #  #  #  # ]:              0 :     if (relkind == RELKIND_RELATION || relkind == RELKIND_PARTITIONED_TABLE)
                                487                 :                :     {
                                488                 :                :         Form_pg_attribute attForm;
                                489                 :                :         CatCList   *attrList;
                                490                 :                :         HeapTuple   atttup;
                                491                 :                :         int         i;
                                492                 :                : 
 4419 rhaas@postgresql.org      493                 :              0 :         attrList = SearchSysCacheList1(ATTNUM, ObjectIdGetDatum(relOid));
 4326 bruce@momjian.us          494         [ #  # ]:              0 :         for (i = 0; i < attrList->n_members; i++)
                                495                 :                :         {
 4419 rhaas@postgresql.org      496                 :              0 :             atttup = &attrList->members[i]->tuple;
                                497                 :              0 :             attForm = (Form_pg_attribute) GETSTRUCT(atttup);
                                498                 :                : 
                                499         [ #  # ]:              0 :             if (attForm->attisdropped)
                                500                 :              0 :                 continue;
                                501                 :                : 
                                502                 :              0 :             object.classId = RelationRelationId;
                                503                 :              0 :             object.objectId = relOid;
                                504                 :              0 :             object.objectSubId = attForm->attnum;
 1369 michael@paquier.xyz       505                 :              0 :             audit_name = getObjectIdentity(&object, false);
                                506                 :                : 
 4419 rhaas@postgresql.org      507                 :              0 :             sepgsql_avc_check_perms(&object,
                                508                 :                :                                     SEPG_CLASS_DB_COLUMN,
                                509                 :                :                                     SEPG_DB_COLUMN__DROP,
                                510                 :                :                                     audit_name,
                                511                 :                :                                     true);
                                512                 :              0 :             pfree(audit_name);
                                513                 :                :         }
                                514                 :              0 :         ReleaseCatCacheList(attrList);
                                515                 :                :     }
                                516                 :                : }
                                517                 :                : 
                                518                 :                : /*
                                519                 :                :  * sepgsql_relation_truncate
                                520                 :                :  *
                                521                 :                :  * Check privileges to TRUNCATE the supplied relation.
                                522                 :                :  */
                                523                 :                : void
 1604 mail@joeconway.com        524                 :              0 : sepgsql_relation_truncate(Oid relOid)
                                525                 :                : {
                                526                 :                :     ObjectAddress object;
                                527                 :                :     char       *audit_name;
                                528                 :              0 :     uint16_t    tclass = 0;
                                529                 :              0 :     char        relkind = get_rel_relkind(relOid);
                                530                 :                : 
                                531         [ #  # ]:              0 :     switch (relkind)
                                532                 :                :     {
                                533                 :              0 :         case RELKIND_RELATION:
                                534                 :                :         case RELKIND_PARTITIONED_TABLE:
                                535                 :              0 :             tclass = SEPG_CLASS_DB_TABLE;
                                536                 :              0 :             break;
                                537                 :              0 :         default:
                                538                 :                :             /* ignore other relkinds */
                                539                 :              0 :             return;
                                540                 :                :     }
                                541                 :                : 
                                542                 :                :     /*
                                543                 :                :      * check db_table:{truncate} permission
                                544                 :                :      */
                                545                 :              0 :     object.classId = RelationRelationId;
                                546                 :              0 :     object.objectId = relOid;
                                547                 :              0 :     object.objectSubId = 0;
 1369 michael@paquier.xyz       548                 :              0 :     audit_name = getObjectIdentity(&object, false);
                                549                 :                : 
 1604 mail@joeconway.com        550                 :              0 :     sepgsql_avc_check_perms(&object,
                                551                 :                :                             tclass,
                                552                 :                :                             SEPG_DB_TABLE__TRUNCATE,
                                553                 :                :                             audit_name,
                                554                 :                :                             true);
                                555                 :              0 :     pfree(audit_name);
                                556                 :                : }
                                557                 :                : 
                                558                 :                : /*
                                559                 :                :  * sepgsql_relation_relabel
                                560                 :                :  *
                                561                 :                :  * It checks privileges to relabel the supplied relation by the `seclabel'.
                                562                 :                :  */
                                563                 :                : void
 4830 rhaas@postgresql.org      564                 :              0 : sepgsql_relation_relabel(Oid relOid, const char *seclabel)
                                565                 :                : {
                                566                 :                :     ObjectAddress object;
                                567                 :                :     char       *audit_name;
 2562 mail@joeconway.com        568                 :              0 :     char        relkind = get_rel_relkind(relOid);
 4830 rhaas@postgresql.org      569                 :              0 :     uint16_t    tclass = 0;
                                570                 :                : 
 2562 mail@joeconway.com        571   [ #  #  #  # ]:              0 :     if (relkind == RELKIND_RELATION || relkind == RELKIND_PARTITIONED_TABLE)
 4830 rhaas@postgresql.org      572                 :              0 :         tclass = SEPG_CLASS_DB_TABLE;
                                573         [ #  # ]:              0 :     else if (relkind == RELKIND_SEQUENCE)
                                574                 :              0 :         tclass = SEPG_CLASS_DB_SEQUENCE;
                                575         [ #  # ]:              0 :     else if (relkind == RELKIND_VIEW)
                                576                 :              0 :         tclass = SEPG_CLASS_DB_VIEW;
                                577                 :                :     else
                                578         [ #  # ]:              0 :         ereport(ERROR,
                                579                 :                :                 (errcode(ERRCODE_WRONG_OBJECT_TYPE),
                                580                 :                :                  errmsg("cannot set security labels on relations except "
                                581                 :                :                         "for tables, sequences or views")));
                                582                 :                : 
 4609                           583                 :              0 :     object.classId = RelationRelationId;
                                584                 :              0 :     object.objectId = relOid;
                                585                 :              0 :     object.objectSubId = 0;
 1369 michael@paquier.xyz       586                 :              0 :     audit_name = getObjectIdentity(&object, false);
                                587                 :                : 
                                588                 :                :     /*
                                589                 :                :      * check db_xxx:{setattr relabelfrom} permission
                                590                 :                :      */
 4609 rhaas@postgresql.org      591                 :              0 :     sepgsql_avc_check_perms(&object,
                                592                 :                :                             tclass,
                                593                 :                :                             SEPG_DB_TABLE__SETATTR |
                                594                 :                :                             SEPG_DB_TABLE__RELABELFROM,
                                595                 :                :                             audit_name,
                                596                 :                :                             true);
                                597                 :                : 
                                598                 :                :     /*
                                599                 :                :      * check db_xxx:{relabelto} permission
                                600                 :                :      */
                                601                 :              0 :     sepgsql_avc_check_perms_label(seclabel,
                                602                 :                :                                   tclass,
                                603                 :                :                                   SEPG_DB_TABLE__RELABELTO,
                                604                 :                :                                   audit_name,
                                605                 :                :                                   true);
 4820                           606                 :              0 :     pfree(audit_name);
 4830                           607                 :              0 : }
                                608                 :                : 
                                609                 :                : /*
                                610                 :                :  * sepgsql_relation_setattr
                                611                 :                :  *
                                612                 :                :  * It checks privileges to set attribute of the supplied relation
                                613                 :                :  */
                                614                 :                : void
 4191 alvherre@alvh.no-ip.      615                 :              0 : sepgsql_relation_setattr(Oid relOid)
                                616                 :                : {
                                617                 :                :     Relation    rel;
                                618                 :                :     ScanKeyData skey;
                                619                 :                :     SysScanDesc sscan;
                                620                 :                :     HeapTuple   oldtup;
                                621                 :                :     HeapTuple   newtup;
                                622                 :                :     Form_pg_class oldform;
                                623                 :                :     Form_pg_class newform;
                                624                 :                :     ObjectAddress object;
                                625                 :                :     char       *audit_name;
                                626                 :                :     uint16_t    tclass;
                                627                 :                : 
                                628   [ #  #  #  #  :              0 :     switch (get_rel_relkind(relOid))
                                                 # ]
                                629                 :                :     {
                                630                 :              0 :         case RELKIND_RELATION:
                                631                 :                :         case RELKIND_PARTITIONED_TABLE:
                                632                 :              0 :             tclass = SEPG_CLASS_DB_TABLE;
                                633                 :              0 :             break;
                                634                 :              0 :         case RELKIND_SEQUENCE:
                                635                 :              0 :             tclass = SEPG_CLASS_DB_SEQUENCE;
                                636                 :              0 :             break;
                                637                 :              0 :         case RELKIND_VIEW:
                                638                 :              0 :             tclass = SEPG_CLASS_DB_VIEW;
                                639                 :              0 :             break;
                                640                 :              0 :         case RELKIND_INDEX:
                                641                 :                :             /* deal with indexes specially */
                                642                 :              0 :             sepgsql_index_modify(relOid);
                                643                 :              0 :             return;
                                644                 :              0 :         default:
                                645                 :                :             /* other relkinds don't need additional work */
                                646                 :              0 :             return;
                                647                 :                :     }
                                648                 :                : 
                                649                 :                :     /*
                                650                 :                :      * Fetch newer catalog
                                651                 :                :      */
 1910 andres@anarazel.de        652                 :              0 :     rel = table_open(RelationRelationId, AccessShareLock);
                                653                 :                : 
 4036 rhaas@postgresql.org      654                 :              0 :     ScanKeyInit(&skey,
                                655                 :                :                 Anum_pg_class_oid,
                                656                 :                :                 BTEqualStrategyNumber, F_OIDEQ,
                                657                 :                :                 ObjectIdGetDatum(relOid));
                                658                 :                : 
                                659                 :              0 :     sscan = systable_beginscan(rel, ClassOidIndexId, true,
                                660                 :                :                                SnapshotSelf, 1, &skey);
                                661                 :                : 
                                662                 :              0 :     newtup = systable_getnext(sscan);
                                663         [ #  # ]:              0 :     if (!HeapTupleIsValid(newtup))
 2506 tgl@sss.pgh.pa.us         664         [ #  # ]:              0 :         elog(ERROR, "could not find tuple for relation %u", relOid);
 4036 rhaas@postgresql.org      665                 :              0 :     newform = (Form_pg_class) GETSTRUCT(newtup);
                                666                 :                : 
                                667                 :                :     /*
                                668                 :                :      * Fetch older catalog
                                669                 :                :      */
                                670                 :              0 :     oldtup = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
                                671         [ #  # ]:              0 :     if (!HeapTupleIsValid(oldtup))
                                672         [ #  # ]:              0 :         elog(ERROR, "cache lookup failed for relation %u", relOid);
                                673                 :              0 :     oldform = (Form_pg_class) GETSTRUCT(oldtup);
                                674                 :                : 
                                675                 :                :     /*
                                676                 :                :      * Does this ALTER command takes operation to namespace?
                                677                 :                :      */
                                678         [ #  # ]:              0 :     if (newform->relnamespace != oldform->relnamespace)
                                679                 :                :     {
                                680                 :              0 :         sepgsql_schema_remove_name(oldform->relnamespace);
                                681                 :              0 :         sepgsql_schema_add_name(newform->relnamespace);
                                682                 :                :     }
                                683         [ #  # ]:              0 :     if (strcmp(NameStr(newform->relname), NameStr(oldform->relname)) != 0)
                                684                 :              0 :         sepgsql_schema_rename(oldform->relnamespace);
                                685                 :                : 
                                686                 :                :     /*
                                687                 :                :      * XXX - In the future version, db_tuple:{use} of system catalog entry
                                688                 :                :      * shall be checked, if tablespace configuration is changed.
                                689                 :                :      */
                                690                 :                : 
                                691                 :                :     /*
                                692                 :                :      * check db_xxx:{setattr} permission
                                693                 :                :      */
                                694                 :              0 :     object.classId = RelationRelationId;
                                695                 :              0 :     object.objectId = relOid;
                                696                 :              0 :     object.objectSubId = 0;
 1369 michael@paquier.xyz       697                 :              0 :     audit_name = getObjectIdentity(&object, false);
                                698                 :                : 
 4191 alvherre@alvh.no-ip.      699                 :              0 :     sepgsql_avc_check_perms(&object,
                                700                 :                :                             tclass,
                                701                 :                :                             SEPG_DB_TABLE__SETATTR,
                                702                 :                :                             audit_name,
                                703                 :                :                             true);
                                704                 :              0 :     pfree(audit_name);
                                705                 :                : 
 4036 rhaas@postgresql.org      706                 :              0 :     ReleaseSysCache(oldtup);
                                707                 :              0 :     systable_endscan(sscan);
 1910 andres@anarazel.de        708                 :              0 :     table_close(rel, AccessShareLock);
                                709                 :                : }
                                710                 :                : 
                                711                 :                : /*
                                712                 :                :  * sepgsql_relation_setattr_extra
                                713                 :                :  *
                                714                 :                :  * It checks permission of the relation being referenced by extra attributes,
                                715                 :                :  * such as pg_index entries. Like core PostgreSQL, sepgsql also does not deal
                                716                 :                :  * with such entries as individual "objects", thus, modification of these
                                717                 :                :  * entries shall be considered as setting an attribute of the underlying
                                718                 :                :  * relation.
                                719                 :                :  */
                                720                 :                : static void
 4191 alvherre@alvh.no-ip.      721                 :              0 : sepgsql_relation_setattr_extra(Relation catalog,
                                722                 :                :                                Oid catindex_id,
                                723                 :                :                                Oid extra_oid,
                                724                 :                :                                AttrNumber anum_relation_id,
                                725                 :                :                                AttrNumber anum_extra_id)
                                726                 :                : {
                                727                 :                :     ScanKeyData skey;
                                728                 :                :     SysScanDesc sscan;
                                729                 :                :     HeapTuple   tuple;
                                730                 :                :     Datum       datum;
                                731                 :                :     bool        isnull;
                                732                 :                : 
                                733                 :              0 :     ScanKeyInit(&skey, anum_extra_id,
                                734                 :                :                 BTEqualStrategyNumber, F_OIDEQ,
                                735                 :                :                 ObjectIdGetDatum(extra_oid));
                                736                 :                : 
                                737                 :              0 :     sscan = systable_beginscan(catalog, catindex_id, true,
                                738                 :                :                                SnapshotSelf, 1, &skey);
                                739                 :              0 :     tuple = systable_getnext(sscan);
                                740         [ #  # ]:              0 :     if (!HeapTupleIsValid(tuple))
 2506 tgl@sss.pgh.pa.us         741         [ #  # ]:              0 :         elog(ERROR, "could not find tuple for object %u in catalog \"%s\"",
                                742                 :                :              extra_oid, RelationGetRelationName(catalog));
                                743                 :                : 
 4191 alvherre@alvh.no-ip.      744                 :              0 :     datum = heap_getattr(tuple, anum_relation_id,
                                745                 :                :                          RelationGetDescr(catalog), &isnull);
                                746         [ #  # ]:              0 :     Assert(!isnull);
                                747                 :                : 
                                748                 :              0 :     sepgsql_relation_setattr(DatumGetObjectId(datum));
                                749                 :                : 
                                750                 :              0 :     systable_endscan(sscan);
                                751                 :              0 : }
                                752                 :                : 
                                753                 :                : /*
                                754                 :                :  * sepgsql_index_modify
                                755                 :                :  *      Handle index create, update, drop
                                756                 :                :  *
                                757                 :                :  * Unlike other relation kinds, indexes do not have their own security labels,
                                758                 :                :  * so instead of doing checks directly, treat them as extra attributes of their
                                759                 :                :  * owning tables; so check 'setattr' permissions on the table.
                                760                 :                :  */
                                761                 :                : static void
                                762                 :              0 : sepgsql_index_modify(Oid indexOid)
                                763                 :                : {
 1910 andres@anarazel.de        764                 :              0 :     Relation    catalog = table_open(IndexRelationId, AccessShareLock);
                                765                 :                : 
                                766                 :                :     /* check db_table:{setattr} permission of the table being indexed */
 4191 alvherre@alvh.no-ip.      767                 :              0 :     sepgsql_relation_setattr_extra(catalog,
                                768                 :                :                                    IndexRelidIndexId,
                                769                 :                :                                    indexOid,
                                770                 :                :                                    Anum_pg_index_indrelid,
                                771                 :                :                                    Anum_pg_index_indexrelid);
 1910 andres@anarazel.de        772                 :              0 :     table_close(catalog, AccessShareLock);
 4191 alvherre@alvh.no-ip.      773                 :              0 : }
        

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