sepgsql: Enforce db_schema:search permission.
KaiGai Kohei, with comment and doc wordsmithing by me
This commit is contained in:
parent
52f436b807
commit
e965e6344c
@ -48,6 +48,9 @@ LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined
|
||||
ALTER SCHEMA regtest_schema_1 OWNER TO regtest_sepgsql_test_user;
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_1"
|
||||
ALTER TABLE regtest_table_1 OWNER TO regtest_sepgsql_test_user;
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_1"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema public"
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_1"
|
||||
ALTER TABLE regtest_table_1 OWNER TO regtest_sepgsql_test_user;
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_1"
|
||||
@ -90,6 +93,8 @@ LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined
|
||||
ALTER SCHEMA regtest_schema_1 RENAME TO regtest_schema;
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_1"
|
||||
ALTER TABLE regtest_table_1 RENAME TO regtest_table;
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema public"
|
||||
LOG: SELinux: allowed { add_name remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_1"
|
||||
ALTER SEQUENCE regtest_seq_1 RENAME TO regtest_seq;
|
||||
@ -109,7 +114,13 @@ ALTER DATABASE regtest_sepgsql_test_database CONNECTION LIMIT 999;
|
||||
LOG: SELinux: allowed { setattr } 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"
|
||||
ALTER DATABASE regtest_sepgsql_test_database SET search_path TO regtest_schema, public; -- not supported yet
|
||||
ALTER TABLE regtest_table ADD COLUMN d float;
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema public"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column d"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_2 column d"
|
||||
ALTER TABLE regtest_table DROP COLUMN d;
|
||||
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_2 column d"
|
||||
@ -132,10 +143,30 @@ ALTER TABLE regtest_table ALTER b SET STORAGE PLAIN;
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column b"
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_2 column b"
|
||||
ALTER TABLE regtest_table ADD CONSTRAINT test_fk FOREIGN KEY (a) REFERENCES regtest_table_3(x); -- not supported
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table"
|
||||
LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column a"
|
||||
LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_3"
|
||||
LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_3 column x"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
|
||||
LINE 1: SELECT fk."a" FROM ONLY "regtest_schema_2"."regtest_table" f...
|
||||
^
|
||||
QUERY: SELECT fk."a" FROM ONLY "regtest_schema_2"."regtest_table" fk LEFT OUTER JOIN ONLY "regtest_schema"."regtest_table_3" pk ON ( pk."x" OPERATOR(pg_catalog.=) fk."a") WHERE pk."x" IS NULL AND (fk."a" IS NOT NULL)
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LINE 1: ...schema_2"."regtest_table" fk LEFT OUTER JOIN ONLY "regtest_s...
|
||||
^
|
||||
QUERY: SELECT fk."a" FROM ONLY "regtest_schema_2"."regtest_table" fk LEFT OUTER JOIN ONLY "regtest_schema"."regtest_table_3" pk ON ( pk."x" OPERATOR(pg_catalog.=) fk."a") WHERE pk."x" IS NULL AND (fk."a" IS NOT NULL)
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
CONTEXT: SQL statement "SELECT fk."a" FROM ONLY "regtest_schema_2"."regtest_table" fk LEFT OUTER JOIN ONLY "regtest_schema"."regtest_table_3" pk ON ( pk."x" OPERATOR(pg_catalog.=) fk."a") WHERE pk."x" IS NULL AND (fk."a" IS NOT NULL)"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
CONTEXT: SQL statement "SELECT fk."a" FROM ONLY "regtest_schema_2"."regtest_table" fk LEFT OUTER JOIN ONLY "regtest_schema"."regtest_table_3" pk ON ( pk."x" OPERATOR(pg_catalog.=) fk."a") WHERE pk."x" IS NULL AND (fk."a" IS NOT NULL)"
|
||||
LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table"
|
||||
CONTEXT: SQL statement "SELECT fk."a" FROM ONLY "regtest_schema_2"."regtest_table" fk LEFT OUTER JOIN ONLY "regtest_schema"."regtest_table_3" pk ON ( pk."x" OPERATOR(pg_catalog.=) fk."a") WHERE pk."x" IS NULL AND (fk."a" IS NOT NULL)"
|
||||
LOG: SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column a"
|
||||
|
@ -24,9 +24,12 @@ LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_
|
||||
CREATE USER regtest_sepgsql_test_user;
|
||||
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"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema public"
|
||||
GRANT ALL ON SCHEMA regtest_schema TO regtest_sepgsql_test_user;
|
||||
SET search_path = regtest_schema, public;
|
||||
CREATE TABLE regtest_table (x serial primary key, y text);
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema public"
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_table_x_seq"
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
@ -39,12 +42,27 @@ LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column ctid"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column x"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column y"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LINE 1: CREATE TABLE regtest_table (x serial primary key, y text);
|
||||
^
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_table_x_seq"
|
||||
ALTER TABLE regtest_table ADD COLUMN z int;
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column z"
|
||||
CREATE TABLE regtest_table_2 (a int) WITH OIDS;
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_2"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_2 column tableoid"
|
||||
@ -67,9 +85,11 @@ CREATE SEQUENCE regtest_seq;
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_seq"
|
||||
CREATE TYPE regtest_comptype AS (a int, b text);
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
CREATE FUNCTION regtest_func(text,int[]) RETURNS bool LANGUAGE plpgsql
|
||||
AS 'BEGIN RAISE NOTICE ''regtest_func => %'', $1; RETURN true; END';
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="function regtest_func(text,integer[])"
|
||||
CREATE AGGREGATE regtest_agg (
|
||||
@ -81,8 +101,12 @@ LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_
|
||||
SET SESSION AUTHORIZATION regtest_sepgsql_test_user;
|
||||
SET search_path = regtest_schema, public;
|
||||
CREATE TABLE regtest_table_3 (x int, y serial);
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema public"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_table_3_y_seq"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_3"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_3 column tableoid"
|
||||
@ -93,12 +117,18 @@ LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_3 column ctid"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_3 column x"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_3 column y"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_table_3_y_seq"
|
||||
CREATE VIEW regtest_view_2 AS SELECT * FROM regtest_table_3 WHERE x < y;
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_view_t:s0 tclass=db_view name="view regtest_view_2"
|
||||
CREATE FUNCTION regtest_func_2(int) RETURNS bool LANGUAGE plpgsql
|
||||
AS 'BEGIN RETURN $1 * $1 < 100; END';
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="function regtest_func_2(integer)"
|
||||
RESET SESSION AUTHORIZATION;
|
||||
@ -106,6 +136,14 @@ RESET SESSION AUTHORIZATION;
|
||||
-- ALTER and CREATE/DROP extra attribute permissions
|
||||
--
|
||||
CREATE TABLE regtest_table_4 (x int primary key, y int, z int);
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema public"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column tableoid"
|
||||
@ -117,6 +155,12 @@ LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column x"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column y"
|
||||
LOG: SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column z"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LINE 1: CREATE TABLE regtest_table_4 (x int primary key, y int, z in...
|
||||
^
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
|
||||
CREATE INDEX regtest_index_tbl4_y ON regtest_table_4(y);
|
||||
@ -126,6 +170,8 @@ CREATE INDEX regtest_index_tbl4_z ON regtest_table_4(z);
|
||||
LOG: SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
|
||||
ALTER TABLE regtest_table_4 ALTER COLUMN y TYPE float;
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column y"
|
||||
DROP INDEX regtest_index_tbl4_y;
|
||||
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
@ -156,9 +202,11 @@ LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:
|
||||
-- DROP Permission checks (with clean-up)
|
||||
--
|
||||
DROP FUNCTION regtest_func(text,int[]);
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="function regtest_func(text,integer[])"
|
||||
DROP AGGREGATE regtest_agg(int);
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema pg_catalog"
|
||||
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="function regtest_agg(integer)"
|
||||
DROP SEQUENCE regtest_seq;
|
||||
@ -187,6 +235,8 @@ LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:
|
||||
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column x"
|
||||
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column z"
|
||||
DROP OWNED BY regtest_sepgsql_test_user;
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema public"
|
||||
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="function regtest_func_2(integer)"
|
||||
LOG: SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
@ -207,6 +257,8 @@ DROP DATABASE regtest_sepgsql_test_database;
|
||||
LOG: SELinux: allowed { drop } 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"
|
||||
DROP USER regtest_sepgsql_test_user;
|
||||
DROP SCHEMA IF EXISTS regtest_schema CASCADE;
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
|
||||
LOG: SELinux: allowed { search } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=system_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema public"
|
||||
NOTICE: drop cascades to 2 other objects
|
||||
DETAIL: drop cascades to table regtest_table_2
|
||||
drop cascades to type regtest_comptype
|
||||
|
@ -47,6 +47,12 @@ ORDER BY objname;
|
||||
column | t5.g | system_u:object_r:sepgsql_secret_table_t:s0
|
||||
(8 rows)
|
||||
|
||||
CREATE SCHEMA my_schema_1;
|
||||
CREATE TABLE my_schema_1.ts1 (a int, b text);
|
||||
CREATE SCHEMA my_schema_2;
|
||||
CREATE TABLE my_schema_2.ts2 (x int, y text);
|
||||
SECURITY LABEL ON SCHEMA my_schema_2
|
||||
IS 'system_u:object_r:sepgsql_regtest_invisible_schema_t:s0';
|
||||
-- Hardwired Rules
|
||||
UPDATE pg_attribute SET attisdropped = true
|
||||
WHERE attrelid = 't5'::regclass AND attname = 'f'; -- failed
|
||||
@ -166,6 +172,23 @@ COPY t5 (e,f) FROM '/dev/null'; -- failed
|
||||
ERROR: SELinux: security policy violation
|
||||
COPY t5 (e) FROM '/dev/null'; -- ok
|
||||
--
|
||||
-- Schema search path
|
||||
--
|
||||
SET search_path = my_schema_1, my_schema_2, public;
|
||||
SELECT * FROM ts1; -- ok
|
||||
a | b
|
||||
---+---
|
||||
(0 rows)
|
||||
|
||||
SELECT * FROM ts2; -- failed (relation not found)
|
||||
ERROR: relation "ts2" does not exist
|
||||
LINE 1: SELECT * FROM ts2;
|
||||
^
|
||||
SELECT * FROM my_schema_2.ts2; -- failed (policy violation)
|
||||
ERROR: SELinux: security policy violation
|
||||
LINE 1: SELECT * FROM my_schema_2.ts2;
|
||||
^
|
||||
--
|
||||
-- Clean up
|
||||
--
|
||||
SELECT sepgsql_getcon(); -- confirm client privilege
|
||||
@ -180,3 +203,7 @@ DROP TABLE IF EXISTS t3 CASCADE;
|
||||
DROP TABLE IF EXISTS t4 CASCADE;
|
||||
DROP TABLE IF EXISTS t5 CASCADE;
|
||||
DROP TABLE IF EXISTS customer CASCADE;
|
||||
DROP SCHEMA IF EXISTS my_schema_1 CASCADE;
|
||||
NOTICE: drop cascades to table my_schema_1.ts1
|
||||
DROP SCHEMA IF EXISTS my_schema_2 CASCADE;
|
||||
NOTICE: drop cascades to table my_schema_2.ts2
|
||||
|
@ -236,6 +236,25 @@ sepgsql_object_access(ObjectAccessType access,
|
||||
}
|
||||
break;
|
||||
|
||||
case OAT_NAMESPACE_SEARCH:
|
||||
{
|
||||
ObjectAccessNamespaceSearch *ns_arg = arg;
|
||||
|
||||
/*
|
||||
* If stacked extension already decided not to allow users
|
||||
* to search this schema, we just stick with that decision.
|
||||
*/
|
||||
if (!ns_arg->result)
|
||||
break;
|
||||
|
||||
Assert(classId == NamespaceRelationId);
|
||||
Assert(ns_arg->result);
|
||||
ns_arg->result
|
||||
= sepgsql_schema_search(objectId,
|
||||
ns_arg->ereport_on_violation);
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
elog(ERROR, "unexpected object access type: %d", (int) access);
|
||||
break;
|
||||
|
@ -173,42 +173,54 @@ sepgsql_schema_relabel(Oid namespaceId, const char *seclabel)
|
||||
*
|
||||
* utility routine to check db_schema:{xxx} permissions
|
||||
*/
|
||||
static void
|
||||
check_schema_perms(Oid namespaceId, uint32 required)
|
||||
static bool
|
||||
check_schema_perms(Oid namespaceId, uint32 required, bool abort_on_violation)
|
||||
{
|
||||
ObjectAddress object;
|
||||
char *audit_name;
|
||||
bool result;
|
||||
|
||||
object.classId = NamespaceRelationId;
|
||||
object.objectId = namespaceId;
|
||||
object.objectSubId = 0;
|
||||
audit_name = getObjectDescription(&object);
|
||||
|
||||
sepgsql_avc_check_perms(&object,
|
||||
SEPG_CLASS_DB_SCHEMA,
|
||||
required,
|
||||
audit_name,
|
||||
true);
|
||||
result = sepgsql_avc_check_perms(&object,
|
||||
SEPG_CLASS_DB_SCHEMA,
|
||||
required,
|
||||
audit_name,
|
||||
abort_on_violation);
|
||||
pfree(audit_name);
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
/* db_schema:{setattr} permission */
|
||||
void
|
||||
sepgsql_schema_setattr(Oid namespaceId)
|
||||
{
|
||||
check_schema_perms(namespaceId, SEPG_DB_SCHEMA__SETATTR);
|
||||
check_schema_perms(namespaceId, SEPG_DB_SCHEMA__SETATTR, true);
|
||||
}
|
||||
|
||||
/* db_schema:{search} permission */
|
||||
bool
|
||||
sepgsql_schema_search(Oid namespaceId, bool abort_on_violation)
|
||||
{
|
||||
return check_schema_perms(namespaceId,
|
||||
SEPG_DB_SCHEMA__SEARCH,
|
||||
abort_on_violation);
|
||||
}
|
||||
|
||||
void
|
||||
sepgsql_schema_add_name(Oid namespaceId)
|
||||
{
|
||||
check_schema_perms(namespaceId, SEPG_DB_SCHEMA__ADD_NAME);
|
||||
check_schema_perms(namespaceId, SEPG_DB_SCHEMA__ADD_NAME, true);
|
||||
}
|
||||
|
||||
void
|
||||
sepgsql_schema_remove_name(Oid namespaceId)
|
||||
{
|
||||
check_schema_perms(namespaceId, SEPG_DB_SCHEMA__REMOVE_NAME);
|
||||
check_schema_perms(namespaceId, SEPG_DB_SCHEMA__REMOVE_NAME, true);
|
||||
}
|
||||
|
||||
void
|
||||
@ -216,5 +228,6 @@ sepgsql_schema_rename(Oid namespaceId)
|
||||
{
|
||||
check_schema_perms(namespaceId,
|
||||
SEPG_DB_SCHEMA__ADD_NAME |
|
||||
SEPG_DB_SCHEMA__REMOVE_NAME);
|
||||
SEPG_DB_SCHEMA__REMOVE_NAME,
|
||||
true);
|
||||
}
|
||||
|
@ -1,4 +1,4 @@
|
||||
policy_module(sepgsql-regtest, 1.05)
|
||||
policy_module(sepgsql-regtest, 1.06)
|
||||
|
||||
gen_require(`
|
||||
all_userspace_class_perms
|
||||
@ -20,6 +20,9 @@ postgresql_procedure_object(sepgsql_regtest_trusted_proc_exec_t)
|
||||
type sepgsql_nosuch_trusted_proc_exec_t;
|
||||
postgresql_procedure_object(sepgsql_nosuch_trusted_proc_exec_t)
|
||||
|
||||
type sepgsql_regtest_invisible_schema_t;
|
||||
postgresql_schema_object(sepgsql_regtest_invisible_schema_t);
|
||||
|
||||
#
|
||||
# Test domains for database administrators
|
||||
#
|
||||
|
@ -303,6 +303,7 @@ extern void sepgsql_schema_post_create(Oid namespaceId);
|
||||
extern void sepgsql_schema_drop(Oid namespaceId);
|
||||
extern void sepgsql_schema_relabel(Oid namespaceId, const char *seclabel);
|
||||
extern void sepgsql_schema_setattr(Oid namespaceId);
|
||||
extern bool sepgsql_schema_search(Oid namespaceId, bool abort_on_violation);
|
||||
extern void sepgsql_schema_add_name(Oid namespaceId);
|
||||
extern void sepgsql_schema_remove_name(Oid namespaceId);
|
||||
extern void sepgsql_schema_rename(Oid namespaceId);
|
||||
|
@ -43,6 +43,14 @@ SELECT objtype, objname, label FROM pg_seclabels
|
||||
AND objname in ('t1', 't2', 't3', 't4', 't5', 't5.e', 't5.f', 't5.g')
|
||||
ORDER BY objname;
|
||||
|
||||
CREATE SCHEMA my_schema_1;
|
||||
CREATE TABLE my_schema_1.ts1 (a int, b text);
|
||||
CREATE SCHEMA my_schema_2;
|
||||
CREATE TABLE my_schema_2.ts2 (x int, y text);
|
||||
|
||||
SECURITY LABEL ON SCHEMA my_schema_2
|
||||
IS 'system_u:object_r:sepgsql_regtest_invisible_schema_t:s0';
|
||||
|
||||
-- Hardwired Rules
|
||||
UPDATE pg_attribute SET attisdropped = true
|
||||
WHERE attrelid = 't5'::regclass AND attname = 'f'; -- failed
|
||||
@ -107,6 +115,14 @@ COPY t5 FROM '/dev/null'; -- failed
|
||||
COPY t5 (e,f) FROM '/dev/null'; -- failed
|
||||
COPY t5 (e) FROM '/dev/null'; -- ok
|
||||
|
||||
--
|
||||
-- Schema search path
|
||||
--
|
||||
SET search_path = my_schema_1, my_schema_2, public;
|
||||
SELECT * FROM ts1; -- ok
|
||||
SELECT * FROM ts2; -- failed (relation not found)
|
||||
SELECT * FROM my_schema_2.ts2; -- failed (policy violation)
|
||||
|
||||
--
|
||||
-- Clean up
|
||||
--
|
||||
@ -117,3 +133,5 @@ DROP TABLE IF EXISTS t3 CASCADE;
|
||||
DROP TABLE IF EXISTS t4 CASCADE;
|
||||
DROP TABLE IF EXISTS t5 CASCADE;
|
||||
DROP TABLE IF EXISTS customer CASCADE;
|
||||
DROP SCHEMA IF EXISTS my_schema_1 CASCADE;
|
||||
DROP SCHEMA IF EXISTS my_schema_2 CASCADE;
|
||||
|
@ -397,6 +397,16 @@ UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100;
|
||||
checked in this version.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
In order to access any schema object, <literal>db_schema:search</>
|
||||
permission is required on the containing schema. When an object is
|
||||
referenced without schema qualification, schemas on which this
|
||||
permission is not present will not be searched (just as if the user did
|
||||
not have <literal>USAGE</> privilege on the schema). If an explicit schema
|
||||
qualification is present, an error will occur if the user does not have
|
||||
the requisite permission on the named schema.
|
||||
</para>
|
||||
|
||||
<para>
|
||||
The client must be allowed to access all referenced tables and
|
||||
columns, even if they originated from views which were then expanded,
|
||||
|
@ -22,6 +22,7 @@
|
||||
#include "access/htup_details.h"
|
||||
#include "access/xact.h"
|
||||
#include "catalog/dependency.h"
|
||||
#include "catalog/objectaccess.h"
|
||||
#include "catalog/pg_authid.h"
|
||||
#include "catalog/pg_collation.h"
|
||||
#include "catalog/pg_conversion.h"
|
||||
@ -2655,7 +2656,10 @@ LookupNamespaceNoError(const char *nspname)
|
||||
if (strcmp(nspname, "pg_temp") == 0)
|
||||
{
|
||||
if (OidIsValid(myTempNamespace))
|
||||
{
|
||||
InvokeNamespaceSearchHook(myTempNamespace, true);
|
||||
return myTempNamespace;
|
||||
}
|
||||
|
||||
/*
|
||||
* Since this is used only for looking up existing objects, there is
|
||||
@ -2702,6 +2706,8 @@ LookupExplicitNamespace(const char *nspname, bool missing_ok)
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
|
||||
nspname);
|
||||
/* Schema search hook for this lookup */
|
||||
InvokeNamespaceSearchHook(namespaceId, true);
|
||||
|
||||
return namespaceId;
|
||||
}
|
||||
@ -3468,7 +3474,8 @@ recomputeNamespacePath(void)
|
||||
if (OidIsValid(namespaceId) &&
|
||||
!list_member_oid(oidlist, namespaceId) &&
|
||||
pg_namespace_aclcheck(namespaceId, roleid,
|
||||
ACL_USAGE) == ACLCHECK_OK)
|
||||
ACL_USAGE) == ACLCHECK_OK &&
|
||||
InvokeNamespaceSearchHook(namespaceId, false))
|
||||
oidlist = lappend_oid(oidlist, namespaceId);
|
||||
}
|
||||
}
|
||||
@ -3477,7 +3484,8 @@ recomputeNamespacePath(void)
|
||||
/* pg_temp --- substitute temp namespace, if any */
|
||||
if (OidIsValid(myTempNamespace))
|
||||
{
|
||||
if (!list_member_oid(oidlist, myTempNamespace))
|
||||
if (!list_member_oid(oidlist, myTempNamespace) &&
|
||||
InvokeNamespaceSearchHook(myTempNamespace, false))
|
||||
oidlist = lappend_oid(oidlist, myTempNamespace);
|
||||
}
|
||||
else
|
||||
@ -3494,7 +3502,8 @@ recomputeNamespacePath(void)
|
||||
if (OidIsValid(namespaceId) &&
|
||||
!list_member_oid(oidlist, namespaceId) &&
|
||||
pg_namespace_aclcheck(namespaceId, roleid,
|
||||
ACL_USAGE) == ACLCHECK_OK)
|
||||
ACL_USAGE) == ACLCHECK_OK &&
|
||||
InvokeNamespaceSearchHook(namespaceId, false))
|
||||
oidlist = lappend_oid(oidlist, namespaceId);
|
||||
}
|
||||
}
|
||||
|
@ -11,6 +11,7 @@
|
||||
#include "postgres.h"
|
||||
|
||||
#include "catalog/objectaccess.h"
|
||||
#include "catalog/pg_namespace.h"
|
||||
|
||||
/*
|
||||
* Hook on object accesses. This is intended as infrastructure for security
|
||||
@ -84,3 +85,27 @@ RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
|
||||
classId, objectId, subId,
|
||||
(void *) &pa_arg);
|
||||
}
|
||||
|
||||
/*
|
||||
* RunNamespaceSearchHook
|
||||
*
|
||||
* It is entrypoint of OAT_NAMESPACE_SEARCH event
|
||||
*/
|
||||
bool
|
||||
RunNamespaceSearchHook(Oid objectId, bool ereport_on_violation)
|
||||
{
|
||||
ObjectAccessNamespaceSearch ns_arg;
|
||||
|
||||
/* XXX - should be checked at caller side */
|
||||
Assert(object_access_hook != NULL);
|
||||
|
||||
memset(&ns_arg, 0, sizeof(ObjectAccessNamespaceSearch));
|
||||
ns_arg.ereport_on_violation = ereport_on_violation;
|
||||
ns_arg.result = true;
|
||||
|
||||
(*object_access_hook)(OAT_NAMESPACE_SEARCH,
|
||||
NamespaceRelationId, objectId, 0,
|
||||
(void *) &ns_arg);
|
||||
|
||||
return ns_arg.result;
|
||||
}
|
||||
|
@ -22,6 +22,7 @@
|
||||
|
||||
#include "access/htup_details.h"
|
||||
#include "access/xact.h"
|
||||
#include "catalog/objectaccess.h"
|
||||
#include "catalog/pg_proc.h"
|
||||
#include "libpq/libpq.h"
|
||||
#include "libpq/pqformat.h"
|
||||
@ -355,6 +356,7 @@ HandleFunctionRequest(StringInfo msgBuf)
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
aclcheck_error(aclresult, ACL_KIND_NAMESPACE,
|
||||
get_namespace_name(fip->namespace));
|
||||
InvokeNamespaceSearchHook(fip->namespace, true);
|
||||
|
||||
aclresult = pg_proc_aclcheck(fid, GetUserId(), ACL_EXECUTE);
|
||||
if (aclresult != ACLCHECK_OK)
|
||||
|
@ -27,6 +27,10 @@
|
||||
* hook can use SnapshotNow and SnapshotSelf to get the old and new
|
||||
* versions of the tuple.
|
||||
*
|
||||
* OAT_NAMESPACE_SEARCH should be invoked prior to object name lookup under
|
||||
* a particular namespace. This event is equivalent to usage permission
|
||||
* permission on a schema under the default access control mechanism.
|
||||
*
|
||||
* Other types may be added in the future.
|
||||
*/
|
||||
typedef enum ObjectAccessType
|
||||
@ -34,6 +38,7 @@ typedef enum ObjectAccessType
|
||||
OAT_POST_CREATE,
|
||||
OAT_DROP,
|
||||
OAT_POST_ALTER,
|
||||
OAT_NAMESPACE_SEARCH,
|
||||
} ObjectAccessType;
|
||||
|
||||
/*
|
||||
@ -84,6 +89,28 @@ typedef struct
|
||||
bool is_internal;
|
||||
} ObjectAccessPostAlter;
|
||||
|
||||
/*
|
||||
* Arguments of OAT_NAMESPACE_SEARCH
|
||||
*/
|
||||
typedef struct
|
||||
{
|
||||
/*
|
||||
* If true, hook should report an error when permission to search this
|
||||
* schema is denied.
|
||||
*/
|
||||
bool ereport_on_violation;
|
||||
|
||||
/*
|
||||
* This is, in essence, an out parameter. Core code should
|
||||
* initialize this to true, and any extension that wants to deny
|
||||
* access should reset it to false. But an extension should be
|
||||
* careful never to store a true value here, so that in case there are
|
||||
* multiple extensions access is only allowed if all extensions
|
||||
* agree.
|
||||
*/
|
||||
bool result;
|
||||
} ObjectAccessNamespaceSearch;
|
||||
|
||||
/* Plugin provides a hook function matching this signature. */
|
||||
typedef void (*object_access_hook_type) (ObjectAccessType access,
|
||||
Oid classId,
|
||||
@ -101,6 +128,7 @@ extern void RunObjectDropHook(Oid classId, Oid objectId, int subId,
|
||||
int dropflags);
|
||||
extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
|
||||
Oid auxiliaryId, bool is_internal);
|
||||
extern bool RunNamespaceSearchHook(Oid objectId, bool ereport_on_volation);
|
||||
|
||||
/*
|
||||
* The following macros are wrappers around the functions above; these should
|
||||
@ -137,4 +165,9 @@ extern void RunObjectPostAlterHook(Oid classId, Oid objectId, int subId,
|
||||
(auxiliaryId),(is_internal)); \
|
||||
} while(0)
|
||||
|
||||
#define InvokeNamespaceSearchHook(objectId, ereport_on_violation) \
|
||||
(!object_access_hook \
|
||||
? true \
|
||||
: RunNamespaceSearchHook((objectId), (ereport_on_violation)))
|
||||
|
||||
#endif /* OBJECTACCESS_H */
|
||||
|
Loading…
x
Reference in New Issue
Block a user