PostgreSQL Source Code git master
Loading...
Searching...
No Matches
seclabel.c File Reference
#include "postgres.h"
#include "access/genam.h"
#include "access/htup_details.h"
#include "access/relation.h"
#include "access/table.h"
#include "catalog/catalog.h"
#include "catalog/indexing.h"
#include "catalog/pg_seclabel.h"
#include "catalog/pg_shseclabel.h"
#include "commands/seclabel.h"
#include "miscadmin.h"
#include "utils/builtins.h"
#include "utils/fmgroids.h"
#include "utils/memutils.h"
#include "utils/rel.h"
Include dependency graph for seclabel.c:

Go to the source code of this file.

Data Structures

struct  LabelProvider
 

Functions

static bool SecLabelSupportsObjectType (ObjectType objtype)
 
ObjectAddress ExecSecLabelStmt (SecLabelStmt *stmt)
 
static charGetSharedSecurityLabel (const ObjectAddress *object, const char *provider)
 
charGetSecurityLabel (const ObjectAddress *object, const char *provider)
 
static void SetSharedSecurityLabel (const ObjectAddress *object, const char *provider, const char *label)
 
void SetSecurityLabel (const ObjectAddress *object, const char *provider, const char *label)
 
void DeleteSharedSecurityLabel (Oid objectId, Oid classId)
 
void DeleteSecurityLabel (const ObjectAddress *object)
 
void register_label_provider (const char *provider_name, check_object_relabel_type hook)
 

Variables

static Listlabel_provider_list = NIL
 

Function Documentation

◆ DeleteSecurityLabel()

void DeleteSecurityLabel ( const ObjectAddress object)

Definition at line 534 of file seclabel.c.

535{
537 ScanKeyData skey[3];
538 SysScanDesc scan;
540 int nkeys;
541
542 /* Shared objects have their own security label catalog. */
543 if (IsSharedRelation(object->classId))
544 {
545 Assert(object->objectSubId == 0);
547 return;
548 }
549
550 ScanKeyInit(&skey[0],
553 ObjectIdGetDatum(object->objectId));
554 ScanKeyInit(&skey[1],
557 ObjectIdGetDatum(object->classId));
558 if (object->objectSubId != 0)
559 {
560 ScanKeyInit(&skey[2],
563 Int32GetDatum(object->objectSubId));
564 nkeys = 3;
565 }
566 else
567 nkeys = 2;
568
570
572 NULL, nkeys, skey);
575 systable_endscan(scan);
576
578}
#define Assert(condition)
Definition c.h:945
bool IsSharedRelation(Oid relationId)
Definition catalog.c:304
void systable_endscan(SysScanDesc sysscan)
Definition genam.c:603
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition genam.c:514
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition genam.c:388
#define HeapTupleIsValid(tuple)
Definition htup.h:78
void CatalogTupleDelete(Relation heapRel, const ItemPointerData *tid)
Definition indexing.c:365
#define RowExclusiveLock
Definition lockdefs.h:38
static Datum ObjectIdGetDatum(Oid X)
Definition postgres.h:252
static Datum Int32GetDatum(int32 X)
Definition postgres.h:212
static int fb(int x)
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition scankey.c:76
void DeleteSharedSecurityLabel(Oid objectId, Oid classId)
Definition seclabel.c:502
#define BTEqualStrategyNumber
Definition stratnum.h:31
void table_close(Relation relation, LOCKMODE lockmode)
Definition table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition table.c:40

References Assert, BTEqualStrategyNumber, CatalogTupleDelete(), ObjectAddress::classId, DeleteSharedSecurityLabel(), fb(), HeapTupleIsValid, Int32GetDatum(), IsSharedRelation(), ObjectAddress::objectId, ObjectIdGetDatum(), ObjectAddress::objectSubId, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), and table_open().

Referenced by deleteOneObject().

◆ DeleteSharedSecurityLabel()

◆ ExecSecLabelStmt()

ObjectAddress ExecSecLabelStmt ( SecLabelStmt stmt)

Definition at line 116 of file seclabel.c.

117{
119 ObjectAddress address;
120 Relation relation;
121 ListCell *lc;
122 bool missing_ok;
123
124 /*
125 * Find the named label provider, or if none specified, check whether
126 * there's exactly one, and if so use it.
127 */
128 if (stmt->provider == NULL)
129 {
133 errmsg("no security label providers have been loaded")));
137 errmsg("must specify provider when multiple security label providers have been loaded")));
139 }
140 else
141 {
142 foreach(lc, label_provider_list)
143 {
145
146 if (strcmp(stmt->provider, lp->provider_name) == 0)
147 {
148 provider = lp;
149 break;
150 }
151 }
152 if (provider == NULL)
155 errmsg("security label provider \"%s\" is not loaded",
156 stmt->provider)));
157 }
158
159 if (!SecLabelSupportsObjectType(stmt->objtype))
162 errmsg("security labels are not supported for this type of object")));
163
164 /*
165 * During binary upgrade, allow nonexistent large objects so that we don't
166 * have to create them during schema restoration. pg_upgrade will
167 * transfer the contents of pg_largeobject_metadata via COPY or by
168 * copying/linking its files from the old cluster later on.
169 */
170 missing_ok = IsBinaryUpgrade && stmt->objtype == OBJECT_LARGEOBJECT;
171
172 /*
173 * Translate the parser representation which identifies this object into
174 * an ObjectAddress. get_object_address() will throw an error if the
175 * object does not exist, and will also acquire a lock on the target to
176 * guard against concurrent modifications.
177 */
178 address = get_object_address(stmt->objtype, stmt->object,
179 &relation, ShareUpdateExclusiveLock,
180 missing_ok);
181
182 /* Require ownership of the target object. */
183 check_object_ownership(GetUserId(), stmt->objtype, address,
184 stmt->object, relation);
185
186 /* Perform other integrity checks as needed. */
187 switch (stmt->objtype)
188 {
189 case OBJECT_COLUMN:
190
191 /*
192 * Allow security labels only on columns of tables, views,
193 * materialized views, composite types, and foreign tables (which
194 * are the only relkinds for which pg_dump will dump labels).
195 */
196 if (relation->rd_rel->relkind != RELKIND_RELATION &&
197 relation->rd_rel->relkind != RELKIND_VIEW &&
198 relation->rd_rel->relkind != RELKIND_MATVIEW &&
199 relation->rd_rel->relkind != RELKIND_COMPOSITE_TYPE &&
200 relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE &&
201 relation->rd_rel->relkind != RELKIND_PARTITIONED_TABLE)
204 errmsg("cannot set security label on relation \"%s\"",
205 RelationGetRelationName(relation)),
206 errdetail_relkind_not_supported(relation->rd_rel->relkind)));
207 break;
208 default:
209 break;
210 }
211
212 /* Provider gets control here, may throw ERROR to veto new label. */
213 provider->hook(&address, stmt->label);
214
215 /* Apply new label. */
216 SetSecurityLabel(&address, provider->provider_name, stmt->label);
217
218 /*
219 * If get_object_address() opened the relation for us, we close it to keep
220 * the reference count correct - but we retain any locks acquired by
221 * get_object_address() until commit time, to guard against concurrent
222 * activity.
223 */
224 if (relation != NULL)
225 relation_close(relation, NoLock);
226
227 return address;
228}
int errcode(int sqlerrcode)
Definition elog.c:874
#define ERROR
Definition elog.h:39
#define ereport(elevel,...)
Definition elog.h:150
bool IsBinaryUpgrade
Definition globals.c:121
#define stmt
#define NoLock
Definition lockdefs.h:34
#define ShareUpdateExclusiveLock
Definition lockdefs.h:39
Oid GetUserId(void)
Definition miscinit.c:470
static char * errmsg
void check_object_ownership(Oid roleid, ObjectType objtype, ObjectAddress address, Node *object, Relation relation)
ObjectAddress get_object_address(ObjectType objtype, Node *object, Relation *relp, LOCKMODE lockmode, bool missing_ok)
@ OBJECT_COLUMN
@ OBJECT_LARGEOBJECT
int errdetail_relkind_not_supported(char relkind)
Definition pg_class.c:24
#define lfirst(lc)
Definition pg_list.h:172
static int list_length(const List *l)
Definition pg_list.h:152
#define NIL
Definition pg_list.h:68
#define linitial(l)
Definition pg_list.h:178
#define RelationGetRelationName(relation)
Definition rel.h:548
void SetSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition seclabel.c:415
static List * label_provider_list
Definition seclabel.c:34
static bool SecLabelSupportsObjectType(ObjectType objtype)
Definition seclabel.c:37
void relation_close(Relation relation, LOCKMODE lockmode)
Definition relation.c:205
Form_pg_class rd_rel
Definition rel.h:111

References check_object_ownership(), ereport, errcode(), errdetail_relkind_not_supported(), errmsg, ERROR, fb(), get_object_address(), GetUserId(), IsBinaryUpgrade, label_provider_list, lfirst, linitial, list_length(), NIL, NoLock, OBJECT_COLUMN, OBJECT_LARGEOBJECT, RelationData::rd_rel, relation_close(), RelationGetRelationName, SecLabelSupportsObjectType(), SetSecurityLabel(), ShareUpdateExclusiveLock, and stmt.

Referenced by ProcessUtilitySlow(), and standard_ProcessUtility().

◆ GetSecurityLabel()

char * GetSecurityLabel ( const ObjectAddress object,
const char provider 
)

Definition at line 283 of file seclabel.c.

284{
286 ScanKeyData keys[4];
287 SysScanDesc scan;
288 HeapTuple tuple;
289 Datum datum;
290 bool isnull;
291 char *seclabel = NULL;
292
293 /* Shared objects have their own security label catalog. */
294 if (IsSharedRelation(object->classId))
295 return GetSharedSecurityLabel(object, provider);
296
297 /* Must be an unshared object, so examine pg_seclabel. */
298 ScanKeyInit(&keys[0],
301 ObjectIdGetDatum(object->objectId));
302 ScanKeyInit(&keys[1],
305 ObjectIdGetDatum(object->classId));
306 ScanKeyInit(&keys[2],
309 Int32GetDatum(object->objectSubId));
310 ScanKeyInit(&keys[3],
314
316
318 NULL, 4, keys);
319
320 tuple = systable_getnext(scan);
321 if (HeapTupleIsValid(tuple))
322 {
324 RelationGetDescr(pg_seclabel), &isnull);
325 if (!isnull)
327 }
328 systable_endscan(scan);
329
331
332 return seclabel;
333}
#define CStringGetTextDatum(s)
Definition builtins.h:98
#define TextDatumGetCString(d)
Definition builtins.h:99
static Datum heap_getattr(HeapTuple tup, int attnum, TupleDesc tupleDesc, bool *isnull)
#define AccessShareLock
Definition lockdefs.h:36
uint64_t Datum
Definition postgres.h:70
#define RelationGetDescr(relation)
Definition rel.h:540
static char * GetSharedSecurityLabel(const ObjectAddress *object, const char *provider)
Definition seclabel.c:235

References AccessShareLock, BTEqualStrategyNumber, ObjectAddress::classId, CStringGetTextDatum, fb(), GetSharedSecurityLabel(), heap_getattr(), HeapTupleIsValid, Int32GetDatum(), IsSharedRelation(), ObjectAddress::objectId, ObjectIdGetDatum(), ObjectAddress::objectSubId, RelationGetDescr, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), and TextDatumGetCString.

Referenced by sepgsql_avc_check_perms(), sepgsql_avc_trusted_proc(), and sepgsql_get_label().

◆ GetSharedSecurityLabel()

static char * GetSharedSecurityLabel ( const ObjectAddress object,
const char provider 
)
static

Definition at line 235 of file seclabel.c.

236{
238 ScanKeyData keys[3];
239 SysScanDesc scan;
240 HeapTuple tuple;
241 Datum datum;
242 bool isnull;
243 char *seclabel = NULL;
244
245 ScanKeyInit(&keys[0],
248 ObjectIdGetDatum(object->objectId));
249 ScanKeyInit(&keys[1],
252 ObjectIdGetDatum(object->classId));
253 ScanKeyInit(&keys[2],
257
259
262
263 tuple = systable_getnext(scan);
264 if (HeapTupleIsValid(tuple))
265 {
268 if (!isnull)
270 }
271 systable_endscan(scan);
272
274
275 return seclabel;
276}
bool criticalSharedRelcachesBuilt
Definition relcache.c:147

References AccessShareLock, BTEqualStrategyNumber, ObjectAddress::classId, criticalSharedRelcachesBuilt, CStringGetTextDatum, fb(), heap_getattr(), HeapTupleIsValid, ObjectAddress::objectId, ObjectIdGetDatum(), RelationGetDescr, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), and TextDatumGetCString.

Referenced by GetSecurityLabel().

◆ register_label_provider()

void register_label_provider ( const char provider_name,
check_object_relabel_type  hook 
)

Definition at line 581 of file seclabel.c.

582{
585
588 provider->provider_name = pstrdup(provider_name);
589 provider->hook = hook;
592}
#define palloc_object(type)
Definition fe_memutils.h:74
List * lappend(List *list, void *datum)
Definition list.c:339
char * pstrdup(const char *in)
Definition mcxt.c:1781
MemoryContext TopMemoryContext
Definition mcxt.c:166
static MemoryContext MemoryContextSwitchTo(MemoryContext context)
Definition palloc.h:124

References fb(), label_provider_list, lappend(), MemoryContextSwitchTo(), palloc_object, pstrdup(), and TopMemoryContext.

Referenced by _PG_init().

◆ SecLabelSupportsObjectType()

static bool SecLabelSupportsObjectType ( ObjectType  objtype)
static

Definition at line 37 of file seclabel.c.

38{
39 switch (objtype)
40 {
42 case OBJECT_COLUMN:
43 case OBJECT_DATABASE:
44 case OBJECT_DOMAIN:
47 case OBJECT_FUNCTION:
48 case OBJECT_LANGUAGE:
50 case OBJECT_MATVIEW:
53 case OBJECT_ROLE:
54 case OBJECT_ROUTINE:
55 case OBJECT_SCHEMA:
56 case OBJECT_SEQUENCE:
58 case OBJECT_TABLE:
60 case OBJECT_TYPE:
61 case OBJECT_VIEW:
62 return true;
63
65 case OBJECT_AMOP:
66 case OBJECT_AMPROC:
68 case OBJECT_CAST:
71 case OBJECT_DEFAULT:
72 case OBJECT_DEFACL:
75 case OBJECT_FDW:
77 case OBJECT_INDEX:
78 case OBJECT_OPCLASS:
79 case OBJECT_OPERATOR:
80 case OBJECT_OPFAMILY:
82 case OBJECT_POLICY:
86 case OBJECT_RULE:
90 case OBJECT_TRIGGER:
93 case OBJECT_TSPARSER:
96 return false;
97
98 /*
99 * There's intentionally no default: case here; we want the
100 * compiler to warn if a new ObjectType hasn't been handled above.
101 */
102 }
103
104 /* Shouldn't get here, but if we do, say "no support" */
105 return false;
106}
@ OBJECT_EVENT_TRIGGER
@ OBJECT_FDW
@ OBJECT_TSPARSER
@ OBJECT_COLLATION
@ OBJECT_USER_MAPPING
@ OBJECT_PROPGRAPH
@ OBJECT_ACCESS_METHOD
@ OBJECT_OPCLASS
@ OBJECT_DEFACL
@ OBJECT_AGGREGATE
@ OBJECT_MATVIEW
@ OBJECT_SCHEMA
@ OBJECT_POLICY
@ OBJECT_OPERATOR
@ OBJECT_FOREIGN_TABLE
@ OBJECT_TSCONFIGURATION
@ OBJECT_OPFAMILY
@ OBJECT_DOMAIN
@ OBJECT_TABLESPACE
@ OBJECT_ROLE
@ OBJECT_ROUTINE
@ OBJECT_PUBLICATION_NAMESPACE
@ OBJECT_PROCEDURE
@ OBJECT_EXTENSION
@ OBJECT_INDEX
@ OBJECT_DEFAULT
@ OBJECT_DATABASE
@ OBJECT_SEQUENCE
@ OBJECT_TSTEMPLATE
@ OBJECT_LANGUAGE
@ OBJECT_AMOP
@ OBJECT_PUBLICATION_REL
@ OBJECT_FOREIGN_SERVER
@ OBJECT_TSDICTIONARY
@ OBJECT_ATTRIBUTE
@ OBJECT_PUBLICATION
@ OBJECT_RULE
@ OBJECT_CONVERSION
@ OBJECT_AMPROC
@ OBJECT_TABLE
@ OBJECT_VIEW
@ OBJECT_PARAMETER_ACL
@ OBJECT_TYPE
@ OBJECT_FUNCTION
@ OBJECT_TABCONSTRAINT
@ OBJECT_DOMCONSTRAINT
@ OBJECT_SUBSCRIPTION
@ OBJECT_STATISTIC_EXT
@ OBJECT_CAST
@ OBJECT_TRIGGER
@ OBJECT_TRANSFORM

References OBJECT_ACCESS_METHOD, OBJECT_AGGREGATE, OBJECT_AMOP, OBJECT_AMPROC, OBJECT_ATTRIBUTE, OBJECT_CAST, OBJECT_COLLATION, OBJECT_COLUMN, OBJECT_CONVERSION, OBJECT_DATABASE, OBJECT_DEFACL, OBJECT_DEFAULT, OBJECT_DOMAIN, OBJECT_DOMCONSTRAINT, OBJECT_EVENT_TRIGGER, OBJECT_EXTENSION, OBJECT_FDW, OBJECT_FOREIGN_SERVER, OBJECT_FOREIGN_TABLE, OBJECT_FUNCTION, OBJECT_INDEX, OBJECT_LANGUAGE, OBJECT_LARGEOBJECT, OBJECT_MATVIEW, OBJECT_OPCLASS, OBJECT_OPERATOR, OBJECT_OPFAMILY, OBJECT_PARAMETER_ACL, OBJECT_POLICY, OBJECT_PROCEDURE, OBJECT_PROPGRAPH, OBJECT_PUBLICATION, OBJECT_PUBLICATION_NAMESPACE, OBJECT_PUBLICATION_REL, OBJECT_ROLE, OBJECT_ROUTINE, OBJECT_RULE, OBJECT_SCHEMA, OBJECT_SEQUENCE, OBJECT_STATISTIC_EXT, OBJECT_SUBSCRIPTION, OBJECT_TABCONSTRAINT, OBJECT_TABLE, OBJECT_TABLESPACE, OBJECT_TRANSFORM, OBJECT_TRIGGER, OBJECT_TSCONFIGURATION, OBJECT_TSDICTIONARY, OBJECT_TSPARSER, OBJECT_TSTEMPLATE, OBJECT_TYPE, OBJECT_USER_MAPPING, and OBJECT_VIEW.

Referenced by ExecSecLabelStmt().

◆ SetSecurityLabel()

void SetSecurityLabel ( const ObjectAddress object,
const char provider,
const char label 
)

Definition at line 415 of file seclabel.c.

417{
419 ScanKeyData keys[4];
420 SysScanDesc scan;
424 bool nulls[Natts_pg_seclabel];
426
427 /* Shared objects have their own security label catalog. */
428 if (IsSharedRelation(object->classId))
429 {
431 return;
432 }
433
434 /* Prepare to form or update a tuple, if necessary. */
435 memset(nulls, false, sizeof(nulls));
436 memset(replaces, false, sizeof(replaces));
441 if (label != NULL)
443
444 /* Use the index to search for a matching old tuple */
445 ScanKeyInit(&keys[0],
448 ObjectIdGetDatum(object->objectId));
449 ScanKeyInit(&keys[1],
452 ObjectIdGetDatum(object->classId));
453 ScanKeyInit(&keys[2],
456 Int32GetDatum(object->objectSubId));
457 ScanKeyInit(&keys[3],
461
463
465 NULL, 4, keys);
466
467 oldtup = systable_getnext(scan);
469 {
470 if (label == NULL)
472 else
473 {
476 values, nulls, replaces);
478 }
479 }
480 systable_endscan(scan);
481
482 /* If we didn't find an old tuple, insert a new one */
483 if (newtup == NULL && label != NULL)
484 {
486 values, nulls);
488 }
489
490 /* Update indexes, if necessary */
491 if (newtup != NULL)
493
495}
static Datum values[MAXATTR]
Definition bootstrap.c:188
HeapTuple heap_modify_tuple(HeapTuple tuple, TupleDesc tupleDesc, const Datum *replValues, const bool *replIsnull, const bool *doReplace)
Definition heaptuple.c:1130
HeapTuple heap_form_tuple(TupleDesc tupleDescriptor, const Datum *values, const bool *isnull)
Definition heaptuple.c:1037
void heap_freetuple(HeapTuple htup)
Definition heaptuple.c:1384
void CatalogTupleUpdate(Relation heapRel, const ItemPointerData *otid, HeapTuple tup)
Definition indexing.c:313
void CatalogTupleInsert(Relation heapRel, HeapTuple tup)
Definition indexing.c:233
static char * label
static void SetSharedSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition seclabel.c:340

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleInsert(), CatalogTupleUpdate(), ObjectAddress::classId, CStringGetTextDatum, fb(), heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), HeapTupleIsValid, Int32GetDatum(), IsSharedRelation(), label, ObjectAddress::objectId, ObjectIdGetDatum(), ObjectAddress::objectSubId, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), SetSharedSecurityLabel(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), and values.

Referenced by exec_object_restorecon(), ExecSecLabelStmt(), sepgsql_attribute_post_create(), sepgsql_database_post_create(), sepgsql_proc_post_create(), sepgsql_relation_post_create(), and sepgsql_schema_post_create().

◆ SetSharedSecurityLabel()

static void SetSharedSecurityLabel ( const ObjectAddress object,
const char provider,
const char label 
)
static

Definition at line 340 of file seclabel.c.

342{
344 ScanKeyData keys[4];
345 SysScanDesc scan;
349 bool nulls[Natts_pg_shseclabel];
351
352 /* Prepare to form or update a tuple, if necessary. */
353 memset(nulls, false, sizeof(nulls));
354 memset(replaces, false, sizeof(replaces));
358 if (label != NULL)
360
361 /* Use the index to search for a matching old tuple */
362 ScanKeyInit(&keys[0],
365 ObjectIdGetDatum(object->objectId));
366 ScanKeyInit(&keys[1],
369 ObjectIdGetDatum(object->classId));
370 ScanKeyInit(&keys[2],
374
376
378 NULL, 3, keys);
379
380 oldtup = systable_getnext(scan);
382 {
383 if (label == NULL)
385 else
386 {
389 values, nulls, replaces);
391 }
392 }
393 systable_endscan(scan);
394
395 /* If we didn't find an old tuple, insert a new one */
396 if (newtup == NULL && label != NULL)
397 {
399 values, nulls);
401 }
402
403 if (newtup != NULL)
405
407}

References BTEqualStrategyNumber, CatalogTupleDelete(), CatalogTupleInsert(), CatalogTupleUpdate(), ObjectAddress::classId, CStringGetTextDatum, fb(), heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), HeapTupleIsValid, label, ObjectAddress::objectId, ObjectIdGetDatum(), RelationGetDescr, RowExclusiveLock, ScanKeyInit(), systable_beginscan(), systable_endscan(), systable_getnext(), table_close(), table_open(), and values.

Referenced by SetSecurityLabel().

Variable Documentation

◆ label_provider_list

List* label_provider_list = NIL
static

Definition at line 34 of file seclabel.c.

Referenced by ExecSecLabelStmt(), and register_label_provider().