PostgreSQL Source Code  git master
relation.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/sysattr.h"
#include "access/table.h"
#include "catalog/dependency.h"
#include "catalog/pg_attribute.h"
#include "catalog/pg_class.h"
#include "catalog/pg_namespace.h"
#include "commands/seclabel.h"
#include "lib/stringinfo.h"
#include "sepgsql.h"
#include "utils/builtins.h"
#include "utils/catcache.h"
#include "utils/fmgroids.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/snapmgr.h"
#include "utils/syscache.h"
Include dependency graph for relation.c:

Go to the source code of this file.

Functions

static void sepgsql_index_modify (Oid indexOid)
 
void sepgsql_attribute_post_create (Oid relOid, AttrNumber attnum)
 
void sepgsql_attribute_drop (Oid relOid, AttrNumber attnum)
 
void sepgsql_attribute_relabel (Oid relOid, AttrNumber attnum, const char *seclabel)
 
void sepgsql_attribute_setattr (Oid relOid, AttrNumber attnum)
 
void sepgsql_relation_post_create (Oid relOid)
 
void sepgsql_relation_drop (Oid relOid)
 
void sepgsql_relation_truncate (Oid relOid)
 
void sepgsql_relation_relabel (Oid relOid, const char *seclabel)
 
void sepgsql_relation_setattr (Oid relOid)
 
static void sepgsql_relation_setattr_extra (Relation catalog, Oid catindex_id, Oid extra_oid, AttrNumber anum_relation_id, AttrNumber anum_extra_id)
 

Function Documentation

◆ sepgsql_attribute_drop()

void sepgsql_attribute_drop ( Oid  relOid,
AttrNumber  attnum 
)

Definition at line 133 of file relation.c.

References attnum, get_rel_relkind(), getObjectIdentity(), pfree(), SEPG_CLASS_DB_COLUMN, SEPG_DB_COLUMN__DROP, and sepgsql_avc_check_perms().

Referenced by sepgsql_object_access().

134 {
135  ObjectAddress object;
136  char *audit_name;
137  char relkind = get_rel_relkind(relOid);
138 
139  if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
140  return;
141 
142  /*
143  * check db_column:{drop} permission
144  */
145  object.classId = RelationRelationId;
146  object.objectId = relOid;
147  object.objectSubId = attnum;
148  audit_name = getObjectIdentity(&object, false);
149 
150  sepgsql_avc_check_perms(&object,
153  audit_name,
154  true);
155  pfree(audit_name);
156 }
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1920
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:419
void pfree(void *pointer)
Definition: mcxt.c:1057
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
#define SEPG_DB_COLUMN__DROP
Definition: sepgsql.h:171
int16 attnum
Definition: pg_attribute.h:79

◆ sepgsql_attribute_post_create()

void sepgsql_attribute_post_create ( Oid  relOid,
AttrNumber  attnum 
)

Definition at line 43 of file relation.c.

References AccessShareLock, appendStringInfo(), attnum, AttributeRelidNumIndexId, BTEqualStrategyNumber, StringInfoData::data, elog, ERROR, get_rel_relkind(), getObjectIdentity(), GETSTRUCT, HeapTupleIsValid, initStringInfo(), Int16GetDatum, NameStr, ObjectIdGetDatum, pfree(), quote_identifier(), ScanKeyInit(), SEPG_CLASS_DB_COLUMN, SEPG_DB_COLUMN__CREATE, sepgsql_avc_check_perms_label(), sepgsql_compute_create(), sepgsql_get_client_label(), sepgsql_get_label(), SEPGSQL_LABEL_TAG, SetSecurityLabel(), SnapshotSelf, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by sepgsql_object_access().

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;
55  char relkind = get_rel_relkind(relOid);
56 
57  /*
58  * Only attributes within regular relations or partition relations have
59  * individual security labels.
60  */
61  if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
62  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  */
68  rel = table_open(AttributeRelationId, AccessShareLock);
69 
70  ScanKeyInit(&skey[0],
71  Anum_pg_attribute_attrelid,
72  BTEqualStrategyNumber, F_OIDEQ,
73  ObjectIdGetDatum(relOid));
74  ScanKeyInit(&skey[1],
75  Anum_pg_attribute_attnum,
76  BTEqualStrategyNumber, F_INT2EQ,
78 
80  SnapshotSelf, 2, &skey[0]);
81 
82  tuple = systable_getnext(sscan);
83  if (!HeapTupleIsValid(tuple))
84  elog(ERROR, "could not find tuple for column %d of relation %u",
85  attnum, relOid);
86 
87  attForm = (Form_pg_attribute) GETSTRUCT(tuple);
88 
89  scontext = sepgsql_get_client_label();
90  tcontext = sepgsql_get_label(RelationRelationId, relOid, 0);
91  ncontext = sepgsql_compute_create(scontext, tcontext,
93  NameStr(attForm->attname));
94 
95  /*
96  * check db_column:{create} permission
97  */
98  object.classId = RelationRelationId;
99  object.objectId = relOid;
100  object.objectSubId = 0;
101 
102  initStringInfo(&audit_name);
103  appendStringInfo(&audit_name, "%s.%s",
104  getObjectIdentity(&object, false),
105  quote_identifier(NameStr(attForm->attname)));
109  audit_name.data,
110  true);
111 
112  /*
113  * Assign the default security label on a new procedure
114  */
115  object.classId = RelationRelationId;
116  object.objectId = relOid;
117  object.objectSubId = attnum;
118  SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
119 
120  systable_endscan(sscan);
122 
123  pfree(tcontext);
124  pfree(ncontext);
125 }
bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:337
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
void SetSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition: seclabel.c:401
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10934
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1920
char * sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
Definition: label.c:445
#define Int16GetDatum(X)
Definition: postgres.h:451
#define AccessShareLock
Definition: lockdefs.h:36
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
void pfree(void *pointer)
Definition: mcxt.c:1057
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
#define SnapshotSelf
Definition: snapmgr.h:67
#define AttributeRelidNumIndexId
Definition: pg_attribute.h:198
#define SEPGSQL_LABEL_TAG
Definition: sepgsql.h:23
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
int16 attnum
Definition: pg_attribute.h:79
#define SEPG_DB_COLUMN__CREATE
Definition: sepgsql.h:170
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
char * sepgsql_get_client_label(void)
Definition: label.c:80
char * sepgsql_compute_create(const char *scontext, const char *tcontext, uint16 tclass, const char *objname)
Definition: selinux.c:836
#define elog(elevel,...)
Definition: elog.h:228
#define NameStr(name)
Definition: c.h:677
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ sepgsql_attribute_relabel()

void sepgsql_attribute_relabel ( Oid  relOid,
AttrNumber  attnum,
const char *  seclabel 
)

Definition at line 165 of file relation.c.

References attnum, ereport, errcode(), errmsg(), ERROR, get_rel_relkind(), getObjectIdentity(), pfree(), SEPG_CLASS_DB_COLUMN, SEPG_DB_COLUMN__RELABELFROM, SEPG_DB_COLUMN__SETATTR, SEPG_DB_PROCEDURE__RELABELTO, sepgsql_avc_check_perms(), and sepgsql_avc_check_perms_label().

Referenced by sepgsql_object_relabel().

167 {
168  ObjectAddress object;
169  char *audit_name;
170  char relkind = get_rel_relkind(relOid);
171 
172  if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
173  ereport(ERROR,
174  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
175  errmsg("cannot set security label on non-regular columns")));
176 
177  object.classId = RelationRelationId;
178  object.objectId = relOid;
179  object.objectSubId = attnum;
180  audit_name = getObjectIdentity(&object, false);
181 
182  /*
183  * check db_column:{setattr relabelfrom} permission
184  */
185  sepgsql_avc_check_perms(&object,
189  audit_name,
190  true);
191 
192  /*
193  * check db_column:{relabelto} permission
194  */
198  audit_name,
199  true);
200  pfree(audit_name);
201 }
bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:337
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
#define SEPG_DB_COLUMN__SETATTR
Definition: sepgsql.h:173
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1920
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:419
int errcode(int sqlerrcode)
Definition: elog.c:691
#define SEPG_DB_COLUMN__RELABELFROM
Definition: sepgsql.h:174
void pfree(void *pointer)
Definition: mcxt.c:1057
#define ERROR
Definition: elog.h:43
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
#define SEPG_DB_PROCEDURE__RELABELTO
Definition: sepgsql.h:165
int16 attnum
Definition: pg_attribute.h:79
#define ereport(elevel,...)
Definition: elog.h:155
int errmsg(const char *fmt,...)
Definition: elog.c:902

◆ sepgsql_attribute_setattr()

void sepgsql_attribute_setattr ( Oid  relOid,
AttrNumber  attnum 
)

Definition at line 209 of file relation.c.

References attnum, get_rel_relkind(), getObjectIdentity(), pfree(), SEPG_CLASS_DB_COLUMN, SEPG_DB_COLUMN__SETATTR, and sepgsql_avc_check_perms().

Referenced by sepgsql_object_access().

210 {
211  ObjectAddress object;
212  char *audit_name;
213  char relkind = get_rel_relkind(relOid);
214 
215  if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
216  return;
217 
218  /*
219  * check db_column:{setattr} permission
220  */
221  object.classId = RelationRelationId;
222  object.objectId = relOid;
223  object.objectSubId = attnum;
224  audit_name = getObjectIdentity(&object, false);
225 
226  sepgsql_avc_check_perms(&object,
229  audit_name,
230  true);
231  pfree(audit_name);
232 }
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
#define SEPG_DB_COLUMN__SETATTR
Definition: sepgsql.h:173
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1920
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:419
void pfree(void *pointer)
Definition: mcxt.c:1057
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
int16 attnum
Definition: pg_attribute.h:79

◆ sepgsql_index_modify()

static void sepgsql_index_modify ( Oid  indexOid)
static

Definition at line 762 of file relation.c.

References AccessShareLock, IndexRelidIndexId, sepgsql_relation_setattr_extra(), table_close(), and table_open().

Referenced by sepgsql_relation_drop(), sepgsql_relation_post_create(), and sepgsql_relation_setattr().

763 {
764  Relation catalog = table_open(IndexRelationId, AccessShareLock);
765 
766  /* check db_table:{setattr} permission of the table being indexed */
769  indexOid,
770  Anum_pg_index_indrelid,
771  Anum_pg_index_indexrelid);
772  table_close(catalog, AccessShareLock);
773 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
#define IndexRelidIndexId
Definition: pg_index.h:73
#define AccessShareLock
Definition: lockdefs.h:36
static void sepgsql_relation_setattr_extra(Relation catalog, Oid catindex_id, Oid extra_oid, AttrNumber anum_relation_id, AttrNumber anum_extra_id)
Definition: relation.c:721
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39

◆ sepgsql_relation_drop()

void sepgsql_relation_drop ( Oid  relOid)

Definition at line 416 of file relation.c.

References ATTNUM, get_rel_namespace(), get_rel_relkind(), getObjectIdentity(), GETSTRUCT, i, catclist::members, catclist::n_members, ObjectIdGetDatum, pfree(), ReleaseCatCacheList(), SearchSysCacheList1, SEPG_CLASS_DB_COLUMN, SEPG_CLASS_DB_SCHEMA, SEPG_CLASS_DB_SEQUENCE, SEPG_CLASS_DB_TABLE, SEPG_CLASS_DB_VIEW, SEPG_DB_COLUMN__DROP, SEPG_DB_SCHEMA__REMOVE_NAME, SEPG_DB_TABLE__DROP, sepgsql_avc_check_perms(), sepgsql_index_modify(), and catctup::tuple.

Referenced by sepgsql_object_access().

417 {
418  ObjectAddress object;
419  char *audit_name;
420  uint16_t tclass = 0;
421  char relkind = get_rel_relkind(relOid);
422 
423  switch (relkind)
424  {
425  case RELKIND_RELATION:
426  case RELKIND_PARTITIONED_TABLE:
427  tclass = SEPG_CLASS_DB_TABLE;
428  break;
429  case RELKIND_SEQUENCE:
430  tclass = SEPG_CLASS_DB_SEQUENCE;
431  break;
432  case RELKIND_VIEW:
433  tclass = SEPG_CLASS_DB_VIEW;
434  break;
435  case RELKIND_INDEX:
436  /* ignore indexes on toast tables */
437  if (get_rel_namespace(relOid) == PG_TOAST_NAMESPACE)
438  return;
439  /* other indexes are handled specially below; no need for tclass */
440  break;
441  default:
442  /* ignore other relkinds */
443  return;
444  }
445 
446  /*
447  * check db_schema:{remove_name} permission
448  */
449  object.classId = NamespaceRelationId;
450  object.objectId = get_rel_namespace(relOid);
451  object.objectSubId = 0;
452  audit_name = getObjectIdentity(&object, false);
453 
454  sepgsql_avc_check_perms(&object,
457  audit_name,
458  true);
459  pfree(audit_name);
460 
461  /* deal with indexes specially */
462  if (relkind == RELKIND_INDEX)
463  {
464  sepgsql_index_modify(relOid);
465  return;
466  }
467 
468  /*
469  * check db_table/sequence/view:{drop} permission
470  */
471  object.classId = RelationRelationId;
472  object.objectId = relOid;
473  object.objectSubId = 0;
474  audit_name = getObjectIdentity(&object, false);
475 
476  sepgsql_avc_check_perms(&object,
477  tclass,
479  audit_name,
480  true);
481  pfree(audit_name);
482 
483  /*
484  * check db_column:{drop} permission
485  */
486  if (relkind == RELKIND_RELATION || relkind == RELKIND_PARTITIONED_TABLE)
487  {
488  Form_pg_attribute attForm;
489  CatCList *attrList;
490  HeapTuple atttup;
491  int i;
492 
493  attrList = SearchSysCacheList1(ATTNUM, ObjectIdGetDatum(relOid));
494  for (i = 0; i < attrList->n_members; i++)
495  {
496  atttup = &attrList->members[i]->tuple;
497  attForm = (Form_pg_attribute) GETSTRUCT(atttup);
498 
499  if (attForm->attisdropped)
500  continue;
501 
502  object.classId = RelationRelationId;
503  object.objectId = relOid;
504  object.objectSubId = attForm->attnum;
505  audit_name = getObjectIdentity(&object, false);
506 
507  sepgsql_avc_check_perms(&object,
510  audit_name,
511  true);
512  pfree(audit_name);
513  }
514  ReleaseCatCacheList(attrList);
515  }
516 }
int n_members
Definition: catcache.h:176
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1920
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:419
Oid get_rel_namespace(Oid relid)
Definition: lsyscache.c:1869
#define SEPG_CLASS_DB_SCHEMA
Definition: sepgsql.h:45
void ReleaseCatCacheList(CatCList *list)
Definition: catcache.c:1782
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:178
void pfree(void *pointer)
Definition: mcxt.c:1057
#define SEPG_CLASS_DB_SEQUENCE
Definition: sepgsql.h:47
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
#define SEPG_DB_TABLE__DROP
Definition: sepgsql.h:138
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:210
static void sepgsql_index_modify(Oid indexOid)
Definition: relation.c:762
#define SEPG_CLASS_DB_VIEW
Definition: sepgsql.h:53
#define SEPG_DB_COLUMN__DROP
Definition: sepgsql.h:171
#define SEPG_CLASS_DB_TABLE
Definition: sepgsql.h:46
int i
HeapTupleData tuple
Definition: catcache.h:121
#define SEPG_DB_SCHEMA__REMOVE_NAME
Definition: sepgsql.h:135

◆ sepgsql_relation_post_create()

void sepgsql_relation_post_create ( Oid  relOid)

Definition at line 240 of file relation.c.

References AccessShareLock, appendStringInfo(), AttributeRelidNumIndexId, BTEqualStrategyNumber, ClassOidIndexId, StringInfoData::data, elog, ERROR, get_namespace_name(), getObjectIdentity(), GETSTRUCT, HeapTupleIsValid, initStringInfo(), NameStr, ObjectIdGetDatum, pfree(), quote_identifier(), resetStringInfo(), ScanKeyInit(), SEPG_CLASS_DB_COLUMN, SEPG_CLASS_DB_SCHEMA, SEPG_CLASS_DB_SEQUENCE, SEPG_CLASS_DB_TABLE, SEPG_CLASS_DB_VIEW, SEPG_DB_COLUMN__CREATE, SEPG_DB_DATABASE__CREATE, SEPG_DB_SCHEMA__ADD_NAME, sepgsql_avc_check_perms(), sepgsql_avc_check_perms_label(), sepgsql_compute_create(), sepgsql_get_client_label(), sepgsql_get_label(), sepgsql_index_modify(), SEPGSQL_LABEL_TAG, SetSecurityLabel(), SnapshotSelf, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by sepgsql_object_access().

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  */
260  rel = table_open(RelationRelationId, AccessShareLock);
261 
262  ScanKeyInit(&skey,
263  Anum_pg_class_oid,
264  BTEqualStrategyNumber, F_OIDEQ,
265  ObjectIdGetDatum(relOid));
266 
267  sscan = systable_beginscan(rel, ClassOidIndexId, true,
268  SnapshotSelf, 1, &skey);
269 
270  tuple = systable_getnext(sscan);
271  if (!HeapTupleIsValid(tuple))
272  elog(ERROR, "could not find tuple for relation %u", relOid);
273 
274  classForm = (Form_pg_class) GETSTRUCT(tuple);
275 
276  /* ignore indexes on toast tables */
277  if (classForm->relkind == RELKIND_INDEX &&
278  classForm->relnamespace == PG_TOAST_NAMESPACE)
279  goto out;
280 
281  /*
282  * check db_schema:{add_name} permission of the namespace
283  */
284  object.classId = NamespaceRelationId;
285  object.objectId = classForm->relnamespace;
286  object.objectSubId = 0;
287  sepgsql_avc_check_perms(&object,
290  getObjectIdentity(&object, false),
291  true);
292 
293  switch (classForm->relkind)
294  {
295  case RELKIND_RELATION:
296  case RELKIND_PARTITIONED_TABLE:
297  tclass = SEPG_CLASS_DB_TABLE;
298  break;
299  case RELKIND_SEQUENCE:
300  tclass = SEPG_CLASS_DB_SEQUENCE;
301  break;
302  case RELKIND_VIEW:
303  tclass = SEPG_CLASS_DB_VIEW;
304  break;
305  case RELKIND_INDEX:
306  /* deal with indexes specially; no need for tclass */
307  sepgsql_index_modify(relOid);
308  goto out;
309  default:
310  /* ignore other relkinds */
311  goto out;
312  }
313 
314  /*
315  * Compute a default security label when we create a new relation object
316  * under the specified namespace.
317  */
318  scontext = sepgsql_get_client_label();
319  tcontext = sepgsql_get_label(NamespaceRelationId,
320  classForm->relnamespace, 0);
321  rcontext = sepgsql_compute_create(scontext, tcontext, tclass,
322  NameStr(classForm->relname));
323 
324  /*
325  * check db_xxx:{create} permission
326  */
327  nsp_name = get_namespace_name(classForm->relnamespace);
328  initStringInfo(&audit_name);
329  appendStringInfo(&audit_name, "%s.%s",
330  quote_identifier(nsp_name),
331  quote_identifier(NameStr(classForm->relname)));
333  tclass,
335  audit_name.data,
336  true);
337 
338  /*
339  * Assign the default security label on the new regular or partitioned
340  * relation.
341  */
342  object.classId = RelationRelationId;
343  object.objectId = relOid;
344  object.objectSubId = 0;
345  SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, rcontext);
346 
347  /*
348  * We also assign a default security label on columns of a new table.
349  */
350  if (classForm->relkind == RELKIND_RELATION ||
351  classForm->relkind == RELKIND_PARTITIONED_TABLE)
352  {
353  Relation arel;
354  ScanKeyData akey;
355  SysScanDesc ascan;
356  HeapTuple atup;
357  Form_pg_attribute attForm;
358 
359  arel = table_open(AttributeRelationId, AccessShareLock);
360 
361  ScanKeyInit(&akey,
362  Anum_pg_attribute_attrelid,
363  BTEqualStrategyNumber, F_OIDEQ,
364  ObjectIdGetDatum(relOid));
365 
366  ascan = systable_beginscan(arel, AttributeRelidNumIndexId, true,
367  SnapshotSelf, 1, &akey);
368 
369  while (HeapTupleIsValid(atup = systable_getnext(ascan)))
370  {
371  attForm = (Form_pg_attribute) GETSTRUCT(atup);
372 
373  resetStringInfo(&audit_name);
374  appendStringInfo(&audit_name, "%s.%s.%s",
375  quote_identifier(nsp_name),
376  quote_identifier(NameStr(classForm->relname)),
377  quote_identifier(NameStr(attForm->attname)));
378 
379  ccontext = sepgsql_compute_create(scontext,
380  rcontext,
382  NameStr(attForm->attname));
383 
384  /*
385  * check db_column:{create} permission
386  */
390  audit_name.data,
391  true);
392 
393  object.classId = RelationRelationId;
394  object.objectId = relOid;
395  object.objectSubId = attForm->attnum;
396  SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ccontext);
397 
398  pfree(ccontext);
399  }
400  systable_endscan(ascan);
402  }
403  pfree(rcontext);
404 
405 out:
406  systable_endscan(sscan);
408 }
bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:337
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
void SetSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition: seclabel.c:401
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10934
char * sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
Definition: label.c:445
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:419
#define AccessShareLock
Definition: lockdefs.h:36
#define SEPG_CLASS_DB_SCHEMA
Definition: sepgsql.h:45
#define ClassOidIndexId
Definition: pg_class.h:156
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define SEPG_DB_DATABASE__CREATE
Definition: sepgsql.h:118
void pfree(void *pointer)
Definition: mcxt.c:1057
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define SEPG_CLASS_DB_SEQUENCE
Definition: sepgsql.h:47
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3196
#define SnapshotSelf
Definition: snapmgr.h:67
#define AttributeRelidNumIndexId
Definition: pg_attribute.h:198
#define SEPGSQL_LABEL_TAG
Definition: sepgsql.h:23
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:193
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:75
static void sepgsql_index_modify(Oid indexOid)
Definition: relation.c:762
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define SEPG_CLASS_DB_VIEW
Definition: sepgsql.h:53
#define SEPG_DB_SCHEMA__ADD_NAME
Definition: sepgsql.h:134
#define SEPG_DB_COLUMN__CREATE
Definition: sepgsql.h:170
#define SEPG_CLASS_DB_TABLE
Definition: sepgsql.h:46
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
char * sepgsql_get_client_label(void)
Definition: label.c:80
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
char * sepgsql_compute_create(const char *scontext, const char *tcontext, uint16 tclass, const char *objname)
Definition: selinux.c:836
#define elog(elevel,...)
Definition: elog.h:228
#define NameStr(name)
Definition: c.h:677
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ sepgsql_relation_relabel()

void sepgsql_relation_relabel ( Oid  relOid,
const char *  seclabel 
)

Definition at line 564 of file relation.c.

References ereport, errcode(), errmsg(), ERROR, get_rel_relkind(), getObjectIdentity(), pfree(), SEPG_CLASS_DB_SEQUENCE, SEPG_CLASS_DB_TABLE, SEPG_CLASS_DB_VIEW, SEPG_DB_TABLE__RELABELFROM, SEPG_DB_TABLE__RELABELTO, SEPG_DB_TABLE__SETATTR, sepgsql_avc_check_perms(), and sepgsql_avc_check_perms_label().

Referenced by sepgsql_object_relabel().

565 {
566  ObjectAddress object;
567  char *audit_name;
568  char relkind = get_rel_relkind(relOid);
569  uint16_t tclass = 0;
570 
571  if (relkind == RELKIND_RELATION || relkind == RELKIND_PARTITIONED_TABLE)
572  tclass = SEPG_CLASS_DB_TABLE;
573  else if (relkind == RELKIND_SEQUENCE)
574  tclass = SEPG_CLASS_DB_SEQUENCE;
575  else if (relkind == RELKIND_VIEW)
576  tclass = SEPG_CLASS_DB_VIEW;
577  else
578  ereport(ERROR,
579  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
580  errmsg("cannot set security labels on relations except "
581  "for tables, sequences or views")));
582 
583  object.classId = RelationRelationId;
584  object.objectId = relOid;
585  object.objectSubId = 0;
586  audit_name = getObjectIdentity(&object, false);
587 
588  /*
589  * check db_xxx:{setattr relabelfrom} permission
590  */
591  sepgsql_avc_check_perms(&object,
592  tclass,
595  audit_name,
596  true);
597 
598  /*
599  * check db_xxx:{relabelto} permission
600  */
602  tclass,
604  audit_name,
605  true);
606  pfree(audit_name);
607 }
bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:337
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1920
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:419
int errcode(int sqlerrcode)
Definition: elog.c:691
#define SEPG_DB_TABLE__SETATTR
Definition: sepgsql.h:140
void pfree(void *pointer)
Definition: mcxt.c:1057
#define SEPG_CLASS_DB_SEQUENCE
Definition: sepgsql.h:47
#define ERROR
Definition: elog.h:43
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
#define SEPG_DB_TABLE__RELABELTO
Definition: sepgsql.h:142
#define SEPG_CLASS_DB_VIEW
Definition: sepgsql.h:53
#define SEPG_DB_TABLE__RELABELFROM
Definition: sepgsql.h:141
#define ereport(elevel,...)
Definition: elog.h:155
#define SEPG_CLASS_DB_TABLE
Definition: sepgsql.h:46
int errmsg(const char *fmt,...)
Definition: elog.c:902

◆ sepgsql_relation_setattr()

void sepgsql_relation_setattr ( Oid  relOid)

Definition at line 615 of file relation.c.

References AccessShareLock, BTEqualStrategyNumber, ClassOidIndexId, elog, ERROR, get_rel_relkind(), getObjectIdentity(), GETSTRUCT, HeapTupleIsValid, NameStr, ObjectIdGetDatum, pfree(), ReleaseSysCache(), RELOID, ScanKeyInit(), SearchSysCache1(), SEPG_CLASS_DB_SEQUENCE, SEPG_CLASS_DB_TABLE, SEPG_CLASS_DB_VIEW, SEPG_DB_TABLE__SETATTR, sepgsql_avc_check_perms(), sepgsql_index_modify(), sepgsql_schema_add_name(), sepgsql_schema_remove_name(), sepgsql_schema_rename(), SnapshotSelf, systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by sepgsql_object_access(), and sepgsql_relation_setattr_extra().

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  switch (get_rel_relkind(relOid))
629  {
630  case RELKIND_RELATION:
631  case RELKIND_PARTITIONED_TABLE:
632  tclass = SEPG_CLASS_DB_TABLE;
633  break;
634  case RELKIND_SEQUENCE:
635  tclass = SEPG_CLASS_DB_SEQUENCE;
636  break;
637  case RELKIND_VIEW:
638  tclass = SEPG_CLASS_DB_VIEW;
639  break;
640  case RELKIND_INDEX:
641  /* deal with indexes specially */
642  sepgsql_index_modify(relOid);
643  return;
644  default:
645  /* other relkinds don't need additional work */
646  return;
647  }
648 
649  /*
650  * Fetch newer catalog
651  */
652  rel = table_open(RelationRelationId, AccessShareLock);
653 
654  ScanKeyInit(&skey,
655  Anum_pg_class_oid,
656  BTEqualStrategyNumber, F_OIDEQ,
657  ObjectIdGetDatum(relOid));
658 
659  sscan = systable_beginscan(rel, ClassOidIndexId, true,
660  SnapshotSelf, 1, &skey);
661 
662  newtup = systable_getnext(sscan);
663  if (!HeapTupleIsValid(newtup))
664  elog(ERROR, "could not find tuple for relation %u", relOid);
665  newform = (Form_pg_class) GETSTRUCT(newtup);
666 
667  /*
668  * Fetch older catalog
669  */
670  oldtup = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
671  if (!HeapTupleIsValid(oldtup))
672  elog(ERROR, "cache lookup failed for relation %u", relOid);
673  oldform = (Form_pg_class) GETSTRUCT(oldtup);
674 
675  /*
676  * Does this ALTER command takes operation to namespace?
677  */
678  if (newform->relnamespace != oldform->relnamespace)
679  {
680  sepgsql_schema_remove_name(oldform->relnamespace);
681  sepgsql_schema_add_name(newform->relnamespace);
682  }
683  if (strcmp(NameStr(newform->relname), NameStr(oldform->relname)) != 0)
684  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  object.classId = RelationRelationId;
695  object.objectId = relOid;
696  object.objectSubId = 0;
697  audit_name = getObjectIdentity(&object, false);
698 
699  sepgsql_avc_check_perms(&object,
700  tclass,
702  audit_name,
703  true);
704  pfree(audit_name);
705 
706  ReleaseSysCache(oldtup);
707  systable_endscan(sscan);
709 }
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define GETSTRUCT(TUP)
Definition: htup_details.h:655
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1920
void sepgsql_schema_add_name(Oid namespaceId)
Definition: schema.c:217
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:419
void sepgsql_schema_remove_name(Oid namespaceId)
Definition: schema.c:223
#define AccessShareLock
Definition: lockdefs.h:36
#define ClassOidIndexId
Definition: pg_class.h:156
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
#define SEPG_DB_TABLE__SETATTR
Definition: sepgsql.h:140
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
void pfree(void *pointer)
Definition: mcxt.c:1057
#define SEPG_CLASS_DB_SEQUENCE
Definition: sepgsql.h:47
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
void sepgsql_schema_rename(Oid namespaceId)
Definition: schema.c:229
#define SnapshotSelf
Definition: snapmgr.h:67
static void sepgsql_index_modify(Oid indexOid)
Definition: relation.c:762
#define SEPG_CLASS_DB_VIEW
Definition: sepgsql.h:53
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:1115
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1163
#define SEPG_CLASS_DB_TABLE
Definition: sepgsql.h:46
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define elog(elevel,...)
Definition: elog.h:228
#define NameStr(name)
Definition: c.h:677
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ sepgsql_relation_setattr_extra()

static void sepgsql_relation_setattr_extra ( Relation  catalog,
Oid  catindex_id,
Oid  extra_oid,
AttrNumber  anum_relation_id,
AttrNumber  anum_extra_id 
)
static

Definition at line 721 of file relation.c.

References Assert, BTEqualStrategyNumber, DatumGetObjectId, elog, ERROR, heap_getattr, HeapTupleIsValid, ObjectIdGetDatum, RelationGetDescr, RelationGetRelationName, ScanKeyInit(), sepgsql_relation_setattr(), SnapshotSelf, systable_beginscan(), systable_endscan(), and systable_getnext().

Referenced by sepgsql_index_modify().

726 {
727  ScanKeyData skey;
728  SysScanDesc sscan;
729  HeapTuple tuple;
730  Datum datum;
731  bool isnull;
732 
733  ScanKeyInit(&skey, anum_extra_id,
734  BTEqualStrategyNumber, F_OIDEQ,
735  ObjectIdGetDatum(extra_oid));
736 
737  sscan = systable_beginscan(catalog, catindex_id, true,
738  SnapshotSelf, 1, &skey);
739  tuple = systable_getnext(sscan);
740  if (!HeapTupleIsValid(tuple))
741  elog(ERROR, "could not find tuple for object %u in catalog \"%s\"",
742  extra_oid, RelationGetRelationName(catalog));
743 
744  datum = heap_getattr(tuple, anum_relation_id,
745  RelationGetDescr(catalog), &isnull);
746  Assert(!isnull);
747 
749 
750  systable_endscan(sscan);
751 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:569
#define RelationGetDescr(relation)
Definition: rel.h:483
#define DatumGetObjectId(X)
Definition: postgres.h:500
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:357
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:476
#define ObjectIdGetDatum(X)
Definition: postgres.h:507
#define ERROR
Definition: elog.h:43
#define SnapshotSelf
Definition: snapmgr.h:67
#define RelationGetRelationName(relation)
Definition: rel.h:491
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:762
uintptr_t Datum
Definition: postgres.h:367
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define Assert(condition)
Definition: c.h:800
#define elog(elevel,...)
Definition: elog.h:228
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void sepgsql_relation_setattr(Oid relOid)
Definition: relation.c:615
#define BTEqualStrategyNumber
Definition: stratnum.h:31

◆ sepgsql_relation_truncate()

void sepgsql_relation_truncate ( Oid  relOid)

Definition at line 524 of file relation.c.

References get_rel_relkind(), getObjectIdentity(), pfree(), SEPG_CLASS_DB_TABLE, SEPG_DB_TABLE__TRUNCATE, and sepgsql_avc_check_perms().

Referenced by sepgsql_object_access().

525 {
526  ObjectAddress object;
527  char *audit_name;
528  uint16_t tclass = 0;
529  char relkind = get_rel_relkind(relOid);
530 
531  switch (relkind)
532  {
533  case RELKIND_RELATION:
534  case RELKIND_PARTITIONED_TABLE:
535  tclass = SEPG_CLASS_DB_TABLE;
536  break;
537  default:
538  /* ignore other relkinds */
539  return;
540  }
541 
542  /*
543  * check db_table:{truncate} permission
544  */
545  object.classId = RelationRelationId;
546  object.objectId = relOid;
547  object.objectSubId = 0;
548  audit_name = getObjectIdentity(&object, false);
549 
550  sepgsql_avc_check_perms(&object,
551  tclass,
553  audit_name,
554  true);
555  pfree(audit_name);
556 }
#define SEPG_DB_TABLE__TRUNCATE
Definition: sepgsql.h:148
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1920
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:419
void pfree(void *pointer)
Definition: mcxt.c:1057
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
#define SEPG_CLASS_DB_TABLE
Definition: sepgsql.h:46