+##
+## Allow unprived users to execute DDL statement
+##
+##
+gen_tunable(sepgsql_enable_users_ddl, true)
+
type postgresql_t;
type postgresql_exec_t;
init_daemon_domain(postgresql_t,postgresql_exec_t)
@@ -27,6 +44,58 @@
type postgresql_var_run_t;
files_pid_file(postgresql_var_run_t)
+# database clients attribute
+attribute sepgsql_client_type;
+attribute sepgsql_unconfined_type;
+
+# database objects attribute
+attribute sepgsql_database_type;
+attribute sepgsql_table_type;
+attribute sepgsql_sysobj_table_type;
+attribute sepgsql_procedure_type;
+attribute sepgsql_blob_type;
+attribute sepgsql_module_type;
+
+# database object types
+type sepgsql_blob_t;
+postgresql_blob_object(sepgsql_blob_t)
+
+type sepgsql_db_t;
+postgresql_database_object(sepgsql_db_t)
+
+type sepgsql_fixed_table_t;
+postgresql_table_object(sepgsql_fixed_table_t)
+
+type sepgsql_proc_t;
+postgresql_procedure_object(sepgsql_proc_t)
+
+type sepgsql_ro_blob_t;
+postgresql_blob_object(sepgsql_ro_blob_t)
+
+type sepgsql_ro_table_t;
+postgresql_table_object(sepgsql_ro_table_t)
+
+type sepgsql_secret_blob_t;
+postgresql_blob_object(sepgsql_secret_blob_t)
+
+type sepgsql_secret_table_t;
+postgresql_table_object(sepgsql_secret_table_t)
+
+type sepgsql_sysobj_t;
+postgresql_system_table_object(sepgsql_sysobj_t)
+
+type sepgsql_table_t;
+postgresql_table_object(sepgsql_table_t)
+
+type sepgsql_trusted_proc_t;
+postgresql_procedure_object(sepgsql_trusted_proc_t)
+
+# Trusted Procedure Domain
+type sepgsql_trusted_domain_t;
+domain_type(sepgsql_trusted_domain_t)
+postgresql_unconfined(sepgsql_trusted_domain_t)
+role system_r types sepgsql_trusted_domain_t;
+
########################################
#
# postgresql Local policy
@@ -42,7 +111,21 @@
allow postgresql_t self:udp_socket create_stream_socket_perms;
allow postgresql_t self:unix_dgram_socket create_socket_perms;
allow postgresql_t self:unix_stream_socket create_stream_socket_perms;
+allow postgresql_t self:netlink_selinux_socket create_socket_perms;
+allow postgresql_t sepgsql_database_type:db_database *;
+type_transition postgresql_t postgresql_t:db_database sepgsql_db_t;
+
+allow postgresql_t sepgsql_module_type:db_database install_module;
+allow postgresql_t sepgsql_table_type:{ db_table db_column db_tuple } *;
+allow postgresql_t sepgsql_procedure_type:db_procedure *;
+allow postgresql_t sepgsql_blob_type:db_blob *;
+
+# server specific type transitions
+type_transition postgresql_t sepgsql_database_type:db_table sepgsql_sysobj_t;
+type_transition postgresql_t sepgsql_database_type:db_procedure sepgsql_proc_t;
+type_transition postgresql_t sepgsql_database_type:db_blob sepgsql_blob_t;
+
manage_dirs_pattern(postgresql_t,postgresql_db_t,postgresql_db_t)
manage_files_pattern(postgresql_t,postgresql_db_t,postgresql_db_t)
manage_lnk_files_pattern(postgresql_t,postgresql_db_t,postgresql_db_t)
@@ -75,6 +158,9 @@
manage_sock_files_pattern(postgresql_t,postgresql_var_run_t,postgresql_var_run_t)
files_pid_filetrans(postgresql_t,postgresql_var_run_t,file)
+# Database/Loadable module
+allow sepgsql_database_type sepgsql_module_type:db_database load_module;
+
kernel_read_kernel_sysctls(postgresql_t)
kernel_read_system_state(postgresql_t)
kernel_list_proc(postgresql_t)
@@ -101,6 +187,12 @@
fs_getattr_all_fs(postgresql_t)
fs_search_auto_mountpoints(postgresql_t)
+selinux_get_enforce_mode(postgresql_t)
+selinux_validate_context(postgresql_t)
+selinux_compute_access_vector(postgresql_t)
+selinux_compute_create_context(postgresql_t)
+selinux_compute_relabel_context(postgresql_t)
+
term_use_controlling_term(postgresql_t)
corecmd_exec_bin(postgresql_t)
@@ -126,7 +218,7 @@
miscfiles_read_localization(postgresql_t)
-seutil_dontaudit_search_config(postgresql_t)
+seutil_libselinux_linked(postgresql_t)
userdom_dontaudit_use_unpriv_user_fds(postgresql_t)
@@ -167,3 +259,89 @@
optional_policy(`
udev_read_db(postgresql_t)
')
+
+########################################
+#
+# Rules common to all clients
+#
+
+allow sepgsql_client_type sepgsql_db_t:db_database { getattr access get_param set_param };
+type_transition sepgsql_client_type sepgsql_client_type:db_database sepgsql_db_t;
+
+allow sepgsql_client_type sepgsql_fixed_table_t:db_table { getattr use select insert };
+allow sepgsql_client_type sepgsql_fixed_table_t:db_column { getattr use select insert };
+allow sepgsql_client_type sepgsql_fixed_table_t:db_tuple { use select insert };
+
+allow sepgsql_client_type sepgsql_table_t:db_table { getattr use select update insert delete };
+allow sepgsql_client_type sepgsql_table_t:db_column { getattr use select update insert };
+allow sepgsql_client_type sepgsql_table_t:db_tuple { use select update insert delete };
+
+allow sepgsql_client_type sepgsql_ro_table_t:db_table { getattr use select };
+allow sepgsql_client_type sepgsql_ro_table_t:db_column { getattr use select };
+allow sepgsql_client_type sepgsql_ro_table_t:db_tuple { use select };
+
+allow sepgsql_client_type sepgsql_secret_table_t:db_table getattr;
+allow sepgsql_client_type sepgsql_secret_table_t:db_column getattr;
+
+allow sepgsql_client_type sepgsql_sysobj_t:db_table { getattr use select };
+allow sepgsql_client_type sepgsql_sysobj_t:db_column { getattr use select };
+allow sepgsql_client_type sepgsql_sysobj_t:db_tuple { use select };
+
+allow sepgsql_client_type sepgsql_proc_t:db_procedure { getattr execute };
+allow sepgsql_client_type sepgsql_trusted_proc_t:db_procedure { getattr execute entrypoint };
+
+allow sepgsql_client_type sepgsql_blob_t:db_blob { create drop getattr setattr read write };
+allow sepgsql_client_type sepgsql_ro_blob_t:db_blob { getattr read };
+allow sepgsql_client_type sepgsql_secret_blob_t:db_blob getattr;
+
+tunable_policy(`sepgsql_enable_users_ddl',`
+ allow sepgsql_client_type sepgsql_table_t:db_table { create drop setattr };
+ allow sepgsql_client_type sepgsql_table_t:db_column { create drop setattr };
+ allow sepgsql_client_type sepgsql_sysobj_t:db_tuple { update insert delete };
+')
+
+########################################
+#
+# Unconfined access to this module
+#
+allow sepgsql_unconfined_type sepgsql_database_type:db_database *;
+type_transition sepgsql_unconfined_type sepgsql_unconfined_type:db_database sepgsql_db_t;
+
+type_transition sepgsql_unconfined_type sepgsql_database_type:db_table sepgsql_table_t;
+type_transition sepgsql_unconfined_type sepgsql_database_type:db_procedure sepgsql_proc_t;
+type_transition sepgsql_unconfined_type sepgsql_database_type:db_blob sepgsql_blob_t;
+
+allow sepgsql_unconfined_type sepgsql_table_type:{ db_table db_column db_tuple } *;
+
+# unconfined domain is not allowed to invoke user defined procedure directly.
+# They have to confirm and relabel it at first.
+allow sepgsql_unconfined_type { sepgsql_proc_t sepgsql_trusted_proc_t }:db_procedure *;
+allow sepgsql_unconfined_type sepgsql_procedure_type:db_procedure { create drop getattr setattr relabelfrom relabelto };
+
+allow sepgsql_unconfined_type sepgsql_blob_type:db_blob *;
+
+allow sepgsql_unconfined_type sepgsql_module_type:db_database install_module;
+
+optional_policy(`
+ kernel_relabelfrom_unlabeled_database(sepgsql_unconfined_type)
+')
+
+########################################
+#
+# Dontaudit deny logs in row-level access control
+#
+
+# NOTE:
+# The purpose of the dontaudit rule in row-level access control is to prevent a flood of logs.
+# If a client tries to SELECT a table including violated tuples, these are filtered from
+# the result set as if not exist, but its access denied longs can be recorded within log files.
+# In generally, the number of tuples are much larger than the number of columns, tables and so on.
+# So, it makes a flood of logs when many tuples are violated.
+#
+# The default policy does not prevent anything for sepgsql_client_type sepgsql_unconfined_type,
+# so we don't need "dontaudit" rules in Type-Enforcement. However, MLS/MCS can prevent them
+# to access classified tuples and can make a audit record.
+#
+# Therefore, the following rule is applied for any domains which can connect SE-PostgreSQL.
+
+dontaudit { postgresql_t sepgsql_client_type sepgsql_unconfined_type } { sepgsql_table_type - sepgsql_sysobj_table_type } : db_tuple { use select update insert delete };
Index: refpolicy/policy/modules/services/postgresql.fc
===================================================================
--- refpolicy/policy/modules/services/postgresql.fc (revision 2710)
+++ refpolicy/policy/modules/services/postgresql.fc (working copy)
@@ -6,8 +6,8 @@
#
# /usr
#
-/usr/bin/initdb -- gen_context(system_u:object_r:postgresql_exec_t,s0)
-/usr/bin/postgres -- gen_context(system_u:object_r:postgresql_exec_t,s0)
+/usr/bin/initdb(\.sepgsql)? -- gen_context(system_u:object_r:postgresql_exec_t,s0)
+/usr/bin/(se)?postgres -- gen_context(system_u:object_r:postgresql_exec_t,s0)
/usr/lib/pgsql/test/regres(/.*)? gen_context(system_u:object_r:postgresql_db_t,s0)
/usr/lib/pgsql/test/regress/pg_regress -- gen_context(system_u:object_r:postgresql_exec_t,s0)
@@ -30,8 +30,12 @@
/var/lib/pgsql/data(/.*)? gen_context(system_u:object_r:postgresql_db_t,s0)
/var/lib/pgsql/pgstartup\.log gen_context(system_u:object_r:postgresql_log_t,s0)
+/var/lib/sepgsql(/.*)? gen_context(system_u:object_r:postgresql_db_t,s0)
+/var/lib/sepgsql/pgstartup\.log -- gen_context(system_u:object_r:postgresql_log_t,s0)
+
/var/log/postgres\.log.* -- gen_context(system_u:object_r:postgresql_log_t,s0)
/var/log/postgresql(/.*)? gen_context(system_u:object_r:postgresql_log_t,s0)
+/var/log/sepostgresql\.log.* -- gen_context(system_u:object_r:postgresql_log_t,s0)
ifdef(`distro_redhat', `
/var/log/rhdb/rhdb(/.*)? gen_context(system_u:object_r:postgresql_log_t,s0)
Index: refpolicy/policy/modules/system/userdomain.if
===================================================================
--- refpolicy/policy/modules/system/userdomain.if (revision 2710)
+++ refpolicy/policy/modules/system/userdomain.if (working copy)
@@ -1197,6 +1197,10 @@
netutils_run_traceroute_cond($1_t,$1_r,{ $1_tty_device_t $1_devpts_t })
')
+ optional_policy(`
+ postgresql_userdom_template($1,$1_t,$1_r)
+ ')
+
# Run pppd in pppd_t by default for user
optional_policy(`
ppp_run_cond($1_t,$1_r,{ $1_tty_device_t $1_devpts_t })
@@ -1367,6 +1371,10 @@
')
optional_policy(`
+ postgresql_unconfined($1_t)
+ ')
+
+ optional_policy(`
userhelper_exec($1_t)
')
')
Index: refpolicy/policy/modules/system/libraries.te
===================================================================
--- refpolicy/policy/modules/system/libraries.te (revision 2710)
+++ refpolicy/policy/modules/system/libraries.te (working copy)
@@ -109,3 +109,8 @@
# blow up.
rpm_manage_script_tmp_files(ldconfig_t)
')
+
+optional_policy(`
+ postgresql_loadable_module(lib_t)
+ postgresql_loadable_module(textrel_shlib_t)
+')
Index: refpolicy/policy/modules/system/unconfined.if
===================================================================
--- refpolicy/policy/modules/system/unconfined.if (revision 2710)
+++ refpolicy/policy/modules/system/unconfined.if (working copy)
@@ -88,6 +88,10 @@
')
optional_policy(`
+ postgresql_unconfined($1)
+ ')
+
+ optional_policy(`
seutil_create_bin_policy($1)
seutil_relabelto_bin_policy($1)
')
Index: refpolicy/policy/modules/system/init.fc
===================================================================
--- refpolicy/policy/modules/system/init.fc (revision 2710)
+++ refpolicy/policy/modules/system/init.fc (working copy)
@@ -38,6 +38,8 @@
#
# /usr
#
+/usr/bin/sepg_ctl -- gen_context(system_u:object_r:initrc_exec_t,s0)
+
/usr/libexec/dcc/start-.* -- gen_context(system_u:object_r:initrc_exec_t,s0)
/usr/libexec/dcc/stop-.* -- gen_context(system_u:object_r:initrc_exec_t,s0)