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
 
 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
 
--- /dev/null
+/* -------------------------------------------------------------------------
+ *
+ * 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);
+}
 
 
 #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"
        case OAT_POST_CREATE:
            switch (classId)
            {
+               case DatabaseRelationId:
+                   sepgsql_database_post_create(objectId);
+                   break;
+
                case NamespaceRelationId:
                    sepgsql_schema_post_create(objectId);
                    break;
 
 #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"
     */
    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,
                                          object->objectSubId,
                                          seclabel);
            break;
+
        case ProcedureRelationId:
            sepgsql_proc_relabel(object->objectId, seclabel);
            break;
                               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;
         */
        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);
 
               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);
 
 #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);
 
    SetSecurityLabel(&object, SEPGSQL_LABEL_TAG, ncontext);
 
    pfree(ncontext);
+   pfree(tcontext);
 }
 
 /*
 
  */
 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
  */