]> granicus.if.org Git - postgresql/commitdiff
Teach sepgsql about database labels.
authorRobert Haas <rhaas@postgresql.org>
Fri, 23 Sep 2011 21:09:34 +0000 (17:09 -0400)
committerRobert Haas <rhaas@postgresql.org>
Fri, 23 Sep 2011 21:09:34 +0000 (17:09 -0400)
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

contrib/sepgsql/Makefile
contrib/sepgsql/database.c [new file with mode: 0644]
contrib/sepgsql/hooks.c
contrib/sepgsql/label.c
contrib/sepgsql/schema.c
contrib/sepgsql/sepgsql.h

index c83b2e3cef80d826b83d41c37aa7d905a050037c..033c41a819920ca029925ba6a34f6e87c9361067 100644 (file)
@@ -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 (file)
index 0000000..7f15d9c
--- /dev/null
@@ -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);
+}
index ca6ce99808001cc74925f9033e466a103802fb0d..331bbd7e78365e27350014c2c6e5fe6fe2482eaf 100644 (file)
@@ -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;
index 669ee35ac3e4a6d3515364e662568d865af1dbb2..a2bf57151ebd6af5bb8742b4ac2178c42e540619 100644 (file)
@@ -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);
index aae68ef964bc2867aee45e0ebd5fcf2bb212a4c2..a167be17b233f27428c60c82529790fa5d76eda8 100644 (file)
 #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"
 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);
 }
 
 /*
index 35b500c3ffa8a4d7b067e45cfebfd61ab05f373f..b4c1dfdfe76bfb50cdbf1ed2395b2b7f615a80e2 100644 (file)
@@ -283,6 +283,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
  */