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-2021, 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"
19 #include "catalog/pg_namespace.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  */
35 void
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  appendStringInfo(&audit_name, "%s", 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  */
113 void
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 
127  sepgsql_avc_check_perms(&object,
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  */
141 void
142 sepgsql_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  */
155  sepgsql_avc_check_perms(&object,
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  */
178 static bool
179 check_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 */
201 void
203 {
204  check_schema_perms(namespaceId, SEPG_DB_SCHEMA__SETATTR, true);
205 }
206 
207 /* db_schema:{search} permission */
208 bool
209 sepgsql_schema_search(Oid namespaceId, bool abort_on_violation)
210 {
211  return check_schema_perms(namespaceId,
213  abort_on_violation);
214 }
215 
216 void
218 {
219  check_schema_perms(namespaceId, SEPG_DB_SCHEMA__ADD_NAME, true);
220 }
221 
222 void
224 {
226 }
227 
228 void
230 {
231  check_schema_perms(namespaceId,
234  true);
235 }
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__DROP
Definition: sepgsql.h:128
void table_close(Relation relation, LOCKMODE lockmode)
Definition: table.c:167
void systable_endscan(SysScanDesc sysscan)
Definition: genam.c:595
#define GETSTRUCT(TUP)
Definition: htup_details.h:654
void sepgsql_schema_setattr(Oid namespaceId)
Definition: schema.c:202
FormData_pg_namespace * Form_pg_namespace
Definition: pg_namespace.h:52
void SetSecurityLabel(const ObjectAddress *object, const char *provider, const char *label)
Definition: seclabel.c:402
void sepgsql_schema_relabel(Oid namespaceId, const char *seclabel)
Definition: schema.c:142
const char * quote_identifier(const char *ident)
Definition: ruleutils.c:11374
void sepgsql_schema_drop(Oid namespaceId)
Definition: schema.c:114
void sepgsql_schema_add_name(Oid namespaceId)
Definition: schema.c:217
char * sepgsql_get_label(Oid classId, Oid objectId, int32 subId)
Definition: label.c:445
bool sepgsql_avc_check_perms(const ObjectAddress *tobject, uint16 tclass, uint32 required, const char *audit_name, bool abort_on_violation)
Definition: uavc.c:419
void sepgsql_schema_remove_name(Oid namespaceId)
Definition: schema.c:223
#define AccessShareLock
Definition: lockdefs.h:36
static bool check_schema_perms(Oid namespaceId, uint32 required, bool abort_on_violation)
Definition: schema.c:179
#define SEPG_CLASS_DB_SCHEMA
Definition: sepgsql.h:45
unsigned int Oid
Definition: postgres_ext.h:31
SysScanDesc systable_beginscan(Relation heapRelation, Oid indexId, bool indexOK, Snapshot snapshot, int nkeys, ScanKey key)
Definition: genam.c:383
#define SEPG_DB_SCHEMA__RELABELFROM
Definition: sepgsql.h:131
void sepgsql_schema_post_create(Oid namespaceId)
Definition: schema.c:36
HeapTuple systable_getnext(SysScanDesc sysscan)
Definition: genam.c:502
void pfree(void *pointer)
Definition: mcxt.c:1169
void appendStringInfo(StringInfo str, const char *fmt,...)
Definition: stringinfo.c:91
#define ObjectIdGetDatum(X)
Definition: postgres.h:551
#define ERROR
Definition: elog.h:46
char * getObjectIdentity(const ObjectAddress *object, bool missing_ok)
void sepgsql_schema_rename(Oid namespaceId)
Definition: schema.c:229
#define SnapshotSelf
Definition: snapmgr.h:66
#define SEPGSQL_LABEL_TAG
Definition: sepgsql.h:23
unsigned int uint32
Definition: c.h:441
void initStringInfo(StringInfo str)
Definition: stringinfo.c:59
#define SEPG_DB_SCHEMA__SEARCH
Definition: sepgsql.h:133
Oid MyDatabaseId
Definition: globals.c:88
bool sepgsql_schema_search(Oid namespaceId, bool abort_on_violation)
Definition: schema.c:209
#define SEPG_DB_SCHEMA__ADD_NAME
Definition: sepgsql.h:134
#define SEPG_DB_SCHEMA__SETATTR
Definition: sepgsql.h:130
#define HeapTupleIsValid(tuple)
Definition: htup.h:78
#define SEPG_DB_SCHEMA__CREATE
Definition: sepgsql.h:127
char * sepgsql_get_client_label(void)
Definition: label.c:80
char * sepgsql_compute_create(const char *scontext, const char *tcontext, uint16 tclass, const char *objname)
Definition: selinux.c:836
#define elog(elevel,...)
Definition: elog.h:232
#define NameStr(name)
Definition: c.h:681
void ScanKeyInit(ScanKey entry, AttrNumber attributeNumber, StrategyNumber strategy, RegProcedure procedure, Datum argument)
Definition: scankey.c:76
Relation table_open(Oid relationId, LOCKMODE lockmode)
Definition: table.c:39
#define SEPG_DB_SCHEMA__RELABELTO
Definition: sepgsql.h:132
#define SEPG_DB_SCHEMA__REMOVE_NAME
Definition: sepgsql.h:135
#define BTEqualStrategyNumber
Definition: stratnum.h:31