PostgreSQL Source Code git master
schema.c
Go to the documentation of this file.
1/* -------------------------------------------------------------------------
2 *
3 * contrib/sepgsql/schema.c
4 *
5 * Routines corresponding to schema objects
6 *
7 * Copyright (c) 2010-2025, PostgreSQL Global Development Group
8 *
9 * -------------------------------------------------------------------------
10 */
11#include "postgres.h"
12
13#include "access/genam.h"
14#include "access/htup_details.h"
15#include "access/sysattr.h"
16#include "access/table.h"
17#include "catalog/dependency.h"
18#include "catalog/pg_database.h"
20#include "commands/seclabel.h"
21#include "lib/stringinfo.h"
22#include "miscadmin.h"
23#include "sepgsql.h"
24#include "utils/builtins.h"
25#include "utils/fmgroids.h"
26#include "utils/lsyscache.h"
27#include "utils/snapmgr.h"
28
29/*
30 * sepgsql_schema_post_create
31 *
32 * This routine assigns a default security label on a newly defined
33 * schema.
34 */
35void
37{
38 Relation rel;
39 ScanKeyData skey;
40 SysScanDesc sscan;
41 HeapTuple tuple;
42 char *tcontext;
43 char *ncontext;
44 const char *nsp_name;
45 ObjectAddress object;
46 Form_pg_namespace nspForm;
47 StringInfoData audit_name;
48
49 /*
50 * Compute a default security label when we create a new schema object
51 * under the working database.
52 *
53 * XXX - upcoming version of libselinux supports to take object name to
54 * handle special treatment on default security label; such as special
55 * label on "pg_temp" schema.
56 */
57 rel = table_open(NamespaceRelationId, AccessShareLock);
58
59 ScanKeyInit(&skey,
60 Anum_pg_namespace_oid,
61 BTEqualStrategyNumber, F_OIDEQ,
62 ObjectIdGetDatum(namespaceId));
63
64 sscan = systable_beginscan(rel, NamespaceOidIndexId, true,
65 SnapshotSelf, 1, &skey);
66 tuple = systable_getnext(sscan);
67 if (!HeapTupleIsValid(tuple))
68 elog(ERROR, "could not find tuple for namespace %u", namespaceId);
69
70 nspForm = (Form_pg_namespace) GETSTRUCT(tuple);
71 nsp_name = NameStr(nspForm->nspname);
72 if (strncmp(nsp_name, "pg_temp_", 8) == 0)
73 nsp_name = "pg_temp";
74 else if (strncmp(nsp_name, "pg_toast_temp_", 14) == 0)
75 nsp_name = "pg_toast_temp";
76
77 tcontext = sepgsql_get_label(DatabaseRelationId, MyDatabaseId, 0);
79 tcontext,
81 nsp_name);
82
83 /*
84 * check db_schema:{create}
85 */
86 initStringInfo(&audit_name);
87 appendStringInfoString(&audit_name, quote_identifier(nsp_name));
91 audit_name.data,
92 true);
93 systable_endscan(sscan);
95
96 /*
97 * Assign the default security label on a new procedure
98 */
99 object.classId = NamespaceRelationId;
100 object.objectId = namespaceId;
101 object.objectSubId = 0;
102 SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
103
104 pfree(ncontext);
105 pfree(tcontext);
106}
107
108/*
109 * sepgsql_schema_drop
110 *
111 * It checks privileges to drop the supplied schema object.
112 */
113void
115{
116 ObjectAddress object;
117 char *audit_name;
118
119 /*
120 * check db_schema:{drop} permission
121 */
122 object.classId = NamespaceRelationId;
123 object.objectId = namespaceId;
124 object.objectSubId = 0;
125 audit_name = getObjectIdentity(&object, false);
126
130 audit_name,
131 true);
132 pfree(audit_name);
133}
134
135/*
136 * sepgsql_schema_relabel
137 *
138 * It checks privileges to relabel the supplied schema
139 * by the `seclabel'.
140 */
141void
142sepgsql_schema_relabel(Oid namespaceId, const char *seclabel)
143{
144 ObjectAddress object;
145 char *audit_name;
146
147 object.classId = NamespaceRelationId;
148 object.objectId = namespaceId;
149 object.objectSubId = 0;
150 audit_name = getObjectIdentity(&object, false);
151
152 /*
153 * check db_schema:{setattr relabelfrom} permission
154 */
159 audit_name,
160 true);
161
162 /*
163 * check db_schema:{relabelto} permission
164 */
168 audit_name,
169 true);
170 pfree(audit_name);
171}
172
173/*
174 * sepgsql_schema_check_perms
175 *
176 * utility routine to check db_schema:{xxx} permissions
177 */
178static bool
179check_schema_perms(Oid namespaceId, uint32 required, bool abort_on_violation)
180{
181 ObjectAddress object;
182 char *audit_name;
183 bool result;
184
185 object.classId = NamespaceRelationId;
186 object.objectId = namespaceId;
187 object.objectSubId = 0;
188 audit_name = getObjectIdentity(&object, false);
189
190 result = sepgsql_avc_check_perms(&object,
192 required,
193 audit_name,
194 abort_on_violation);
195 pfree(audit_name);
196
197 return result;
198}
199
200/* db_schema:{setattr} permission */
201void
203{
205}
206
207/* db_schema:{search} permission */
208bool
209sepgsql_schema_search(Oid namespaceId, bool abort_on_violation)
210{
211 return check_schema_perms(namespaceId,
213 abort_on_violation);
214}
215
216void
218{
220}
221
222void
224{
226}
227
228void
230{
231 check_schema_perms(namespaceId,
234 true);
235}
#define NameStr(name)
Definition: c.h:703
uint32_t uint32
Definition: c.h:488
#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
Oid MyDatabaseId
Definition: globals.c:93
#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
void pfree(void *pointer)
Definition: mcxt.c:1521
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
FormData_pg_namespace * Form_pg_namespace
Definition: pg_namespace.h:52
static Datum ObjectIdGetDatum(Oid X)
Definition: postgres.h:257
unsigned int Oid
Definition: postgres_ext.h:32
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:12940
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
void sepgsql_schema_post_create(Oid namespaceId)
Definition: schema.c:36
void sepgsql_schema_setattr(Oid namespaceId)
Definition: schema.c:202
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 sepgsql_schema_relabel(Oid namespaceId, const char *seclabel)
Definition: schema.c:142
bool sepgsql_schema_search(Oid namespaceId, bool abort_on_violation)
Definition: schema.c:209
void sepgsql_schema_drop(Oid namespaceId)
Definition: schema.c:114
static bool check_schema_perms(Oid namespaceId, uint32 required, bool abort_on_violation)
Definition: schema.c:179
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_SCHEMA__DROP
Definition: sepgsql.h:128
#define SEPG_CLASS_DB_SCHEMA
Definition: sepgsql.h:45
#define SEPG_DB_SCHEMA__SETATTR
Definition: sepgsql.h:130
#define SEPG_DB_SCHEMA__CREATE
Definition: sepgsql.h:127
#define SEPG_DB_SCHEMA__REMOVE_NAME
Definition: sepgsql.h:135
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 SEPG_DB_SCHEMA__ADD_NAME
Definition: sepgsql.h:134
#define SEPG_DB_SCHEMA__RELABELFROM
Definition: sepgsql.h:131
#define SEPG_DB_SCHEMA__SEARCH
Definition: sepgsql.h:133
#define SEPGSQL_LABEL_TAG
Definition: sepgsql.h:23
#define SEPG_DB_SCHEMA__RELABELTO
Definition: sepgsql.h:132
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:420
#define SnapshotSelf
Definition: snapmgr.h:32
#define BTEqualStrategyNumber
Definition: stratnum.h:31
void appendStringInfoString(StringInfo str, const char *s)
Definition: stringinfo.c:230
void initStringInfo(StringInfo str)
Definition: stringinfo.c:97
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:126
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:40