contrib/sepgsql/expected/create.out | 4 +++ contrib/sepgsql/schema.c | 50 ++++++++++++++++++++++++++++++++--- contrib/sepgsql/sql/create.sql | 6 ++++ 3 files changed, 56 insertions(+), 4 deletions(-) diff --git a/contrib/sepgsql/expected/create.out b/contrib/sepgsql/expected/create.out index 8ff8c77..dbe0591 100644 --- a/contrib/sepgsql/expected/create.out +++ b/contrib/sepgsql/expected/create.out @@ -13,7 +13,11 @@ SET client_min_messages = LOG; CREATE DATABASE regtest_sepgsql_test_database; LOG: SELinux: allowed { getattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_db_t:s0 tclass=db_database name="database template1" LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_db_t:s0 tclass=db_database name="database regtest_sepgsql_test_database" +CREATE SCHEMA regtest_schema; +LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema" +SET search_path = regtest_schema, public; -- -- clean-up -- DROP DATABASE IF EXISTS regtest_sepgsql_test_database; +DROP SCHEMA IF EXISTS regtest_schema CASCADE; diff --git a/contrib/sepgsql/schema.c b/contrib/sepgsql/schema.c index a167be1..c8bb8c9 100644 --- a/contrib/sepgsql/schema.c +++ b/contrib/sepgsql/schema.c @@ -10,12 +10,18 @@ */ #include "postgres.h" +#include "access/genam.h" +#include "access/heapam.h" +#include "access/sysattr.h" #include "catalog/dependency.h" +#include "catalog/indexing.h" #include "catalog/pg_database.h" #include "catalog/pg_namespace.h" #include "commands/seclabel.h" #include "miscadmin.h" +#include "utils/fmgroids.h" #include "utils/lsyscache.h" +#include "utils/tqual.h" #include "sepgsql.h" @@ -28,19 +34,55 @@ void sepgsql_schema_post_create(Oid namespaceId) { - char *scontext; + Relation rel; + ScanKeyData skey; + SysScanDesc sscan; + HeapTuple tuple; char *tcontext; char *ncontext; - ObjectAddress object; + char audit_name[NAMEDATALEN + 20]; + ObjectAddress object; + Form_pg_namespace nspForm; /* * Compute a default security label when we create a new schema object * under the working database. + * + * XXX - uncoming version of libselinux supports to take object + * name to handle special treatment on default security label; + * such as special label on "pg_temp" schema. */ - scontext = sepgsql_get_client_label(); + rel = heap_open(NamespaceRelationId, AccessShareLock); + + ScanKeyInit(&skey, + ObjectIdAttributeNumber, + BTEqualStrategyNumber, F_OIDEQ, + ObjectIdGetDatum(namespaceId)); + + sscan = systable_beginscan(rel, NamespaceOidIndexId, true, + SnapshotSelf, 1, &skey); + tuple = systable_getnext(sscan); + if (!HeapTupleIsValid(tuple)) + elog(ERROR, "catalog lookup failed for namespace %u", namespaceId); + + nspForm = (Form_pg_namespace) GETSTRUCT(tuple); + tcontext = sepgsql_get_label(DatabaseRelationId, MyDatabaseId, 0); - ncontext = sepgsql_compute_create(scontext, tcontext, + ncontext = sepgsql_compute_create(sepgsql_get_client_label(), + tcontext, SEPG_CLASS_DB_SCHEMA); + /* + * check db_schema:{create} + */ + snprintf(audit_name, sizeof(audit_name), + "schema %s", NameStr(nspForm->nspname)); + sepgsql_avc_check_perms_label(ncontext, + SEPG_CLASS_DB_SCHEMA, + SEPG_DB_SCHEMA__CREATE, + audit_name, + true); + systable_endscan(sscan); + heap_close(rel, AccessShareLock); /* * Assign the default security label on a new procedure diff --git a/contrib/sepgsql/sql/create.sql b/contrib/sepgsql/sql/create.sql index 6cd5656..a03c977 100644 --- a/contrib/sepgsql/sql/create.sql +++ b/contrib/sepgsql/sql/create.sql @@ -9,7 +9,13 @@ SET client_min_messages = LOG; CREATE DATABASE regtest_sepgsql_test_database; +CREATE SCHEMA regtest_schema; + +SET search_path = regtest_schema, public; + -- -- clean-up -- DROP DATABASE IF EXISTS regtest_sepgsql_test_database; + +DROP SCHEMA IF EXISTS regtest_schema CASCADE;