#include "postgres.h"
#include "access/genam.h"
#include "access/heapam.h"
#include "access/htup_details.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 "utils/tqual.h"
Go to the source code of this file.
Data Structures | |
struct | LabelProvider |
Functions | |
Oid | ExecSecLabelStmt (SecLabelStmt *stmt) |
static char * | GetSharedSecurityLabel (const ObjectAddress *object, const char *provider) |
char * | GetSecurityLabel (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 List * | label_provider_list = NIL |
void DeleteSecurityLabel | ( | const ObjectAddress * | object | ) |
Definition at line 450 of file seclabel.c.
References Anum_pg_seclabel_classoid, Anum_pg_seclabel_objoid, Anum_pg_seclabel_objsubid, Assert, BTEqualStrategyNumber, ObjectAddress::classId, DeleteSharedSecurityLabel(), heap_close, heap_open(), HeapTupleIsValid, Int32GetDatum, IsSharedRelation(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RowExclusiveLock, ScanKeyInit(), SecLabelObjectIndexId, SecLabelRelationId, simple_heap_delete(), SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.
Referenced by deleteOneObject().
{ Relation pg_seclabel; ScanKeyData skey[3]; SysScanDesc scan; HeapTuple oldtup; int nkeys; /* Shared objects have their own security label catalog. */ if (IsSharedRelation(object->classId)) { Assert(object->objectSubId == 0); DeleteSharedSecurityLabel(object->objectId, object->classId); return; } ScanKeyInit(&skey[0], Anum_pg_seclabel_objoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); ScanKeyInit(&skey[1], Anum_pg_seclabel_classoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->classId)); if (object->objectSubId != 0) { ScanKeyInit(&skey[2], Anum_pg_seclabel_objsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(object->objectSubId)); nkeys = 3; } else nkeys = 2; pg_seclabel = heap_open(SecLabelRelationId, RowExclusiveLock); scan = systable_beginscan(pg_seclabel, SecLabelObjectIndexId, true, SnapshotNow, nkeys, skey); while (HeapTupleIsValid(oldtup = systable_getnext(scan))) simple_heap_delete(pg_seclabel, &oldtup->t_self); systable_endscan(scan); heap_close(pg_seclabel, RowExclusiveLock); }
Definition at line 418 of file seclabel.c.
References Anum_pg_shseclabel_classoid, Anum_pg_shseclabel_objoid, BTEqualStrategyNumber, heap_close, heap_open(), HeapTupleIsValid, ObjectIdGetDatum, RowExclusiveLock, ScanKeyInit(), SharedSecLabelObjectIndexId, SharedSecLabelRelationId, simple_heap_delete(), SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), and HeapTupleData::t_self.
Referenced by DeleteSecurityLabel(), dropdb(), DropRole(), and DropTableSpace().
{ Relation pg_shseclabel; ScanKeyData skey[2]; SysScanDesc scan; HeapTuple oldtup; ScanKeyInit(&skey[0], Anum_pg_shseclabel_objoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(objectId)); ScanKeyInit(&skey[1], Anum_pg_shseclabel_classoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(classId)); pg_shseclabel = heap_open(SharedSecLabelRelationId, RowExclusiveLock); scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId, true, SnapshotNow, 2, skey); while (HeapTupleIsValid(oldtup = systable_getnext(scan))) simple_heap_delete(pg_shseclabel, &oldtup->t_self); systable_endscan(scan); heap_close(pg_shseclabel, RowExclusiveLock); }
Oid ExecSecLabelStmt | ( | SecLabelStmt * | stmt | ) |
Definition at line 42 of file seclabel.c.
References check_object_ownership(), ereport, errcode(), errmsg(), ERROR, get_object_address(), GetUserId(), LabelProvider::hook, SecLabelStmt::label, lfirst, linitial, list_head(), lnext, NIL, NoLock, NULL, SecLabelStmt::objargs, OBJECT_COLUMN, ObjectAddress::objectId, SecLabelStmt::objname, SecLabelStmt::objtype, SecLabelStmt::provider, LabelProvider::provider_name, RelationData::rd_rel, relation_close(), RelationGetRelationName, RELKIND_COMPOSITE_TYPE, RELKIND_FOREIGN_TABLE, RELKIND_MATVIEW, RELKIND_RELATION, RELKIND_VIEW, SetSecurityLabel(), and ShareUpdateExclusiveLock.
Referenced by standard_ProcessUtility().
{ LabelProvider *provider = NULL; ObjectAddress address; Relation relation; ListCell *lc; /* * Find the named label provider, or if none specified, check whether * there's exactly one, and if so use it. */ if (stmt->provider == NULL) { if (label_provider_list == NIL) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("no security label providers have been loaded"))); if (lnext(list_head(label_provider_list)) != NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("must specify provider when multiple security label providers have been loaded"))); provider = (LabelProvider *) linitial(label_provider_list); } else { foreach(lc, label_provider_list) { LabelProvider *lp = lfirst(lc); if (strcmp(stmt->provider, lp->provider_name) == 0) { provider = lp; break; } } if (provider == NULL) ereport(ERROR, (errcode(ERRCODE_INVALID_PARAMETER_VALUE), errmsg("security label provider \"%s\" is not loaded", stmt->provider))); } /* * Translate the parser representation which identifies this object into * an ObjectAddress. get_object_address() will throw an error if the * object does not exist, and will also acquire a lock on the target to * guard against concurrent modifications. */ address = get_object_address(stmt->objtype, stmt->objname, stmt->objargs, &relation, ShareUpdateExclusiveLock, false); /* Require ownership of the target object. */ check_object_ownership(GetUserId(), stmt->objtype, address, stmt->objname, stmt->objargs, relation); /* Perform other integrity checks as needed. */ switch (stmt->objtype) { case OBJECT_COLUMN: /* * Allow security labels only on columns of tables, views, * materialized views, composite types, and foreign tables (which * are the only relkinds for which pg_dump will dump labels). */ if (relation->rd_rel->relkind != RELKIND_RELATION && relation->rd_rel->relkind != RELKIND_VIEW && relation->rd_rel->relkind != RELKIND_MATVIEW && relation->rd_rel->relkind != RELKIND_COMPOSITE_TYPE && relation->rd_rel->relkind != RELKIND_FOREIGN_TABLE) ereport(ERROR, (errcode(ERRCODE_WRONG_OBJECT_TYPE), errmsg("\"%s\" is not a table, view, composite type, or foreign table", RelationGetRelationName(relation)))); break; default: break; } /* Provider gets control here, may throw ERROR to veto new label. */ (*provider->hook) (&address, stmt->label); /* Apply new label. */ SetSecurityLabel(&address, provider->provider_name, stmt->label); /* * If get_object_address() opened the relation for us, we close it to keep * the reference count correct - but we retain any locks acquired by * get_object_address() until commit time, to guard against concurrent * activity. */ if (relation != NULL) relation_close(relation, NoLock); return address.objectId; }
char* GetSecurityLabel | ( | const ObjectAddress * | object, | |
const char * | provider | |||
) |
Definition at line 192 of file seclabel.c.
References AccessShareLock, Anum_pg_seclabel_classoid, Anum_pg_seclabel_label, Anum_pg_seclabel_objoid, Anum_pg_seclabel_objsubid, Anum_pg_seclabel_provider, BTEqualStrategyNumber, ObjectAddress::classId, CStringGetTextDatum, GetSharedSecurityLabel(), heap_close, heap_getattr, heap_open(), HeapTupleIsValid, Int32GetDatum, IsSharedRelation(), ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RelationGetDescr, ScanKeyInit(), SecLabelObjectIndexId, SecLabelRelationId, SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), and TextDatumGetCString.
Referenced by sepgsql_avc_check_perms(), sepgsql_avc_trusted_proc(), and sepgsql_get_label().
{ Relation pg_seclabel; ScanKeyData keys[4]; SysScanDesc scan; HeapTuple tuple; Datum datum; bool isnull; char *seclabel = NULL; /* Shared objects have their own security label catalog. */ if (IsSharedRelation(object->classId)) return GetSharedSecurityLabel(object, provider); /* Must be an unshared object, so examine pg_seclabel. */ ScanKeyInit(&keys[0], Anum_pg_seclabel_objoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); ScanKeyInit(&keys[1], Anum_pg_seclabel_classoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->classId)); ScanKeyInit(&keys[2], Anum_pg_seclabel_objsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(object->objectSubId)); ScanKeyInit(&keys[3], Anum_pg_seclabel_provider, BTEqualStrategyNumber, F_TEXTEQ, CStringGetTextDatum(provider)); pg_seclabel = heap_open(SecLabelRelationId, AccessShareLock); scan = systable_beginscan(pg_seclabel, SecLabelObjectIndexId, true, SnapshotNow, 4, keys); tuple = systable_getnext(scan); if (HeapTupleIsValid(tuple)) { datum = heap_getattr(tuple, Anum_pg_seclabel_label, RelationGetDescr(pg_seclabel), &isnull); if (!isnull) seclabel = TextDatumGetCString(datum); } systable_endscan(scan); heap_close(pg_seclabel, AccessShareLock); return seclabel; }
static char* GetSharedSecurityLabel | ( | const ObjectAddress * | object, | |
const char * | provider | |||
) | [static] |
Definition at line 144 of file seclabel.c.
References AccessShareLock, Anum_pg_shseclabel_classoid, Anum_pg_shseclabel_label, Anum_pg_shseclabel_objoid, Anum_pg_shseclabel_provider, BTEqualStrategyNumber, ObjectAddress::classId, CStringGetTextDatum, heap_close, heap_getattr, heap_open(), HeapTupleIsValid, ObjectAddress::objectId, ObjectIdGetDatum, RelationGetDescr, ScanKeyInit(), SharedSecLabelObjectIndexId, SharedSecLabelRelationId, SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), and TextDatumGetCString.
Referenced by GetSecurityLabel().
{ Relation pg_shseclabel; ScanKeyData keys[3]; SysScanDesc scan; HeapTuple tuple; Datum datum; bool isnull; char *seclabel = NULL; ScanKeyInit(&keys[0], Anum_pg_shseclabel_objoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); ScanKeyInit(&keys[1], Anum_pg_shseclabel_classoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->classId)); ScanKeyInit(&keys[2], Anum_pg_shseclabel_provider, BTEqualStrategyNumber, F_TEXTEQ, CStringGetTextDatum(provider)); pg_shseclabel = heap_open(SharedSecLabelRelationId, AccessShareLock); scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId, true, SnapshotNow, 3, keys); tuple = systable_getnext(scan); if (HeapTupleIsValid(tuple)) { datum = heap_getattr(tuple, Anum_pg_shseclabel_label, RelationGetDescr(pg_shseclabel), &isnull); if (!isnull) seclabel = TextDatumGetCString(datum); } systable_endscan(scan); heap_close(pg_shseclabel, AccessShareLock); return seclabel; }
void register_label_provider | ( | const char * | provider_name, | |
check_object_relabel_type | hook | |||
) |
Definition at line 497 of file seclabel.c.
References LabelProvider::hook, lappend(), MemoryContextSwitchTo(), palloc(), LabelProvider::provider_name, pstrdup(), and TopMemoryContext.
Referenced by _PG_init().
{ LabelProvider *provider; MemoryContext oldcxt; oldcxt = MemoryContextSwitchTo(TopMemoryContext); provider = palloc(sizeof(LabelProvider)); provider->provider_name = pstrdup(provider_name); provider->hook = hook; label_provider_list = lappend(label_provider_list, provider); MemoryContextSwitchTo(oldcxt); }
void SetSecurityLabel | ( | const ObjectAddress * | object, | |
const char * | provider, | |||
const char * | label | |||
) |
Definition at line 328 of file seclabel.c.
References Anum_pg_seclabel_classoid, Anum_pg_seclabel_label, Anum_pg_seclabel_objoid, Anum_pg_seclabel_objsubid, Anum_pg_seclabel_provider, BTEqualStrategyNumber, CatalogUpdateIndexes(), ObjectAddress::classId, CStringGetTextDatum, heap_close, heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleIsValid, Int32GetDatum, IsSharedRelation(), NULL, ObjectAddress::objectId, ObjectIdGetDatum, ObjectAddress::objectSubId, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), SecLabelObjectIndexId, SecLabelRelationId, SetSharedSecurityLabel(), simple_heap_delete(), simple_heap_insert(), simple_heap_update(), SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, 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().
{ Relation pg_seclabel; ScanKeyData keys[4]; SysScanDesc scan; HeapTuple oldtup; HeapTuple newtup = NULL; Datum values[Natts_pg_seclabel]; bool nulls[Natts_pg_seclabel]; bool replaces[Natts_pg_seclabel]; /* Shared objects have their own security label catalog. */ if (IsSharedRelation(object->classId)) { SetSharedSecurityLabel(object, provider, label); return; } /* Prepare to form or update a tuple, if necessary. */ memset(nulls, false, sizeof(nulls)); memset(replaces, false, sizeof(replaces)); values[Anum_pg_seclabel_objoid - 1] = ObjectIdGetDatum(object->objectId); values[Anum_pg_seclabel_classoid - 1] = ObjectIdGetDatum(object->classId); values[Anum_pg_seclabel_objsubid - 1] = Int32GetDatum(object->objectSubId); values[Anum_pg_seclabel_provider - 1] = CStringGetTextDatum(provider); if (label != NULL) values[Anum_pg_seclabel_label - 1] = CStringGetTextDatum(label); /* Use the index to search for a matching old tuple */ ScanKeyInit(&keys[0], Anum_pg_seclabel_objoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); ScanKeyInit(&keys[1], Anum_pg_seclabel_classoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->classId)); ScanKeyInit(&keys[2], Anum_pg_seclabel_objsubid, BTEqualStrategyNumber, F_INT4EQ, Int32GetDatum(object->objectSubId)); ScanKeyInit(&keys[3], Anum_pg_seclabel_provider, BTEqualStrategyNumber, F_TEXTEQ, CStringGetTextDatum(provider)); pg_seclabel = heap_open(SecLabelRelationId, RowExclusiveLock); scan = systable_beginscan(pg_seclabel, SecLabelObjectIndexId, true, SnapshotNow, 4, keys); oldtup = systable_getnext(scan); if (HeapTupleIsValid(oldtup)) { if (label == NULL) simple_heap_delete(pg_seclabel, &oldtup->t_self); else { replaces[Anum_pg_seclabel_label - 1] = true; newtup = heap_modify_tuple(oldtup, RelationGetDescr(pg_seclabel), values, nulls, replaces); simple_heap_update(pg_seclabel, &oldtup->t_self, newtup); } } systable_endscan(scan); /* If we didn't find an old tuple, insert a new one */ if (newtup == NULL && label != NULL) { newtup = heap_form_tuple(RelationGetDescr(pg_seclabel), values, nulls); simple_heap_insert(pg_seclabel, newtup); } /* Update indexes, if necessary */ if (newtup != NULL) { CatalogUpdateIndexes(pg_seclabel, newtup); heap_freetuple(newtup); } heap_close(pg_seclabel, RowExclusiveLock); }
static void SetSharedSecurityLabel | ( | const ObjectAddress * | object, | |
const char * | provider, | |||
const char * | label | |||
) | [static] |
Definition at line 249 of file seclabel.c.
References Anum_pg_shseclabel_classoid, Anum_pg_shseclabel_label, Anum_pg_shseclabel_objoid, Anum_pg_shseclabel_provider, BTEqualStrategyNumber, CatalogUpdateIndexes(), ObjectAddress::classId, CStringGetTextDatum, heap_close, heap_form_tuple(), heap_freetuple(), heap_modify_tuple(), heap_open(), HeapTupleIsValid, NULL, ObjectAddress::objectId, ObjectIdGetDatum, RelationGetDescr, RowExclusiveLock, ScanKeyInit(), SharedSecLabelObjectIndexId, SharedSecLabelRelationId, simple_heap_delete(), simple_heap_insert(), simple_heap_update(), SnapshotNow, systable_beginscan(), systable_endscan(), systable_getnext(), HeapTupleData::t_self, and values.
Referenced by SetSecurityLabel().
{ Relation pg_shseclabel; ScanKeyData keys[4]; SysScanDesc scan; HeapTuple oldtup; HeapTuple newtup = NULL; Datum values[Natts_pg_shseclabel]; bool nulls[Natts_pg_shseclabel]; bool replaces[Natts_pg_shseclabel]; /* Prepare to form or update a tuple, if necessary. */ memset(nulls, false, sizeof(nulls)); memset(replaces, false, sizeof(replaces)); values[Anum_pg_shseclabel_objoid - 1] = ObjectIdGetDatum(object->objectId); values[Anum_pg_shseclabel_classoid - 1] = ObjectIdGetDatum(object->classId); values[Anum_pg_shseclabel_provider - 1] = CStringGetTextDatum(provider); if (label != NULL) values[Anum_pg_shseclabel_label - 1] = CStringGetTextDatum(label); /* Use the index to search for a matching old tuple */ ScanKeyInit(&keys[0], Anum_pg_shseclabel_objoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->objectId)); ScanKeyInit(&keys[1], Anum_pg_shseclabel_classoid, BTEqualStrategyNumber, F_OIDEQ, ObjectIdGetDatum(object->classId)); ScanKeyInit(&keys[2], Anum_pg_shseclabel_provider, BTEqualStrategyNumber, F_TEXTEQ, CStringGetTextDatum(provider)); pg_shseclabel = heap_open(SharedSecLabelRelationId, RowExclusiveLock); scan = systable_beginscan(pg_shseclabel, SharedSecLabelObjectIndexId, true, SnapshotNow, 3, keys); oldtup = systable_getnext(scan); if (HeapTupleIsValid(oldtup)) { if (label == NULL) simple_heap_delete(pg_shseclabel, &oldtup->t_self); else { replaces[Anum_pg_shseclabel_label - 1] = true; newtup = heap_modify_tuple(oldtup, RelationGetDescr(pg_shseclabel), values, nulls, replaces); simple_heap_update(pg_shseclabel, &oldtup->t_self, newtup); } } systable_endscan(scan); /* If we didn't find an old tuple, insert a new one */ if (newtup == NULL && label != NULL) { newtup = heap_form_tuple(RelationGetDescr(pg_shseclabel), values, nulls); simple_heap_insert(pg_shseclabel, newtup); } /* Update indexes, if necessary */ if (newtup != NULL) { CatalogUpdateIndexes(pg_shseclabel, newtup); heap_freetuple(newtup); } heap_close(pg_shseclabel, RowExclusiveLock); }
List* label_provider_list = NIL [static] |
Definition at line 34 of file seclabel.c.