summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRobert Haas2011-09-23 21:09:34 +0000
committerRobert Haas2011-09-23 21:09:34 +0000
commit291873c1554ceecc71a81c25aef4f1260c15c222 (patch)
treef664ac2dd332d3184cf55262454d7c3aafd5d2c4
parenta5e94ea52b002a049ffa52849f2958c096cc0f92 (diff)
Teach sepgsql about database labels.
This is still a bit of a hack, but it's better than the old way, for sure. KaiGai Kohei, with one change by me to make it compile
-rw-r--r--contrib/sepgsql/Makefile2
-rw-r--r--contrib/sepgsql/database.c88
-rw-r--r--contrib/sepgsql/hooks.c5
-rw-r--r--contrib/sepgsql/label.c26
-rw-r--r--contrib/sepgsql/schema.c14
-rw-r--r--contrib/sepgsql/sepgsql.h6
6 files changed, 128 insertions, 13 deletions
diff --git a/contrib/sepgsql/Makefile b/contrib/sepgsql/Makefile
index c83b2e3cef8..033c41a8199 100644
--- a/contrib/sepgsql/Makefile
+++ b/contrib/sepgsql/Makefile
@@ -2,7 +2,7 @@
MODULE_big = sepgsql
OBJS = hooks.o selinux.o uavc.o label.o dml.o \
- schema.o relation.o proc.o
+ database.o schema.o relation.o proc.o
DATA_built = sepgsql.sql
REGRESS = label dml misc
diff --git a/contrib/sepgsql/database.c b/contrib/sepgsql/database.c
new file mode 100644
index 00000000000..7f15d9ce715
--- /dev/null
+++ b/contrib/sepgsql/database.c
@@ -0,0 +1,88 @@
+/* -------------------------------------------------------------------------
+ *
+ * contrib/sepgsql/database.c
+ *
+ * Routines corresponding to database objects
+ *
+ * Copyright (c) 2010-2011, PostgreSQL Global Development Group
+ *
+ * -------------------------------------------------------------------------
+ */
+#include "postgres.h"
+
+#include "catalog/dependency.h"
+#include "catalog/pg_database.h"
+#include "commands/seclabel.h"
+#include "sepgsql.h"
+
+void
+sepgsql_database_post_create(Oid databaseId)
+{
+ char *scontext = sepgsql_get_client_label();
+ char *tcontext;
+ char *ncontext;
+ ObjectAddress object;
+
+ /*
+ * Compute a default security label of the newly created database
+ * based on a pair of security label of client and source database.
+ *
+ * XXX - Right now, this logic uses "template1" as its source, because
+ * here is no way to know the Oid of source database.
+ */
+ object.classId = DatabaseRelationId;
+ object.objectId = TemplateDbOid;
+ object.objectSubId = 0;
+ tcontext = GetSecurityLabel(&object, SEPGSQL_LABEL_TAG);
+
+ ncontext = sepgsql_compute_create(scontext, tcontext,
+ SEPG_CLASS_DB_DATABASE);
+
+ /*
+ * Assign the default security label on the new database
+ */
+ object.classId = DatabaseRelationId;
+ object.objectId = databaseId;
+ object.objectSubId = 0;
+
+ SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
+
+ pfree(ncontext);
+ pfree(tcontext);
+}
+
+/*
+ * sepgsql_database_relabel
+ *
+ * It checks privileges to relabel the supplied database with the `seclabel'
+ */
+void
+sepgsql_database_relabel(Oid databaseId, const char *seclabel)
+{
+ ObjectAddress object;
+ char *audit_name;
+
+ object.classId = DatabaseRelationId;
+ object.objectId = databaseId;
+ object.objectSubId = 0;
+ audit_name = getObjectDescription(&object);
+
+ /*
+ * check db_database:{setattr relabelfrom} permission
+ */
+ sepgsql_avc_check_perms(&object,
+ SEPG_CLASS_DB_DATABASE,
+ SEPG_DB_DATABASE__SETATTR |
+ SEPG_DB_DATABASE__RELABELFROM,
+ audit_name,
+ true);
+ /*
+ * check db_database:{relabelto} permission
+ */
+ sepgsql_avc_check_perms_label(seclabel,
+ SEPG_CLASS_DB_DATABASE,
+ SEPG_DB_DATABASE__RELABELTO,
+ audit_name,
+ true);
+ pfree(audit_name);
+}
diff --git a/contrib/sepgsql/hooks.c b/contrib/sepgsql/hooks.c
index ca6ce998080..331bbd7e783 100644
--- a/contrib/sepgsql/hooks.c
+++ b/contrib/sepgsql/hooks.c
@@ -12,6 +12,7 @@
#include "catalog/objectaccess.h"
#include "catalog/pg_class.h"
+#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "commands/seclabel.h"
@@ -125,6 +126,10 @@ sepgsql_object_access(ObjectAccessType access,
case OAT_POST_CREATE:
switch (classId)
{
+ case DatabaseRelationId:
+ sepgsql_database_post_create(objectId);
+ break;
+
case NamespaceRelationId:
sepgsql_schema_post_create(objectId);
break;
diff --git a/contrib/sepgsql/label.c b/contrib/sepgsql/label.c
index 669ee35ac3e..a2bf57151eb 100644
--- a/contrib/sepgsql/label.c
+++ b/contrib/sepgsql/label.c
@@ -17,6 +17,7 @@
#include "catalog/indexing.h"
#include "catalog/pg_attribute.h"
#include "catalog/pg_class.h"
+#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h"
#include "catalog/pg_proc.h"
#include "commands/dbcommands.h"
@@ -121,9 +122,14 @@ sepgsql_object_relabel(const ObjectAddress *object, const char *seclabel)
*/
switch (object->classId)
{
+ case DatabaseRelationId:
+ sepgsql_database_relabel(object->objectId, seclabel);
+ break;
+
case NamespaceRelationId:
sepgsql_schema_relabel(object->objectId, seclabel);
break;
+
case RelationRelationId:
if (object->objectSubId == 0)
sepgsql_relation_relabel(object->objectId,
@@ -133,6 +139,7 @@ sepgsql_object_relabel(const ObjectAddress *object, const char *seclabel)
object->objectSubId,
seclabel);
break;
+
case ProcedureRelationId:
sepgsql_proc_relabel(object->objectId, seclabel);
break;
@@ -315,6 +322,7 @@ exec_object_restorecon(struct selabel_handle * sehnd, Oid catalogId)
SnapshotNow, 0, NULL);
while (HeapTupleIsValid(tuple = systable_getnext(sscan)))
{
+ Form_pg_database datForm;
Form_pg_namespace nspForm;
Form_pg_class relForm;
Form_pg_attribute attForm;
@@ -330,6 +338,19 @@ exec_object_restorecon(struct selabel_handle * sehnd, Oid catalogId)
*/
switch (catalogId)
{
+ case DatabaseRelationId:
+ datForm = (Form_pg_database) GETSTRUCT(tuple);
+
+ objtype = SELABEL_DB_DATABASE;
+
+ objname = quote_object_name(NameStr(datForm->datname),
+ NULL, NULL, NULL);
+
+ object.classId = DatabaseRelationId;
+ object.objectId = HeapTupleGetOid(tuple);
+ object.objectSubId = 0;
+ break;
+
case NamespaceRelationId:
nspForm = (Form_pg_namespace) GETSTRUCT(tuple);
@@ -506,10 +527,7 @@ sepgsql_restorecon(PG_FUNCTION_ARGS)
errmsg("SELinux: failed to initialize labeling handle: %m")));
PG_TRY();
{
- /*
- * Right now, we have no support labeling on the shared database
- * objects, such as database, role, or tablespace.
- */
+ exec_object_restorecon(sehnd, DatabaseRelationId);
exec_object_restorecon(sehnd, NamespaceRelationId);
exec_object_restorecon(sehnd, RelationRelationId);
exec_object_restorecon(sehnd, AttributeRelationId);
diff --git a/contrib/sepgsql/schema.c b/contrib/sepgsql/schema.c
index aae68ef964b..a167be17b23 100644
--- a/contrib/sepgsql/schema.c
+++ b/contrib/sepgsql/schema.c
@@ -11,8 +11,10 @@
#include "postgres.h"
#include "catalog/dependency.h"
+#include "catalog/pg_database.h"
#include "catalog/pg_namespace.h"
#include "commands/seclabel.h"
+#include "miscadmin.h"
#include "utils/lsyscache.h"
#include "sepgsql.h"
@@ -26,22 +28,17 @@
void
sepgsql_schema_post_create(Oid namespaceId)
{
- char *scontext = sepgsql_get_client_label();
+ char *scontext;
char *tcontext;
char *ncontext;
ObjectAddress object;
/*
- * FIXME: Right now, we assume pg_database object has a fixed security
- * label, because pg_seclabel does not support to store label of shared
- * database objects.
- */
- tcontext = "system_u:object_r:sepgsql_db_t:s0";
-
- /*
* Compute a default security label when we create a new schema object
* under the working database.
*/
+ scontext = sepgsql_get_client_label();
+ tcontext = sepgsql_get_label(DatabaseRelationId, MyDatabaseId, 0);
ncontext = sepgsql_compute_create(scontext, tcontext,
SEPG_CLASS_DB_SCHEMA);
@@ -54,6 +51,7 @@ sepgsql_schema_post_create(Oid namespaceId)
SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
pfree(ncontext);
+ pfree(tcontext);
}
/*
diff --git a/contrib/sepgsql/sepgsql.h b/contrib/sepgsql/sepgsql.h
index 35b500c3ffa..b4c1dfdfe76 100644
--- a/contrib/sepgsql/sepgsql.h
+++ b/contrib/sepgsql/sepgsql.h
@@ -284,6 +284,12 @@ extern Datum sepgsql_restorecon(PG_FUNCTION_ARGS);
extern bool sepgsql_dml_privileges(List *rangeTabls, bool abort);
/*
+ * database.c
+ */
+extern void sepgsql_database_post_create(Oid databaseId);
+extern void sepgsql_database_relabel(Oid databaseId, const char *seclabel);
+
+/*
* schema.c
*/
extern void sepgsql_schema_post_create(Oid namespaceId);