]> granicus.if.org Git - postgresql/blob - contrib/sepgsql/database.c
pgindent run prior to branching
[postgresql] / contrib / sepgsql / database.c
1 /* -------------------------------------------------------------------------
2  *
3  * contrib/sepgsql/database.c
4  *
5  * Routines corresponding to database objects
6  *
7  * Copyright (c) 2010-2018, PostgreSQL Global Development Group
8  *
9  * -------------------------------------------------------------------------
10  */
11 #include "postgres.h"
12
13 #include "access/genam.h"
14 #include "access/heapam.h"
15 #include "access/htup_details.h"
16 #include "access/sysattr.h"
17 #include "catalog/dependency.h"
18 #include "catalog/pg_database.h"
19 #include "catalog/indexing.h"
20 #include "commands/dbcommands.h"
21 #include "commands/seclabel.h"
22 #include "utils/builtins.h"
23 #include "utils/fmgroids.h"
24 #include "utils/tqual.h"
25 #include "sepgsql.h"
26
27 /*
28  * sepgsql_database_post_create
29  *
30  * This routine assigns a default security label on a newly defined
31  * database, and check permission needed for its creation.
32  */
33 void
34 sepgsql_database_post_create(Oid databaseId, const char *dtemplate)
35 {
36         Relation        rel;
37         ScanKeyData skey;
38         SysScanDesc sscan;
39         HeapTuple       tuple;
40         char       *tcontext;
41         char       *ncontext;
42         ObjectAddress object;
43         Form_pg_database datForm;
44         StringInfoData audit_name;
45
46         /*
47          * Oid of the source database is not saved in pg_database catalog, so we
48          * collect its identifier using contextual information. If NULL, its
49          * default is "template1" according to createdb().
50          */
51         if (!dtemplate)
52                 dtemplate = "template1";
53
54         object.classId = DatabaseRelationId;
55         object.objectId = get_database_oid(dtemplate, false);
56         object.objectSubId = 0;
57
58         tcontext = sepgsql_get_label(object.classId,
59                                                                  object.objectId,
60                                                                  object.objectSubId);
61
62         /*
63          * check db_database:{getattr} permission
64          */
65         initStringInfo(&audit_name);
66         appendStringInfo(&audit_name, "%s", quote_identifier(dtemplate));
67         sepgsql_avc_check_perms_label(tcontext,
68                                                                   SEPG_CLASS_DB_DATABASE,
69                                                                   SEPG_DB_DATABASE__GETATTR,
70                                                                   audit_name.data,
71                                                                   true);
72
73         /*
74          * Compute a default security label of the newly created database based on
75          * a pair of security label of client and source database.
76          *
77          * XXX - uncoming version of libselinux supports to take object name to
78          * handle special treatment on default security label.
79          */
80         rel = heap_open(DatabaseRelationId, AccessShareLock);
81
82         ScanKeyInit(&skey,
83                                 ObjectIdAttributeNumber,
84                                 BTEqualStrategyNumber, F_OIDEQ,
85                                 ObjectIdGetDatum(databaseId));
86
87         sscan = systable_beginscan(rel, DatabaseOidIndexId, true,
88                                                            SnapshotSelf, 1, &skey);
89         tuple = systable_getnext(sscan);
90         if (!HeapTupleIsValid(tuple))
91                 elog(ERROR, "could not find tuple for database %u", databaseId);
92
93         datForm = (Form_pg_database) GETSTRUCT(tuple);
94
95         ncontext = sepgsql_compute_create(sepgsql_get_client_label(),
96                                                                           tcontext,
97                                                                           SEPG_CLASS_DB_DATABASE,
98                                                                           NameStr(datForm->datname));
99
100         /*
101          * check db_database:{create} permission
102          */
103         resetStringInfo(&audit_name);
104         appendStringInfo(&audit_name, "%s",
105                                          quote_identifier(NameStr(datForm->datname)));
106         sepgsql_avc_check_perms_label(ncontext,
107                                                                   SEPG_CLASS_DB_DATABASE,
108                                                                   SEPG_DB_DATABASE__CREATE,
109                                                                   audit_name.data,
110                                                                   true);
111
112         systable_endscan(sscan);
113         heap_close(rel, AccessShareLock);
114
115         /*
116          * Assign the default security label on the new database
117          */
118         object.classId = DatabaseRelationId;
119         object.objectId = databaseId;
120         object.objectSubId = 0;
121
122         SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
123
124         pfree(ncontext);
125         pfree(tcontext);
126 }
127
128 /*
129  * sepgsql_database_drop
130  *
131  * It checks privileges to drop the supplied database
132  */
133 void
134 sepgsql_database_drop(Oid databaseId)
135 {
136         ObjectAddress object;
137         char       *audit_name;
138
139         /*
140          * check db_database:{drop} permission
141          */
142         object.classId = DatabaseRelationId;
143         object.objectId = databaseId;
144         object.objectSubId = 0;
145         audit_name = getObjectIdentity(&object);
146
147         sepgsql_avc_check_perms(&object,
148                                                         SEPG_CLASS_DB_DATABASE,
149                                                         SEPG_DB_DATABASE__DROP,
150                                                         audit_name,
151                                                         true);
152         pfree(audit_name);
153 }
154
155 /*
156  * sepgsql_database_post_alter
157  *
158  * It checks privileges to alter the supplied database
159  */
160 void
161 sepgsql_database_setattr(Oid databaseId)
162 {
163         ObjectAddress object;
164         char       *audit_name;
165
166         /*
167          * check db_database:{setattr} permission
168          */
169         object.classId = DatabaseRelationId;
170         object.objectId = databaseId;
171         object.objectSubId = 0;
172         audit_name = getObjectIdentity(&object);
173
174         sepgsql_avc_check_perms(&object,
175                                                         SEPG_CLASS_DB_DATABASE,
176                                                         SEPG_DB_DATABASE__SETATTR,
177                                                         audit_name,
178                                                         true);
179         pfree(audit_name);
180 }
181
182 /*
183  * sepgsql_database_relabel
184  *
185  * It checks privileges to relabel the supplied database with the `seclabel'
186  */
187 void
188 sepgsql_database_relabel(Oid databaseId, const char *seclabel)
189 {
190         ObjectAddress object;
191         char       *audit_name;
192
193         object.classId = DatabaseRelationId;
194         object.objectId = databaseId;
195         object.objectSubId = 0;
196         audit_name = getObjectIdentity(&object);
197
198         /*
199          * check db_database:{setattr relabelfrom} permission
200          */
201         sepgsql_avc_check_perms(&object,
202                                                         SEPG_CLASS_DB_DATABASE,
203                                                         SEPG_DB_DATABASE__SETATTR |
204                                                         SEPG_DB_DATABASE__RELABELFROM,
205                                                         audit_name,
206                                                         true);
207
208         /*
209          * check db_database:{relabelto} permission
210          */
211         sepgsql_avc_check_perms_label(seclabel,
212                                                                   SEPG_CLASS_DB_DATABASE,
213                                                                   SEPG_DB_DATABASE__RELABELTO,
214                                                                   audit_name,
215                                                                   true);
216         pfree(audit_name);
217 }