PostgreSQL Source Code git master
All Data Structures Namespaces Files Functions Variables Typedefs Enumerations Enumerator Macros Pages
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.

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
153 audit_name,
154 true);
155 pfree(audit_name);
156}
char get_rel_relkind(Oid relid)
Definition: lsyscache.c:2003
void pfree(void *pointer)
Definition: mcxt.c:1521
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
int16 attnum
Definition: pg_attribute.h:74
#define SEPG_DB_COLUMN__DROP
Definition: sepgsql.h:171
#define SEPG_CLASS_DB_COLUMN
Definition: sepgsql.h:49
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:420

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().

◆ sepgsql_attribute_post_create()

void sepgsql_attribute_post_create ( Oid  relOid,
AttrNumber  attnum 
)

Definition at line 43 of file relation.c.

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
79 sscan = systable_beginscan(rel, AttributeRelidNumIndexId, true,
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}
#define NameStr(name)
Definition: c.h:700
#define ERROR
Definition: elog.h:39
#define elog(elevel,...)
Definition: elog.h:225
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:606
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:513
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:387
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define GETSTRUCT(TUP)
Definition: htup_details.h:653
char * sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
Definition: label.c:445
char * sepgsql_get_client_label(void)
Definition: label.c:80
#define AccessShareLock
Definition: lockdefs.h:36
FormData_pg_attribute * Form_pg_attribute
Definition: pg_attribute.h:200
static Datum Int16GetDatum(int16 X)
Definition: postgres.h:172
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:252
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:12870
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void SetSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition: seclabel.c:404
char * sepgsql_compute_create(const char *scontext, const char *tcontext, uint16 tclass, const char *objname)
Definition: selinux.c:842
#define SEPG_DB_COLUMN__CREATE
Definition: sepgsql.h:170
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 SEPGSQL_LABEL_TAG
Definition: sepgsql.h:23
#define SnapshotSelf
Definition: snapmgr.h:32
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:94
void initStringInfo(StringInfo str)
Definition: stringinfo.c:56
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40

References AccessShareLock, appendStringInfo(), attnum, 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().

◆ sepgsql_attribute_relabel()

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

Definition at line 165 of file relation.c.

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)
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 */
189 audit_name,
190 true);
191
192 /*
193 * check db_column:{relabelto} permission
194 */
198 audit_name,
199 true);
200 pfree(audit_name);
201}
int errcode(int sqlerrcode)
Definition: elog.c:853
int errmsg(const char *fmt,...)
Definition: elog.c:1070
#define ereport(elevel,...)
Definition: elog.h:149
#define SEPG_DB_COLUMN__SETATTR
Definition: sepgsql.h:173
#define SEPG_DB_COLUMN__RELABELFROM
Definition: sepgsql.h:174
#define SEPG_DB_PROCEDURE__RELABELTO
Definition: sepgsql.h:165

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().

◆ sepgsql_attribute_setattr()

void sepgsql_attribute_setattr ( Oid  relOid,
AttrNumber  attnum 
)

Definition at line 209 of file relation.c.

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
229 audit_name,
230 true);
231 pfree(audit_name);
232}

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().

◆ sepgsql_index_modify()

static void sepgsql_index_modify ( Oid  indexOid)
static

Definition at line 762 of file relation.c.

763{
764 Relation catalog = table_open(IndexRelationId, AccessShareLock);
765
766 /* check db_table:{setattr} permission of the table being indexed */
768 IndexRelidIndexId,
769 indexOid,
770 Anum_pg_index_indrelid,
771 Anum_pg_index_indexrelid);
773}
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

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

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

◆ sepgsql_relation_drop()

void sepgsql_relation_drop ( Oid  relOid)

Definition at line 416 of file relation.c.

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
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
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
510 audit_name,
511 true);
512 pfree(audit_name);
513 }
514 ReleaseCatCacheList(attrList);
515 }
516}
void ReleaseCatCacheList(CatCList *list)
Definition: catcache.c:1985
static void sepgsql_index_modify(Oid indexOid)
Definition: relation.c:762
int i
Definition: isn.c:72
Oid get_rel_namespace(Oid relid)
Definition: lsyscache.c:1952
#define SEPG_CLASS_DB_SCHEMA
Definition: sepgsql.h:45
#define SEPG_CLASS_DB_TABLE
Definition: sepgsql.h:46
#define SEPG_DB_SCHEMA__REMOVE_NAME
Definition: sepgsql.h:135
#define SEPG_DB_TABLE__DROP
Definition: sepgsql.h:138
#define SEPG_CLASS_DB_VIEW
Definition: sepgsql.h:53
#define SEPG_CLASS_DB_SEQUENCE
Definition: sepgsql.h:47
CatCTup * members[FLEXIBLE_ARRAY_MEMBER]
Definition: catcache.h:180
int n_members
Definition: catcache.h:178
HeapTupleData tuple
Definition: catcache.h:123
#define SearchSysCacheList1(cacheId, key1)
Definition: syscache.h:127

References 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().

◆ sepgsql_relation_post_create()

void sepgsql_relation_post_create ( Oid  relOid)

Definition at line 240 of file relation.c.

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;
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
405out:
406 systable_endscan(sscan);
408}
char * get_namespace_name(Oid nspid)
Definition: lsyscache.c:3366
FormData_pg_class * Form_pg_class
Definition: pg_class.h:153
#define SEPG_DB_DATABASE__CREATE
Definition: sepgsql.h:118
#define SEPG_DB_SCHEMA__ADD_NAME
Definition: sepgsql.h:134
void resetStringInfo(StringInfo str)
Definition: stringinfo.c:75

References AccessShareLock, appendStringInfo(), BTEqualStrategyNumber, 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().

◆ sepgsql_relation_relabel()

void sepgsql_relation_relabel ( Oid  relOid,
const char *  seclabel 
)

Definition at line 564 of file relation.c.

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
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 */
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}
#define SEPG_DB_TABLE__SETATTR
Definition: sepgsql.h:140
#define SEPG_DB_TABLE__RELABELFROM
Definition: sepgsql.h:141
#define SEPG_DB_TABLE__RELABELTO
Definition: sepgsql.h:142

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().

◆ sepgsql_relation_setattr()

void sepgsql_relation_setattr ( Oid  relOid)

Definition at line 615 of file relation.c.

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
700 tclass,
702 audit_name,
703 true);
704 pfree(audit_name);
705
706 ReleaseSysCache(oldtup);
707 systable_endscan(sscan);
709}
void sepgsql_schema_rename(Oid namespaceId)
Definition: schema.c:229
void sepgsql_schema_remove_name(Oid namespaceId)
Definition: schema.c:223
void sepgsql_schema_add_name(Oid namespaceId)
Definition: schema.c:217
void ReleaseSysCache(HeapTuple tuple)
Definition: syscache.c:269
HeapTuple SearchSysCache1(int cacheId, Datum key1)
Definition: syscache.c:221

References AccessShareLock, BTEqualStrategyNumber, elog, ERROR, get_rel_relkind(), getObjectIdentity(), GETSTRUCT, HeapTupleIsValid, NameStr, ObjectIdGetDatum(), pfree(), ReleaseSysCache(), 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().

◆ 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.

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}
#define Assert(condition)
Definition: c.h:812
void sepgsql_relation_setattr(Oid relOid)
Definition: relation.c:615
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
Definition: htup_details.h:792
uintptr_t Datum
Definition: postgres.h:64
static Oid DatumGetObjectId(Datum X)
Definition: postgres.h:242
#define RelationGetDescr(relation)
Definition: rel.h:531
#define RelationGetRelationName(relation)
Definition: rel.h:539

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().

◆ sepgsql_relation_truncate()

void sepgsql_relation_truncate ( Oid  relOid)

Definition at line 524 of file relation.c.

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
551 tclass,
553 audit_name,
554 true);
555 pfree(audit_name);
556}
#define SEPG_DB_TABLE__TRUNCATE
Definition: sepgsql.h:148

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

Referenced by sepgsql_object_access().