diff -rpNU3 base/src/test/regress/expected/sanity_check.out sepgsql-new/src/test/regress/expected/sanity_check.out --- base/src/test/regress/expected/sanity_check.out 2007-11-25 12:49:12.000000000 +0900 +++ sepgsql-new/src/test/regress/expected/sanity_check.out 2009-03-13 18:14:33.000000000 +0900 @@ -111,6 +111,7 @@ SELECT relname, relhasindex pg_pltemplate | t pg_proc | t pg_rewrite | t + pg_security | t pg_shdepend | t pg_shdescription | t pg_statistic | t @@ -149,7 +150,7 @@ SELECT relname, relhasindex timetz_tbl | f tinterval_tbl | f varchar_tbl | f -(138 rows) +(139 rows) -- -- another sanity check: every system catalog that has OIDs should have diff -rpNU3 base/src/test/sepgsql/Makefile sepgsql-new/src/test/sepgsql/Makefile --- base/src/test/sepgsql/Makefile 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/Makefile 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,65 @@ +# ---------------------------------------------------- +# Makefile for SE-PostgreSQL testcases +# ---------------------------------------------------- +PSQL := $(shell which psql) +DIFF := $(shell which diff) +RUNCON := $(shell which runcon) +GETSEBOOL := $(shell which getsebool) +DBNAME := test + +TESTCASES = $(wildcard sql/*.sql) + +test: init check setup results.diff + +init: + rm -f results.diff results/*.out results/*.diff + +clean: init + rm -f launch_psql + +launch_psql: launch_psql.c + $(CC) $< -o $@ -lselinux + +results.diff: $(TESTCASES:sql/%.sql=results/%.diff) + @for x in $^; do cat $$x >> $@; done + @test -s $@ && echo "HINT: See $@ to confirm errors" || : + +results/%.diff: sql/%.sql + @./launch_psql $(PSQL) -a $(DBNAME) < $< >& $(@:%.diff=%.out) + @$(DIFF) -u $(<:sql/%.sql=expected/%.out) \ + $(<:sql/%.sql=results/%.out) >& $@ \ + && echo -n "PASS: " || echo -n "FAIL: " + @echo $(notdir $(@:.diff=)) + +setup: launch_psql + @cp -f /dev/null /tmp/sepgsql_test_copy_1 + @cp -f /dev/null /tmp/sepgsql_test_copy_2 + @chcon -t postgresql_tmp_t -l s0 /tmp/sepgsql_test_copy_1 + @chcon -t postgresql_db_t -l s0 /tmp/sepgsql_test_copy_2 + @dd if=/dev/zero of=/tmp/sepgsql_test_blob1 bs=1024 count=20 >& /dev/null + @dd if=/dev/zero of=/tmp/sepgsql_test_blob2 bs=1024 count=20 >& /dev/null + @chcon -t postgresql_tmp_t -l s0 /tmp/sepgsql_test_blob1 + @chcon -t postgresql_db_t -l s0 /tmp/sepgsql_test_blob2 + @chmod 0666 /tmp/sepgsql_test_* + @echo "PASS: setup filesystem objects" + +check: + @test -x $(PSQL) || \ + (echo "HINT: $(PSQL) is not available"; exit 1) + @$(PSQL) -qt -c 'SHOW sepostgresql' -d $(DBNAME) 2>/dev/null | grep -q on || \ + (echo "HINT: database \"$(DBNAME)\" is not available"; \ + echo "HINT: SE-PostgreSQL may not be available on server"; exit 1) + @$(GETSEBOOL) allow_user_postgresql_connect | grep -q on || \ + (echo "HINT: check allow_user_postgresql_connect boolean"; exit 1) + @$(GETSEBOOL) sepgsql_regression_test_mode | grep -q on || \ + (echo "HINT: check sepgsql_regression_test_mode boolean"; \ + echo "HINT: check sepostgresql-devel.pp installed"; exit 1) + @$(RUNCON) -t sepgsql_test_t -l s0-s0:c0.c15 \ + $(PSQL) -c 'SELECT sepgsql_getcon()' $(DBNAME) >& /dev/null || \ + (echo "HINT: /sbin/restorecon -R and restart"; \ + echo "HINT: user shell should have 's0-s0:c0.c15' range, at least"; \ + echo " semanage enables to set up it"; exit 1) + @test -x /etc/init.d/mcstrans && /etc/init.d/mcstrans status >& /dev/null && \ + (echo "HINT: stop mcstrans daemon"; exit 1) || \ + (test $$? -eq 3 && exit 0 || exit 1) + @echo "PASS: check runtime environment" diff -rpNU3 base/src/test/sepgsql/expected/basic.out sepgsql-new/src/test/sepgsql/expected/basic.out --- base/src/test/sepgsql/expected/basic.out 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/expected/basic.out 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,108 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- + unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +(1 row) + +-- cleanup previous tests +SET client_min_messages TO 'error'; +SET +DROP TABLE IF EXISTS t4 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t3 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t2 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t1 CASCADE; +DROP TABLE +DROP FUNCTION IF EXISTS f1(int) CASCADE; +DROP FUNCTION +RESET client_min_messages; +RESET +-- SETUP +CREATE TABLE t1 +( + a int, + b text + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_ro_table_t:s0', + c bool + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0' +); +CREATE TABLE +INSERT INTO t1 VALUES (1, 'aaa', false), (2, 'bbb', true); +INSERT 0 2 +CREATE TABLE t2 +( + s int, + t int, + u int +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0:c0'; +CREATE TABLE +ALTER TABLE t2 DROP COLUMN t; -- disturbing factor +ALTER TABLE +CREATE TABLE t3 +( + x text + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0:c1' +) inherits(t2); +CREATE TABLE +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 +SELECT sepgsql_getcon(); + sepgsql_getcon +--------------------------------------------------- + unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 +(1 row) + +SELECT * FROM t1; -- to be denied +ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c +SELECT a, b FROM t1; + a | b +---+----- + 1 | aaa + 2 | bbb +(2 rows) + +SELECT COUNT(*) FROM t1 WHERE c; -- to be denied +ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c +UPDATE t1 SET b = 'ccc'; -- to be denied +ERROR: SELinux: denied { update } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_ro_table_t:s0 tclass=db_column name=t1.b +UPDATE t1 SET a = a + 2; +UPDATE 2 +INSERT INTO t1 VALUES (5, 'eee', true); -- to be denied +ERROR: SELinux: denied { insert } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_ro_table_t:s0 tclass=db_column name=t1.b +INSERT INTO t1 VALUES (5); +INSERT 0 1 +SELECT * FROM t2; + s | u +---+--- +(0 rows) + +SELECT t2 FROM t2; + t2 +---- +(0 rows) + +SELECT t3 FROM t3; -- to be denied +ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0:c1 tclass=db_column name=t3.x +SELECT 1 FROM t3; + ?column? +---------- +(0 rows) + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1 +SELECT sepgsql_getcon(); + sepgsql_getcon +--------------------------------------------------- + unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1 +(1 row) + +SELECT * FROM t2; -- to be denied +ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1 tcontext=unconfined_u:object_r:sepgsql_table_t:s0:c0 tclass=db_table name=t2 +SELECT t2 FROM t2; -- to be denied +ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1 tcontext=unconfined_u:object_r:sepgsql_table_t:s0:c0 tclass=db_table name=t2 +SELECT t3 FROM t3; + t3 +---- +(0 rows) + diff -rpNU3 base/src/test/sepgsql/expected/copy_stmt.out sepgsql-new/src/test/sepgsql/expected/copy_stmt.out --- base/src/test/sepgsql/expected/copy_stmt.out 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/expected/copy_stmt.out 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,90 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- + unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +(1 row) + +-- cleanup previous tests +SET client_min_messages TO 'error'; +SET +DROP TABLE IF EXISTS t3 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t2 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t1 CASCADE; +DROP TABLE +DROP FUNCTION IF EXISTS f1(int) CASCADE; +DROP FUNCTION +RESET client_min_messages; +RESET +-- setup tables +CREATE TABLE t1 +( + a int, + b text +); +CREATE TABLE +INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'); +INSERT 0 2 +CREATE TABLE t2 +( + x int, + y text + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0' +); +CREATE TABLE +SELECT security_context from pg_attribute where attrelid = 't2'::regclass and attname = 'y'; + security_context +------------------------------------------------- + unconfined_u:object_r:sepgsql_secret_table_t:s0 +(1 row) + +INSERT INTO t2 VALUES (1, 'xxx'), (2, 'yyy'); +INSERT 0 2 +CREATE TABLE t3 -- read only table +( + s int, + t text +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_ro_table_t:s0'; +CREATE TABLE +INSERT INTO t2 VALUES (1, 'sss'), (2, 'ttt'); +INSERT 0 2 +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 +SELECT sepgsql_getcon(); + sepgsql_getcon +--------------------------------------------------- + unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 +(1 row) + +COPY t1 TO stdout; +1 aaa +2 bbb +COPY t1 FROM stdin; +COPY t1 TO '/tmp/sepgsql_test_copy_1'; +COPY 4 +COPY t1 TO '/tmp/sepgsql_test_copy_2'; -- to be denied +ERROR: SELinux: denied { write } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:postgresql_db_t:s0 tclass=file name=/tmp/sepgsql_test_copy_2 +COPY t2 TO stdout; -- to be denied +ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t2.y +COPY t2 FROM stdin; -- to be denied +ERROR: SELinux: denied { insert } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t2.y +COPY t2 (x) TO stdout; +1 +2 +1 +2 +COPY t3 TO stdout; +COPY t3 FROM '/tmp/sepgsql_test_copy_1'; -- to be denied +ERROR: SELinux: denied { insert } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_ro_table_t:s0 tclass=db_table name=t3 +COPY t1 FROM '/tmp/sepgsql_test_copy_1'; +COPY 4 +COPY t1 TO stdout; +1 aaa +2 bbb +3 ccc +4 ddd +1 aaa +2 bbb +3 ccc +4 ddd diff -rpNU3 base/src/test/sepgsql/expected/enhanced_ddl_stmt.out sepgsql-new/src/test/sepgsql/expected/enhanced_ddl_stmt.out --- base/src/test/sepgsql/expected/enhanced_ddl_stmt.out 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/expected/enhanced_ddl_stmt.out 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,180 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- + unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +(1 row) + +-- cleanup previous tests +SET client_min_messages TO 'error'; +SET +DROP TABLE IF EXISTS t4 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t3 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t2 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t1 CASCADE; +DROP TABLE +DROP FUNCTION IF EXISTS f1(int) CASCADE; +DROP FUNCTION +DROP FUNCTION IF EXISTS f2(int) CASCADE; +DROP FUNCTION +RESET client_min_messages; +RESET +-- CREATE TABLE with SECURITY_LABEL clause +CREATE TABLE t1 ( + a int, + b text +); +CREATE TABLE +SELECT relname, security_context FROM pg_class WHERE oid = 't1'::regclass; + relname | security_context +---------+------------------------------------------ + t1 | unconfined_u:object_r:sepgsql_table_t:s0 +(1 row) + +SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't1'::regclass and attnum > 0; + attname | security_context +---------+------------------------------------------ + a | unconfined_u:object_r:sepgsql_table_t:s0 + b | unconfined_u:object_r:sepgsql_table_t:s0 +(2 rows) + +CREATE TABLE t2 ( + a int, + b text +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_ro_table_t:s0'; +CREATE TABLE +SELECT relname, security_context FROM pg_class WHERE oid = 't2'::regclass; + relname | security_context +---------+--------------------------------------------- + t2 | unconfined_u:object_r:sepgsql_ro_table_t:s0 +(1 row) + +SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't2'::regclass and attnum > 0; + attname | security_context +---------+--------------------------------------------- + a | unconfined_u:object_r:sepgsql_ro_table_t:s0 + b | unconfined_u:object_r:sepgsql_ro_table_t:s0 +(2 rows) + +CREATE TABLE t3 ( + a int, + b text SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_fixed_table_t:s0', + c bool SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0', + d int +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0:c0'; +CREATE TABLE +SELECT relname, security_context FROM pg_class WHERE oid = 't3'::regclass; + relname | security_context +---------+--------------------------------------------- + t3 | unconfined_u:object_r:sepgsql_table_t:s0:c0 +(1 row) + +SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't3'::regclass and attnum > 0; + attname | security_context +---------+------------------------------------------------- + a | unconfined_u:object_r:sepgsql_table_t:s0 + b | unconfined_u:object_r:sepgsql_fixed_table_t:s0 + c | unconfined_u:object_r:sepgsql_secret_table_t:s0 + d | unconfined_u:object_r:sepgsql_table_t:s0 +(4 rows) + +CREATE TABLE t4 ( + a int, + b text +) SECURITY_CONTEXT = 'unconfined_u:object_r:invalid_label_t:s0'; -- to be failed +ERROR: invalid security label: unconfined_u:object_r:invalid_label_t:s0 +CREATE TABLE t4 ( + a int, + b text +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0'; -- to be denied +ERROR: SELinux: denied { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 tcontext=unconfined_u:object_r:sepgsql_proc_t:s0 tclass=db_table name=t4 +-- ALTER TABLE with SECURITY_CONTEXT clause +ALTER TABLE t2 SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0'; +ALTER TABLE +ALTER TABLE t2 ADD COLUMN c bool; -- it inherits table's one +ALTER TABLE +SELECT relname, security_context FROM pg_class WHERE oid = 't2'::regclass; + relname | security_context +---------+------------------------------------------------- + t2 | unconfined_u:object_r:sepgsql_secret_table_t:s0 +(1 row) + +SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't2'::regclass and attnum > 0; + attname | security_context +---------+------------------------------------------------- + a | unconfined_u:object_r:sepgsql_ro_table_t:s0 + b | unconfined_u:object_r:sepgsql_ro_table_t:s0 + c | unconfined_u:object_r:sepgsql_secret_table_t:s0 +(3 rows) + +ALTER TABLE t3 ALTER b SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0'; +ALTER TABLE +SELECT relname, security_context FROM pg_class WHERE oid = 't3'::regclass; + relname | security_context +---------+--------------------------------------------- + t3 | unconfined_u:object_r:sepgsql_table_t:s0:c0 +(1 row) + +SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't3'::regclass and attnum > 0; + attname | security_context +---------+------------------------------------------------- + a | unconfined_u:object_r:sepgsql_table_t:s0 + b | unconfined_u:object_r:sepgsql_table_t:s0 + c | unconfined_u:object_r:sepgsql_secret_table_t:s0 + d | unconfined_u:object_r:sepgsql_table_t:s0 +(4 rows) + +-- CREATE FUNCTION with SECURITY_CONTEXT clause +CREATE FUNCTION f1 (int) RETURNS int + LANGUAGE 'sql' + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c0' + AS 'SELECT $1 * 2'; +CREATE FUNCTION +SELECT proname, security_context FROM pg_proc WHERE oid = 'f1'::regproc; + proname | security_context +---------+-------------------------------------------- + f1 | unconfined_u:object_r:sepgsql_proc_t:s0:c0 +(1 row) + +CREATE FUNCTION f2 (int) RETURNS int + LANGUAGE 'sql' + SECURITY_CONTEXT = 'unconfined_u:object_r:invalid_label_t:s0' + AS 'SELECT $1 + $1'; -- to be failed +ERROR: invalid security label: unconfined_u:object_r:invalid_label_t:s0 +CREATE FUNCTION f2 (int) RETURNS int + LANGUAGE 'sql' + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c16' + AS 'SELECT $1 + $1'; -- to be denied +ERROR: SELinux: denied { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 tcontext=unconfined_u:object_r:sepgsql_proc_t:s0:c16 tclass=db_procedure name=f2 +CREATE FUNCTION f2 (int) RETURNS int + LANGUAGE 'sql' + AS 'SELECT $1 + $1'; +CREATE FUNCTION +SELECT proname, security_context FROM pg_proc WHERE oid = 'f2'::regproc; + proname | security_context +---------+----------------------------------------- + f2 | unconfined_u:object_r:sepgsql_proc_t:s0 +(1 row) + +-- ALTER FUNCTION with SECURITY_CONTEXT clause +ALTER FUNCTION f1(int) + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c1'; +ALTER FUNCTION +SELECT proname, security_context FROM pg_proc WHERE oid = 'f1'::regproc; + proname | security_context +---------+-------------------------------------------- + f1 | unconfined_u:object_r:sepgsql_proc_t:s0:c1 +(1 row) + +ALTER FUNCTION f2(int) + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c16'; -- to be denied +ERROR: SELinux: denied { relabelto } scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 tcontext=unconfined_u:object_r:sepgsql_proc_t:s0:c16 tclass=db_procedure name=f2 +SELECT proname, security_context FROM pg_proc WHERE oid = 'f2'::regproc; + proname | security_context +---------+----------------------------------------- + f2 | unconfined_u:object_r:sepgsql_proc_t:s0 +(1 row) + diff -rpNU3 base/src/test/sepgsql/expected/join_query.out sepgsql-new/src/test/sepgsql/expected/join_query.out --- base/src/test/sepgsql/expected/join_query.out 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/expected/join_query.out 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,85 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- + unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +(1 row) + +-- cleanup previous tests +SET client_min_messages TO 'error'; +SET +DROP TABLE IF EXISTS t4 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t3 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t2 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t1 CASCADE; +DROP TABLE +DROP FUNCTION IF EXISTS f1(int) CASCADE; +DROP FUNCTION +RESET client_min_messages; +RESET +-- SETUP +CREATE TABLE t1 +( + a int, + b text, + c int + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0' +); +CREATE TABLE +INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc'); +INSERT 0 3 +CREATE TABLE t2 +( + x int, + y text +); +CREATE TABLE +INSERT INTO t2 VALUES (2, 'xxx'), (3, 'yyy'), (4,'zzz'); +INSERT 0 3 +CREATE TABLE t3 +( + d int +) INHERITS (t1); +CREATE TABLE +INSERT INTO t3 VALUES (4, 'ddd'), (5, 'eee'); +INSERT 0 2 +CREATE TABLE t4 +( + z int + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0' +) INHERITS (t2); +CREATE TABLE +INSERT INTO t2 VALUES (1, 'sss'), (5, 'ttt'); +INSERT 0 2 +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 +SELECT sepgsql_getcon(); + sepgsql_getcon +--------------------------------------------------- + unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 +(1 row) + +SELECT * FROM t1 JOIN t2 ON a = x; -- to be denied +ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c +SELECT a, b, y FROM t1 JOIN t2 ON a = x; + a | b | y +---+-----+----- + 1 | aaa | sss + 2 | bbb | xxx + 3 | ccc | yyy + 4 | ddd | zzz + 5 | eee | ttt +(5 rows) + +SELECT a, b, y FROM t1 JOIN t2 ON c = x; -- to be denied +ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c +SELECT COUNT(*) FROM t1 JOIN t2 ON a = x; + count +------- + 5 +(1 row) + +SELECT j FROM (t1 JOIN t2 ON a = x) AS j; -- to be denied +ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c diff -rpNU3 base/src/test/sepgsql/expected/large_object.out sepgsql-new/src/test/sepgsql/expected/large_object.out --- base/src/test/sepgsql/expected/large_object.out 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/expected/large_object.out 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,293 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- + unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +(1 row) + +-- cleanup previous tests +SET client_min_messages TO 'error'; +SET +DROP TABLE IF EXISTS lolabel CASCADE; +DROP TABLE +DROP FUNCTION IF EXISTS lo_label(oid) CASCADE; +DROP FUNCTION +RESET client_min_messages; +RESET +CREATE TABLE lolabel( + loid oid, + label text +); +CREATE TABLE +CREATE OR REPLACE FUNCTION lo_label(oid) + RETURNS TEXT LANGUAGE 'sql' + AS 'SELECT label FROM lolabel WHERE loid = $1'; +CREATE FUNCTION +INSERT INTO lolabel (SELECT lo_import('/tmp/sepgsql_test_blob1'), 'normal'); +INSERT 0 1 +INSERT INTO lolabel (SELECT lo_import('/tmp/sepgsql_test_blob1'), 'readonly'); +INSERT 0 1 +INSERT INTO lolabel (SELECT lo_import('/tmp/sepgsql_test_blob1'), 'secret'); +INSERT 0 1 +SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_blob_t:s0') + FROM lolabel WHERE label = 'normal'; + lo_set_security +----------------- + t +(1 row) + +SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_ro_blob_t:s0') + FROM lolabel WHERE label = 'readonly'; + lo_set_security +----------------- + t +(1 row) + +SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_secret_blob_t:s0') + FROM lolabel WHERE label = 'secret'; + lo_set_security +----------------- + t +(1 row) + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0:c0 +SELECT sepgsql_getcon(); + sepgsql_getcon +------------------------------------------------ + unconfined_u:unconfined_r:sepgsql_test_t:s0:c0 +(1 row) + +SELECT lo_get_security(loid) FROM lolabel; + lo_get_security +-------------------------------------------- + system_u:object_r:sepgsql_blob_t:s0 + system_u:object_r:sepgsql_ro_blob_t:s0 + system_u:object_r:sepgsql_secret_blob_t:s0 +(3 rows) + +SELECT security_context, lo_label(loid) AS label, COUNT(*) + FROM pg_largeobject GROUP BY security_context, loid ORDER by label; + security_context | label | count +--------------------------------------------+----------+------- + system_u:object_r:sepgsql_blob_t:s0 | normal | 10 + system_u:object_r:sepgsql_ro_blob_t:s0 | readonly | 10 + system_u:object_r:sepgsql_secret_blob_t:s0 | secret | 10 +(3 rows) + +-- read large object +BEGIN; +BEGIN +SELECT lo_open(loid, x'40000'::int) FROM lolabel WHERE label = 'normal'; + lo_open +--------- + 0 +(1 row) + +SELECT loread(0, 32); + loread +---------------------------------------------------------------------------------------------------------------------------------- + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +(1 row) + +ROLLBACK; +ROLLBACK +BEGIN; +BEGIN +SELECT lo_open(loid, x'40000'::int) FROM lolabel WHERE label = 'readonly'; + lo_open +--------- + 0 +(1 row) + +SELECT loread(0, 32); + loread +---------------------------------------------------------------------------------------------------------------------------------- + \000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000\000 +(1 row) + +ROLLBACK; +ROLLBACK +BEGIN; +BEGIN +SELECT lo_open(loid, x'40000'::int) FROM lolabel WHERE label = 'secret'; + lo_open +--------- + 0 +(1 row) + +SELECT loread(0, 32); -- to be denied +ERROR: SELinux: security policy violation +ROLLBACK; +ROLLBACK +-- write large object +BEGIN; +BEGIN +SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'normal'; + lo_open +--------- + 0 +(1 row) + +SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + lowrite +--------- + 26 +(1 row) + +ROLLBACK; +ROLLBACK +BEGIN; +BEGIN +SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'readonly'; + lo_open +--------- + 0 +(1 row) + +SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); -- to be denied +ERROR: SELinux: security policy violation +ROLLBACK; +ROLLBACK +BEGIN; +BEGIN +SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'secret'; + lo_open +--------- + 0 +(1 row) + +SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); -- to be denied +ERROR: SELinux: security policy violation +ROLLBACK; +ROLLBACK +-- create large object +BEGIN; +BEGIN +INSERT INTO lolabel (SELECT lo_create(6004), 'local'); +INSERT 0 1 +SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'local'; + lo_open +--------- + 0 +(1 row) + +SELECT lowrite(0, 'abcdefghijklmnopqrstuvwxyz'); + lowrite +--------- + 26 +(1 row) + +SELECT lo_close(0); + lo_close +---------- + 0 +(1 row) + +COMMIT; +COMMIT +-- getattr/setattr +BEGIN; +BEGIN +SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'local'; + lo_open +--------- + 0 +(1 row) + +SELECT lo_lseek(0, 0, 2); -- seek to end + lo_lseek +---------- + 26 +(1 row) + +SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + lowrite +--------- + 26 +(1 row) + +SELECT lo_tell(0); + lo_tell +--------- + 52 +(1 row) + +SELECT lo_lseek(0, 0, 0); -- seek to head + lo_lseek +---------- + 0 +(1 row) + +SELECT loread(0, 50); + loread +---------------------------------------------------- + abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWX +(1 row) + +SELECT lo_close(0); + lo_close +---------- + 0 +(1 row) + +COMMIT; +COMMIT +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- + unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +(1 row) + +-- change security label +BEGIN; +BEGIN +SELECT lo_open(loid, x'40000'::int) FROM lolabel; -- a seed of trouble + lo_open +--------- + 0 + 1 + 2 + 3 +(4 rows) + +SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_blob_t:s0:c4') + FROM lolabel WHERE label in ('normal', 'readonly'); + lo_set_security +----------------- + t + t +(2 rows) + +SELECT lo_get_security(loid) FROM lolabel; + lo_get_security +--------------------------------------------------------- + system_u:object_r:sepgsql_blob_t:s0:c4 + system_u:object_r:sepgsql_blob_t:s0:c4 + system_u:object_r:sepgsql_secret_blob_t:s0 + unconfined_u:object_r:sepgsql_test_sepgsql_blob_t:s0:c0 +(4 rows) + +SELECT security_context, lo_label(loid) AS label, count(*) + FROM pg_largeobject WHERE loid in (SELECT loid FROM lolabel) + GROUP BY security_context, loid ORDER BY label; + security_context | label | count +---------------------------------------------------------+----------+------- + unconfined_u:object_r:sepgsql_test_sepgsql_blob_t:s0:c0 | local | 1 + system_u:object_r:sepgsql_blob_t:s0:c4 | normal | 10 + system_u:object_r:sepgsql_blob_t:s0:c4 | readonly | 10 + system_u:object_r:sepgsql_secret_blob_t:s0 | secret | 10 +(4 rows) + +ROLLBACK; +ROLLBACK +-- cleanup +SELECT lo_unlink(loid) FROM lolabel; + lo_unlink +----------- + 1 + 1 + 1 + 1 +(4 rows) + diff -rpNU3 base/src/test/sepgsql/expected/row_level.out sepgsql-new/src/test/sepgsql/expected/row_level.out --- base/src/test/sepgsql/expected/row_level.out 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/expected/row_level.out 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,131 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- + unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +(1 row) + +-- cleanup previous tests +SET client_min_messages TO 'error'; +SET +DROP TABLE IF EXISTS t4 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t3 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t2 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t1 CASCADE; +DROP TABLE +DROP FUNCTION IF EXISTS f1(int) CASCADE; +DROP FUNCTION +DROP FUNCTION IF EXISTS f2(int) CASCADE; +DROP FUNCTION +RESET client_min_messages; +RESET +-- test begins here +CREATE TABLE t1 ( + a int primary key, + b text +); +NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t1_pkey" for table "t1" +CREATE TABLE +CREATE TABLE t2 ( + x int references t1 (a) on update cascade, + y text +); +CREATE TABLE +INSERT INTO t1 (security_context, a, b) VALUES + ('system_u:object_r:sepgsql_table_t:s0', 1, 'aaa'), + ('system_u:object_r:sepgsql_table_t:s0:c0', 2, 'bbb'), + ('system_u:object_r:sepgsql_table_t:s0:c1', 3, 'ccc'), + ('system_u:object_r:sepgsql_ro_table_t:s0', 4, 'ddd'), + ('system_u:object_r:sepgsql_ro_table_t:s0:c0', 5, 'eee'), + ('system_u:object_r:sepgsql_ro_table_t:s0:c1', 6, 'fff'); +INSERT 0 6 +INSERT INTO t2 (security_context, x, y) VALUES + ('system_u:object_r:sepgsql_table_t:s0:c1', 1, 'xxx'), + ('system_u:object_r:sepgsql_table_t:s0:c0', 2, 'yyy'), + ('system_u:object_r:sepgsql_table_t:s0', 3, 'zzz'); +INSERT 0 3 +SELECT security_context, * FROM t1; + security_context | a | b +--------------------------------------------+---+----- + system_u:object_r:sepgsql_table_t:s0 | 1 | aaa + system_u:object_r:sepgsql_table_t:s0:c0 | 2 | bbb + system_u:object_r:sepgsql_table_t:s0:c1 | 3 | ccc + system_u:object_r:sepgsql_ro_table_t:s0 | 4 | ddd + system_u:object_r:sepgsql_ro_table_t:s0:c0 | 5 | eee + system_u:object_r:sepgsql_ro_table_t:s0:c1 | 6 | fff +(6 rows) + +SELECT security_context, * FROM t2; + security_context | x | y +-----------------------------------------+---+----- + system_u:object_r:sepgsql_table_t:s0:c1 | 1 | xxx + system_u:object_r:sepgsql_table_t:s0:c0 | 2 | yyy + system_u:object_r:sepgsql_table_t:s0 | 3 | zzz +(3 rows) + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0:c0 +SELECT sepgsql_getcon(); + sepgsql_getcon +------------------------------------------------ + unconfined_u:unconfined_r:sepgsql_test_t:s0:c0 +(1 row) + +SELECT security_context, * FROM t1; + security_context | a | b +--------------------------------------------+---+----- + system_u:object_r:sepgsql_table_t:s0 | 1 | aaa + system_u:object_r:sepgsql_table_t:s0:c0 | 2 | bbb + system_u:object_r:sepgsql_ro_table_t:s0 | 4 | ddd + system_u:object_r:sepgsql_ro_table_t:s0:c0 | 5 | eee +(4 rows) + +SELECT security_context, * FROM t2; + security_context | x | y +-----------------------------------------+---+----- + system_u:object_r:sepgsql_table_t:s0:c0 | 2 | yyy + system_u:object_r:sepgsql_table_t:s0 | 3 | zzz +(2 rows) + +COPY t1 TO stdout; +1 aaa +2 bbb +4 ddd +5 eee +COPY t2 (security_context, x, y) TO stdout; +system_u:object_r:sepgsql_table_t:s0:c0 2 yyy +system_u:object_r:sepgsql_table_t:s0 3 zzz +UPDATE t1 SET a = 99 WHERE a = 1 RETURNING *; -- to be failed +ERROR: SELinux: security policy violation +CONTEXT: SQL statement "UPDATE ONLY "public"."t2" SET "x" = $1 WHERE $2 OPERATOR(pg_catalog.=) "x"" +UPDATE t1 SET a = 99 WHERE a = 2 RETURNING *; + a | b +----+----- + 99 | bbb +(1 row) + +UPDATE 1 +UPDATE t1 SET a = 99 WHERE a = 4 RETURNING *; -- to be denied + a | b +---+--- +(0 rows) + +UPDATE 0 +INSERT INTO t1 VALUES (3, 'ccc'); -- to be failed +ERROR: duplicate key value violates unique constraint "t1_pkey" +INSERT INTO t1 VALUES (7, 'ggg'); +INSERT 0 1 +INSERT INTO t2 VALUES (3, 'XXX'); -- to be failed +ERROR: insert or update on table "t2" violates foreign key constraint "t2_x_fkey" +DETAIL: Key (x)=(3) is not present in table "t1". +INSERT INTO t2 VALUES (4, 'XXX'); +INSERT 0 1 +DELETE FROM t1; -- to be failed +ERROR: SELinux: security policy violation +CONTEXT: SQL statement "SELECT 1 FROM ONLY "public"."t2" x WHERE $1 OPERATOR(pg_catalog.=) "x" FOR SHARE OF x" +DELETE FROM t1 WHERE a not in (SELECT x FROM t2); -- to be failed +ERROR: SELinux: security policy violation +DELETE FROM t1 WHERE a = 7; +DELETE 1 diff -rpNU3 base/src/test/sepgsql/expected/security_label.out sepgsql-new/src/test/sepgsql/expected/security_label.out --- base/src/test/sepgsql/expected/security_label.out 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/expected/security_label.out 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,127 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +SELECT sepgsql_getcon(); + sepgsql_getcon +----------------------------------------------------- + unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 +(1 row) + +-- cleanup previous tests +SET client_min_messages TO 'error'; +SET +DROP TABLE IF EXISTS t4 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t3 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t2 CASCADE; +DROP TABLE +DROP TABLE IF EXISTS t1 CASCADE; +DROP TABLE +DROP FUNCTION IF EXISTS f1(int) CASCADE; +DROP FUNCTION +DROP FUNCTION IF EXISTS f2(int) CASCADE; +DROP FUNCTION +RESET client_min_messages; +RESET +-- test begins here +CREATE TABLE t1 ( + a int, + b text +); +CREATE TABLE +CREATE TABLE t2 ( + x int, + y text +); +CREATE TABLE +CREATE TABLE t3 ( + s int, + t text +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_fixed_table_t:s0'; +CREATE TABLE +INSERT INTO t1 VALUES (1, 'aaa'); +INSERT 0 1 +INSERT INTO t1 (security_context, a, b) VALUES ('unconfined_u:object_r:sepgsql_ro_table_t:s0', 2, 'bbb'); +INSERT 0 1 +INSERT INTO t1 (security_context, a, b) VALUES ('unconfined_u:object_r:sepgsql_table_t:s0:c1', 3, 'ccc'); +INSERT 0 1 +INSERT INTO t1 VALUES (4, 'ddd'), (5, 'eee'); +INSERT 0 2 +INSERT INTO t1 (security_context, a, b) VALUES ('invalid security context', 6, 'fff'); -- to be failed +ERROR: invalid security label: invalid security context +INSERT INTO t1 (security_context, a, b) VALUES ('system_u:object_r:sepgsql_table_t:s0:c20', 6, 'fff'); -- to be denied +INSERT 0 0 +SELECT security_context, * FROM t1; + security_context | a | b +---------------------------------------------+---+----- + unconfined_u:object_r:sepgsql_table_t:s0 | 1 | aaa + unconfined_u:object_r:sepgsql_ro_table_t:s0 | 2 | bbb + unconfined_u:object_r:sepgsql_table_t:s0:c1 | 3 | ccc + unconfined_u:object_r:sepgsql_table_t:s0 | 4 | ddd + unconfined_u:object_r:sepgsql_table_t:s0 | 5 | eee +(5 rows) + +INSERT INTO t2 (security_context, x, y) + (SELECT sepgsql_set_user(security_context, 'system_u'), a + 5, b || '_cpy' FROM t1); +INSERT 0 5 +SELECT security_context, * FROM t2; + security_context | x | y +-----------------------------------------+----+--------- + system_u:object_r:sepgsql_table_t:s0 | 6 | aaa_cpy + system_u:object_r:sepgsql_ro_table_t:s0 | 7 | bbb_cpy + system_u:object_r:sepgsql_table_t:s0:c1 | 8 | ccc_cpy + system_u:object_r:sepgsql_table_t:s0 | 9 | ddd_cpy + system_u:object_r:sepgsql_table_t:s0 | 10 | eee_cpy +(5 rows) + +INSERT INTO t3 VALUES (98, 'xxx'); +INSERT 0 1 +INSERT INTO t3 (security_context, s, t) VALUES ('system_u:object_r:sepgsql_ro_table_t:s0', 99, 'yyy'); +INSERT 0 1 +INSERT INTO t3 (SELECT * FROM t1); +INSERT 0 5 +INSERT INTO t3 (security_context, s, t) (SELECT security_context, x, y FROM t2); +INSERT 0 5 +SELECT security_context, * FROM t3; + security_context | s | t +------------------------------------------------+----+--------- + unconfined_u:object_r:sepgsql_fixed_table_t:s0 | 98 | xxx + system_u:object_r:sepgsql_ro_table_t:s0 | 99 | yyy + unconfined_u:object_r:sepgsql_fixed_table_t:s0 | 1 | aaa + unconfined_u:object_r:sepgsql_fixed_table_t:s0 | 2 | bbb + unconfined_u:object_r:sepgsql_fixed_table_t:s0 | 3 | ccc + unconfined_u:object_r:sepgsql_fixed_table_t:s0 | 4 | ddd + unconfined_u:object_r:sepgsql_fixed_table_t:s0 | 5 | eee + system_u:object_r:sepgsql_table_t:s0 | 6 | aaa_cpy + system_u:object_r:sepgsql_ro_table_t:s0 | 7 | bbb_cpy + system_u:object_r:sepgsql_table_t:s0:c1 | 8 | ccc_cpy + system_u:object_r:sepgsql_table_t:s0 | 9 | ddd_cpy + system_u:object_r:sepgsql_table_t:s0 | 10 | eee_cpy +(12 rows) + +SELECT sepgsql_set_range(security_context, 's0:c' || s) AS security_context, * INTO t4 FROM t3; -- partially denied +SELECT +SELECT security_context, * FROM t4; + security_context | s | t +---------------------------------------------------+----+--------- + unconfined_u:object_r:sepgsql_fixed_table_t:s0:c1 | 1 | aaa + unconfined_u:object_r:sepgsql_fixed_table_t:s0:c2 | 2 | bbb + unconfined_u:object_r:sepgsql_fixed_table_t:s0:c3 | 3 | ccc + unconfined_u:object_r:sepgsql_fixed_table_t:s0:c4 | 4 | ddd + unconfined_u:object_r:sepgsql_fixed_table_t:s0:c5 | 5 | eee + system_u:object_r:sepgsql_table_t:s0:c6 | 6 | aaa_cpy + system_u:object_r:sepgsql_ro_table_t:s0:c7 | 7 | bbb_cpy + system_u:object_r:sepgsql_table_t:s0:c8 | 8 | ccc_cpy + system_u:object_r:sepgsql_table_t:s0:c9 | 9 | ddd_cpy + system_u:object_r:sepgsql_table_t:s0:c10 | 10 | eee_cpy +(10 rows) + +COPY t1 (security_context, a, b) FROM stdin; -- partially denied +COPY t1 (security_context, a, b) TO stdout; +unconfined_u:object_r:sepgsql_table_t:s0 1 aaa +unconfined_u:object_r:sepgsql_ro_table_t:s0 2 bbb +unconfined_u:object_r:sepgsql_table_t:s0:c1 3 ccc +unconfined_u:object_r:sepgsql_table_t:s0 4 ddd +unconfined_u:object_r:sepgsql_table_t:s0 5 eee +system_u:object_r:sepgsql_table_t:s0:c2 10 kkk +system_u:object_r:sepgsql_table_t:s0:c3 11 lll +system_u:object_r:sepgsql_table_t:s0:c4 13 nnn diff -rpNU3 base/src/test/sepgsql/launch_psql.c sepgsql-new/src/test/sepgsql/launch_psql.c --- base/src/test/sepgsql/launch_psql.c 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/launch_psql.c 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,87 @@ +/* + * launch_psql.c + * + * It invokes psql with proper security context. + */ +#include +#include +#include +#include +#include +#include + +#define SETEXECCON_CMD "--@SECURITY_CONTEXT=" + +int main(int argc, char *const argv[]) +{ + char buffer[2048], cmd[512]; + FILE *filp = NULL; + int i, ofs; + + if (argc < 2) + { + fprintf(stderr, "usage: %s [ ...]\n", argv[0]); + return 1; + } + + for (i=1, ofs=0; argv[i] != NULL; i++) + ofs += snprintf(cmd + ofs, sizeof(cmd) - ofs, " %s", argv[i]); + + while (fgets(buffer, sizeof(buffer), stdin) != NULL) + { + if (strncasecmp(buffer, SETEXECCON_CMD, + sizeof(SETEXECCON_CMD) - 1) == 0) + { + security_context_t context = buffer + sizeof(SETEXECCON_CMD) - 1; + char *pos; + + /* set exec security context */ + pos = strchr(context, '#'); + if (pos) + *pos = '\0'; + pos = context + strlen(context) - 1; + while (isspace(*pos)) + *pos-- = '\0'; + if (setexeccon(context) < 0) + { + fprintf(stderr, "%s: setexeccon('%s') = %s\n", + argv[0], context, strerror(errno)); + return 1; + } + + if (filp != NULL) + { + pclose(filp); + filp = NULL; + } + + /* Inject a pseudo sepgsql_getcon() to confirm new context */ + ofs = strlen(buffer); + snprintf(buffer + ofs, sizeof(buffer) - ofs, + "\nSELECT sepgsql_getcon();\n"); + } + + if (filp == NULL) + { + filp = popen(cmd, "w"); + if (!filp) + { + fprintf(stderr, "%s: popen('%s', 'w') = %s\n", + argv[0], cmd, strerror(errno)); + return 1; + } + } + + if (fwrite(buffer, 1, strlen(buffer), filp) < 0) + { + fprintf(stderr, "%s: fwrite(...) = %s\n", + argv[0], strerror(errno)); + return 1; + } + } + + if (filp) + pclose(filp); + + return 0; +} diff -rpNU3 base/src/test/sepgsql/sql/basic.sql sepgsql-new/src/test/sepgsql/sql/basic.sql --- base/src/test/sepgsql/sql/basic.sql 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/sql/basic.sql 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,59 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 + +-- cleanup previous tests +SET client_min_messages TO 'error'; + +DROP TABLE IF EXISTS t4 CASCADE; +DROP TABLE IF EXISTS t3 CASCADE; +DROP TABLE IF EXISTS t2 CASCADE; +DROP TABLE IF EXISTS t1 CASCADE; + +DROP FUNCTION IF EXISTS f1(int) CASCADE; + +RESET client_min_messages; + +-- SETUP + +CREATE TABLE t1 +( + a int, + b text + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_ro_table_t:s0', + c bool + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0' +); +INSERT INTO t1 VALUES (1, 'aaa', false), (2, 'bbb', true); + +CREATE TABLE t2 +( + s int, + t int, + u int +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0:c0'; +ALTER TABLE t2 DROP COLUMN t; -- disturbing factor + +CREATE TABLE t3 +( + x text + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0:c1' +) inherits(t2); + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 + +SELECT * FROM t1; -- to be denied +SELECT a, b FROM t1; +SELECT COUNT(*) FROM t1 WHERE c; -- to be denied +UPDATE t1 SET b = 'ccc'; -- to be denied +UPDATE t1 SET a = a + 2; +INSERT INTO t1 VALUES (5, 'eee', true); -- to be denied +INSERT INTO t1 VALUES (5); + +SELECT * FROM t2; +SELECT t2 FROM t2; +SELECT t3 FROM t3; -- to be denied +SELECT 1 FROM t3; + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c1 +SELECT * FROM t2; -- to be denied +SELECT t2 FROM t2; -- to be denied +SELECT t3 FROM t3; diff -rpNU3 base/src/test/sepgsql/sql/copy_stmt.sql sepgsql-new/src/test/sepgsql/sql/copy_stmt.sql --- base/src/test/sepgsql/sql/copy_stmt.sql 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/sql/copy_stmt.sql 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,58 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 + +-- cleanup previous tests +SET client_min_messages TO 'error'; + +DROP TABLE IF EXISTS t3 CASCADE; +DROP TABLE IF EXISTS t2 CASCADE; +DROP TABLE IF EXISTS t1 CASCADE; + +DROP FUNCTION IF EXISTS f1(int) CASCADE; + +RESET client_min_messages; + +-- setup tables + +CREATE TABLE t1 +( + a int, + b text +); + +INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'); + +CREATE TABLE t2 +( + x int, + y text + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0' +); +SELECT security_context from pg_attribute where attrelid = 't2'::regclass and attname = 'y'; +INSERT INTO t2 VALUES (1, 'xxx'), (2, 'yyy'); + +CREATE TABLE t3 -- read only table +( + s int, + t text +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_ro_table_t:s0'; +INSERT INTO t2 VALUES (1, 'sss'), (2, 'ttt'); + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 +COPY t1 TO stdout; +COPY t1 FROM stdin; +3 ccc +4 ddd +\. + +COPY t1 TO '/tmp/sepgsql_test_copy_1'; +COPY t1 TO '/tmp/sepgsql_test_copy_2'; -- to be denied + +COPY t2 TO stdout; -- to be denied +COPY t2 FROM stdin; -- to be denied +COPY t2 (x) TO stdout; + +COPY t3 TO stdout; +COPY t3 FROM '/tmp/sepgsql_test_copy_1'; -- to be denied + +COPY t1 FROM '/tmp/sepgsql_test_copy_1'; +COPY t1 TO stdout; diff -rpNU3 base/src/test/sepgsql/sql/enhanced_ddl_stmt.sql sepgsql-new/src/test/sepgsql/sql/enhanced_ddl_stmt.sql --- base/src/test/sepgsql/sql/enhanced_ddl_stmt.sql 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/sql/enhanced_ddl_stmt.sql 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,89 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 + +-- cleanup previous tests +SET client_min_messages TO 'error'; + +DROP TABLE IF EXISTS t4 CASCADE; +DROP TABLE IF EXISTS t3 CASCADE; +DROP TABLE IF EXISTS t2 CASCADE; +DROP TABLE IF EXISTS t1 CASCADE; + +DROP FUNCTION IF EXISTS f1(int) CASCADE; +DROP FUNCTION IF EXISTS f2(int) CASCADE; + +RESET client_min_messages; + +-- CREATE TABLE with SECURITY_LABEL clause +CREATE TABLE t1 ( + a int, + b text +); +SELECT relname, security_context FROM pg_class WHERE oid = 't1'::regclass; +SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't1'::regclass and attnum > 0; + +CREATE TABLE t2 ( + a int, + b text +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_ro_table_t:s0'; +SELECT relname, security_context FROM pg_class WHERE oid = 't2'::regclass; +SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't2'::regclass and attnum > 0; + +CREATE TABLE t3 ( + a int, + b text SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_fixed_table_t:s0', + c bool SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0', + d int +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0:c0'; +SELECT relname, security_context FROM pg_class WHERE oid = 't3'::regclass; +SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't3'::regclass and attnum > 0; + +CREATE TABLE t4 ( + a int, + b text +) SECURITY_CONTEXT = 'unconfined_u:object_r:invalid_label_t:s0'; -- to be failed + +CREATE TABLE t4 ( + a int, + b text +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0'; -- to be denied + +-- ALTER TABLE with SECURITY_CONTEXT clause +ALTER TABLE t2 SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0'; +ALTER TABLE t2 ADD COLUMN c bool; -- it inherits table's one +SELECT relname, security_context FROM pg_class WHERE oid = 't2'::regclass; +SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't2'::regclass and attnum > 0; + +ALTER TABLE t3 ALTER b SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_table_t:s0'; +SELECT relname, security_context FROM pg_class WHERE oid = 't3'::regclass; +SELECT attname, security_context FROM pg_attribute WHERE attrelid = 't3'::regclass and attnum > 0; + +-- CREATE FUNCTION with SECURITY_CONTEXT clause +CREATE FUNCTION f1 (int) RETURNS int + LANGUAGE 'sql' + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c0' + AS 'SELECT $1 * 2'; +SELECT proname, security_context FROM pg_proc WHERE oid = 'f1'::regproc; + +CREATE FUNCTION f2 (int) RETURNS int + LANGUAGE 'sql' + SECURITY_CONTEXT = 'unconfined_u:object_r:invalid_label_t:s0' + AS 'SELECT $1 + $1'; -- to be failed + +CREATE FUNCTION f2 (int) RETURNS int + LANGUAGE 'sql' + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c16' + AS 'SELECT $1 + $1'; -- to be denied + +CREATE FUNCTION f2 (int) RETURNS int + LANGUAGE 'sql' + AS 'SELECT $1 + $1'; +SELECT proname, security_context FROM pg_proc WHERE oid = 'f2'::regproc; + +-- ALTER FUNCTION with SECURITY_CONTEXT clause +ALTER FUNCTION f1(int) + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c1'; +SELECT proname, security_context FROM pg_proc WHERE oid = 'f1'::regproc; + +ALTER FUNCTION f2(int) + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_proc_t:s0:c16'; -- to be denied +SELECT proname, security_context FROM pg_proc WHERE oid = 'f2'::regproc; diff -rpNU3 base/src/test/sepgsql/sql/join_query.sql sepgsql-new/src/test/sepgsql/sql/join_query.sql --- base/src/test/sepgsql/sql/join_query.sql 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/sql/join_query.sql 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,50 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 + +-- cleanup previous tests +SET client_min_messages TO 'error'; + +DROP TABLE IF EXISTS t4 CASCADE; +DROP TABLE IF EXISTS t3 CASCADE; +DROP TABLE IF EXISTS t2 CASCADE; +DROP TABLE IF EXISTS t1 CASCADE; + +DROP FUNCTION IF EXISTS f1(int) CASCADE; + +RESET client_min_messages; + +-- SETUP +CREATE TABLE t1 +( + a int, + b text, + c int + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0' +); +INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'), (3, 'ccc'); + +CREATE TABLE t2 +( + x int, + y text +); +INSERT INTO t2 VALUES (2, 'xxx'), (3, 'yyy'), (4,'zzz'); + +CREATE TABLE t3 +( + d int +) INHERITS (t1); +INSERT INTO t3 VALUES (4, 'ddd'), (5, 'eee'); + +CREATE TABLE t4 +( + z int + SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_secret_table_t:s0' +) INHERITS (t2); +INSERT INTO t2 VALUES (1, 'sss'), (5, 'ttt'); + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 +SELECT * FROM t1 JOIN t2 ON a = x; -- to be denied +SELECT a, b, y FROM t1 JOIN t2 ON a = x; +SELECT a, b, y FROM t1 JOIN t2 ON c = x; -- to be denied +SELECT COUNT(*) FROM t1 JOIN t2 ON a = x; +SELECT j FROM (t1 JOIN t2 ON a = x) AS j; -- to be denied diff -rpNU3 base/src/test/sepgsql/sql/large_object.sql sepgsql-new/src/test/sepgsql/sql/large_object.sql --- base/src/test/sepgsql/sql/large_object.sql 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/sql/large_object.sql 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,103 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 + +-- cleanup previous tests +SET client_min_messages TO 'error'; + +DROP TABLE IF EXISTS lolabel CASCADE; +DROP FUNCTION IF EXISTS lo_label(oid) CASCADE; + +RESET client_min_messages; + +CREATE TABLE lolabel( + loid oid, + label text +); + +CREATE OR REPLACE FUNCTION lo_label(oid) + RETURNS TEXT LANGUAGE 'sql' + AS 'SELECT label FROM lolabel WHERE loid = $1'; + +INSERT INTO lolabel (SELECT lo_import('/tmp/sepgsql_test_blob1'), 'normal'); +INSERT INTO lolabel (SELECT lo_import('/tmp/sepgsql_test_blob1'), 'readonly'); +INSERT INTO lolabel (SELECT lo_import('/tmp/sepgsql_test_blob1'), 'secret'); + +SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_blob_t:s0') + FROM lolabel WHERE label = 'normal'; +SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_ro_blob_t:s0') + FROM lolabel WHERE label = 'readonly'; +SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_secret_blob_t:s0') + FROM lolabel WHERE label = 'secret'; + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0:c0 + +SELECT lo_get_security(loid) FROM lolabel; + +SELECT security_context, lo_label(loid) AS label, COUNT(*) + FROM pg_largeobject GROUP BY security_context, loid ORDER by label; + +-- read large object +BEGIN; +SELECT lo_open(loid, x'40000'::int) FROM lolabel WHERE label = 'normal'; +SELECT loread(0, 32); +ROLLBACK; + +BEGIN; +SELECT lo_open(loid, x'40000'::int) FROM lolabel WHERE label = 'readonly'; +SELECT loread(0, 32); +ROLLBACK; + +BEGIN; +SELECT lo_open(loid, x'40000'::int) FROM lolabel WHERE label = 'secret'; +SELECT loread(0, 32); -- to be denied +ROLLBACK; + +-- write large object +BEGIN; +SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'normal'; +SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); +ROLLBACK; + +BEGIN; +SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'readonly'; +SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); -- to be denied +ROLLBACK; + +BEGIN; +SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'secret'; +SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); -- to be denied +ROLLBACK; + +-- create large object +BEGIN; +INSERT INTO lolabel (SELECT lo_create(6004), 'local'); +SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'local'; +SELECT lowrite(0, 'abcdefghijklmnopqrstuvwxyz'); +SELECT lo_close(0); +COMMIT; + +-- getattr/setattr +BEGIN; +SELECT lo_open(loid, x'20000'::int) FROM lolabel WHERE label = 'local'; +SELECT lo_lseek(0, 0, 2); -- seek to end +SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); +SELECT lo_tell(0); +SELECT lo_lseek(0, 0, 0); -- seek to head +SELECT loread(0, 50); +SELECT lo_close(0); +COMMIT; + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 + +-- change security label +BEGIN; +SELECT lo_open(loid, x'40000'::int) FROM lolabel; -- a seed of trouble +SELECT lo_set_security(loid, 'system_u:object_r:sepgsql_blob_t:s0:c4') + FROM lolabel WHERE label in ('normal', 'readonly'); +SELECT lo_get_security(loid) FROM lolabel; +SELECT security_context, lo_label(loid) AS label, count(*) + FROM pg_largeobject WHERE loid in (SELECT loid FROM lolabel) + GROUP BY security_context, loid ORDER BY label; +ROLLBACK; + +-- cleanup +SELECT lo_unlink(loid) FROM lolabel; diff -rpNU3 base/src/test/sepgsql/sql/row_level.sql sepgsql-new/src/test/sepgsql/sql/row_level.sql --- base/src/test/sepgsql/sql/row_level.sql 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/sql/row_level.sql 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,61 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 + +-- cleanup previous tests +SET client_min_messages TO 'error'; + +DROP TABLE IF EXISTS t4 CASCADE; +DROP TABLE IF EXISTS t3 CASCADE; +DROP TABLE IF EXISTS t2 CASCADE; +DROP TABLE IF EXISTS t1 CASCADE; + +DROP FUNCTION IF EXISTS f1(int) CASCADE; +DROP FUNCTION IF EXISTS f2(int) CASCADE; + +RESET client_min_messages; + +-- test begins here +CREATE TABLE t1 ( + a int primary key, + b text +); + +CREATE TABLE t2 ( + x int references t1 (a) on update cascade, + y text +); + +INSERT INTO t1 (security_context, a, b) VALUES + ('system_u:object_r:sepgsql_table_t:s0', 1, 'aaa'), + ('system_u:object_r:sepgsql_table_t:s0:c0', 2, 'bbb'), + ('system_u:object_r:sepgsql_table_t:s0:c1', 3, 'ccc'), + ('system_u:object_r:sepgsql_ro_table_t:s0', 4, 'ddd'), + ('system_u:object_r:sepgsql_ro_table_t:s0:c0', 5, 'eee'), + ('system_u:object_r:sepgsql_ro_table_t:s0:c1', 6, 'fff'); + +INSERT INTO t2 (security_context, x, y) VALUES + ('system_u:object_r:sepgsql_table_t:s0:c1', 1, 'xxx'), + ('system_u:object_r:sepgsql_table_t:s0:c0', 2, 'yyy'), + ('system_u:object_r:sepgsql_table_t:s0', 3, 'zzz'); + +SELECT security_context, * FROM t1; +SELECT security_context, * FROM t2; + +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:sepgsql_test_t:s0:c0 +SELECT security_context, * FROM t1; +SELECT security_context, * FROM t2; + +COPY t1 TO stdout; +COPY t2 (security_context, x, y) TO stdout; + +UPDATE t1 SET a = 99 WHERE a = 1 RETURNING *; -- to be failed +UPDATE t1 SET a = 99 WHERE a = 2 RETURNING *; +UPDATE t1 SET a = 99 WHERE a = 4 RETURNING *; -- to be denied + +INSERT INTO t1 VALUES (3, 'ccc'); -- to be failed +INSERT INTO t1 VALUES (7, 'ggg'); +INSERT INTO t2 VALUES (3, 'XXX'); -- to be failed +INSERT INTO t2 VALUES (4, 'XXX'); + +DELETE FROM t1; -- to be failed +DELETE FROM t1 WHERE a not in (SELECT x FROM t2); -- to be failed +DELETE FROM t1 WHERE a = 7; diff -rpNU3 base/src/test/sepgsql/sql/security_label.sql sepgsql-new/src/test/sepgsql/sql/security_label.sql --- base/src/test/sepgsql/sql/security_label.sql 1970-01-01 09:00:00.000000000 +0900 +++ sepgsql-new/src/test/sepgsql/sql/security_label.sql 2009-03-15 17:38:39.000000000 +0900 @@ -0,0 +1,60 @@ +--@SECURITY_CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 + +-- cleanup previous tests +SET client_min_messages TO 'error'; + +DROP TABLE IF EXISTS t4 CASCADE; +DROP TABLE IF EXISTS t3 CASCADE; +DROP TABLE IF EXISTS t2 CASCADE; +DROP TABLE IF EXISTS t1 CASCADE; + +DROP FUNCTION IF EXISTS f1(int) CASCADE; +DROP FUNCTION IF EXISTS f2(int) CASCADE; + +RESET client_min_messages; + +-- test begins here +CREATE TABLE t1 ( + a int, + b text +); + +CREATE TABLE t2 ( + x int, + y text +); + +CREATE TABLE t3 ( + s int, + t text +) SECURITY_CONTEXT = 'unconfined_u:object_r:sepgsql_fixed_table_t:s0'; + +INSERT INTO t1 VALUES (1, 'aaa'); +INSERT INTO t1 (security_context, a, b) VALUES ('unconfined_u:object_r:sepgsql_ro_table_t:s0', 2, 'bbb'); +INSERT INTO t1 (security_context, a, b) VALUES ('unconfined_u:object_r:sepgsql_table_t:s0:c1', 3, 'ccc'); +INSERT INTO t1 VALUES (4, 'ddd'), (5, 'eee'); +INSERT INTO t1 (security_context, a, b) VALUES ('invalid security context', 6, 'fff'); -- to be failed +INSERT INTO t1 (security_context, a, b) VALUES ('system_u:object_r:sepgsql_table_t:s0:c20', 6, 'fff'); -- to be denied +SELECT security_context, * FROM t1; + +INSERT INTO t2 (security_context, x, y) + (SELECT sepgsql_set_user(security_context, 'system_u'), a + 5, b || '_cpy' FROM t1); +SELECT security_context, * FROM t2; + +INSERT INTO t3 VALUES (98, 'xxx'); +INSERT INTO t3 (security_context, s, t) VALUES ('system_u:object_r:sepgsql_ro_table_t:s0', 99, 'yyy'); +INSERT INTO t3 (SELECT * FROM t1); +INSERT INTO t3 (security_context, s, t) (SELECT security_context, x, y FROM t2); +SELECT security_context, * FROM t3; + +SELECT sepgsql_set_range(security_context, 's0:c' || s) AS security_context, * INTO t4 FROM t3; -- partially denied +SELECT security_context, * FROM t4; + +COPY t1 (security_context, a, b) FROM stdin; -- partially denied +system_u:object_r:sepgsql_table_t:s0:c2 10 kkk +system_u:object_r:sepgsql_table_t:s0:c3 11 lll +system_u:object_r:sepgsql_table_t:s0:c20 12 mmm +system_u:object_r:sepgsql_table_t:s0:c4 13 nnn +\. + +COPY t1 (security_context, a, b) TO stdout;