sepgsql: Support for new post-ALTER access hook.
authorRobert Haas
Wed, 27 Mar 2013 12:10:14 +0000 (08:10 -0400)
committerRobert Haas
Wed, 27 Mar 2013 12:14:19 +0000 (08:14 -0400)
KaiGai Kohei

12 files changed:
contrib/sepgsql/database.c
contrib/sepgsql/expected/alter.out [new file with mode: 0644]
contrib/sepgsql/expected/ddl.out
contrib/sepgsql/hooks.c
contrib/sepgsql/proc.c
contrib/sepgsql/relation.c
contrib/sepgsql/schema.c
contrib/sepgsql/sepgsql.h
contrib/sepgsql/sql/alter.sql [new file with mode: 0644]
contrib/sepgsql/sql/ddl.sql
contrib/sepgsql/test_sepgsql
doc/src/sgml/sepgsql.sgml

index 975c1d47958fd04084b1f2c5f6f13e592c51ba3e..64d37a3ca9939b17bb31ac878a89c4141333fce5 100644 (file)
@@ -148,6 +148,33 @@ sepgsql_database_drop(Oid databaseId)
    pfree(audit_name);
 }
 
+/*
+ * sepgsql_database_post_alter
+ *
+ * It checks privileges to alter the supplied database
+ */
+void
+sepgsql_database_setattr(Oid databaseId)
+{
+   ObjectAddress object;
+   char       *audit_name;
+
+   /*
+    * check db_database:{setattr} permission
+    */
+   object.classId = DatabaseRelationId;
+   object.objectId = databaseId;
+   object.objectSubId = 0;
+   audit_name = getObjectDescription(&object);
+
+   sepgsql_avc_check_perms(&object,
+                           SEPG_CLASS_DB_DATABASE,
+                           SEPG_DB_DATABASE__SETATTR,
+                           audit_name,
+                           true);
+   pfree(audit_name);
+}
+
 /*
  * sepgsql_database_relabel
  *
diff --git a/contrib/sepgsql/expected/alter.out b/contrib/sepgsql/expected/alter.out
new file mode 100644 (file)
index 0000000..ef9abb3
--- /dev/null
@@ -0,0 +1,192 @@
+--
+-- Test for various ALTER statements
+--
+-- clean-up in case a prior regression run failed
+SET client_min_messages TO 'warning';
+DROP DATABASE IF EXISTS regtest_sepgsql_test_database_1;
+DROP DATABASE IF EXISTS regtest_sepgsql_test_database;
+DROP USER IF EXISTS regtest_sepgsql_test_user;
+RESET client_min_messages;
+SELECT sepgsql_getcon();   -- confirm client privilege
+              sepgsql_getcon               
+-------------------------------------------
+ unconfined_u:unconfined_r:unconfined_t:s0
+(1 row)
+
+--
+-- CREATE Objects to be altered (with debug_audit being silent)
+--
+CREATE DATABASE regtest_sepgsql_test_database_1;
+CREATE USER regtest_sepgsql_test_user;
+CREATE SCHEMA regtest_schema_1;
+CREATE SCHEMA regtest_schema_2;
+GRANT ALL ON SCHEMA regtest_schema_1 TO public;
+GRANT ALL ON SCHEMA regtest_schema_2  TO public;
+SET search_path = regtest_schema_1, regtest_schema_2, public;
+CREATE TABLE regtest_table_1 (a int, b text);
+CREATE TABLE regtest_table_2 (c text) inherits (regtest_table_1);
+CREATE TABLE regtest_table_3 (x int primary key, y text);
+CREATE SEQUENCE regtest_seq_1;
+CREATE VIEW regtest_view_1 AS SELECT * FROM regtest_table_1 WHERE a > 0;
+CREATE FUNCTION regtest_func_1 (text) RETURNS bool
+  AS 'BEGIN RETURN true; END' LANGUAGE 'plpgsql';
+-- switch on debug_audit
+SET sepgsql.debug_audit = true;
+SET client_min_messages = LOG;
+--
+-- ALTER xxx OWNER TO
+--
+-- XXX: It should take db_xxx:{setattr} permission checks even if
+--      owner is not actually changed.
+--
+ALTER DATABASE regtest_sepgsql_test_database_1 OWNER TO regtest_sepgsql_test_user;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_db_t:s0 tclass=db_database name="database regtest_sepgsql_test_database_1"
+ALTER DATABASE regtest_sepgsql_test_database_1 OWNER TO regtest_sepgsql_test_user;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_db_t:s0 tclass=db_database name="database regtest_sepgsql_test_database_1"
+ALTER SCHEMA regtest_schema_1 OWNER TO regtest_sepgsql_test_user;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_1"
+ALTER SCHEMA regtest_schema_1 OWNER TO regtest_sepgsql_test_user;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_1"
+ALTER TABLE regtest_table_1 OWNER TO regtest_sepgsql_test_user;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_1"
+ALTER TABLE regtest_table_1 OWNER TO regtest_sepgsql_test_user;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_1"
+ALTER SEQUENCE regtest_seq_1 OWNER TO regtest_sepgsql_test_user;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_seq_1"
+ALTER SEQUENCE regtest_seq_1 OWNER TO regtest_sepgsql_test_user;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_seq_1"
+ALTER VIEW regtest_view_1 OWNER TO regtest_sepgsql_test_user;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_view_t:s0 tclass=db_view name="view regtest_view_1"
+ALTER VIEW regtest_view_1 OWNER TO regtest_sepgsql_test_user;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_view_t:s0 tclass=db_view name="view regtest_view_1"
+ALTER FUNCTION regtest_func_1(text) OWNER TO regtest_sepgsql_test_user;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="function regtest_func_1(text)"
+ALTER FUNCTION regtest_func_1(text) OWNER TO regtest_sepgsql_test_user;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="function regtest_func_1(text)"
+--
+-- ALTER xxx SET SCHEMA
+--
+ALTER TABLE regtest_table_1 SET SCHEMA regtest_schema_2;
+LOG:  SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_1"
+LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_1"
+ALTER SEQUENCE regtest_seq_1 SET SCHEMA regtest_schema_2;
+LOG:  SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_1"
+LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_seq_1"
+ALTER VIEW regtest_view_1 SET SCHEMA regtest_schema_2;
+LOG:  SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_1"
+LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_view_t:s0 tclass=db_view name="view regtest_view_1"
+ALTER FUNCTION regtest_func_1(text) SET SCHEMA regtest_schema_2;
+LOG:  SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_1"
+LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_1"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="function regtest_func_1(text)"
+--
+-- ALTER xxx RENAME TO
+--
+ALTER DATABASE regtest_sepgsql_test_database_1 RENAME TO regtest_sepgsql_test_database;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_db_t:s0 tclass=db_database name="database regtest_sepgsql_test_database_1"
+ALTER SCHEMA regtest_schema_1 RENAME TO regtest_schema;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_1"
+ALTER TABLE regtest_table_1 RENAME TO regtest_table;
+LOG:  SELinux: allowed { add_name remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_1"
+ALTER SEQUENCE regtest_seq_1 RENAME TO regtest_seq;
+LOG:  SELinux: allowed { add_name remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_seq_1"
+ALTER VIEW regtest_view_1 RENAME TO regtest_view;
+LOG:  SELinux: allowed { add_name remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_view_t:s0 tclass=db_view name="view regtest_view_1"
+ALTER FUNCTION regtest_func_1(text) RENAME TO regtest_func;
+LOG:  SELinux: allowed { add_name remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema_2"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_proc_exec_t:s0 tclass=db_procedure name="function regtest_func_1(text)"
+SET search_path = regtest_schema, regtest_schema_2, public;
+--
+-- misc ALTER commands
+--
+ALTER DATABASE regtest_sepgsql_test_database CONNECTION LIMIT 999;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_db_t:s0 tclass=db_database name="database regtest_sepgsql_test_database"
+ALTER DATABASE regtest_sepgsql_test_database SET search_path TO regtest_schema, public; -- not supported yet
+ALTER TABLE regtest_table ADD COLUMN d float;
+LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column d"
+LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_2 column d"
+ALTER TABLE regtest_table DROP COLUMN d;
+LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_2 column d"
+LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column d"
+ALTER TABLE regtest_table ALTER b SET DEFAULT 'abcd';   -- not supported yet
+ALTER TABLE regtest_table ALTER b SET DEFAULT 'XYZ';    -- not supported yet
+ALTER TABLE regtest_table ALTER b DROP DEFAULT;         -- not supported yet
+ALTER TABLE regtest_table ALTER b SET NOT NULL;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column b"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_2 column b"
+ALTER TABLE regtest_table ALTER b DROP NOT NULL;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column b"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_2 column b"
+ALTER TABLE regtest_table ALTER b SET STATISTICS -1;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column b"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_2 column b"
+ALTER TABLE regtest_table ALTER b SET (n_distinct = 999);
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column b"
+ALTER TABLE regtest_table ALTER b SET STORAGE PLAIN;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column b"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_2 column b"
+ALTER TABLE regtest_table ADD CONSTRAINT test_fk FOREIGN KEY (a) REFERENCES regtest_table_3(x); -- not supported
+LOG:  SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table"
+LOG:  SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column a"
+LOG:  SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_3"
+LOG:  SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_3 column x"
+LOG:  SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table"
+CONTEXT:  SQL statement "SELECT fk."a" FROM ONLY "regtest_schema_2"."regtest_table" fk LEFT OUTER JOIN ONLY "regtest_schema"."regtest_table_3" pk ON ( pk."x" OPERATOR(pg_catalog.=) fk."a") WHERE pk."x" IS NULL AND (fk."a" IS NOT NULL)"
+LOG:  SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column a"
+CONTEXT:  SQL statement "SELECT fk."a" FROM ONLY "regtest_schema_2"."regtest_table" fk LEFT OUTER JOIN ONLY "regtest_schema"."regtest_table_3" pk ON ( pk."x" OPERATOR(pg_catalog.=) fk."a") WHERE pk."x" IS NULL AND (fk."a" IS NOT NULL)"
+LOG:  SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_3"
+CONTEXT:  SQL statement "SELECT fk."a" FROM ONLY "regtest_schema_2"."regtest_table" fk LEFT OUTER JOIN ONLY "regtest_schema"."regtest_table_3" pk ON ( pk."x" OPERATOR(pg_catalog.=) fk."a") WHERE pk."x" IS NULL AND (fk."a" IS NOT NULL)"
+LOG:  SELinux: allowed { select } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_3 column x"
+CONTEXT:  SQL statement "SELECT fk."a" FROM ONLY "regtest_schema_2"."regtest_table" fk LEFT OUTER JOIN ONLY "regtest_schema"."regtest_table_3" pk ON ( pk."x" OPERATOR(pg_catalog.=) fk."a") WHERE pk."x" IS NULL AND (fk."a" IS NOT NULL)"
+ALTER TABLE regtest_table ADD CONSTRAINT test_ck CHECK (b like '%abc%') NOT VALID;      -- not supported
+ALTER TABLE regtest_table VALIDATE CONSTRAINT test_ck;  -- not supported
+ALTER TABLE regtest_table DROP CONSTRAINT test_ck;      -- not supported
+CREATE TRIGGER regtest_test_trig BEFORE UPDATE ON regtest_table
+    FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
+ALTER TABLE regtest_table DISABLE TRIGGER regtest_test_trig;    -- not supported
+ALTER TABLE regtest_table ENABLE  TRIGGER regtest_test_trig;    -- not supported
+CREATE RULE regtest_test_rule AS ON INSERT TO regtest_table_3 DO ALSO NOTHING;
+ALTER TABLE regtest_table_3 DISABLE RULE regtest_test_rule;     -- not supported
+ALTER TABLE regtest_table_3 ENABLE RULE regtest_test_rule;      -- not supported
+ALTER TABLE regtest_table SET WITH OIDS;
+LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column oid"
+LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_2 column oid"
+ALTER TABLE regtest_table SET WITHOUT OIDS;
+LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_2 column oid"
+LOG:  SELinux: allowed { drop } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column oid"
+ALTER TABLE regtest_table SET (fillfactor = 75);
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table"
+ALTER TABLE regtest_table RESET (fillfactor);
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table"
+ALTER TABLE regtest_table_2 NO INHERIT regtest_table;   -- not supported
+ALTER TABLE regtest_table_2 INHERIT regtest_table;      -- not supported
+ALTER TABLE regtest_table SET TABLESPACE pg_default;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table"
+ALTER VIEW regtest_view SET (security_barrier);
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_view_t:s0 tclass=db_view name="view regtest_view"
+ALTER SEQUENCE regtest_seq INCREMENT BY 10 START WITH 1000;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_seq"
+--
+-- clean-up objects
+--
+RESET sepgsql.debug_audit;
+RESET client_min_messages;
+DROP DATABASE regtest_sepgsql_test_database;
+DROP SCHEMA regtest_schema CASCADE;
+NOTICE:  drop cascades to 3 other objects
+DETAIL:  drop cascades to table regtest_table_2
+drop cascades to table regtest_table_3
+drop cascades to constraint test_fk on table regtest_table
+DROP SCHEMA regtest_schema_2 CASCADE;
+NOTICE:  drop cascades to 4 other objects
+DETAIL:  drop cascades to table regtest_table
+drop cascades to sequence regtest_seq
+drop cascades to view regtest_view
+drop cascades to function regtest_func(text)
+DROP USER regtest_sepgsql_test_user;
index 1f7ea886b00227b103680d427c14da12f082ef80..d60c65bdb1b1543fd559c92ccddc972cc79e4810 100644 (file)
@@ -1,6 +1,11 @@
 --
 -- Regression Test for DDL of Object Permission Checks
 --
+-- clean-up in case a prior regression run failed
+SET client_min_messages TO 'warning';
+DROP DATABASE IF EXISTS regtest_sepgsql_test_database;
+DROP USER IF EXISTS regtest_sepgsql_test_user;
+RESET client_min_messages;
 -- confirm required permissions using audit messages
 SELECT sepgsql_getcon();   -- confirm client privilege
               sepgsql_getcon               
@@ -36,6 +41,7 @@ LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_
 LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column y"
 LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
 LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_table_x_seq"
 ALTER TABLE regtest_table ADD COLUMN z int;
 LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table column z"
 CREATE TABLE regtest_table_2 (a int) WITH OIDS;
@@ -61,6 +67,7 @@ CREATE SEQUENCE regtest_seq;
 LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
 LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_seq"
 CREATE TYPE regtest_comptype AS (a int, b text);
+LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
 CREATE FUNCTION regtest_func(text,int[]) RETURNS bool LANGUAGE plpgsql
       AS 'BEGIN RAISE NOTICE ''regtest_func => %'', $1; RETURN true; END';
 LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
@@ -86,6 +93,7 @@ LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_
 LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_3 column ctid"
 LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_3 column x"
 LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_3 column y"
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_seq_t:s0 tclass=db_sequence name="sequence regtest_table_3_y_seq"
 CREATE VIEW regtest_view_2 AS SELECT * FROM regtest_table_3 WHERE x < y;
 LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
 LOG:  SELinux: allowed { create } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_view_t:s0 tclass=db_view name="view regtest_view_2"
@@ -118,6 +126,7 @@ CREATE INDEX regtest_index_tbl4_z ON regtest_table_4(z);
 LOG:  SELinux: allowed { add_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
 LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
 ALTER TABLE regtest_table_4 ALTER COLUMN y TYPE float;
+LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_column name="table regtest_table_4 column y"
 DROP INDEX regtest_index_tbl4_y;
 LOG:  SELinux: allowed { remove_name } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_schema_t:s0 tclass=db_schema name="schema regtest_schema"
 LOG:  SELinux: allowed { setattr } scontext=unconfined_u:unconfined_r:unconfined_t:s0 tcontext=unconfined_u:object_r:sepgsql_table_t:s0 tclass=db_table name="table regtest_table_4"
index 7ec72a05632c16cbcdc52af5106c7747842484ea..0715aa8bc6e802d0ad80245cd8c0db41ad86b619 100644 (file)
@@ -188,6 +188,54 @@ sepgsql_object_access(ObjectAccessType access,
            }
            break;
 
+       case OAT_POST_ALTER:
+           {
+               ObjectAccessPostAlter  *pa_arg = arg;
+               bool    is_internal = pa_arg->is_internal;
+
+               switch (classId)
+               {
+                   case DatabaseRelationId:
+                       Assert(!is_internal);
+                       sepgsql_database_setattr(objectId);
+                       break;
+
+                   case NamespaceRelationId:
+                       Assert(!is_internal);
+                       sepgsql_schema_setattr(objectId);
+                       break;
+
+                   case RelationRelationId:
+                       if (subId == 0)
+                        {
+                           /*
+                            * A case when we don't want to apply permission
+                            * check is that relation is internally altered
+                            * without user's intention. E.g, no need to
+                            * check on toast table/index to be renamed at
+                            * end of the table rewrites.
+                            */
+                           if (is_internal)
+                                break;
+
+                           sepgsql_relation_setattr(objectId);
+                        }
+                        else
+                            sepgsql_attribute_setattr(objectId, subId);
+                       break;
+
+                   case ProcedureRelationId:
+                       Assert(!is_internal);
+                       sepgsql_proc_setattr(objectId);
+                       break;
+
+                   default:
+                       /* Ignore unsupported object classes */
+                       break;
+               }
+           }
+           break;
+
        default:
            elog(ERROR, "unexpected object access type: %d", (int) access);
            break;
index b47c880f54c117a4614fe6cdc8a262fa86efef83..53b941d85583e19976fd53aaead03f7fda9f598b 100644 (file)
@@ -23,6 +23,7 @@
 #include "utils/builtins.h"
 #include "utils/fmgroids.h"
 #include "utils/lsyscache.h"
+#include "utils/syscache.h"
 #include "utils/tqual.h"
 
 #include "sepgsql.h"
@@ -43,6 +44,7 @@ sepgsql_proc_post_create(Oid functionId)
    char       *scontext;
    char       *tcontext;
    char       *ncontext;
+   uint32      required;
    int         i;
    StringInfoData audit_name;
    ObjectAddress object;
@@ -96,7 +98,7 @@ sepgsql_proc_post_create(Oid functionId)
                                      SEPG_CLASS_DB_PROCEDURE);
 
    /*
-    * check db_procedure:{create} permission
+    * check db_procedure:{create (install)} permission
     */
    initStringInfo(&audit_name);
    appendStringInfo(&audit_name, "function %s(", NameStr(proForm->proname));
@@ -110,9 +112,13 @@ sepgsql_proc_post_create(Oid functionId)
    }
    appendStringInfoChar(&audit_name, ')');
 
+   required = SEPG_DB_PROCEDURE__CREATE;
+   if (proForm->proleakproof)
+       required |= SEPG_DB_PROCEDURE__INSTALL;
+
    sepgsql_avc_check_perms_label(ncontext,
                                  SEPG_CLASS_DB_PROCEDURE,
-                                 SEPG_DB_PROCEDURE__CREATE,
+                                 required,
                                  audit_name.data,
                                  true);
 
@@ -214,3 +220,83 @@ sepgsql_proc_relabel(Oid functionId, const char *seclabel)
                                  true);
    pfree(audit_name);
 }
+
+/*
+ * sepgsql_proc_setattr
+ *
+ * It checks privileges to alter the supplied function.
+ */
+void
+sepgsql_proc_setattr(Oid functionId)
+{
+   Relation        rel;
+   ScanKeyData     skey;
+   SysScanDesc     sscan;
+   HeapTuple       oldtup;
+   HeapTuple       newtup;
+   Form_pg_proc    oldform;
+   Form_pg_proc    newform;
+   uint32          required;
+   ObjectAddress   object;
+   char           *audit_name;
+
+   /*
+    * Fetch newer catalog
+    */
+   rel = heap_open(ProcedureRelationId, AccessShareLock);
+
+   ScanKeyInit(&skey,
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(functionId));
+
+   sscan = systable_beginscan(rel, ProcedureOidIndexId, true,
+                              SnapshotSelf, 1, &skey);
+   newtup = systable_getnext(sscan);
+   if (!HeapTupleIsValid(newtup))
+       elog(ERROR, "catalog lookup failed for function %u", functionId);
+   newform = (Form_pg_proc) GETSTRUCT(newtup);
+
+   /*
+    * Fetch older catalog
+    */
+   oldtup = SearchSysCache1(PROCOID, ObjectIdGetDatum(functionId));
+   if (!HeapTupleIsValid(oldtup))
+       elog(ERROR, "cache lookup failed for function %u", functionId);
+   oldform = (Form_pg_proc) GETSTRUCT(oldtup);
+
+   /*
+    * Does this ALTER command takes operation to namespace?
+    */
+   if (newform->pronamespace != oldform->pronamespace)
+   {
+       sepgsql_schema_remove_name(oldform->pronamespace);
+       sepgsql_schema_add_name(oldform->pronamespace);
+   }
+   if (strcmp(NameStr(newform->proname), NameStr(oldform->proname)) != 0)
+       sepgsql_schema_rename(oldform->pronamespace);
+
+   /*
+    * check db_procedure:{setattr (install)} permission
+    */
+   required = SEPG_DB_PROCEDURE__SETATTR;
+   if (!oldform->proleakproof && newform->proleakproof)
+       required |= SEPG_DB_PROCEDURE__INSTALL;
+
+   object.classId = ProcedureRelationId;
+   object.objectId = functionId;
+   object.objectSubId = 0;
+   audit_name = getObjectDescription(&object);
+
+   sepgsql_avc_check_perms(&object,
+                           SEPG_CLASS_DB_PROCEDURE,
+                            required,
+                           audit_name,
+                           true);
+   /* cleanups */
+   pfree(audit_name);
+
+   ReleaseSysCache(oldtup);
+   systable_endscan(sscan);
+   heap_close(rel, AccessShareLock);
+}
index a277fab06646f095f4382ff89f0daea65236571c..8bcaa41d312e1e20e0a02d10443562b449159c1f 100644 (file)
@@ -190,6 +190,36 @@ sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
    pfree(audit_name);
 }
 
+/*
+ * sepgsql_attribute_setattr
+ *
+ * It checks privileges to alter the supplied column.
+ */
+void
+sepgsql_attribute_setattr(Oid relOid, AttrNumber attnum)
+{
+   ObjectAddress object;
+   char       *audit_name;
+
+   if (get_rel_relkind(relOid) != RELKIND_RELATION)
+       return;
+
+   /*
+    * check db_column:{setattr} permission
+    */
+   object.classId = RelationRelationId;
+   object.objectId = relOid;
+   object.objectSubId = attnum;
+   audit_name = getObjectDescription(&object);
+
+   sepgsql_avc_check_perms(&object,
+                           SEPG_CLASS_DB_COLUMN,
+                           SEPG_DB_COLUMN__SETATTR,
+                           audit_name,
+                           true);
+   pfree(audit_name);
+}
+
 /*
  * sepgsql_relation_post_create
  *
@@ -529,6 +559,13 @@ sepgsql_relation_relabel(Oid relOid, const char *seclabel)
 void
 sepgsql_relation_setattr(Oid relOid)
 {
+   Relation        rel;
+   ScanKeyData     skey;
+   SysScanDesc     sscan;
+   HeapTuple       oldtup;
+   HeapTuple       newtup;
+   Form_pg_class   oldform;
+   Form_pg_class   newform;
    ObjectAddress object;
    char       *audit_name;
    uint16_t    tclass;
@@ -553,26 +590,66 @@ sepgsql_relation_setattr(Oid relOid)
            return;
    }
 
-   object.classId = RelationRelationId;
-   object.objectId = relOid;
-   object.objectSubId = 0;
-   audit_name = getObjectDescription(&object);
+   /*
+    * Fetch newer catalog
+    */
+   rel = heap_open(RelationRelationId, AccessShareLock);
+
+   ScanKeyInit(&skey,
+               ObjectIdAttributeNumber,
+               BTEqualStrategyNumber, F_OIDEQ,
+               ObjectIdGetDatum(relOid));
+
+   sscan = systable_beginscan(rel, ClassOidIndexId, true,
+                              SnapshotSelf, 1, &skey);
+
+   newtup = systable_getnext(sscan);
+   if (!HeapTupleIsValid(newtup))
+       elog(ERROR, "catalog lookup failed for relation %u", relOid);
+   newform = (Form_pg_class) GETSTRUCT(newtup);
 
    /*
-    * XXX - we should add checks related to namespace stuff, when
-    * object_access_hook get support for ALTER statement.  Right now, there is
-    * no invocation path on ALTER ...  RENAME TO / SET SCHEMA.
+    * Fetch older catalog
+    */
+   oldtup = SearchSysCache1(RELOID, ObjectIdGetDatum(relOid));
+   if (!HeapTupleIsValid(oldtup))
+       elog(ERROR, "cache lookup failed for relation %u", relOid);
+   oldform = (Form_pg_class) GETSTRUCT(oldtup);
+
+   /*
+    * Does this ALTER command takes operation to namespace?
+    */
+   if (newform->relnamespace != oldform->relnamespace)
+   {
+       sepgsql_schema_remove_name(oldform->relnamespace);
+       sepgsql_schema_add_name(newform->relnamespace);
+   }
+   if (strcmp(NameStr(newform->relname), NameStr(oldform->relname)) != 0)
+       sepgsql_schema_rename(oldform->relnamespace);
+
+   /*
+    * XXX - In the future version, db_tuple:{use} of system catalog entry
+    * shall be checked, if tablespace configuration is changed.
     */
 
    /*
     * check db_xxx:{setattr} permission
     */
+   object.classId = RelationRelationId;
+   object.objectId = relOid;
+   object.objectSubId = 0;
+   audit_name = getObjectDescription(&object);
+
    sepgsql_avc_check_perms(&object,
                            tclass,
                            SEPG_DB_TABLE__SETATTR,
                            audit_name,
                            true);
    pfree(audit_name);
+
+   ReleaseSysCache(oldtup);
+   systable_endscan(sscan);
+   heap_close(rel, AccessShareLock);
 }
 
 /*
index 75b28261ce625a3d79a654d8ca548951c39a32ce..ecdfd738d911cef23b1d1e9affdaba34b8fb071f 100644 (file)
@@ -162,3 +162,54 @@ sepgsql_schema_relabel(Oid namespaceId, const char *seclabel)
                                  true);
    pfree(audit_name);
 }
+
+/*
+ * sepgsql_schema_check_perms
+ *
+ * utility routine to check db_schema:{xxx} permissions
+ */
+static void
+check_schema_perms(Oid namespaceId, uint32 required)
+{
+   ObjectAddress object;
+   char       *audit_name;
+
+   object.classId = NamespaceRelationId;
+   object.objectId = namespaceId;
+   object.objectSubId = 0;
+   audit_name = getObjectDescription(&object);
+
+   sepgsql_avc_check_perms(&object,
+                           SEPG_CLASS_DB_SCHEMA,
+                           required,
+                           audit_name,
+                           true);
+   pfree(audit_name);
+}
+
+/* db_schema:{setattr} permission */
+void
+sepgsql_schema_setattr(Oid namespaceId)
+{
+   check_schema_perms(namespaceId, SEPG_DB_SCHEMA__SETATTR);
+}
+
+void
+sepgsql_schema_add_name(Oid namespaceId)
+{
+   check_schema_perms(namespaceId, SEPG_DB_SCHEMA__ADD_NAME);
+}
+
+void
+sepgsql_schema_remove_name(Oid namespaceId)
+{
+   check_schema_perms(namespaceId, SEPG_DB_SCHEMA__REMOVE_NAME);
+}
+
+void
+sepgsql_schema_rename(Oid namespaceId)
+{
+   check_schema_perms(namespaceId,
+                      SEPG_DB_SCHEMA__ADD_NAME |
+                      SEPG_DB_SCHEMA__REMOVE_NAME);
+}
index 5ae51469d724507c19bcb8a5750329e546b2d159..d4ee94be5a08d62e1cfea65fc75952da40b45cf3 100644 (file)
@@ -293,6 +293,7 @@ extern void sepgsql_database_post_create(Oid databaseId,
                             const char *dtemplate);
 extern void sepgsql_database_drop(Oid databaseId);
 extern void sepgsql_database_relabel(Oid databaseId, const char *seclabel);
+extern void sepgsql_database_setattr(Oid databaseId);
 
 /*
  * schema.c
@@ -300,6 +301,10 @@ extern void sepgsql_database_relabel(Oid databaseId, const char *seclabel);
 extern void sepgsql_schema_post_create(Oid namespaceId);
 extern void sepgsql_schema_drop(Oid namespaceId);
 extern void sepgsql_schema_relabel(Oid namespaceId, const char *seclabel);
+extern void sepgsql_schema_setattr(Oid namespaceId);
+extern void sepgsql_schema_add_name(Oid namespaceId);
+extern void sepgsql_schema_remove_name(Oid namespaceId);
+extern void sepgsql_schema_rename(Oid namespaceId);
 
 /*
  * relation.c
@@ -308,6 +313,7 @@ extern void sepgsql_attribute_post_create(Oid relOid, AttrNumber attnum);
 extern void sepgsql_attribute_drop(Oid relOid, AttrNumber attnum);
 extern void sepgsql_attribute_relabel(Oid relOid, AttrNumber attnum,
                          const char *seclabel);
+extern void sepgsql_attribute_setattr(Oid relOid, AttrNumber attnum);
 extern void sepgsql_relation_post_create(Oid relOid);
 extern void sepgsql_relation_drop(Oid relOid);
 extern void sepgsql_relation_relabel(Oid relOid, const char *seclabel);
@@ -319,5 +325,6 @@ extern void sepgsql_relation_setattr(Oid relOid);
 extern void sepgsql_proc_post_create(Oid functionId);
 extern void sepgsql_proc_drop(Oid functionId);
 extern void sepgsql_proc_relabel(Oid functionId, const char *seclabel);
+extern void sepgsql_proc_setattr(Oid functionId);
 
 #endif   /* SEPGSQL_H */
diff --git a/contrib/sepgsql/sql/alter.sql b/contrib/sepgsql/sql/alter.sql
new file mode 100644 (file)
index 0000000..4bded7e
--- /dev/null
@@ -0,0 +1,136 @@
+--
+-- Test for various ALTER statements
+--
+
+-- clean-up in case a prior regression run failed
+SET client_min_messages TO 'warning';
+DROP DATABASE IF EXISTS regtest_sepgsql_test_database_1;
+DROP DATABASE IF EXISTS regtest_sepgsql_test_database;
+DROP USER IF EXISTS regtest_sepgsql_test_user;
+RESET client_min_messages;
+
+-- @SECURITY-CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0
+
+--
+-- CREATE Objects to be altered (with debug_audit being silent)
+--
+CREATE DATABASE regtest_sepgsql_test_database_1;
+
+CREATE USER regtest_sepgsql_test_user;
+
+CREATE SCHEMA regtest_schema_1;
+CREATE SCHEMA regtest_schema_2;
+
+GRANT ALL ON SCHEMA regtest_schema_1 TO public;
+GRANT ALL ON SCHEMA regtest_schema_2  TO public;
+
+SET search_path = regtest_schema_1, regtest_schema_2, public;
+
+CREATE TABLE regtest_table_1 (a int, b text);
+
+CREATE TABLE regtest_table_2 (c text) inherits (regtest_table_1);
+
+CREATE TABLE regtest_table_3 (x int primary key, y text);
+
+CREATE SEQUENCE regtest_seq_1;
+
+CREATE VIEW regtest_view_1 AS SELECT * FROM regtest_table_1 WHERE a > 0;
+
+CREATE FUNCTION regtest_func_1 (text) RETURNS bool
+  AS 'BEGIN RETURN true; END' LANGUAGE 'plpgsql';
+
+-- switch on debug_audit
+SET sepgsql.debug_audit = true;
+SET client_min_messages = LOG;
+
+--
+-- ALTER xxx OWNER TO
+--
+-- XXX: It should take db_xxx:{setattr} permission checks even if
+--      owner is not actually changed.
+--
+ALTER DATABASE regtest_sepgsql_test_database_1 OWNER TO regtest_sepgsql_test_user;
+ALTER DATABASE regtest_sepgsql_test_database_1 OWNER TO regtest_sepgsql_test_user;
+ALTER SCHEMA regtest_schema_1 OWNER TO regtest_sepgsql_test_user;
+ALTER SCHEMA regtest_schema_1 OWNER TO regtest_sepgsql_test_user;
+ALTER TABLE regtest_table_1 OWNER TO regtest_sepgsql_test_user;
+ALTER TABLE regtest_table_1 OWNER TO regtest_sepgsql_test_user;
+ALTER SEQUENCE regtest_seq_1 OWNER TO regtest_sepgsql_test_user;
+ALTER SEQUENCE regtest_seq_1 OWNER TO regtest_sepgsql_test_user;
+ALTER VIEW regtest_view_1 OWNER TO regtest_sepgsql_test_user;
+ALTER VIEW regtest_view_1 OWNER TO regtest_sepgsql_test_user;
+ALTER FUNCTION regtest_func_1(text) OWNER TO regtest_sepgsql_test_user;
+ALTER FUNCTION regtest_func_1(text) OWNER TO regtest_sepgsql_test_user;
+
+--
+-- ALTER xxx SET SCHEMA
+--
+ALTER TABLE regtest_table_1 SET SCHEMA regtest_schema_2;
+ALTER SEQUENCE regtest_seq_1 SET SCHEMA regtest_schema_2;
+ALTER VIEW regtest_view_1 SET SCHEMA regtest_schema_2;
+ALTER FUNCTION regtest_func_1(text) SET SCHEMA regtest_schema_2;
+
+--
+-- ALTER xxx RENAME TO
+--
+ALTER DATABASE regtest_sepgsql_test_database_1 RENAME TO regtest_sepgsql_test_database;
+ALTER SCHEMA regtest_schema_1 RENAME TO regtest_schema;
+ALTER TABLE regtest_table_1 RENAME TO regtest_table;
+ALTER SEQUENCE regtest_seq_1 RENAME TO regtest_seq;
+ALTER VIEW regtest_view_1 RENAME TO regtest_view;
+ALTER FUNCTION regtest_func_1(text) RENAME TO regtest_func;
+
+SET search_path = regtest_schema, regtest_schema_2, public;
+
+--
+-- misc ALTER commands
+--
+ALTER DATABASE regtest_sepgsql_test_database CONNECTION LIMIT 999;
+ALTER DATABASE regtest_sepgsql_test_database SET search_path TO regtest_schema, public; -- not supported yet
+
+ALTER TABLE regtest_table ADD COLUMN d float;
+ALTER TABLE regtest_table DROP COLUMN d;
+ALTER TABLE regtest_table ALTER b SET DEFAULT 'abcd';   -- not supported yet
+ALTER TABLE regtest_table ALTER b SET DEFAULT 'XYZ';    -- not supported yet
+ALTER TABLE regtest_table ALTER b DROP DEFAULT;         -- not supported yet
+ALTER TABLE regtest_table ALTER b SET NOT NULL;
+ALTER TABLE regtest_table ALTER b DROP NOT NULL;
+ALTER TABLE regtest_table ALTER b SET STATISTICS -1;
+ALTER TABLE regtest_table ALTER b SET (n_distinct = 999);
+ALTER TABLE regtest_table ALTER b SET STORAGE PLAIN;
+ALTER TABLE regtest_table ADD CONSTRAINT test_fk FOREIGN KEY (a) REFERENCES regtest_table_3(x); -- not supported
+ALTER TABLE regtest_table ADD CONSTRAINT test_ck CHECK (b like '%abc%') NOT VALID;      -- not supported
+ALTER TABLE regtest_table VALIDATE CONSTRAINT test_ck;  -- not supported
+ALTER TABLE regtest_table DROP CONSTRAINT test_ck;      -- not supported
+
+CREATE TRIGGER regtest_test_trig BEFORE UPDATE ON regtest_table
+    FOR EACH ROW EXECUTE PROCEDURE suppress_redundant_updates_trigger();
+
+ALTER TABLE regtest_table DISABLE TRIGGER regtest_test_trig;    -- not supported
+ALTER TABLE regtest_table ENABLE  TRIGGER regtest_test_trig;    -- not supported
+
+CREATE RULE regtest_test_rule AS ON INSERT TO regtest_table_3 DO ALSO NOTHING;
+ALTER TABLE regtest_table_3 DISABLE RULE regtest_test_rule;     -- not supported
+ALTER TABLE regtest_table_3 ENABLE RULE regtest_test_rule;      -- not supported
+
+ALTER TABLE regtest_table SET WITH OIDS;
+ALTER TABLE regtest_table SET WITHOUT OIDS;
+ALTER TABLE regtest_table SET (fillfactor = 75);
+ALTER TABLE regtest_table RESET (fillfactor);
+ALTER TABLE regtest_table_2 NO INHERIT regtest_table;   -- not supported
+ALTER TABLE regtest_table_2 INHERIT regtest_table;      -- not supported
+ALTER TABLE regtest_table SET TABLESPACE pg_default;
+
+ALTER VIEW regtest_view SET (security_barrier);
+
+ALTER SEQUENCE regtest_seq INCREMENT BY 10 START WITH 1000;
+
+--
+-- clean-up objects
+--
+RESET sepgsql.debug_audit;
+RESET client_min_messages;
+DROP DATABASE regtest_sepgsql_test_database;
+DROP SCHEMA regtest_schema CASCADE;
+DROP SCHEMA regtest_schema_2 CASCADE;
+DROP USER regtest_sepgsql_test_user;
index 5afe1ba193cf4861b6b5786c8fb8020ca9a1118d..c91c4cf572f15c69aa1afa37ec8f17debca4d6c4 100644 (file)
@@ -2,6 +2,12 @@
 -- Regression Test for DDL of Object Permission Checks
 --
 
+-- clean-up in case a prior regression run failed
+SET client_min_messages TO 'warning';
+DROP DATABASE IF EXISTS regtest_sepgsql_test_database;
+DROP USER IF EXISTS regtest_sepgsql_test_user;
+RESET client_min_messages;
+
 -- confirm required permissions using audit messages
 -- @SECURITY-CONTEXT=unconfined_u:unconfined_r:unconfined_t:s0
 SET sepgsql.debug_audit = true;
index 473004f6d22e37f0fa1c9968e847021aefab13dd..8d1a35ce8518ee9607f70339c2d74632b84eea8c 100755 (executable)
@@ -162,6 +162,31 @@ if [ "${POLICY_STATUS}" != on ]; then
     echo ""
     exit 1
 fi
+POLICY_STATUS=`getsebool sepgsql_enable_users_ddl | awk '{print $3}'`
+echo ${POLICY_STATUS:-failed}
+if [ "${POLICY_STATUS}" != on ]; then
+    echo ""
+    echo "The SELinux boolean 'sepgsql_enable_users_ddl' must be"
+    echo "turned on in order to enable the rules necessary to run"
+    echo "the regression tests."
+    echo ""
+    if [ "${POLICY_STATUS}" = "" ]; then
+        echo "We attempted to determine the state of this Boolean using"
+        echo "'getsebool', but that command did not produce the expected"
+        echo "output.  Please verify that getsebool is available and in"
+        echo "your PATH."
+    else
+        echo "You can turn on this variable using the following commands:"
+        echo ""
+        echo "  \$ sudo setsebool sepgsql_enable_users_ddl on"
+        echo ""
+        echo "For security reasons, it is suggested that you turn off this"
+        echo "variable when regression testing is complete, unless you"
+        echo "don't want to allow unprivileged users DDL commands."
+    fi
+    echo ""
+    exit 1
+fi
 
 # 'psql' command must be executable from test domain
 echo -n "checking whether we can run psql    ... "
@@ -259,6 +284,6 @@ echo "found ${NUM}"
 echo
 echo "============== running sepgsql regression tests       =============="
 
-make REGRESS="label dml ddl misc" REGRESS_OPTS="--launcher ./launcher" installcheck
+make REGRESS="label dml ddl alter misc" REGRESS_OPTS="--launcher ./launcher" installcheck
 
 # exit with the exit code provided by "make"
index e7ce8b5d5b3df811ec0e0946c83eaa123837cfd8..5ee08e1dee2b36553c39f9c9af5b9c16ed1bc932 100644 (file)
@@ -438,6 +438,12 @@ UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100;
     On creation of objects within a particular schema (tables, views,
     sequences and procedures), add_name will be also checked
     on the schema, not only create on the new object itself.
+    On install permission
+    will be checked if leakproof attribute was given, not only
+    create on the new function. This permission will be also
+    checked when user tries to turn on leakproof attribute
+    using  command, with
+    setattr permission on the function being altered.
    
 
    
@@ -450,9 +456,19 @@ UPDATE t1 SET x = 2, y = md5sum(y) WHERE z = 100;
    
 
    
-    When objects that are subsidiary of other objects (such as a table's indexes
-    or triggers) are created or dropped, setattr permission will be
-    checked on the main object, instead of the subsidiary object itself.
+    When ALTER command is executed, setattr will be
+    checked on the object being modified for each object types. 
+    In addition, remove_name and add_name
+    will be checked on the old and new schemas, respectively, when an
+    object is moved to a new schema.
+    For certain object types, additional checks are performed.
+   
+
+   
+    When objects that are subsidiary of other objects (such as a table's
+    indexes or triggers) are created, dropped or altered,
+    setattr permission will be checked on the main object,
+    instead of the subsidiary object itself.