PostgreSQL Source Code  git master
 All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros
relation.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/htup_details.h"
#include "access/sysattr.h"
#include "catalog/indexing.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 "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/catcache.h"
#include "utils/lsyscache.h"
#include "utils/rel.h"
#include "utils/syscache.h"
#include "utils/tqual.h"
#include "sepgsql.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_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

void sepgsql_attribute_drop ( Oid  relOid,
AttrNumber  attnum 
)

Definition at line 135 of file relation.c.

References get_rel_relkind(), getObjectIdentity(), pfree(), RelationRelationId, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, SEPG_CLASS_DB_COLUMN, SEPG_DB_COLUMN__DROP, and sepgsql_avc_check_perms().

Referenced by sepgsql_object_access().

136 {
137  ObjectAddress object;
138  char *audit_name;
139  char relkind = get_rel_relkind(relOid);
140 
141  if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
142  return;
143 
144  /*
145  * check db_column:{drop} permission
146  */
147  object.classId = RelationRelationId;
148  object.objectId = relOid;
149  object.objectSubId = attnum;
150  audit_name = getObjectIdentity(&object);
151 
152  sepgsql_avc_check_perms(&object,
155  audit_name,
156  true);
157  pfree(audit_name);
158 }
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1801
#define RelationRelationId
Definition: pg_class.h:29
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:428
void pfree(void *pointer)
Definition: mcxt.c:950
char * getObjectIdentity(const ObjectAddress *object)
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
#define SEPG_DB_COLUMN__DROP
Definition: sepgsql.h:170
#define RELKIND_RELATION
Definition: pg_class.h:160
void sepgsql_attribute_post_create ( Oid  relOid,
AttrNumber  attnum 
)

Definition at line 45 of file relation.c.

References AccessShareLock, Anum_pg_attribute_attnum, Anum_pg_attribute_attrelid, appendStringInfo(), AttributeRelationId, AttributeRelidNumIndexId, BTEqualStrategyNumber, StringInfoData::data, elog, ERROR, get_rel_relkind(), getObjectIdentity(), GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, initStringInfo(), Int16GetDatum, NameStr, ObjectIdGetDatum, pfree(), quote_identifier(), RelationRelationId, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, 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(), and systable_getnext().

Referenced by sepgsql_object_access().

46 {
47  Relation rel;
48  ScanKeyData skey[2];
49  SysScanDesc sscan;
50  HeapTuple tuple;
51  char *scontext;
52  char *tcontext;
53  char *ncontext;
54  ObjectAddress object;
55  Form_pg_attribute attForm;
56  StringInfoData audit_name;
57  char relkind = get_rel_relkind(relOid);
58 
59  /*
60  * Only attributes within regular relations or partition relations have
61  * individual security labels.
62  */
63  if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
64  return;
65 
66  /*
67  * Compute a default security label of the new column underlying the
68  * specified relation, and check permission to create it.
69  */
71 
72  ScanKeyInit(&skey[0],
74  BTEqualStrategyNumber, F_OIDEQ,
75  ObjectIdGetDatum(relOid));
76  ScanKeyInit(&skey[1],
78  BTEqualStrategyNumber, F_INT2EQ,
79  Int16GetDatum(attnum));
80 
82  SnapshotSelf, 2, &skey[0]);
83 
84  tuple = systable_getnext(sscan);
85  if (!HeapTupleIsValid(tuple))
86  elog(ERROR, "catalog lookup failed for column %d of relation %u",
87  attnum, relOid);
88 
89  attForm = (Form_pg_attribute) GETSTRUCT(tuple);
90 
91  scontext = sepgsql_get_client_label();
92  tcontext = sepgsql_get_label(RelationRelationId, relOid, 0);
93  ncontext = sepgsql_compute_create(scontext, tcontext,
95  NameStr(attForm->attname));
96 
97  /*
98  * check db_column:{create} permission
99  */
100  object.classId = RelationRelationId;
101  object.objectId = relOid;
102  object.objectSubId = 0;
103 
104  initStringInfo(&audit_name);
105  appendStringInfo(&audit_name, "%s.%s",
106  getObjectIdentity(&object),
107  quote_identifier(NameStr(attForm->attname)));
111  audit_name.data,
112  true);
113 
114  /*
115  * Assign the default security label on a new procedure
116  */
117  object.classId = RelationRelationId;
118  object.objectId = relOid;
119  object.objectSubId = attnum;
120  SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
121 
122  systable_endscan(sscan);
124 
125  pfree(tcontext);
126  pfree(ncontext);
127 }
#define AttributeRelidNumIndexId
Definition: indexing.h:94
bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:346
#define Anum_pg_attribute_attrelid
Definition: pg_attribute.h:195
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
void SetSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition: seclabel.c:327
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10284
#define Anum_pg_attribute_attnum
Definition: pg_attribute.h:200
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1801
#define RelationRelationId
Definition: pg_class.h:29
char * sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
Definition: label.c:463
#define Int16GetDatum(X)
Definition: postgres.h:457
#define AccessShareLock
Definition: lockdefs.h:36
#define AttributeRelationId
Definition: pg_attribute.h:33
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
void pfree(void *pointer)
Definition: mcxt.c:950
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
char * getObjectIdentity(const ObjectAddress *object)
#define SEPGSQL_LABEL_TAG
Definition: sepgsql.h:23
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
#define SnapshotSelf
Definition: tqual.h:27
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define SEPG_DB_COLUMN__CREATE
Definition: sepgsql.h:169
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
char * sepgsql_get_client_label(void)
Definition: label.c:91
char * sepgsql_compute_create(const char *scontext, const char *tcontext, uint16 tclass, const char *objname)
Definition: selinux.c:837
#define NameStr(name)
Definition: c.h:499
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
#define RELKIND_RELATION
Definition: pg_class.h:160
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void sepgsql_attribute_relabel ( Oid  relOid,
AttrNumber  attnum,
const char *  seclabel 
)

Definition at line 167 of file relation.c.

References ereport, errcode(), errmsg(), ERROR, get_rel_relkind(), getObjectIdentity(), pfree(), RelationRelationId, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, 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().

169 {
170  ObjectAddress object;
171  char *audit_name;
172  char relkind = get_rel_relkind(relOid);
173 
174  if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
175  ereport(ERROR,
176  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
177  errmsg("cannot set security label on non-regular columns")));
178 
179  object.classId = RelationRelationId;
180  object.objectId = relOid;
181  object.objectSubId = attnum;
182  audit_name = getObjectIdentity(&object);
183 
184  /*
185  * check db_column:{setattr relabelfrom} permission
186  */
187  sepgsql_avc_check_perms(&object,
191  audit_name,
192  true);
193 
194  /*
195  * check db_column:{relabelto} permission
196  */
200  audit_name,
201  true);
202  pfree(audit_name);
203 }
bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:346
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
#define SEPG_DB_COLUMN__SETATTR
Definition: sepgsql.h:172
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1801
#define RelationRelationId
Definition: pg_class.h:29
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:428
int errcode(int sqlerrcode)
Definition: elog.c:575
#define SEPG_DB_COLUMN__RELABELFROM
Definition: sepgsql.h:173
void pfree(void *pointer)
Definition: mcxt.c:950
#define ERROR
Definition: elog.h:43
char * getObjectIdentity(const ObjectAddress *object)
#define SEPG_DB_PROCEDURE__RELABELTO
Definition: sepgsql.h:164
#define ereport(elevel, rest)
Definition: elog.h:122
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_RELATION
Definition: pg_class.h:160
void sepgsql_attribute_setattr ( Oid  relOid,
AttrNumber  attnum 
)

Definition at line 211 of file relation.c.

References get_rel_relkind(), getObjectIdentity(), pfree(), RelationRelationId, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, SEPG_CLASS_DB_COLUMN, SEPG_DB_COLUMN__SETATTR, and sepgsql_avc_check_perms().

Referenced by sepgsql_object_access().

212 {
213  ObjectAddress object;
214  char *audit_name;
215  char relkind = get_rel_relkind(relOid);
216 
217  if (relkind != RELKIND_RELATION && relkind != RELKIND_PARTITIONED_TABLE)
218  return;
219 
220  /*
221  * check db_column:{setattr} permission
222  */
223  object.classId = RelationRelationId;
224  object.objectId = relOid;
225  object.objectSubId = attnum;
226  audit_name = getObjectIdentity(&object);
227 
228  sepgsql_avc_check_perms(&object,
231  audit_name,
232  true);
233  pfree(audit_name);
234 }
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
#define SEPG_DB_COLUMN__SETATTR
Definition: sepgsql.h:172
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1801
#define RelationRelationId
Definition: pg_class.h:29
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:428
void pfree(void *pointer)
Definition: mcxt.c:950
char * getObjectIdentity(const ObjectAddress *object)
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
#define RELKIND_RELATION
Definition: pg_class.h:160
static void sepgsql_index_modify ( Oid  indexOid)
static

Definition at line 724 of file relation.c.

References AccessShareLock, Anum_pg_index_indexrelid, Anum_pg_index_indrelid, heap_close, heap_open(), IndexRelationId, IndexRelidIndexId, and sepgsql_relation_setattr_extra().

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

725 {
727 
728  /* check db_table:{setattr} permission of the table being indexed */
731  indexOid,
734  heap_close(catalog, AccessShareLock);
735 }
#define IndexRelidIndexId
Definition: indexing.h:164
#define IndexRelationId
Definition: pg_index.h:29
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
#define Anum_pg_index_indrelid
Definition: pg_index.h:75
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:683
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define Anum_pg_index_indexrelid
Definition: pg_index.h:74
void sepgsql_relation_drop ( Oid  relOid)

Definition at line 418 of file relation.c.

References ATTNUM, get_rel_namespace(), get_rel_relkind(), getObjectIdentity(), GETSTRUCT, i, catclist::members, catclist::n_members, NamespaceRelationId, ObjectIdGetDatum, pfree(), PG_TOAST_NAMESPACE, RelationRelationId, ReleaseCatCacheList(), RELKIND_INDEX, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW, 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().

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

Definition at line 242 of file relation.c.

References AccessShareLock, Anum_pg_attribute_attrelid, appendStringInfo(), AttributeRelationId, AttributeRelidNumIndexId, BTEqualStrategyNumber, ClassOidIndexId, StringInfoData::data, elog, ERROR, get_namespace_name(), getObjectIdentity(), GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, initStringInfo(), NamespaceRelationId, NameStr, ObjectIdAttributeNumber, ObjectIdGetDatum, pfree(), PG_TOAST_NAMESPACE, quote_identifier(), RelationRelationId, RELKIND_INDEX, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW, 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(), and systable_getnext().

Referenced by sepgsql_object_access().

243 {
244  Relation rel;
245  ScanKeyData skey;
246  SysScanDesc sscan;
247  HeapTuple tuple;
248  Form_pg_class classForm;
249  ObjectAddress object;
250  uint16_t tclass;
251  char *scontext; /* subject */
252  char *tcontext; /* schema */
253  char *rcontext; /* relation */
254  char *ccontext; /* column */
255  char *nsp_name;
256  StringInfoData audit_name;
257 
258  /*
259  * Fetch catalog record of the new relation. Because pg_class entry is not
260  * visible right now, we need to scan the catalog using SnapshotSelf.
261  */
263 
264  ScanKeyInit(&skey,
266  BTEqualStrategyNumber, F_OIDEQ,
267  ObjectIdGetDatum(relOid));
268 
269  sscan = systable_beginscan(rel, ClassOidIndexId, true,
270  SnapshotSelf, 1, &skey);
271 
272  tuple = systable_getnext(sscan);
273  if (!HeapTupleIsValid(tuple))
274  elog(ERROR, "catalog lookup failed for relation %u", relOid);
275 
276  classForm = (Form_pg_class) GETSTRUCT(tuple);
277 
278  /* ignore indexes on toast tables */
279  if (classForm->relkind == RELKIND_INDEX &&
280  classForm->relnamespace == PG_TOAST_NAMESPACE)
281  goto out;
282 
283  /*
284  * check db_schema:{add_name} permission of the namespace
285  */
286  object.classId = NamespaceRelationId;
287  object.objectId = classForm->relnamespace;
288  object.objectSubId = 0;
289  sepgsql_avc_check_perms(&object,
292  getObjectIdentity(&object),
293  true);
294 
295  switch (classForm->relkind)
296  {
297  case RELKIND_RELATION:
299  tclass = SEPG_CLASS_DB_TABLE;
300  break;
301  case RELKIND_SEQUENCE:
302  tclass = SEPG_CLASS_DB_SEQUENCE;
303  break;
304  case RELKIND_VIEW:
305  tclass = SEPG_CLASS_DB_VIEW;
306  break;
307  case RELKIND_INDEX:
308  /* deal with indexes specially; no need for tclass */
309  sepgsql_index_modify(relOid);
310  goto out;
311  default:
312  /* ignore other relkinds */
313  goto out;
314  }
315 
316  /*
317  * Compute a default security label when we create a new relation object
318  * under the specified namespace.
319  */
320  scontext = sepgsql_get_client_label();
322  classForm->relnamespace, 0);
323  rcontext = sepgsql_compute_create(scontext, tcontext, tclass,
324  NameStr(classForm->relname));
325 
326  /*
327  * check db_xxx:{create} permission
328  */
329  nsp_name = get_namespace_name(classForm->relnamespace);
330  initStringInfo(&audit_name);
331  appendStringInfo(&audit_name, "%s.%s",
332  quote_identifier(nsp_name),
333  quote_identifier(NameStr(classForm->relname)));
335  tclass,
337  audit_name.data,
338  true);
339 
340  /*
341  * Assign the default security label on the new regular or partitioned
342  * relation.
343  */
344  object.classId = RelationRelationId;
345  object.objectId = relOid;
346  object.objectSubId = 0;
347  SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, rcontext);
348 
349  /*
350  * We also assign a default security label on columns of a new table.
351  */
352  if (classForm->relkind == RELKIND_RELATION ||
353  classForm->relkind == RELKIND_PARTITIONED_TABLE)
354  {
355  Relation arel;
356  ScanKeyData akey;
357  SysScanDesc ascan;
358  HeapTuple atup;
359  Form_pg_attribute attForm;
360 
362 
363  ScanKeyInit(&akey,
365  BTEqualStrategyNumber, F_OIDEQ,
366  ObjectIdGetDatum(relOid));
367 
368  ascan = systable_beginscan(arel, AttributeRelidNumIndexId, true,
369  SnapshotSelf, 1, &akey);
370 
371  while (HeapTupleIsValid(atup = systable_getnext(ascan)))
372  {
373  attForm = (Form_pg_attribute) GETSTRUCT(atup);
374 
375  resetStringInfo(&audit_name);
376  appendStringInfo(&audit_name, "%s.%s.%s",
377  quote_identifier(nsp_name),
378  quote_identifier(NameStr(classForm->relname)),
379  quote_identifier(NameStr(attForm->attname)));
380 
381  ccontext = sepgsql_compute_create(scontext,
382  rcontext,
384  NameStr(attForm->attname));
385 
386  /*
387  * check db_column:{create} permission
388  */
392  audit_name.data,
393  true);
394 
395  object.classId = RelationRelationId;
396  object.objectId = relOid;
397  object.objectSubId = attForm->attnum;
398  SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ccontext);
399 
400  pfree(ccontext);
401  }
402  systable_endscan(ascan);
404  }
405  pfree(rcontext);
406 
407 out:
408  systable_endscan(sscan);
410 }
#define AttributeRelidNumIndexId
Definition: indexing.h:94
bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:346
#define Anum_pg_attribute_attrelid
Definition: pg_attribute.h:195
#define NamespaceRelationId
Definition: pg_namespace.h:34
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
void SetSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition: seclabel.c:327
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:10284
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
#define RelationRelationId
Definition: pg_class.h:29
char * sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
Definition: label.c:463
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:428
#define AccessShareLock
Definition: lockdefs.h:36
#define AttributeRelationId
Definition: pg_attribute.h:33
#define heap_close(r, l)
Definition: heapam.h:97
#define SEPG_CLASS_DB_SCHEMA
Definition: sepgsql.h:45
#define PG_TOAST_NAMESPACE
Definition: pg_namespace.h:74
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define SEPG_DB_DATABASE__CREATE
Definition: sepgsql.h:118
void pfree(void *pointer)
Definition: mcxt.c:950
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:78
#define SEPG_CLASS_DB_SEQUENCE
Definition: sepgsql.h:47
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
char * getObjectIdentity(const ObjectAddress *object)
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3033
#define SEPGSQL_LABEL_TAG
Definition: sepgsql.h:23
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:187
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:62
#define ClassOidIndexId
Definition: indexing.h:112
#define SnapshotSelf
Definition: tqual.h:27
static void sepgsql_index_modify(Oid indexOid)
Definition: relation.c:724
void initStringInfo(StringInfo str)
Definition: stringinfo.c:46
#define SEPG_CLASS_DB_VIEW
Definition: sepgsql.h:53
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define SEPG_DB_SCHEMA__ADD_NAME
Definition: sepgsql.h:134
#define SEPG_DB_COLUMN__CREATE
Definition: sepgsql.h:169
#define SEPG_CLASS_DB_TABLE
Definition: sepgsql.h:46
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
char * sepgsql_get_client_label(void)
Definition: label.c:91
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
char * sepgsql_compute_create(const char *scontext, const char *tcontext, uint16 tclass, const char *objname)
Definition: selinux.c:837
#define RELKIND_VIEW
Definition: pg_class.h:164
#define NameStr(name)
Definition: c.h:499
#define RELKIND_INDEX
Definition: pg_class.h:161
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
#define RELKIND_RELATION
Definition: pg_class.h:160
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void sepgsql_relation_relabel ( Oid  relOid,
const char *  seclabel 
)

Definition at line 526 of file relation.c.

References ereport, errcode(), errmsg(), ERROR, get_rel_relkind(), getObjectIdentity(), pfree(), RelationRelationId, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW, 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().

527 {
528  ObjectAddress object;
529  char *audit_name;
530  char relkind = get_rel_relkind(relOid);
531  uint16_t tclass = 0;
532 
533  if (relkind == RELKIND_RELATION || relkind == RELKIND_PARTITIONED_TABLE)
534  tclass = SEPG_CLASS_DB_TABLE;
535  else if (relkind == RELKIND_SEQUENCE)
536  tclass = SEPG_CLASS_DB_SEQUENCE;
537  else if (relkind == RELKIND_VIEW)
538  tclass = SEPG_CLASS_DB_VIEW;
539  else
540  ereport(ERROR,
541  (errcode(ERRCODE_WRONG_OBJECT_TYPE),
542  errmsg("cannot set security labels on relations except "
543  "for tables, sequences or views")));
544 
545  object.classId = RelationRelationId;
546  object.objectId = relOid;
547  object.objectSubId = 0;
548  audit_name = getObjectIdentity(&object);
549 
550  /*
551  * check db_xxx:{setattr relabelfrom} permission
552  */
553  sepgsql_avc_check_perms(&object,
554  tclass,
557  audit_name,
558  true);
559 
560  /*
561  * check db_xxx:{relabelto} permission
562  */
564  tclass,
566  audit_name,
567  true);
568  pfree(audit_name);
569 }
bool sepgsql_avc_check_perms_label(const char *tcontext, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:346
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1801
#define RelationRelationId
Definition: pg_class.h:29
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:428
int errcode(int sqlerrcode)
Definition: elog.c:575
#define SEPG_DB_TABLE__SETATTR
Definition: sepgsql.h:140
void pfree(void *pointer)
Definition: mcxt.c:950
#define SEPG_CLASS_DB_SEQUENCE
Definition: sepgsql.h:47
#define ERROR
Definition: elog.h:43
char * getObjectIdentity(const ObjectAddress *object)
#define SEPG_DB_TABLE__RELABELTO
Definition: sepgsql.h:142
#define ereport(elevel, rest)
Definition: elog.h:122
#define SEPG_CLASS_DB_VIEW
Definition: sepgsql.h:53
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
#define SEPG_DB_TABLE__RELABELFROM
Definition: sepgsql.h:141
#define SEPG_CLASS_DB_TABLE
Definition: sepgsql.h:46
int errmsg(const char *fmt,...)
Definition: elog.c:797
#define RELKIND_VIEW
Definition: pg_class.h:164
#define RELKIND_RELATION
Definition: pg_class.h:160
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
void sepgsql_relation_setattr ( Oid  relOid)

Definition at line 577 of file relation.c.

References AccessShareLock, BTEqualStrategyNumber, ClassOidIndexId, elog, ERROR, get_rel_relkind(), getObjectIdentity(), GETSTRUCT, heap_close, heap_open(), HeapTupleIsValid, NameStr, ObjectIdAttributeNumber, ObjectIdGetDatum, pfree(), RelationRelationId, ReleaseSysCache(), RELKIND_INDEX, RELKIND_PARTITIONED_TABLE, RELKIND_RELATION, RELKIND_SEQUENCE, RELKIND_VIEW, 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(), and systable_getnext().

Referenced by sepgsql_object_access(), and sepgsql_relation_setattr_extra().

578 {
579  Relation rel;
580  ScanKeyData skey;
581  SysScanDesc sscan;
582  HeapTuple oldtup;
583  HeapTuple newtup;
584  Form_pg_class oldform;
585  Form_pg_class newform;
586  ObjectAddress object;
587  char *audit_name;
588  uint16_t tclass;
589 
590  switch (get_rel_relkind(relOid))
591  {
592  case RELKIND_RELATION:
594  tclass = SEPG_CLASS_DB_TABLE;
595  break;
596  case RELKIND_SEQUENCE:
597  tclass = SEPG_CLASS_DB_SEQUENCE;
598  break;
599  case RELKIND_VIEW:
600  tclass = SEPG_CLASS_DB_VIEW;
601  break;
602  case RELKIND_INDEX:
603  /* deal with indexes specially */
604  sepgsql_index_modify(relOid);
605  return;
606  default:
607  /* other relkinds don't need additional work */
608  return;
609  }
610 
611  /*
612  * Fetch newer catalog
613  */
615 
616  ScanKeyInit(&skey,
618  BTEqualStrategyNumber, F_OIDEQ,
619  ObjectIdGetDatum(relOid));
620 
621  sscan = systable_beginscan(rel, ClassOidIndexId, true,
622  SnapshotSelf, 1, &skey);
623 
624  newtup = systable_getnext(sscan);
625  if (!HeapTupleIsValid(newtup))
626  elog(ERROR, "catalog lookup failed for relation %u", relOid);
627  newform = (Form_pg_class) GETSTRUCT(newtup);
628 
629  /*
630  * Fetch older catalog
631  */
632  oldtup = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
633  if (!HeapTupleIsValid(oldtup))
634  elog(ERROR, "cache lookup failed for relation %u", relOid);
635  oldform = (Form_pg_class) GETSTRUCT(oldtup);
636 
637  /*
638  * Does this ALTER command takes operation to namespace?
639  */
640  if (newform->relnamespace != oldform->relnamespace)
641  {
642  sepgsql_schema_remove_name(oldform->relnamespace);
643  sepgsql_schema_add_name(newform->relnamespace);
644  }
645  if (strcmp(NameStr(newform->relname), NameStr(oldform->relname)) != 0)
646  sepgsql_schema_rename(oldform->relnamespace);
647 
648  /*
649  * XXX - In the future version, db_tuple:{use} of system catalog entry
650  * shall be checked, if tablespace configuration is changed.
651  */
652 
653  /*
654  * check db_xxx:{setattr} permission
655  */
656  object.classId = RelationRelationId;
657  object.objectId = relOid;
658  object.objectSubId = 0;
659  audit_name = getObjectIdentity(&object);
660 
661  sepgsql_avc_check_perms(&object,
662  tclass,
664  audit_name,
665  true);
666  pfree(audit_name);
667 
668  ReleaseSysCache(oldtup);
669  systable_endscan(sscan);
671 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define GETSTRUCT(TUP)
Definition: htup_details.h:656
#define ObjectIdAttributeNumber
Definition: sysattr.h:22
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:1801
#define RelationRelationId
Definition: pg_class.h:29
void sepgsql_schema_add_name(Oid namespaceId)
Definition: schema.c:219
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:428
void sepgsql_schema_remove_name(Oid namespaceId)
Definition: schema.c:225
#define AccessShareLock
Definition: lockdefs.h:36
#define heap_close(r, l)
Definition: heapam.h:97
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
#define SearchSysCache1(cacheId, key1)
Definition: syscache.h:156
#define SEPG_DB_TABLE__SETATTR
Definition: sepgsql.h:140
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
void pfree(void *pointer)
Definition: mcxt.c:950
#define SEPG_CLASS_DB_SEQUENCE
Definition: sepgsql.h:47
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
char * getObjectIdentity(const ObjectAddress *object)
void sepgsql_schema_rename(Oid namespaceId)
Definition: schema.c:231
#define ClassOidIndexId
Definition: indexing.h:112
#define SnapshotSelf
Definition: tqual.h:27
static void sepgsql_index_modify(Oid indexOid)
Definition: relation.c:724
#define SEPG_CLASS_DB_VIEW
Definition: sepgsql.h:53
#define RELKIND_PARTITIONED_TABLE
Definition: pg_class.h:168
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:1117
Relation heap_open(Oid relationId, LOCKMODE lockmode)
Definition: heapam.c:1284
#define SEPG_CLASS_DB_TABLE
Definition: sepgsql.h:46
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
FormData_pg_class * Form_pg_class
Definition: pg_class.h:95
#define RELKIND_VIEW
Definition: pg_class.h:164
#define NameStr(name)
Definition: c.h:499
#define RELKIND_INDEX
Definition: pg_class.h:161
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
#define RELKIND_RELATION
Definition: pg_class.h:160
#define RELKIND_SEQUENCE
Definition: pg_class.h:162
#define BTEqualStrategyNumber
Definition: stratnum.h:31
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 683 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().

688 {
689  ScanKeyData skey;
690  SysScanDesc sscan;
691  HeapTuple tuple;
692  Datum datum;
693  bool isnull;
694 
695  ScanKeyInit(&skey, anum_extra_id,
696  BTEqualStrategyNumber, F_OIDEQ,
697  ObjectIdGetDatum(extra_oid));
698 
699  sscan = systable_beginscan(catalog, catindex_id, true,
700  SnapshotSelf, 1, &skey);
701  tuple = systable_getnext(sscan);
702  if (!HeapTupleIsValid(tuple))
703  elog(ERROR, "catalog lookup failed for object %u in catalog \"%s\"",
704  extra_oid, RelationGetRelationName(catalog));
705 
706  datum = heap_getattr(tuple, anum_relation_id,
707  RelationGetDescr(catalog), &isnull);
708  Assert(!isnull);
709 
711 
712  systable_endscan(sscan);
713 }
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:499
#define RelationGetDescr(relation)
Definition: rel.h:429
#define DatumGetObjectId(X)
Definition: postgres.h:506
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:328
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:416
#define ObjectIdGetDatum(X)
Definition: postgres.h:513
#define ERROR
Definition: elog.h:43
#define RelationGetRelationName(relation)
Definition: rel.h:437
#define SnapshotSelf
Definition: tqual.h:27
#define heap_getattr(tup, attnum, tupleDesc, isnull)
Definition: htup_details.h:769
uintptr_t Datum
Definition: postgres.h:372
#define HeapTupleIsValid(tuple)
Definition: htup.h:77
#define Assert(condition)
Definition: c.h:675
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
#define elog
Definition: elog.h:219
void sepgsql_relation_setattr(Oid relOid)
Definition: relation.c:577
#define BTEqualStrategyNumber
Definition: stratnum.h:31