diff -Nrpc base/src/test/regress/expected/rowacl.out sepgsql/src/test/regress/expected/rowacl.out *** base/src/test/regress/expected/rowacl.out Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/regress/expected/rowacl.out Mon Dec 29 19:11:24 2008 *************** *** 0 **** --- 1,544 ---- + -- + -- Testcases for Row-level Database ACLs + -- + SET client_min_messages TO 'error'; + DROP TABLE IF EXISTS ratbl_f CASCADE; + DROP TABLE IF EXISTS ratbl_p CASCADE; + DROP ROLE IF EXISTS rausr_o; + DROP ROLE IF EXISTS rausr_x; + DROP ROLE IF EXISTS rausr_y; + RESET client_min_messages; + -- initial setup + CREATE USER rausr_o; -- owner + CREATE USER rausr_x; + CREATE USER rausr_y; + SET SESSION AUTHORIZATION rausr_o; + CREATE TABLE ratbl_p + ( + a int primary key, + b text + ) WITH (row_level_acl=on); + NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "ratbl_p_pkey" for table "ratbl_p" + GRANT all ON ratbl_p TO public; + CREATE TABLE ratbl_f + ( + x int references ratbl_p(a) + ON DELETE SET NULL, + y text + ) WITH (row_level_acl=on); + GRANT all ON ratbl_f TO public; + INSERT INTO ratbl_p VALUES (1, 'aaa'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=r/rausr_o}', 2, 'bbb'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=rw/rausr_o}', 3, 'ccc'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=rd/rausr_o}', 4, 'ddd'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=rx/rausr_o}', 5, 'eee'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=x/rausr_o}', 6, 'fff'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=wx/rausr_o}', 7, 'ggg'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=dx/rausr_o}', 8, 'hhh'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=r/rausr_o}', 9, 'BBB'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=rw/rausr_o}', 10, 'CCC'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=rd/rausr_o}', 11, 'DDD'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=rx/rausr_o}', 12, 'EEE'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=x/rausr_o}', 13, 'FFF'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=wx/rausr_o}', 14, 'GGG'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=dx/rausr_o}', 15, 'HHH'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=rw/rausr_o,rausr_y=rd/rausr_o}', 20, 'xxx'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=rd/rausr_o,rausr_y=rw/rausr_o}', 21, 'yyy'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=r/rausr_o,rausr_y=r/rausr_o}', 22, 'zzz'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES (NULL, 30, 'xxx'); -- to be failed + ERROR: setting NULL on "security_acl" system column is not supported + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{invalid acl}', 30, 'xxx'); -- to be failed + ERROR: unrecognized key word: "invalid" + LINE 2: VALUES ('{invalid acl}', 30, 'xxx'); + ^ + HINT: ACL key word must be "group" or "user". + -- it allows owner to see all tuples + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+----+----- + {=rwdx/rausr_o} | 1 | aaa + {rausr_x=r/rausr_o} | 2 | bbb + {rausr_x=rw/rausr_o} | 3 | ccc + {rausr_x=rd/rausr_o} | 4 | ddd + {rausr_x=rx/rausr_o} | 5 | eee + {rausr_x=x/rausr_o} | 6 | fff + {rausr_x=wx/rausr_o} | 7 | ggg + {rausr_x=dx/rausr_o} | 8 | hhh + {rausr_y=r/rausr_o} | 9 | BBB + {rausr_y=rw/rausr_o} | 10 | CCC + {rausr_y=rd/rausr_o} | 11 | DDD + {rausr_y=rx/rausr_o} | 12 | EEE + {rausr_y=x/rausr_o} | 13 | FFF + {rausr_y=wx/rausr_o} | 14 | GGG + {rausr_y=dx/rausr_o} | 15 | HHH + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz + (18 rows) + + BEGIN; + UPDATE ratbl_p SET b = b || '_updt' RETURNING security_acl, *; + security_acl | a | b + -----------------------------------------+----+---------- + {=rwdx/rausr_o} | 1 | aaa_updt + {rausr_x=r/rausr_o} | 2 | bbb_updt + {rausr_x=rw/rausr_o} | 3 | ccc_updt + {rausr_x=rd/rausr_o} | 4 | ddd_updt + {rausr_x=rx/rausr_o} | 5 | eee_updt + {rausr_x=x/rausr_o} | 6 | fff_updt + {rausr_x=wx/rausr_o} | 7 | ggg_updt + {rausr_x=dx/rausr_o} | 8 | hhh_updt + {rausr_y=r/rausr_o} | 9 | BBB_updt + {rausr_y=rw/rausr_o} | 10 | CCC_updt + {rausr_y=rd/rausr_o} | 11 | DDD_updt + {rausr_y=rx/rausr_o} | 12 | EEE_updt + {rausr_y=x/rausr_o} | 13 | FFF_updt + {rausr_y=wx/rausr_o} | 14 | GGG_updt + {rausr_y=dx/rausr_o} | 15 | HHH_updt + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx_updt + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy_updt + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz_updt + (18 rows) + + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+----+---------- + {=rwdx/rausr_o} | 1 | aaa_updt + {rausr_x=r/rausr_o} | 2 | bbb_updt + {rausr_x=rw/rausr_o} | 3 | ccc_updt + {rausr_x=rd/rausr_o} | 4 | ddd_updt + {rausr_x=rx/rausr_o} | 5 | eee_updt + {rausr_x=x/rausr_o} | 6 | fff_updt + {rausr_x=wx/rausr_o} | 7 | ggg_updt + {rausr_x=dx/rausr_o} | 8 | hhh_updt + {rausr_y=r/rausr_o} | 9 | BBB_updt + {rausr_y=rw/rausr_o} | 10 | CCC_updt + {rausr_y=rd/rausr_o} | 11 | DDD_updt + {rausr_y=rx/rausr_o} | 12 | EEE_updt + {rausr_y=x/rausr_o} | 13 | FFF_updt + {rausr_y=wx/rausr_o} | 14 | GGG_updt + {rausr_y=dx/rausr_o} | 15 | HHH_updt + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx_updt + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy_updt + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz_updt + (18 rows) + + ABORT; + BEGIN; + DELETE FROM ratbl_p RETURNING security_acl, *; + security_acl | a | b + -----------------------------------------+----+----- + {=rwdx/rausr_o} | 1 | aaa + {rausr_x=r/rausr_o} | 2 | bbb + {rausr_x=rw/rausr_o} | 3 | ccc + {rausr_x=rd/rausr_o} | 4 | ddd + {rausr_x=rx/rausr_o} | 5 | eee + {rausr_x=x/rausr_o} | 6 | fff + {rausr_x=wx/rausr_o} | 7 | ggg + {rausr_x=dx/rausr_o} | 8 | hhh + {rausr_y=r/rausr_o} | 9 | BBB + {rausr_y=rw/rausr_o} | 10 | CCC + {rausr_y=rd/rausr_o} | 11 | DDD + {rausr_y=rx/rausr_o} | 12 | EEE + {rausr_y=x/rausr_o} | 13 | FFF + {rausr_y=wx/rausr_o} | 14 | GGG + {rausr_y=dx/rausr_o} | 15 | HHH + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz + (18 rows) + + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + --------------+---+--- + (0 rows) + + ABORT; + -- switch to superuser + \c - + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+----+----- + {=rwdx/rausr_o} | 1 | aaa + {rausr_x=r/rausr_o} | 2 | bbb + {rausr_x=rw/rausr_o} | 3 | ccc + {rausr_x=rd/rausr_o} | 4 | ddd + {rausr_x=rx/rausr_o} | 5 | eee + {rausr_x=x/rausr_o} | 6 | fff + {rausr_x=wx/rausr_o} | 7 | ggg + {rausr_x=dx/rausr_o} | 8 | hhh + {rausr_y=r/rausr_o} | 9 | BBB + {rausr_y=rw/rausr_o} | 10 | CCC + {rausr_y=rd/rausr_o} | 11 | DDD + {rausr_y=rx/rausr_o} | 12 | EEE + {rausr_y=x/rausr_o} | 13 | FFF + {rausr_y=wx/rausr_o} | 14 | GGG + {rausr_y=dx/rausr_o} | 15 | HHH + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz + (18 rows) + + BEGIN; + UPDATE ratbl_p SET b = b || '_updt' RETURNING security_acl, *; + security_acl | a | b + -----------------------------------------+----+---------- + {=rwdx/rausr_o} | 1 | aaa_updt + {rausr_x=r/rausr_o} | 2 | bbb_updt + {rausr_x=rw/rausr_o} | 3 | ccc_updt + {rausr_x=rd/rausr_o} | 4 | ddd_updt + {rausr_x=rx/rausr_o} | 5 | eee_updt + {rausr_x=x/rausr_o} | 6 | fff_updt + {rausr_x=wx/rausr_o} | 7 | ggg_updt + {rausr_x=dx/rausr_o} | 8 | hhh_updt + {rausr_y=r/rausr_o} | 9 | BBB_updt + {rausr_y=rw/rausr_o} | 10 | CCC_updt + {rausr_y=rd/rausr_o} | 11 | DDD_updt + {rausr_y=rx/rausr_o} | 12 | EEE_updt + {rausr_y=x/rausr_o} | 13 | FFF_updt + {rausr_y=wx/rausr_o} | 14 | GGG_updt + {rausr_y=dx/rausr_o} | 15 | HHH_updt + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx_updt + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy_updt + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz_updt + (18 rows) + + ABORT; + BEGIN; + DELETE FROM ratbl_p RETURNING security_acl, *; + security_acl | a | b + -----------------------------------------+----+----- + {=rwdx/rausr_o} | 1 | aaa + {rausr_x=r/rausr_o} | 2 | bbb + {rausr_x=rw/rausr_o} | 3 | ccc + {rausr_x=rd/rausr_o} | 4 | ddd + {rausr_x=rx/rausr_o} | 5 | eee + {rausr_x=x/rausr_o} | 6 | fff + {rausr_x=wx/rausr_o} | 7 | ggg + {rausr_x=dx/rausr_o} | 8 | hhh + {rausr_y=r/rausr_o} | 9 | BBB + {rausr_y=rw/rausr_o} | 10 | CCC + {rausr_y=rd/rausr_o} | 11 | DDD + {rausr_y=rx/rausr_o} | 12 | EEE + {rausr_y=x/rausr_o} | 13 | FFF + {rausr_y=wx/rausr_o} | 14 | GGG + {rausr_y=dx/rausr_o} | 15 | HHH + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz + (18 rows) + + ABORT; + -- switch to rausr_x + SET SESSION AUTHORIZATION rausr_x; + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+----+----- + {=rwdx/rausr_o} | 1 | aaa + {rausr_x=r/rausr_o} | 2 | bbb + {rausr_x=rw/rausr_o} | 3 | ccc + {rausr_x=rd/rausr_o} | 4 | ddd + {rausr_x=rx/rausr_o} | 5 | eee + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz + (8 rows) + + BEGIN; + UPDATE ratbl_p SET b = b || '_updt' RETURNING security_acl, *; + security_acl | a | b + -----------------------------------------+----+---------- + {=rwdx/rausr_o} | 1 | aaa_updt + {rausr_x=rw/rausr_o} | 3 | ccc_updt + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx_updt + (3 rows) + + UPDATE ratbl_p SET b = b || '_updt'; + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+----+--------------- + {rausr_x=r/rausr_o} | 2 | bbb + {rausr_x=rd/rausr_o} | 4 | ddd + {rausr_x=rx/rausr_o} | 5 | eee + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz + {=rwdx/rausr_o} | 1 | aaa_updt_updt + {rausr_x=rw/rausr_o} | 3 | ccc_updt_updt + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx_updt_updt + (8 rows) + + ABORT; + BEGIN; + DELETE FROM ratbl_p RETURNING security_acl, *; + security_acl | a | b + -----------------------------------------+----+----- + {=rwdx/rausr_o} | 1 | aaa + {rausr_x=rd/rausr_o} | 4 | ddd + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy + (3 rows) + + DELETE FROM ratbl_p; + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+----+----- + {rausr_x=r/rausr_o} | 2 | bbb + {rausr_x=rw/rausr_o} | 3 | ccc + {rausr_x=rx/rausr_o} | 5 | eee + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz + (5 rows) + + ABORT; + \c - + -- switch to rausr_y + SET SESSION AUTHORIZATION rausr_y; + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+----+----- + {=rwdx/rausr_o} | 1 | aaa + {rausr_y=r/rausr_o} | 9 | BBB + {rausr_y=rw/rausr_o} | 10 | CCC + {rausr_y=rd/rausr_o} | 11 | DDD + {rausr_y=rx/rausr_o} | 12 | EEE + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz + (8 rows) + + BEGIN; + UPDATE ratbl_p SET b = b || '_updt' RETURNING security_acl, *; + security_acl | a | b + -----------------------------------------+----+---------- + {=rwdx/rausr_o} | 1 | aaa_updt + {rausr_y=rw/rausr_o} | 10 | CCC_updt + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy_updt + (3 rows) + + UPDATE ratbl_p SET b = b || '_updt'; + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+----+--------------- + {rausr_y=r/rausr_o} | 9 | BBB + {rausr_y=rd/rausr_o} | 11 | DDD + {rausr_y=rx/rausr_o} | 12 | EEE + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz + {=rwdx/rausr_o} | 1 | aaa_updt_updt + {rausr_y=rw/rausr_o} | 10 | CCC_updt_updt + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy_updt_updt + (8 rows) + + ABORT; + BEGIN; + DELETE FROM ratbl_p RETURNING *; + a | b + ----+----- + 1 | aaa + 11 | DDD + 20 | xxx + (3 rows) + + DELETE FROM ratbl_p; + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+----+----- + {rausr_y=r/rausr_o} | 9 | BBB + {rausr_y=rw/rausr_o} | 10 | CCC + {rausr_y=rx/rausr_o} | 12 | EEE + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz + (5 rows) + + ABORT; + \c - + -- switch to rausr_x again (For FK/PK testing) + SET SESSION AUTHORIZATION rausr_x; + INSERT INTO ratbl_p VALUES(6, 'fff'); -- to be failed + ERROR: duplicate key value violates unique constraint "ratbl_p_pkey" + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{=r/rausr_x}', 30, 'xxx'); -- to be failed + ERROR: Only owner or superuser can set ACL + INSERT INTO ratbl_f VALUES ( 1, 'red'); + INSERT INTO ratbl_f VALUES ( 2, 'blue'); -- to be failed + ERROR: insert or update on table "ratbl_f" violates foreign key constraint "ratbl_f_x_fkey" + DETAIL: Key (x)=(2) is not present in table "ratbl_p". + INSERT INTO ratbl_f VALUES ( 5, 'green'); + INSERT INTO ratbl_f VALUES ( 6, 'yellow'); + INSERT INTO ratbl_f VALUES ( 7, 'orange'); + INSERT INTO ratbl_f VALUES ( 8, 'pink'); + INSERT INTO ratbl_f VALUES (10, 'white'); -- to be failed + ERROR: insert or update on table "ratbl_f" violates foreign key constraint "ratbl_f_x_fkey" + DETAIL: Key (x)=(10) is not present in table "ratbl_p". + INSERT INTO ratbl_f VALUES (12, 'black'); -- to be failed + ERROR: insert or update on table "ratbl_f" violates foreign key constraint "ratbl_f_x_fkey" + DETAIL: Key (x)=(12) is not present in table "ratbl_p". + SELECT security_acl, * FROM ratbl_f; + security_acl | x | y + -----------------+---+-------- + {=rwdx/rausr_o} | 1 | red + {=rwdx/rausr_o} | 5 | green + {=rwdx/rausr_o} | 6 | yellow + {=rwdx/rausr_o} | 7 | orange + {=rwdx/rausr_o} | 8 | pink + (5 rows) + + \c - + -- switch to rausr_o again + SET SESSION AUTHORIZATION rausr_o; + UPDATE ratbl_f SET security_acl = '{rausr_x=r/rausr_o}' WHERE x = 5; + UPDATE ratbl_f SET security_acl = '{rausr_x=x/rausr_o}' WHERE x = 6; + UPDATE ratbl_f SET security_acl = '{rausr_x=w/rausr_o}' WHERE x = 7; + UPDATE ratbl_f SET security_acl = '{rausr_x=d/rausr_o}' WHERE x = 8; + \c - + -- switch to rausr_x again + SET SESSION AUTHORIZATION rausr_x; + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+----+----- + {=rwdx/rausr_o} | 1 | aaa + {rausr_x=r/rausr_o} | 2 | bbb + {rausr_x=rw/rausr_o} | 3 | ccc + {rausr_x=rd/rausr_o} | 4 | ddd + {rausr_x=rx/rausr_o} | 5 | eee + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz + (8 rows) + + SELECT security_acl, * FROM ratbl_f; + security_acl | x | y + ---------------------+---+------- + {=rwdx/rausr_o} | 1 | red + {rausr_x=r/rausr_o} | 5 | green + (2 rows) + + UPDATE ratbl_p SET a = 300 WHERE a = 3; + UPDATE ratbl_p SET a = 700 WHERE a = 7; -- to be failed + ERROR: access violation in row-level acl + CONTEXT: SQL statement "SELECT 1 FROM ONLY "public"."ratbl_f" x WHERE $1 OPERATOR(pg_catalog.=) "x" FOR SHARE OF x" + DELETE FROM ratbl_p WHERE a = 4; + DELETE FROM ratbl_p WHERE a = 8; -- to be failed + ERROR: access violation in row-level acl + CONTEXT: SQL statement "UPDATE ONLY "public"."ratbl_f" SET "x" = NULL WHERE $1 OPERATOR(pg_catalog.=) "x"" + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+-----+----- + {=rwdx/rausr_o} | 1 | aaa + {rausr_x=r/rausr_o} | 2 | bbb + {rausr_x=rx/rausr_o} | 5 | eee + {rausr_x=rw/rausr_o,rausr_y=rd/rausr_o} | 20 | xxx + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 21 | yyy + {rausr_x=r/rausr_o,rausr_y=r/rausr_o} | 22 | zzz + {rausr_x=rw/rausr_o} | 300 | ccc + (7 rows) + + \c - + -- switch to rausr_o again (TABLE Option related) + SET SESSION AUTHORIZATION rausr_o; + DELETE FROM ratbl_p WHERE a > 8; + ALTER TABLE ratbl_p SET (row_level_acl=off); + INSERT INTO ratbl_p VALUES (40, 'foo'); + INSERT INTO ratbl_p VALUES (41, 'var'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=rx/rausr_o}', 42, 'baz'); -- to be failed + ERROR: Row-level ACLs are unavailable for relation: ratbl_p + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------+----+----- + {=rwdx/rausr_o} | 1 | aaa + {=rwdx/rausr_o} | 2 | bbb + {=rwdx/rausr_o} | 5 | eee + {=rwdx/rausr_o} | 6 | fff + {=rwdx/rausr_o} | 7 | ggg + {=rwdx/rausr_o} | 8 | hhh + {=rwdx/rausr_o} | 40 | foo + {=rwdx/rausr_o} | 41 | var + (8 rows) + + ALTER TABLE ratbl_p SET (row_level_acl=on); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=rx/rausr_o}', 42, 'baz'); + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + ----------------------+----+----- + {=rwdx/rausr_o} | 1 | aaa + {rausr_x=r/rausr_o} | 2 | bbb + {rausr_x=rx/rausr_o} | 5 | eee + {rausr_x=x/rausr_o} | 6 | fff + {rausr_x=wx/rausr_o} | 7 | ggg + {rausr_x=dx/rausr_o} | 8 | hhh + {=rwdx/rausr_o} | 40 | foo + {=rwdx/rausr_o} | 41 | var + {rausr_y=rx/rausr_o} | 42 | baz + (9 rows) + + ALTER TABLE ratbl_p SET (default_row_acl='{rausr_x=rd/rausr_o,rausr_y=rw/rausr_o}'); + INSERT INTO ratbl_p VALUES (50, 'coffee'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=r/rausr_o}', 51, 'juice'); + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+----+-------- + {=rwdx/rausr_o} | 1 | aaa + {rausr_x=r/rausr_o} | 2 | bbb + {rausr_x=rx/rausr_o} | 5 | eee + {rausr_x=x/rausr_o} | 6 | fff + {rausr_x=wx/rausr_o} | 7 | ggg + {rausr_x=dx/rausr_o} | 8 | hhh + {=rwdx/rausr_o} | 40 | foo + {=rwdx/rausr_o} | 41 | var + {rausr_y=rx/rausr_o} | 42 | baz + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 50 | coffee + {rausr_x=r/rausr_o} | 51 | juice + (11 rows) + + ALTER TABLE ratbl_p RESET (default_row_acl); + INSERT INTO ratbl_p VALUES (52, 'coke'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=rwd/rausr_o}', 53, 'red tea'); -- to be failed + SELECT security_acl, * FROM ratbl_p; + security_acl | a | b + -----------------------------------------+----+--------- + {=rwdx/rausr_o} | 1 | aaa + {rausr_x=r/rausr_o} | 2 | bbb + {rausr_x=rx/rausr_o} | 5 | eee + {rausr_x=x/rausr_o} | 6 | fff + {rausr_x=wx/rausr_o} | 7 | ggg + {rausr_x=dx/rausr_o} | 8 | hhh + {=rwdx/rausr_o} | 40 | foo + {=rwdx/rausr_o} | 41 | var + {rausr_y=rx/rausr_o} | 42 | baz + {rausr_x=rd/rausr_o,rausr_y=rw/rausr_o} | 50 | coffee + {rausr_x=r/rausr_o} | 51 | juice + {=rwdx/rausr_o} | 52 | coke + {rausr_x=rwd/rausr_o} | 53 | red tea + (13 rows) + + \c - + -- cleanups + SET client_min_messages TO 'error'; + DROP TABLE IF EXISTS ratbl_f CASCADE; + DROP TABLE IF EXISTS ratbl_p CASCADE; + DROP ROLE IF EXISTS rausr_o; + DROP ROLE IF EXISTS rausr_x; + DROP ROLE IF EXISTS rausr_y; + RESET client_min_messages; diff -Nrpc base/src/test/regress/expected/sanity_check.out sepgsql/src/test/regress/expected/sanity_check.out *** base/src/test/regress/expected/sanity_check.out Wed Dec 24 11:45:25 2008 --- sepgsql/src/test/regress/expected/sanity_check.out Wed Dec 24 12:18:39 2008 *************** SELECT relname, relhasindex *** 113,118 **** --- 113,119 ---- pg_pltemplate | t pg_proc | t pg_rewrite | t + pg_security | t pg_shdepend | t pg_shdescription | t pg_statistic | t *************** SELECT relname, relhasindex *** 152,158 **** timetz_tbl | f tinterval_tbl | f varchar_tbl | f ! (141 rows) -- -- another sanity check: every system catalog that has OIDs should have --- 153,159 ---- timetz_tbl | f tinterval_tbl | f varchar_tbl | f ! (142 rows) -- -- another sanity check: every system catalog that has OIDs should have diff -Nrpc base/src/test/regress/parallel_schedule sepgsql/src/test/regress/parallel_schedule *** base/src/test/regress/parallel_schedule Sat Jan 3 13:01:35 2009 --- sepgsql/src/test/regress/parallel_schedule Sat Jan 3 15:58:18 2009 *************** ignore: random *** 71,77 **** # ---------- test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace prepared_xacts delete ! test: privileges test: misc # ---------- --- 71,77 ---- # ---------- test: select_into select_distinct select_distinct_on select_implicit select_having subselect union case join aggregates transactions random portals arrays btree_index hash_index update namespace prepared_xacts delete ! test: privileges rowacl test: misc # ---------- diff -Nrpc base/src/test/regress/sql/rowacl.sql sepgsql/src/test/regress/sql/rowacl.sql *** base/src/test/regress/sql/rowacl.sql Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/regress/sql/rowacl.sql Mon Dec 29 19:11:24 2008 *************** *** 0 **** --- 1,234 ---- + -- + -- Testcases for Row-level Database ACLs + -- + + SET client_min_messages TO 'error'; + + DROP TABLE IF EXISTS ratbl_f CASCADE; + DROP TABLE IF EXISTS ratbl_p CASCADE; + + DROP ROLE IF EXISTS rausr_o; + DROP ROLE IF EXISTS rausr_x; + DROP ROLE IF EXISTS rausr_y; + + RESET client_min_messages; + + -- initial setup + CREATE USER rausr_o; -- owner + CREATE USER rausr_x; + CREATE USER rausr_y; + + SET SESSION AUTHORIZATION rausr_o; + + CREATE TABLE ratbl_p + ( + a int primary key, + b text + ) WITH (row_level_acl=on); + GRANT all ON ratbl_p TO public; + + CREATE TABLE ratbl_f + ( + x int references ratbl_p(a) + ON DELETE SET NULL, + y text + ) WITH (row_level_acl=on); + GRANT all ON ratbl_f TO public; + + INSERT INTO ratbl_p VALUES (1, 'aaa'); + + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=r/rausr_o}', 2, 'bbb'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=rw/rausr_o}', 3, 'ccc'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=rd/rausr_o}', 4, 'ddd'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=rx/rausr_o}', 5, 'eee'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=x/rausr_o}', 6, 'fff'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=wx/rausr_o}', 7, 'ggg'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=dx/rausr_o}', 8, 'hhh'); + + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=r/rausr_o}', 9, 'BBB'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=rw/rausr_o}', 10, 'CCC'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=rd/rausr_o}', 11, 'DDD'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=rx/rausr_o}', 12, 'EEE'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=x/rausr_o}', 13, 'FFF'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=wx/rausr_o}', 14, 'GGG'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=dx/rausr_o}', 15, 'HHH'); + + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=rw/rausr_o,rausr_y=rd/rausr_o}', 20, 'xxx'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=rd/rausr_o,rausr_y=rw/rausr_o}', 21, 'yyy'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=r/rausr_o,rausr_y=r/rausr_o}', 22, 'zzz'); + + INSERT INTO ratbl_p (security_acl, a, b) + VALUES (NULL, 30, 'xxx'); -- to be failed + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{invalid acl}', 30, 'xxx'); -- to be failed + + -- it allows owner to see all tuples + SELECT security_acl, * FROM ratbl_p; + + BEGIN; + UPDATE ratbl_p SET b = b || '_updt' RETURNING security_acl, *; + SELECT security_acl, * FROM ratbl_p; + ABORT; + + BEGIN; + DELETE FROM ratbl_p RETURNING security_acl, *; + SELECT security_acl, * FROM ratbl_p; + ABORT; + + -- switch to superuser + \c - + + SELECT security_acl, * FROM ratbl_p; + + BEGIN; + UPDATE ratbl_p SET b = b || '_updt' RETURNING security_acl, *; + ABORT; + + BEGIN; + DELETE FROM ratbl_p RETURNING security_acl, *; + ABORT; + + -- switch to rausr_x + SET SESSION AUTHORIZATION rausr_x; + + SELECT security_acl, * FROM ratbl_p; + + BEGIN; + UPDATE ratbl_p SET b = b || '_updt' RETURNING security_acl, *; + UPDATE ratbl_p SET b = b || '_updt'; + SELECT security_acl, * FROM ratbl_p; + ABORT; + + BEGIN; + DELETE FROM ratbl_p RETURNING security_acl, *; + DELETE FROM ratbl_p; + SELECT security_acl, * FROM ratbl_p; + ABORT; + + \c - + -- switch to rausr_y + SET SESSION AUTHORIZATION rausr_y; + + SELECT security_acl, * FROM ratbl_p; + + BEGIN; + UPDATE ratbl_p SET b = b || '_updt' RETURNING security_acl, *; + UPDATE ratbl_p SET b = b || '_updt'; + SELECT security_acl, * FROM ratbl_p; + ABORT; + + BEGIN; + DELETE FROM ratbl_p RETURNING *; + DELETE FROM ratbl_p; + SELECT security_acl, * FROM ratbl_p; + ABORT; + + \c - + -- switch to rausr_x again (For FK/PK testing) + SET SESSION AUTHORIZATION rausr_x; + + INSERT INTO ratbl_p VALUES(6, 'fff'); -- to be failed + + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{=r/rausr_x}', 30, 'xxx'); -- to be failed + + INSERT INTO ratbl_f VALUES ( 1, 'red'); + INSERT INTO ratbl_f VALUES ( 2, 'blue'); -- to be failed + INSERT INTO ratbl_f VALUES ( 5, 'green'); + INSERT INTO ratbl_f VALUES ( 6, 'yellow'); + INSERT INTO ratbl_f VALUES ( 7, 'orange'); + INSERT INTO ratbl_f VALUES ( 8, 'pink'); + INSERT INTO ratbl_f VALUES (10, 'white'); -- to be failed + INSERT INTO ratbl_f VALUES (12, 'black'); -- to be failed + + SELECT security_acl, * FROM ratbl_f; + + \c - + -- switch to rausr_o again + SET SESSION AUTHORIZATION rausr_o; + + UPDATE ratbl_f SET security_acl = '{rausr_x=r/rausr_o}' WHERE x = 5; + UPDATE ratbl_f SET security_acl = '{rausr_x=x/rausr_o}' WHERE x = 6; + UPDATE ratbl_f SET security_acl = '{rausr_x=w/rausr_o}' WHERE x = 7; + UPDATE ratbl_f SET security_acl = '{rausr_x=d/rausr_o}' WHERE x = 8; + + \c - + -- switch to rausr_x again + SET SESSION AUTHORIZATION rausr_x; + + SELECT security_acl, * FROM ratbl_p; + SELECT security_acl, * FROM ratbl_f; + + UPDATE ratbl_p SET a = 300 WHERE a = 3; + UPDATE ratbl_p SET a = 700 WHERE a = 7; -- to be failed + + DELETE FROM ratbl_p WHERE a = 4; + DELETE FROM ratbl_p WHERE a = 8; -- to be failed + + SELECT security_acl, * FROM ratbl_p; + + \c - + -- switch to rausr_o again (TABLE Option related) + SET SESSION AUTHORIZATION rausr_o; + + DELETE FROM ratbl_p WHERE a > 8; + + ALTER TABLE ratbl_p SET (row_level_acl=off); + + INSERT INTO ratbl_p VALUES (40, 'foo'); + INSERT INTO ratbl_p VALUES (41, 'var'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=rx/rausr_o}', 42, 'baz'); -- to be failed + + SELECT security_acl, * FROM ratbl_p; + + ALTER TABLE ratbl_p SET (row_level_acl=on); + + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_y=rx/rausr_o}', 42, 'baz'); + + SELECT security_acl, * FROM ratbl_p; + + ALTER TABLE ratbl_p SET (default_row_acl='{rausr_x=rd/rausr_o,rausr_y=rw/rausr_o}'); + + INSERT INTO ratbl_p VALUES (50, 'coffee'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=r/rausr_o}', 51, 'juice'); + SELECT security_acl, * FROM ratbl_p; + + ALTER TABLE ratbl_p RESET (default_row_acl); + + INSERT INTO ratbl_p VALUES (52, 'coke'); + INSERT INTO ratbl_p (security_acl, a, b) + VALUES ('{rausr_x=rwd/rausr_o}', 53, 'red tea'); -- to be failed + SELECT security_acl, * FROM ratbl_p; + + \c - + -- cleanups + SET client_min_messages TO 'error'; + + DROP TABLE IF EXISTS ratbl_f CASCADE; + DROP TABLE IF EXISTS ratbl_p CASCADE; + + DROP ROLE IF EXISTS rausr_o; + DROP ROLE IF EXISTS rausr_x; + DROP ROLE IF EXISTS rausr_y; + + RESET client_min_messages; diff -Nrpc base/src/test/sepgsql/Makefile sepgsql/src/test/sepgsql/Makefile *** base/src/test/sepgsql/Makefile Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/Makefile Thu Dec 25 20:24:25 2008 *************** *** 0 **** --- 1,51 ---- + PSQL := $(shell which psql) + RUNCON := $(shell which runcon) + DBNAME := test + + RUN_DBA = $(RUNCON) unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 $(PSQL) -aq $(DBNAME) + RUN_USER = $(RUNCON) unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 $(PSQL) -aq $(DBNAME) + + TESTCASES = $(notdir $(wildcard sql/*.sql)) + + test: clean run_test + + clean: + @rm -f results/*.out results/*.diff + + run_test: environment filesystem $(TESTCASES:.sql=.test) + + %.test: sql/%.sql + @touch results/$*.out + @test -r sql/$*.init && $(RUN_DBA) -f sql/$*.init >> results/$*.out 2>&1 || : + @$(RUN_USER) -f sql/$*.sql >> results/$*.out 2>&1 || : + @test -r sql/$*.fini && $(RUN_DBA) -f sql/$*.fini >> results/$*.out 2>&1 || : + @diff -u expected/$*.out results/$*.out > results/$*.diff 2>/dev/null && echo -n "PASS: " || echo -n "FAIL: " + @echo $@ + + filesystem: + @test -e /tmp/sepgsql_test_copy_1 && rm -f /tmp/sepgsql_test_copy_1 || : + @test -e /tmp/sepgsql_test_copy_2 && rm -f /tmp/sepgsql_test_copy_2 || : + @test -e /tmp/sepgsql_test_blob && rm -f /tmp/sepgsql_test_blob || : + @touch /tmp/sepgsql_test_copy_1 /tmp/sepgsql_test_copy_2 + @dd if=/dev/zero of=/tmp/sepgsql_test_blob bs=1024 count=20 >& /dev/null + @chcon -t postgresql_db_t -l s0 /tmp/sepgsql_test_copy_1 + @chcon -t postgresql_tmp_t -l s0 /tmp/sepgsql_test_copy_2 + @chcon -t postgresql_tmp_t -l s0 /tmp/sepgsql_test_blob + + environment: + @test -x $(PSQL) || (echo "$(PSQL) is not available"; exit 1) + @test -x $(RUNCON) || (echo "$(RUNCON) is not available"; exit 1) + @$(PSQL) -qt -c '' -d $(DBNAME) || \ + (echo "HINT: connection to $(DBNAME) is not available"; exit 1) + @$(PSQL) -qt -c 'SHOW pgace_feature' -d $(DBNAME) | grep -q selinux || \ + (echo "HINT: daemon is not SE-PostgreSQL"; exit 1) + @/usr/sbin/selinuxenabled || \ + (echo "HINT: SELinux is disabled!"; exit 1) + @$(RUNCON) -t sepgsql_test_t -l s0-s0:c0.c15 id -Z > /dev/null || \ + (echo "HINT: install sepostgresql-devel.pp"; exit 1) + @$(RUN_USER) -c 'SELECT sepgsql_getcon()' >& /dev/null || \ + (echo "HINT: do /sbin/restorecon -R and restart"; exit 1) + @/etc/init.d/mcstrans status > /dev/null && \ + (echo "HINT: stop 'mcstrans' daemon!"; exit 1) || \ + (test $$? -eq 3 && exit 0 || exit 1) + @echo "PASS: platform environment for the test" diff -Nrpc base/src/test/sepgsql/expected/column_level_mac.out sepgsql/src/test/sepgsql/expected/column_level_mac.out *** base/src/test/sepgsql/expected/column_level_mac.out Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/expected/column_level_mac.out Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,123 ---- + -- Basic column-level access controls + -- ================================== + 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'; + DROP TABLE IF EXISTS t1 CASCADE; + DROP FUNCTION IF EXISTS f1(integer); + RESET client_min_messages; + CREATE TABLE t1 + ( + a int, + b text + SECURITY_LABEL = 'system_u:object_r:sepgsql_ro_table_t:s0', + c text + SECURITY_LABEL = 'system_u:object_r:sepgsql_secret_table_t:s0' + ); + INSERT INTO t1 VALUES (1, 'aaa', '0000-1111-2222'), + (2, 'bbb', '3333-4444-5555'), + (3, 'ccc', '6666-7777-8888'); + SELECT security_label, attname FROM pg_attribute + WHERE attrelid IN (SELECT tableoid FROM t1); + security_label | attname + ---------------------------------------------+---------------- + unconfined_u:object_r:sepgsql_table_t:s0 | security_label + unconfined_u:object_r:sepgsql_table_t:s0 | security_acl + unconfined_u:object_r:sepgsql_table_t:s0 | tableoid + unconfined_u:object_r:sepgsql_table_t:s0 | cmax + unconfined_u:object_r:sepgsql_table_t:s0 | xmax + unconfined_u:object_r:sepgsql_table_t:s0 | cmin + unconfined_u:object_r:sepgsql_table_t:s0 | xmin + unconfined_u:object_r:sepgsql_table_t:s0 | ctid + unconfined_u:object_r:sepgsql_table_t:s0 | a + system_u:object_r:sepgsql_ro_table_t:s0 | b + system_u:object_r:sepgsql_secret_table_t:s0 | c + (11 rows) + + CREATE OR REPLACE FUNCTION f1(integer) RETURNS TEXT + LANGUAGE 'sql' + SECURITY_LABEL = 'system_u:object_r:sepgsql_trusted_proc_exec_t:s0' + AS 'SELECT substring(c FROM ''^[0-9]+-'') || ''xxxx-xxxx'' FROM t1 WHERE a = $1'; + -- Basic column-level access controls + -- ================================== + SELECT sepgsql_getcon(); + sepgsql_getcon + --------------------------------------------------- + unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 + (1 row) + + SELECT * FROM t1; -- to be failed + psql:sql/column_level_mac.sql:6: ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_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 + 3 | ccc + (3 rows) + + SELECT a, b FROM t1 WHERE c = 'abc'; -- to be failed + psql:sql/column_level_mac.sql:10: ERROR: SELinux: denied { use } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c + SELECT a, b FROM t1 WHERE c is null; -- to be failed + psql:sql/column_level_mac.sql:12: ERROR: SELinux: denied { use } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c + SELECT a, b FROM t1 ORDER BY c; -- to be failed + psql:sql/column_level_mac.sql:14: ERROR: SELinux: denied { use } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c + UPDATE t1 SET a = 4, b = 'ddd', c = '1234-5678-9012'; -- to be failed + psql:sql/column_level_mac.sql:16: ERROR: SELinux: denied { update } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_ro_table_t:s0 tclass=db_column name=t1.b + UPDATE t1 SET a = 4, b = 'ddd'; -- to be failed + psql:sql/column_level_mac.sql:18: ERROR: SELinux: denied { update } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_ro_table_t:s0 tclass=db_column name=t1.b + UPDATE t1 SET a = 4 WHERE b = 'bbb'; + SELECT security_label, * FROM t1; + psql:sql/column_level_mac.sql:22: ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c + INSERT INTO t1 (a, b, c) VALUES (5, 'eee', '1234-5678-9012'); -- to be failed + psql:sql/column_level_mac.sql:24: ERROR: SELinux: denied { insert } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_ro_table_t:s0 tclass=db_column name=t1.b + INSERT INTO t1 (a, b) VALUES (5, 'eee'); -- to be failed + psql:sql/column_level_mac.sql:26: ERROR: SELinux: denied { insert } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_ro_table_t:s0 tclass=db_column name=t1.b + INSERT INTO t1 (a) VALUES (5); + SELECT security_label, a, b FROM t1; + security_label | a | b + ------------------------------------------+---+----- + unconfined_u:object_r:sepgsql_table_t:s0 | 1 | aaa + unconfined_u:object_r:sepgsql_table_t:s0 | 3 | ccc + unconfined_u:object_r:sepgsql_table_t:s0 | 4 | bbb + unconfined_u:object_r:sepgsql_table_t:s0 | 5 | + (4 rows) + + DELETE FROM t1 RETURNING a, b, c; -- to be failed + psql:sql/column_level_mac.sql:32: ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t1.c + BEGIN; + DELETE FROM t1 RETURNING a, b; + a | b + ---+----- + 1 | aaa + 3 | ccc + 4 | bbb + 5 | + (4 rows) + + ABORT; + BEGIN; + DELETE FROM t1 RETURNING a; + a + --- + 1 + 3 + 4 + 5 + (4 rows) + + ABORT; + SELECT a, b, f1(a) FROM t1; + a | b | f1 + ---+-----+---------------- + 1 | aaa | 0000-xxxx-xxxx + 3 | ccc | 6666-xxxx-xxxx + 4 | bbb | 3333-xxxx-xxxx + 5 | | + (4 rows) + diff -Nrpc base/src/test/sepgsql/expected/constraint.out sepgsql/src/test/sepgsql/expected/constraint.out *** base/src/test/sepgsql/expected/constraint.out Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/expected/constraint.out Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,158 ---- + -- PK/FK constraint test + -- ===================== + SELECT sepgsql_getcon(); + sepgsql_getcon + ----------------------------------------------------- + unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 + (1 row) + + 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; + RESET client_min_messages; + CREATE TABLE t1 + ( + x int primary key, + y text + ); + psql:sql/constraint.init:19: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t1_pkey" for table "t1" + INSERT INTO t1 (security_label, x, y) + VALUES ('system_u:object_r:sepgsql_table_t:s0', 1, 'aaa'), + ('system_u:object_r:sepgsql_table_t:s0', 2, 'bbb'), + ('system_u:object_r:sepgsql_table_t:s0:c1', 3, 'ccc'), + ('system_u:object_r:sepgsql_table_t:s0:c1', 4, 'ddd'); + CREATE TABLE t2 + ( + x int primary key, + y text + ); + psql:sql/constraint.init:31: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t2_pkey" for table "t2" + INSERT INTO t2 (security_label, x, y) + (SELECT security_label, x, y FROM t1); + CREATE TABLE t3 + ( + a int references t1(x) + ); + INSERT INTO t3 (security_label, a) + VALUES ('system_u:object_r:sepgsql_table_t:s0', 1), + ('system_u:object_r:sepgsql_table_t:s0:c1', 2), + ('system_u:object_r:sepgsql_table_t:s0', 3), + ('system_u:object_r:sepgsql_table_t:s0:c1', 4); + CREATE TABLE t4 + ( + b int references t2(x) + ON UPDATE CASCADE ON DELETE SET NULL + ); + INSERT INTO t4 (security_label, b) + VALUES ('system_u:object_r:sepgsql_table_t:s0:c1', 1), + ('system_u:object_r:sepgsql_table_t:s0', 2), + ('system_u:object_r:sepgsql_table_t:s0:c1', 3), + ('system_u:object_r:sepgsql_table_t:s0', 4); + SELECT security_label, * FROM t1; + security_label | x | y + -----------------------------------------+---+----- + system_u:object_r:sepgsql_table_t:s0 | 1 | aaa + system_u:object_r:sepgsql_table_t:s0 | 2 | bbb + system_u:object_r:sepgsql_table_t:s0:c1 | 3 | ccc + system_u:object_r:sepgsql_table_t:s0:c1 | 4 | ddd + (4 rows) + + SELECT security_label, * FROM t2; + security_label | x | y + -----------------------------------------+---+----- + system_u:object_r:sepgsql_table_t:s0 | 1 | aaa + system_u:object_r:sepgsql_table_t:s0 | 2 | bbb + system_u:object_r:sepgsql_table_t:s0:c1 | 3 | ccc + system_u:object_r:sepgsql_table_t:s0:c1 | 4 | ddd + (4 rows) + + SELECT security_label, * FROM t3; + security_label | a + -----------------------------------------+--- + system_u:object_r:sepgsql_table_t:s0 | 1 + system_u:object_r:sepgsql_table_t:s0:c1 | 2 + system_u:object_r:sepgsql_table_t:s0 | 3 + system_u:object_r:sepgsql_table_t:s0:c1 | 4 + (4 rows) + + SELECT security_label, * FROM t4; + security_label | b + -----------------------------------------+--- + system_u:object_r:sepgsql_table_t:s0:c1 | 1 + system_u:object_r:sepgsql_table_t:s0 | 2 + system_u:object_r:sepgsql_table_t:s0:c1 | 3 + system_u:object_r:sepgsql_table_t:s0 | 4 + (4 rows) + + -- PK/FK constraint test + -- ===================== + SELECT sepgsql_getcon(); + sepgsql_getcon + --------------------------------------------------- + unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 + (1 row) + + SELECT security_label, * FROM t1; + security_label | x | y + --------------------------------------+---+----- + system_u:object_r:sepgsql_table_t:s0 | 1 | aaa + system_u:object_r:sepgsql_table_t:s0 | 2 | bbb + (2 rows) + + SELECT security_label, * FROM t2; + security_label | x | y + --------------------------------------+---+----- + system_u:object_r:sepgsql_table_t:s0 | 1 | aaa + system_u:object_r:sepgsql_table_t:s0 | 2 | bbb + (2 rows) + + SELECT security_label, * FROM t3; + security_label | a + --------------------------------------+--- + system_u:object_r:sepgsql_table_t:s0 | 1 + system_u:object_r:sepgsql_table_t:s0 | 3 + (2 rows) + + SELECT security_label, * FROM t4; + security_label | b + --------------------------------------+--- + system_u:object_r:sepgsql_table_t:s0 | 2 + system_u:object_r:sepgsql_table_t:s0 | 4 + (2 rows) + + INSERT INTO t1 VALUES (4, 'ddd'); -- to be failed + psql:sql/constraint.sql:11: ERROR: duplicate key value violates unique constraint "t1_pkey" + INSERT INTO t1 VALUES (5, 'eee'); + INSERT INTO t3 VALUES (2); + INSERT INTO t3 VALUES (3); -- to be failed + psql:sql/constraint.sql:15: ERROR: insert or update on table "t3" violates foreign key constraint "t3_a_fkey" + DETAIL: Key (a)=(3) is not present in table "t1". + DELETE FROM t1 WHERE x = 5 RETURNING *; + x | y + ---+----- + 5 | eee + (1 row) + + DELETE FROM t1 WHERE x = 2 RETURNING *; -- to be failed + psql:sql/constraint.sql:18: ERROR: SELinux: security policy violation + CONTEXT: SQL statement "SELECT 1 FROM ONLY "public"."t3" x WHERE $1 OPERATOR(pg_catalog.=) "a" FOR SHARE OF x" + UPDATE t2 SET x = x + 10 RETURNING *; -- to be failed + psql:sql/constraint.sql:20: ERROR: SELinux: security policy violation + CONTEXT: SQL statement "UPDATE ONLY "public"."t4" SET "b" = $1 WHERE $2 OPERATOR(pg_catalog.=) "b"" + UPDATE t2 SET x = x + 10 WHERE x = 2 RETURNING *; + x | y + ----+----- + 12 | bbb + (1 row) + + DELETE FROM t2 WHERE x = 1 RETURNING *; -- to be failed + psql:sql/constraint.sql:23: ERROR: SELinux: security policy violation + CONTEXT: SQL statement "UPDATE ONLY "public"."t4" SET "b" = NULL WHERE $1 OPERATOR(pg_catalog.=) "b"" + DELETE FROM t2 WHERE x = 12 RETURNING *; + x | y + ----+----- + 12 | bbb + (1 row) + diff -Nrpc base/src/test/sepgsql/expected/copy_stmt.out sepgsql/src/test/sepgsql/expected/copy_stmt.out *** base/src/test/sepgsql/expected/copy_stmt.out Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/expected/copy_stmt.out Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,82 ---- + -- COPY TO/FROM statement + -- ====================== + 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'; + DROP TABLE IF EXISTS t1 CASCADE; + DROP TABLE IF EXISTS t2 CASCADE; + RESET client_min_messages; + CREATE TABLE t1 + ( + a int, + b text + ); + COPY t1 (security_label, a, b) FROM stdin; + COPY t1 (security_label, a, b) TO stdout; + 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_table_t:s0 4 ddd + system_u:object_r:sepgsql_table_t:s0:c0 5 eee + system_u:object_r:sepgsql_table_t:s0:c1 6 fff + COPY t1 (security_label, a, b) TO '/tmp/sepgsql_test_copy_1'; + COPY t1 (security_label, a, b) TO '/tmp/sepgsql_test_copy_2'; + CREATE TABLE t2 + ( + x int, + y text + SECURITY_LABEL = 'system_u:object_r:sepgsql_ro_table_t:s0', + z text + SECURITY_LABEL = 'system_u:object_r:sepgsql_secret_table_t:s0' + ); + COPY t2 FROM stdin; + -- COPY TO/FROM statement + -- ====================== + 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 + 4 ddd + 5 eee + COPY t2 TO stdout; -- to be failed + psql:sql/copy_stmt.sql:7: ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t2.z + COPY t1 (security_label, a, b) TO stdout; + 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 4 ddd + system_u:object_r:sepgsql_table_t:s0:c0 5 eee + COPY t2 (security_label, x, y) TO stdout; + unconfined_u:object_r:sepgsql_table_t:s0 1 xxx + unconfined_u:object_r:sepgsql_table_t:s0 2 yyy + unconfined_u:object_r:sepgsql_table_t:s0 3 zzz + COPY t2 (security_label, y, z) TO stdout; -- to be failed + psql:sql/copy_stmt.sql:11: ERROR: SELinux: denied { select } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_secret_table_t:s0 tclass=db_column name=t2.z + COPY t1 FROM stdin; + COPY t1 (security_label, a, b) FROM stdin; + COPY t2 (security_label, x, y) FROM stdin; -- to be failed + psql:sql/copy_stmt.sql:21: ERROR: SELinux: denied { insert } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_ro_table_t:s0 tclass=db_column name=t2.y + COPY t1 (security_label, a, b) FROM '/tmp/sepgsql_test_copy_1'; -- to be failed + psql:sql/copy_stmt.sql:23: ERROR: SELinux: denied { read } 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_1 + COPY t1 (security_label, a, b) FROM '/tmp/sepgsql_test_copy_2'; -- partial success + COPY t1 (security_label, a, b) TO stdout; + 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 4 ddd + system_u:object_r:sepgsql_table_t:s0:c0 5 eee + unconfined_u:object_r:sepgsql_table_t:s0 98 yyy + unconfined_u:object_r:sepgsql_table_t:s0 99 zzz + system_u:object_r:sepgsql_table_t:s0 97 xxx + 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 4 ddd + system_u:object_r:sepgsql_table_t:s0:c0 5 eee diff -Nrpc base/src/test/sepgsql/expected/largeobject.out sepgsql/src/test/sepgsql/expected/largeobject.out *** base/src/test/sepgsql/expected/largeobject.out Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/expected/largeobject.out Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,255 ---- + -- Binary Large Object + -- =================== + SELECT sepgsql_getcon(); + sepgsql_getcon + ----------------------------------------------------- + unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 + (1 row) + + SELECT lo_import('/tmp/sepgsql_test_blob', 6001); + lo_import + ----------- + 6001 + (1 row) + + SELECT lo_import('/tmp/sepgsql_test_blob', 6002); + lo_import + ----------- + 6002 + (1 row) + + SELECT lo_import('/tmp/sepgsql_test_blob', 6003); + lo_import + ----------- + 6003 + (1 row) + + SELECT lo_set_security(6001, 'system_u:object_r:sepgsql_blob_t:s0'); + lo_set_security + ----------------- + t + (1 row) + + SELECT lo_set_security(6002, 'system_u:object_r:sepgsql_ro_blob_t:s0'); + lo_set_security + ----------------- + t + (1 row) + + SELECT lo_set_security(6003, 'system_u:object_r:sepgsql_secret_blob_t:s0'); + lo_set_security + ----------------- + t + (1 row) + + -- Binary Large Object + -- =================== + SELECT sepgsql_getcon(); + sepgsql_getcon + --------------------------------------------------- + unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 + (1 row) + + SELECT lo_get_security(6001); + lo_get_security + ------------------------------------- + system_u:object_r:sepgsql_blob_t:s0 + (1 row) + + SELECT lo_get_security(6002); + lo_get_security + ---------------------------------------- + system_u:object_r:sepgsql_ro_blob_t:s0 + (1 row) + + SELECT lo_get_security(6003); + lo_get_security + -------------------------------------------- + system_u:object_r:sepgsql_secret_blob_t:s0 + (1 row) + + SELECT security_label, loid, COUNT(*) FROM pg_largeobject + GROUP BY security_label, loid; + security_label | loid | count + --------------------------------------------+------+------- + system_u:object_r:sepgsql_ro_blob_t:s0 | 6002 | 10 + system_u:object_r:sepgsql_secret_blob_t:s0 | 6003 | 10 + system_u:object_r:sepgsql_blob_t:s0 | 6001 | 10 + (3 rows) + + -- read large object + BEGIN; + SELECT lo_open(6001, x'40000'::int); + lo_open + --------- + 0 + (1 row) + + SELECT loread(0, 24); + 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 + (1 row) + + ROLLBACK; + BEGIN; + SELECT lo_open(6002, x'40000'::int); + lo_open + --------- + 0 + (1 row) + + SELECT loread(0, 24); + 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 + (1 row) + + ROLLBACK; + BEGIN; + SELECT lo_open(6003, x'40000'::int); + lo_open + --------- + 0 + (1 row) + + SELECT loread(0, 24); -- to be failed + psql:sql/largeobject.sql:26: ERROR: SELinux: denied { read } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_secret_blob_t:s0 tclass=db_blob name=loid:6003 + ROLLBACK; + -- write large object + BEGIN; + SELECT lo_open(6001, x'20000'::int); + lo_open + --------- + 0 + (1 row) + + SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + lowrite + --------- + 26 + (1 row) + + COMMIT; + BEGIN; + SELECT lo_open(6002, x'20000'::int); + lo_open + --------- + 0 + (1 row) + + SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); -- to be failed + psql:sql/largeobject.sql:37: ERROR: SELinux: denied { write } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_ro_blob_t:s0 tclass=db_blob name=loid:6002 + COMMIT; + BEGIN; + SELECT lo_open(6003, x'20000'::int); + lo_open + --------- + 0 + (1 row) + + SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); -- to be failed + psql:sql/largeobject.sql:42: ERROR: SELinux: denied { write } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_secret_blob_t:s0 tclass=db_blob name=loid:6003 + COMMIT; + -- create large object + BEGIN; + SELECT lo_create(6004); + lo_create + ----------- + 6004 + (1 row) + + SELECT lo_open(6004, x'20000'::int); + lo_open + --------- + 0 + (1 row) + + SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + lowrite + --------- + 26 + (1 row) + + SELECT lo_close(0); + lo_close + ---------- + 0 + (1 row) + + COMMIT; + -- append large object + BEGIN; + SELECT lo_open(6001, x'60000'::int); + lo_open + --------- + 0 + (1 row) + + SELECT lo_lseek(0, 0, 2); -- seek to end + lo_lseek + ---------- + 20480 + (1 row) + + SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + lowrite + --------- + 26 + (1 row) + + SELECT lo_close(0); + lo_close + ---------- + 0 + (1 row) + + COMMIT; + -- import/export large object + SELECT lo_import('/tmp/sepgsql_test_blob', 6005); + psql:sql/largeobject.sql:62: ERROR: SELinux: denied { import } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=unconfined_u:object_r:sepgsql_blob_t:s0 tclass=db_blob name=loid:6005 + SELECT lo_export(6001, '/tmp/sepgsql_test_blob'); + psql:sql/largeobject.sql:64: ERROR: SELinux: denied { export } scontext=unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 tcontext=system_u:object_r:sepgsql_blob_t:s0 tclass=db_blob name=loid:6001 + -- check result + SELECT security_label, loid, COUNT(*) FROM pg_largeobject + GROUP BY security_label, loid; + security_label | loid | count + --------------------------------------------+------+------- + system_u:object_r:sepgsql_ro_blob_t:s0 | 6002 | 10 + unconfined_u:object_r:sepgsql_blob_t:s0 | 6004 | 1 + system_u:object_r:sepgsql_secret_blob_t:s0 | 6003 | 10 + system_u:object_r:sepgsql_blob_t:s0 | 6001 | 11 + (4 rows) + + -- Binary Large Object + -- =================== + SELECT sepgsql_getcon(); + sepgsql_getcon + ----------------------------------------------------- + unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 + (1 row) + + SELECT lo_unlink(6001); + lo_unlink + ----------- + 1 + (1 row) + + SELECT lo_unlink(6002); + lo_unlink + ----------- + 1 + (1 row) + + SELECT lo_unlink(6003); + lo_unlink + ----------- + 1 + (1 row) + + SELECT lo_unlink(6004); + lo_unlink + ----------- + 1 + (1 row) + diff -Nrpc base/src/test/sepgsql/expected/row_level_mac.out sepgsql/src/test/sepgsql/expected/row_level_mac.out *** base/src/test/sepgsql/expected/row_level_mac.out Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/expected/row_level_mac.out Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,104 ---- + -- Basic Row-level Access Controls + -- ==================================== + 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'; + DROP TABLE IF EXISTS t2 CASCADE; + DROP TABLE IF EXISTS t1 CASCADE; + RESET client_min_messages; + CREATE TABLE t1 + ( + a int primary key, + b text + ); + psql:sql/row_level_mac.init:18: NOTICE: CREATE TABLE / PRIMARY KEY will create implicit index "t1_pkey" for table "t1" + CREATE TABLE t2 + ( + x int references t1(a), + y text + ); + INSERT INTO t1 (security_label, 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 (x, y) VALUES + (1, 'red'), (2, 'blue'), (3, 'yellow'), + (4, 'green'), (5, 'orange'), (6, 'white'); + UPDATE t2 SET security_label = sepgsql_set_range(security_label, 's0:c1') + WHERE x IN (1, 3, 4) + -- Basic Row-level Access Controls + -- ==================================== + SELECT sepgsql_getcon(); + sepgsql_getcon + --------------------------------------------------- + unconfined_u:unconfined_r:sepgsql_test_t:s0-s0:c0 + (1 row) + + SELECT security_label, * FROM t1; + security_label | 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_label, * FROM t2; + security_label | x | y + ------------------------------------------+---+-------- + unconfined_u:object_r:sepgsql_table_t:s0 | 2 | blue + unconfined_u:object_r:sepgsql_table_t:s0 | 5 | orange + unconfined_u:object_r:sepgsql_table_t:s0 | 6 | white + (3 rows) + + COPY t1 (security_label, a, b) TO stdout; + 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 + COPY t2 (security_label, x, y) TO stdout; + unconfined_u:object_r:sepgsql_table_t:s0 2 blue + unconfined_u:object_r:sepgsql_table_t:s0 5 orange + unconfined_u:object_r:sepgsql_table_t:s0 6 white + SELECT t1.security_label, t2.security_label, * FROM t1 JOIN t2 ON t1.a = t2.x; + security_label | security_label | a | b | x | y + --------------------------------------------+------------------------------------------+---+-----+---+-------- + system_u:object_r:sepgsql_table_t:s0:c0 | unconfined_u:object_r:sepgsql_table_t:s0 | 2 | bbb | 2 | blue + system_u:object_r:sepgsql_ro_table_t:s0:c0 | unconfined_u:object_r:sepgsql_table_t:s0 | 5 | eee | 5 | orange + (2 rows) + + BEGIN; + UPDATE t1 SET b = b || '_updt'; + SELECT security_label, * FROM t1; + security_label | a | b + --------------------------------------------+---+---------- + 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_table_t:s0 | 1 | aaa_updt + system_u:object_r:sepgsql_table_t:s0:c0 | 2 | bbb_updt + (4 rows) + + ABORT; + BEGIN; + DELETE FROM t2 RETURNING *; + x | y + ---+-------- + 2 | blue + 5 | orange + 6 | white + (3 rows) + + ABORT; + INSERT INTO t1 VALUES (6, 'fff'); -- to be failed + psql:sql/row_level_mac.sql:23: ERROR: duplicate key value violates unique constraint "t1_pkey" + DELETE FROM t1 WHERE a = 1; -- to be failed + psql:sql/row_level_mac.sql:24: 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" diff -Nrpc base/src/test/sepgsql/expected/security_label_sysattr.out sepgsql/src/test/sepgsql/expected/security_label_sysattr.out *** base/src/test/sepgsql/expected/security_label_sysattr.out Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/expected/security_label_sysattr.out Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,126 ---- + -- Basic security_label management + -- =============================== + 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'; + DROP TABLE IF EXISTS t4 CASCADE; + DROP TABLE IF EXISTS t3 CASCADE; + DROP TABLE IF EXISTS t2 CASCADE; + DROP TABLE IF EXISTS t1 CASCADE; + RESET client_min_messages; + -- test proper begins here + CREATE TABLE t1 + ( + a int, + b text + ); + CREATE TABLE t2 + ( + x int, + y text + ); + INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'); + INSERT INTO t1 (security_label, a, b) VALUES ('system_u:object_r:sepgsql_ro_table_t:s0', 3, 'ccc'); + INSERT INTO t1 (security_label, a, b) + (SELECT sepgsql_set_range(security_label, 's0:c' || a) AS security_label, a+3 AS a, b || '_ins' AS b FROM t1); + INSERT INTO t1 (security_label, a, b) VALUES ('invalid label', 99, 'zzz'); -- to be failed + psql:sql/security_label_sysattr.init:33: ERROR: PGACE: invalid security label: invalid label + INSERT INTO t1 (security_label, a, b) VALUES ('system_u:object_r:sepgsql_table_t:s0:c99', 99, 'zzz'); -- to be failed + SELECT security_label, * FROM t1; + security_label | a | b + ---------------------------------------------+---+--------- + unconfined_u:object_r:sepgsql_table_t:s0 | 1 | aaa + unconfined_u:object_r:sepgsql_table_t:s0 | 2 | bbb + system_u:object_r:sepgsql_ro_table_t:s0 | 3 | ccc + unconfined_u:object_r:sepgsql_table_t:s0:c1 | 4 | aaa_ins + unconfined_u:object_r:sepgsql_table_t:s0:c2 | 5 | bbb_ins + system_u:object_r:sepgsql_ro_table_t:s0:c3 | 6 | ccc_ins + (6 rows) + + INSERT INTO t2 (security_label, x, y) (SELECT security_label, a * 2, security_label || '_ins' FROM t1); + SELECT security_label, * FROM t2; + security_label | x | y + ---------------------------------------------+----+------------------------------------------------- + unconfined_u:object_r:sepgsql_table_t:s0 | 2 | unconfined_u:object_r:sepgsql_table_t:s0_ins + unconfined_u:object_r:sepgsql_table_t:s0 | 4 | unconfined_u:object_r:sepgsql_table_t:s0_ins + system_u:object_r:sepgsql_ro_table_t:s0 | 6 | system_u:object_r:sepgsql_ro_table_t:s0_ins + unconfined_u:object_r:sepgsql_table_t:s0:c1 | 8 | unconfined_u:object_r:sepgsql_table_t:s0:c1_ins + unconfined_u:object_r:sepgsql_table_t:s0:c2 | 10 | unconfined_u:object_r:sepgsql_table_t:s0:c2_ins + system_u:object_r:sepgsql_ro_table_t:s0:c3 | 12 | system_u:object_r:sepgsql_ro_table_t:s0:c3_ins + (6 rows) + + UPDATE t1 SET security_label = sepgsql_set_range(security_label, 's0:c' || a); + SELECT security_label, * FROM t1; + security_label | a | b + ---------------------------------------------+---+--------- + unconfined_u:object_r:sepgsql_table_t:s0:c1 | 1 | aaa + unconfined_u:object_r:sepgsql_table_t:s0:c2 | 2 | bbb + system_u:object_r:sepgsql_ro_table_t:s0:c3 | 3 | ccc + unconfined_u:object_r:sepgsql_table_t:s0:c4 | 4 | aaa_ins + unconfined_u:object_r:sepgsql_table_t:s0:c5 | 5 | bbb_ins + system_u:object_r:sepgsql_ro_table_t:s0:c6 | 6 | ccc_ins + (6 rows) + + UPDATE t1 SET security_label = sepgsql_set_type(security_label, 'sepgsql_ro_t') WHERE a IN (1,3,5); + psql:sql/security_label_sysattr.init:42: ERROR: PGACE: invalid security label: unconfined_u:object_r:sepgsql_ro_t:s0:c1 + UPDATE t1 SET security_label = sepgsql_set_range(security_label, 's0:c' || (a+11)); -- partial success + psql:sql/security_label_sysattr.init:44: NOTICE: SELinux: denied { relabelto } scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 tcontext=unconfined_u:object_r:sepgsql_table_t:s0:c16 tclass=db_tuple + psql:sql/security_label_sysattr.init:44: NOTICE: SELinux: denied { relabelto } scontext=unconfined_u:unconfined_r:unconfined_t:s0-s0:c0.c15 tcontext=system_u:object_r:sepgsql_ro_table_t:s0:c17 tclass=db_tuple + SELECT security_label, * FROM t1; + security_label | a | b + ----------------------------------------------+---+--------- + unconfined_u:object_r:sepgsql_table_t:s0:c5 | 5 | bbb_ins + system_u:object_r:sepgsql_ro_table_t:s0:c6 | 6 | ccc_ins + unconfined_u:object_r:sepgsql_table_t:s0:c12 | 1 | aaa + unconfined_u:object_r:sepgsql_table_t:s0:c13 | 2 | bbb + system_u:object_r:sepgsql_ro_table_t:s0:c14 | 3 | ccc + unconfined_u:object_r:sepgsql_table_t:s0:c15 | 4 | aaa_ins + (6 rows) + + UPDATE t1 SET security_label = 'invalid label'; -- to be failed + psql:sql/security_label_sysattr.init:46: ERROR: PGACE: invalid security label: invalid label + SELECT security_label, a+10 AS a, b || '_t3' INTO t3 FROM t1; + SELECT security_label, * FROM t3; + security_label | a | ?column? + ----------------------------------------------+----+------------ + unconfined_u:object_r:sepgsql_table_t:s0:c5 | 15 | bbb_ins_t3 + system_u:object_r:sepgsql_ro_table_t:s0:c6 | 16 | ccc_ins_t3 + unconfined_u:object_r:sepgsql_table_t:s0:c12 | 11 | aaa_t3 + unconfined_u:object_r:sepgsql_table_t:s0:c13 | 12 | bbb_t3 + system_u:object_r:sepgsql_ro_table_t:s0:c14 | 13 | ccc_t3 + unconfined_u:object_r:sepgsql_table_t:s0:c15 | 14 | aaa_ins_t3 + (6 rows) + + SELECT a+20 AS a, b || '_t4' INTO t4 FROM t1; + SELECT security_label, * FROM t4; + security_label | a | ?column? + ------------------------------------------+----+------------ + unconfined_u:object_r:sepgsql_table_t:s0 | 25 | bbb_ins_t4 + unconfined_u:object_r:sepgsql_table_t:s0 | 26 | ccc_ins_t4 + unconfined_u:object_r:sepgsql_table_t:s0 | 21 | aaa_t4 + unconfined_u:object_r:sepgsql_table_t:s0 | 22 | bbb_t4 + unconfined_u:object_r:sepgsql_table_t:s0 | 23 | ccc_t4 + unconfined_u:object_r:sepgsql_table_t:s0 | 24 | aaa_ins_t4 + (6 rows) + + TRUNCATE t2; + COPY t2 (security_label, x, y) FROM stdin; + COPY t2 TO stdout; + 1 aaa + 2 bbb + 3 ccc + COPY t2 (security_label, x, y) TO stdout; + system_u:object_r:sepgsql_table_t:s0 1 aaa + system_u:object_r:sepgsql_table_t:s0:c1 2 bbb + system_u:object_r:sepgsql_table_t:s0:c2 3 ccc + COPY t2 (security_label, x, y) TO stdout CSV FORCE QUOTE security_label,y; + "system_u:object_r:sepgsql_table_t:s0",1,"aaa" + "system_u:object_r:sepgsql_table_t:s0:c1",2,"bbb" + "system_u:object_r:sepgsql_table_t:s0:c2",3,"ccc" + -- Basic security label + -- ==================== diff -Nrpc base/src/test/sepgsql/sql/column_level_mac.init sepgsql/src/test/sepgsql/sql/column_level_mac.init *** base/src/test/sepgsql/sql/column_level_mac.init Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/column_level_mac.init Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,33 ---- + -- Basic column-level access controls + -- ================================== + + SELECT sepgsql_getcon(); + + -- cleanup previous tests + SET client_min_messages TO 'error'; + + DROP TABLE IF EXISTS t1 CASCADE; + DROP FUNCTION IF EXISTS f1(integer); + + RESET client_min_messages; + + CREATE TABLE t1 + ( + a int, + b text + SECURITY_LABEL = 'system_u:object_r:sepgsql_ro_table_t:s0', + c text + SECURITY_LABEL = 'system_u:object_r:sepgsql_secret_table_t:s0' + ); + + INSERT INTO t1 VALUES (1, 'aaa', '0000-1111-2222'), + (2, 'bbb', '3333-4444-5555'), + (3, 'ccc', '6666-7777-8888'); + + SELECT security_label, attname FROM pg_attribute + WHERE attrelid IN (SELECT tableoid FROM t1); + + CREATE OR REPLACE FUNCTION f1(integer) RETURNS TEXT + LANGUAGE 'sql' + SECURITY_LABEL = 'system_u:object_r:sepgsql_trusted_proc_exec_t:s0' + AS 'SELECT substring(c FROM ''^[0-9]+-'') || ''xxxx-xxxx'' FROM t1 WHERE a = $1'; diff -Nrpc base/src/test/sepgsql/sql/column_level_mac.sql sepgsql/src/test/sepgsql/sql/column_level_mac.sql *** base/src/test/sepgsql/sql/column_level_mac.sql Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/column_level_mac.sql Tue Dec 16 14:59:51 2008 *************** *** 0 **** --- 1,42 ---- + -- Basic column-level access controls + -- ================================== + + SELECT sepgsql_getcon(); + + SELECT * FROM t1; -- to be failed + + SELECT a, b FROM t1; + + SELECT a, b FROM t1 WHERE c = 'abc'; -- to be failed + + SELECT a, b FROM t1 WHERE c is null; -- to be failed + + SELECT a, b FROM t1 ORDER BY c; -- to be failed + + UPDATE t1 SET a = 4, b = 'ddd', c = '1234-5678-9012'; -- to be failed + + UPDATE t1 SET a = 4, b = 'ddd'; -- to be failed + + UPDATE t1 SET a = 4 WHERE b = 'bbb'; + + SELECT security_label, * FROM t1; + + INSERT INTO t1 (a, b, c) VALUES (5, 'eee', '1234-5678-9012'); -- to be failed + + INSERT INTO t1 (a, b) VALUES (5, 'eee'); -- to be failed + + INSERT INTO t1 (a) VALUES (5); + + SELECT security_label, a, b FROM t1; + + DELETE FROM t1 RETURNING a, b, c; -- to be failed + + BEGIN; + DELETE FROM t1 RETURNING a, b; + ABORT; + + BEGIN; + DELETE FROM t1 RETURNING a; + ABORT; + + SELECT a, b, f1(a) FROM t1; \ No newline at end of file diff -Nrpc base/src/test/sepgsql/sql/constraint.init sepgsql/src/test/sepgsql/sql/constraint.init *** base/src/test/sepgsql/sql/constraint.init Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/constraint.init Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,59 ---- + -- PK/FK constraint test + -- ===================== + + SELECT sepgsql_getcon(); + + 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; + + RESET client_min_messages; + + CREATE TABLE t1 + ( + x int primary key, + y text + ); + + INSERT INTO t1 (security_label, x, y) + VALUES ('system_u:object_r:sepgsql_table_t:s0', 1, 'aaa'), + ('system_u:object_r:sepgsql_table_t:s0', 2, 'bbb'), + ('system_u:object_r:sepgsql_table_t:s0:c1', 3, 'ccc'), + ('system_u:object_r:sepgsql_table_t:s0:c1', 4, 'ddd'); + + CREATE TABLE t2 + ( + x int primary key, + y text + ); + INSERT INTO t2 (security_label, x, y) + (SELECT security_label, x, y FROM t1); + + CREATE TABLE t3 + ( + a int references t1(x) + ); + INSERT INTO t3 (security_label, a) + VALUES ('system_u:object_r:sepgsql_table_t:s0', 1), + ('system_u:object_r:sepgsql_table_t:s0:c1', 2), + ('system_u:object_r:sepgsql_table_t:s0', 3), + ('system_u:object_r:sepgsql_table_t:s0:c1', 4); + + CREATE TABLE t4 + ( + b int references t2(x) + ON UPDATE CASCADE ON DELETE SET NULL + ); + INSERT INTO t4 (security_label, b) + VALUES ('system_u:object_r:sepgsql_table_t:s0:c1', 1), + ('system_u:object_r:sepgsql_table_t:s0', 2), + ('system_u:object_r:sepgsql_table_t:s0:c1', 3), + ('system_u:object_r:sepgsql_table_t:s0', 4); + + SELECT security_label, * FROM t1; + SELECT security_label, * FROM t2; + SELECT security_label, * FROM t3; + SELECT security_label, * FROM t4; diff -Nrpc base/src/test/sepgsql/sql/constraint.sql sepgsql/src/test/sepgsql/sql/constraint.sql *** base/src/test/sepgsql/sql/constraint.sql Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/constraint.sql Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,24 ---- + -- PK/FK constraint test + -- ===================== + + SELECT sepgsql_getcon(); + + SELECT security_label, * FROM t1; + SELECT security_label, * FROM t2; + SELECT security_label, * FROM t3; + SELECT security_label, * FROM t4; + + INSERT INTO t1 VALUES (4, 'ddd'); -- to be failed + INSERT INTO t1 VALUES (5, 'eee'); + + INSERT INTO t3 VALUES (2); + INSERT INTO t3 VALUES (3); -- to be failed + + DELETE FROM t1 WHERE x = 5 RETURNING *; + DELETE FROM t1 WHERE x = 2 RETURNING *; -- to be failed + + UPDATE t2 SET x = x + 10 RETURNING *; -- to be failed + UPDATE t2 SET x = x + 10 WHERE x = 2 RETURNING *; + + DELETE FROM t2 WHERE x = 1 RETURNING *; -- to be failed + DELETE FROM t2 WHERE x = 12 RETURNING *; \ No newline at end of file diff -Nrpc base/src/test/sepgsql/sql/copy_stmt.init sepgsql/src/test/sepgsql/sql/copy_stmt.init *** base/src/test/sepgsql/sql/copy_stmt.init Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/copy_stmt.init Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,46 ---- + -- COPY TO/FROM statement + -- ====================== + + SELECT sepgsql_getcon(); + + -- cleanup previous tests + SET client_min_messages TO 'error'; + + DROP TABLE IF EXISTS t1 CASCADE; + DROP TABLE IF EXISTS t2 CASCADE; + + RESET client_min_messages; + + CREATE TABLE t1 + ( + a int, + b text + ); + + COPY t1 (security_label, a, b) FROM stdin; + 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_table_t:s0 4 ddd + system_u:object_r:sepgsql_table_t:s0:c0 5 eee + system_u:object_r:sepgsql_table_t:s0:c1 6 fff + \. + + COPY t1 (security_label, a, b) TO stdout; + COPY t1 (security_label, a, b) TO '/tmp/sepgsql_test_copy_1'; + COPY t1 (security_label, a, b) TO '/tmp/sepgsql_test_copy_2'; + + CREATE TABLE t2 + ( + x int, + y text + SECURITY_LABEL = 'system_u:object_r:sepgsql_ro_table_t:s0', + z text + SECURITY_LABEL = 'system_u:object_r:sepgsql_secret_table_t:s0' + ); + + COPY t2 FROM stdin; + 1 xxx red + 2 yyy blue + 3 zzz green + \. diff -Nrpc base/src/test/sepgsql/sql/copy_stmt.sql sepgsql/src/test/sepgsql/sql/copy_stmt.sql *** base/src/test/sepgsql/sql/copy_stmt.sql Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/copy_stmt.sql Tue Dec 16 16:22:25 2008 *************** *** 0 **** --- 1,25 ---- + -- COPY TO/FROM statement + -- ====================== + + SELECT sepgsql_getcon(); + + COPY t1 TO stdout; + COPY t2 TO stdout; -- to be failed + + COPY t1 (security_label, a, b) TO stdout; + COPY t2 (security_label, x, y) TO stdout; + COPY t2 (security_label, y, z) TO stdout; -- to be failed + + COPY t1 FROM stdin; + 98 yyy + 99 zzz + \. + + COPY t1 (security_label, a, b) FROM stdin; + system_u:object_r:sepgsql_table_t:s0 97 xxx + \. + COPY t2 (security_label, x, y) FROM stdin; -- to be failed + + COPY t1 (security_label, a, b) FROM '/tmp/sepgsql_test_copy_1'; -- to be failed + COPY t1 (security_label, a, b) FROM '/tmp/sepgsql_test_copy_2'; -- partial success + COPY t1 (security_label, a, b) TO stdout; diff -Nrpc base/src/test/sepgsql/sql/largeobject.fini sepgsql/src/test/sepgsql/sql/largeobject.fini *** base/src/test/sepgsql/sql/largeobject.fini Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/largeobject.fini Tue Dec 16 16:22:25 2008 *************** *** 0 **** --- 1,9 ---- + -- Binary Large Object + -- =================== + + SELECT sepgsql_getcon(); + + SELECT lo_unlink(6001); + SELECT lo_unlink(6002); + SELECT lo_unlink(6003); + SELECT lo_unlink(6004); diff -Nrpc base/src/test/sepgsql/sql/largeobject.init sepgsql/src/test/sepgsql/sql/largeobject.init *** base/src/test/sepgsql/sql/largeobject.init Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/largeobject.init Tue Dec 16 16:22:25 2008 *************** *** 0 **** --- 1,12 ---- + -- Binary Large Object + -- =================== + + SELECT sepgsql_getcon(); + + SELECT lo_import('/tmp/sepgsql_test_blob', 6001); + SELECT lo_import('/tmp/sepgsql_test_blob', 6002); + SELECT lo_import('/tmp/sepgsql_test_blob', 6003); + + SELECT lo_set_security(6001, 'system_u:object_r:sepgsql_blob_t:s0'); + SELECT lo_set_security(6002, 'system_u:object_r:sepgsql_ro_blob_t:s0'); + SELECT lo_set_security(6003, 'system_u:object_r:sepgsql_secret_blob_t:s0'); diff -Nrpc base/src/test/sepgsql/sql/largeobject.sql sepgsql/src/test/sepgsql/sql/largeobject.sql *** base/src/test/sepgsql/sql/largeobject.sql Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/largeobject.sql Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,68 ---- + -- Binary Large Object + -- =================== + + SELECT sepgsql_getcon(); + + SELECT lo_get_security(6001); + SELECT lo_get_security(6002); + SELECT lo_get_security(6003); + + SELECT security_label, loid, COUNT(*) FROM pg_largeobject + GROUP BY security_label, loid; + + -- read large object + BEGIN; + SELECT lo_open(6001, x'40000'::int); + SELECT loread(0, 24); + ROLLBACK; + + BEGIN; + SELECT lo_open(6002, x'40000'::int); + SELECT loread(0, 24); + ROLLBACK; + + BEGIN; + SELECT lo_open(6003, x'40000'::int); + SELECT loread(0, 24); -- to be failed + ROLLBACK; + + -- write large object + BEGIN; + SELECT lo_open(6001, x'20000'::int); + SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + COMMIT; + + BEGIN; + SELECT lo_open(6002, x'20000'::int); + SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); -- to be failed + COMMIT; + + BEGIN; + SELECT lo_open(6003, x'20000'::int); + SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); -- to be failed + COMMIT; + + -- create large object + BEGIN; + SELECT lo_create(6004); + SELECT lo_open(6004, x'20000'::int); + SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + SELECT lo_close(0); + COMMIT; + + -- append large object + BEGIN; + SELECT lo_open(6001, x'60000'::int); + SELECT lo_lseek(0, 0, 2); -- seek to end + SELECT lowrite(0, 'ABCDEFGHIJKLMNOPQRSTUVWXYZ'); + SELECT lo_close(0); + COMMIT; + + -- import/export large object + SELECT lo_import('/tmp/sepgsql_test_blob', 6005); + + SELECT lo_export(6001, '/tmp/sepgsql_test_blob'); + + -- check result + SELECT security_label, loid, COUNT(*) FROM pg_largeobject + GROUP BY security_label, loid; diff -Nrpc base/src/test/sepgsql/sql/row_level_mac.init sepgsql/src/test/sepgsql/sql/row_level_mac.init *** base/src/test/sepgsql/sql/row_level_mac.init Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/row_level_mac.init Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,38 ---- + -- Basic Row-level Access Controls + -- ==================================== + + SELECT sepgsql_getcon(); + + -- cleanup previous tests + SET client_min_messages TO 'error'; + + DROP TABLE IF EXISTS t2 CASCADE; + DROP TABLE IF EXISTS t1 CASCADE; + + RESET client_min_messages; + + CREATE TABLE t1 + ( + a int primary key, + b text + ); + + CREATE TABLE t2 + ( + x int references t1(a), + y text + ); + + INSERT INTO t1 (security_label, 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 (x, y) VALUES + (1, 'red'), (2, 'blue'), (3, 'yellow'), + (4, 'green'), (5, 'orange'), (6, 'white'); + UPDATE t2 SET security_label = sepgsql_set_range(security_label, 's0:c1') + WHERE x IN (1, 3, 4) diff -Nrpc base/src/test/sepgsql/sql/row_level_mac.sql sepgsql/src/test/sepgsql/sql/row_level_mac.sql *** base/src/test/sepgsql/sql/row_level_mac.sql Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/row_level_mac.sql Tue Dec 16 14:59:51 2008 *************** *** 0 **** --- 1,24 ---- + -- Basic Row-level Access Controls + -- ==================================== + + SELECT sepgsql_getcon(); + + SELECT security_label, * FROM t1; + SELECT security_label, * FROM t2; + + COPY t1 (security_label, a, b) TO stdout; + COPY t2 (security_label, x, y) TO stdout; + + SELECT t1.security_label, t2.security_label, * FROM t1 JOIN t2 ON t1.a = t2.x; + + BEGIN; + UPDATE t1 SET b = b || '_updt'; + SELECT security_label, * FROM t1; + ABORT; + + BEGIN; + DELETE FROM t2 RETURNING *; + ABORT; + + INSERT INTO t1 VALUES (6, 'fff'); -- to be failed + DELETE FROM t1 WHERE a = 1; -- to be failed diff -Nrpc base/src/test/sepgsql/sql/security_label_sysattr.init sepgsql/src/test/sepgsql/sql/security_label_sysattr.init *** base/src/test/sepgsql/sql/security_label_sysattr.init Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/security_label_sysattr.init Tue Dec 16 17:03:36 2008 *************** *** 0 **** --- 1,64 ---- + -- Basic security_label management + -- =============================== + + SELECT sepgsql_getcon(); + + -- 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; + + RESET client_min_messages; + + -- test proper begins here + CREATE TABLE t1 + ( + a int, + b text + ); + + CREATE TABLE t2 + ( + x int, + y text + ); + + INSERT INTO t1 VALUES (1, 'aaa'), (2, 'bbb'); + INSERT INTO t1 (security_label, a, b) VALUES ('system_u:object_r:sepgsql_ro_table_t:s0', 3, 'ccc'); + INSERT INTO t1 (security_label, a, b) + (SELECT sepgsql_set_range(security_label, 's0:c' || a) AS security_label, a+3 AS a, b || '_ins' AS b FROM t1); + INSERT INTO t1 (security_label, a, b) VALUES ('invalid label', 99, 'zzz'); -- to be failed + INSERT INTO t1 (security_label, a, b) VALUES ('system_u:object_r:sepgsql_table_t:s0:c99', 99, 'zzz'); -- to be failed + SELECT security_label, * FROM t1; + + INSERT INTO t2 (security_label, x, y) (SELECT security_label, a * 2, security_label || '_ins' FROM t1); + SELECT security_label, * FROM t2; + + UPDATE t1 SET security_label = sepgsql_set_range(security_label, 's0:c' || a); + SELECT security_label, * FROM t1; + UPDATE t1 SET security_label = sepgsql_set_type(security_label, 'sepgsql_ro_t') WHERE a IN (1,3,5); + + UPDATE t1 SET security_label = sepgsql_set_range(security_label, 's0:c' || (a+11)); -- partial success + SELECT security_label, * FROM t1; + UPDATE t1 SET security_label = 'invalid label'; -- to be failed + + SELECT security_label, a+10 AS a, b || '_t3' INTO t3 FROM t1; + SELECT security_label, * FROM t3; + + SELECT a+20 AS a, b || '_t4' INTO t4 FROM t1; + SELECT security_label, * FROM t4; + + TRUNCATE t2; + + COPY t2 (security_label, x, y) FROM stdin; + system_u:object_r:sepgsql_table_t:s0 1 aaa + system_u:object_r:sepgsql_table_t:s0:c1 2 bbb + system_u:object_r:sepgsql_table_t:s0:c2 3 ccc + \. + + COPY t2 TO stdout; + COPY t2 (security_label, x, y) TO stdout; + COPY t2 (security_label, x, y) TO stdout CSV FORCE QUOTE security_label,y; \ No newline at end of file diff -Nrpc base/src/test/sepgsql/sql/security_label_sysattr.sql sepgsql/src/test/sepgsql/sql/security_label_sysattr.sql *** base/src/test/sepgsql/sql/security_label_sysattr.sql Thu Jan 1 09:00:00 1970 --- sepgsql/src/test/sepgsql/sql/security_label_sysattr.sql Tue Dec 16 14:59:51 2008 *************** *** 0 **** --- 1,2 ---- + -- Basic security label + -- ==================== \ No newline at end of file