1
/* -------------------------------------------------------------------------
3
* contrib/sepgsql/label.c
5
* Routines corresponding to relation/attribute objects
7
* Copyright (c) 2010-2011, PostgreSQL Global Development Group
9
* -------------------------------------------------------------------------
13
#include "access/genam.h"
14
#include "access/heapam.h"
15
#include "access/sysattr.h"
16
#include "catalog/indexing.h"
17
#include "catalog/dependency.h"
18
#include "catalog/pg_attribute.h"
19
#include "catalog/pg_class.h"
20
#include "catalog/pg_namespace.h"
21
#include "commands/seclabel.h"
22
#include "utils/fmgroids.h"
23
#include "utils/lsyscache.h"
24
#include "utils/tqual.h"
29
* sepgsql_attribute_post_create
31
* This routine assigns a default security label on a newly defined
32
* column, using ALTER TABLE ... ADD COLUMN.
33
* Note that this routine is not invoked in the case of CREATE TABLE,
34
* although it also defines columns in addition to table.
37
sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum)
39
char *scontext = sepgsql_get_client_label();
45
* Only attributes within regular relation have individual security
48
if (get_rel_relkind(relOid) != RELKIND_RELATION)
52
* Compute a default security label when we create a new procedure object
53
* under the specified namespace.
55
scontext = sepgsql_get_client_label();
56
tcontext = sepgsql_get_label(RelationRelationId, relOid, 0);
57
ncontext = sepgsql_compute_create(scontext, tcontext,
58
SEPG_CLASS_DB_COLUMN);
61
* Assign the default security label on a new procedure
63
object.classId = RelationRelationId;
64
object.objectId = relOid;
65
object.objectSubId = attnum;
66
SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
73
* sepgsql_attribute_relabel
75
* It checks privileges to relabel the supplied column
79
sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
82
char *scontext = sepgsql_get_client_label();
87
if (get_rel_relkind(relOid) != RELKIND_RELATION)
89
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
90
errmsg("cannot set security label on non-regular columns")));
92
object.classId = RelationRelationId;
93
object.objectId = relOid;
94
object.objectSubId = attnum;
95
audit_name = getObjectDescription(&object);
98
* check db_column:{setattr relabelfrom} permission
100
tcontext = sepgsql_get_label(RelationRelationId, relOid, attnum);
101
sepgsql_check_perms(scontext,
103
SEPG_CLASS_DB_COLUMN,
104
SEPG_DB_COLUMN__SETATTR |
105
SEPG_DB_COLUMN__RELABELFROM,
110
* check db_column:{relabelto} permission
112
sepgsql_check_perms(scontext,
114
SEPG_CLASS_DB_COLUMN,
115
SEPG_DB_PROCEDURE__RELABELTO,
124
* sepgsql_relation_post_create
126
* The post creation hook of relation/attribute
129
sepgsql_relation_post_create(Oid relOid)
135
Form_pg_class classForm;
136
ObjectAddress object;
138
char *scontext; /* subject */
139
char *tcontext; /* schema */
140
char *rcontext; /* relation */
141
char *ccontext; /* column */
144
* Fetch catalog record of the new relation. Because pg_class entry is not
145
* visible right now, we need to scan the catalog using SnapshotSelf.
147
rel = heap_open(RelationRelationId, AccessShareLock);
150
ObjectIdAttributeNumber,
151
BTEqualStrategyNumber, F_OIDEQ,
152
ObjectIdGetDatum(relOid));
154
sscan = systable_beginscan(rel, ClassOidIndexId, true,
155
SnapshotSelf, 1, &skey);
157
tuple = systable_getnext(sscan);
158
if (!HeapTupleIsValid(tuple))
159
elog(ERROR, "catalog lookup failed for relation %u", relOid);
161
classForm = (Form_pg_class) GETSTRUCT(tuple);
163
if (classForm->relkind == RELKIND_RELATION)
164
tclass = SEPG_CLASS_DB_TABLE;
165
else if (classForm->relkind == RELKIND_SEQUENCE)
166
tclass = SEPG_CLASS_DB_SEQUENCE;
167
else if (classForm->relkind == RELKIND_VIEW)
168
tclass = SEPG_CLASS_DB_VIEW;
170
goto out; /* No need to assign individual labels */
173
* Compute a default security label when we create a new relation object
174
* under the specified namespace.
176
scontext = sepgsql_get_client_label();
177
tcontext = sepgsql_get_label(NamespaceRelationId,
178
classForm->relnamespace, 0);
179
rcontext = sepgsql_compute_create(scontext, tcontext, tclass);
182
* Assign the default security label on the new relation
184
object.classId = RelationRelationId;
185
object.objectId = relOid;
186
object.objectSubId = 0;
187
SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, rcontext);
190
* We also assigns a default security label on columns of the new regular
193
if (classForm->relkind == RELKIND_RELATION)
197
ccontext = sepgsql_compute_create(scontext, rcontext,
198
SEPG_CLASS_DB_COLUMN);
199
for (index = FirstLowInvalidHeapAttributeNumber + 1;
200
index <= classForm->relnatts;
203
if (index == InvalidAttrNumber)
206
if (index == ObjectIdAttributeNumber && !classForm->relhasoids)
209
object.classId = RelationRelationId;
210
object.objectId = relOid;
211
object.objectSubId = index;
212
SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ccontext);
218
systable_endscan(sscan);
219
heap_close(rel, AccessShareLock);
223
* sepgsql_relation_relabel
225
* It checks privileges to relabel the supplied relation by the `seclabel'.
228
sepgsql_relation_relabel(Oid relOid, const char *seclabel)
230
char *scontext = sepgsql_get_client_label();
236
relkind = get_rel_relkind(relOid);
237
if (relkind == RELKIND_RELATION)
238
tclass = SEPG_CLASS_DB_TABLE;
239
else if (relkind == RELKIND_SEQUENCE)
240
tclass = SEPG_CLASS_DB_SEQUENCE;
241
else if (relkind == RELKIND_VIEW)
242
tclass = SEPG_CLASS_DB_VIEW;
245
(errcode(ERRCODE_WRONG_OBJECT_TYPE),
246
errmsg("cannot set security labels on relations except "
247
"for tables, sequences or views")));
249
audit_name = getObjectDescriptionOids(RelationRelationId, relOid);
252
* check db_xxx:{setattr relabelfrom} permission
254
tcontext = sepgsql_get_label(RelationRelationId, relOid, 0);
256
sepgsql_check_perms(scontext,
259
SEPG_DB_TABLE__SETATTR |
260
SEPG_DB_TABLE__RELABELFROM,
265
* check db_xxx:{relabelto} permission
267
sepgsql_check_perms(scontext,
270
SEPG_DB_TABLE__RELABELTO,