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