1 /* -------------------------------------------------------------------------
3 * contrib/sepgsql/database.c
5 * Routines corresponding to database objects
7 * Copyright (c) 2010-2024, PostgreSQL Global Development Group
9 * -------------------------------------------------------------------------
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"
22 #include "utils/builtins.h"
23 #include "utils/fmgroids.h"
24 #include "utils/snapmgr.h"
27 * sepgsql_database_post_create
29 * This routine assigns a default security label on a newly defined
30 * database, and check permission needed for its creation.
33 sepgsql_database_post_create(Oid databaseId
, const char *dtemplate
)
42 Form_pg_database datForm
;
43 StringInfoData audit_name
;
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().
51 dtemplate
= "template1";
53 object
.classId
= DatabaseRelationId
;
54 object
.objectId
= get_database_oid(dtemplate
, false);
55 object
.objectSubId
= 0;
57 tcontext
= sepgsql_get_label(object
.classId
,
62 * check db_database:{getattr} permission
64 initStringInfo(&audit_name
);
65 appendStringInfoString(&audit_name
, quote_identifier(dtemplate
));
66 sepgsql_avc_check_perms_label(tcontext
,
67 SEPG_CLASS_DB_DATABASE
,
68 SEPG_DB_DATABASE__GETATTR
,
73 * Compute a default security label of the newly created database based on
74 * a pair of security label of client and source database.
76 * XXX - upcoming version of libselinux supports to take object name to
77 * handle special treatment on default security label.
79 rel
= table_open(DatabaseRelationId
, AccessShareLock
);
83 BTEqualStrategyNumber
, F_OIDEQ
,
84 ObjectIdGetDatum(databaseId
));
86 sscan
= systable_beginscan(rel
, DatabaseOidIndexId
, true,
87 SnapshotSelf
, 1, &skey
);
88 tuple
= systable_getnext(sscan
);
89 if (!HeapTupleIsValid(tuple
))
90 elog(ERROR
, "could not find tuple for database %u", databaseId
);
92 datForm
= (Form_pg_database
) GETSTRUCT(tuple
);
94 ncontext
= sepgsql_compute_create(sepgsql_get_client_label(),
96 SEPG_CLASS_DB_DATABASE
,
97 NameStr(datForm
->datname
));
100 * check db_database:{create} permission
102 resetStringInfo(&audit_name
);
103 appendStringInfoString(&audit_name
,
104 quote_identifier(NameStr(datForm
->datname
)));
105 sepgsql_avc_check_perms_label(ncontext
,
106 SEPG_CLASS_DB_DATABASE
,
107 SEPG_DB_DATABASE__CREATE
,
111 systable_endscan(sscan
);
112 table_close(rel
, AccessShareLock
);
115 * Assign the default security label on the new database
117 object
.classId
= DatabaseRelationId
;
118 object
.objectId
= databaseId
;
119 object
.objectSubId
= 0;
121 SetSecurityLabel(&object
, SEPGSQL_LABEL_TAG
, ncontext
);
128 * sepgsql_database_drop
130 * It checks privileges to drop the supplied database
133 sepgsql_database_drop(Oid databaseId
)
135 ObjectAddress object
;
139 * check db_database:{drop} permission
141 object
.classId
= DatabaseRelationId
;
142 object
.objectId
= databaseId
;
143 object
.objectSubId
= 0;
144 audit_name
= getObjectIdentity(&object
, false);
146 sepgsql_avc_check_perms(&object
,
147 SEPG_CLASS_DB_DATABASE
,
148 SEPG_DB_DATABASE__DROP
,
155 * sepgsql_database_post_alter
157 * It checks privileges to alter the supplied database
160 sepgsql_database_setattr(Oid databaseId
)
162 ObjectAddress object
;
166 * check db_database:{setattr} permission
168 object
.classId
= DatabaseRelationId
;
169 object
.objectId
= databaseId
;
170 object
.objectSubId
= 0;
171 audit_name
= getObjectIdentity(&object
, false);
173 sepgsql_avc_check_perms(&object
,
174 SEPG_CLASS_DB_DATABASE
,
175 SEPG_DB_DATABASE__SETATTR
,
182 * sepgsql_database_relabel
184 * It checks privileges to relabel the supplied database with the `seclabel'
187 sepgsql_database_relabel(Oid databaseId
, const char *seclabel
)
189 ObjectAddress object
;
192 object
.classId
= DatabaseRelationId
;
193 object
.objectId
= databaseId
;
194 object
.objectSubId
= 0;
195 audit_name
= getObjectIdentity(&object
, false);
198 * check db_database:{setattr relabelfrom} permission
200 sepgsql_avc_check_perms(&object
,
201 SEPG_CLASS_DB_DATABASE
,
202 SEPG_DB_DATABASE__SETATTR
|
203 SEPG_DB_DATABASE__RELABELFROM
,
208 * check db_database:{relabelto} permission
210 sepgsql_avc_check_perms_label(seclabel
,
211 SEPG_CLASS_DB_DATABASE
,
212 SEPG_DB_DATABASE__RELABELTO
,