policy_module(userdomain, 4.9.1)

########################################
#
# Declarations
#

## <desc>
## <p>
## Allow users to connect to the local mysql server
## </p>
## </desc>
gen_tunable(selinuxuser_mysql_connect_enabled, false)

## <desc>
## <p>
## Allow users to connect to PostgreSQL
## </p>
## </desc>
gen_tunable(selinuxuser_postgresql_connect_enabled, false)

## <desc>
## <p>
## Allow user to r/w files on filesystems
## that do not have extended attributes (FAT, CDROM, FLOPPY)
## </p>
## </desc>
gen_tunable(selinuxuser_rw_noexattrfile, false)

## <desc>
## <p>
## Allow user music sharing
## </p>
## </desc>
gen_tunable(selinuxuser_share_music, false)

## <desc>
## <p>
## Allow user  to use ssh chroot environment.
## </p>
## </desc>
gen_tunable(selinuxuser_use_ssh_chroot, false)

attribute admindomain;
attribute login_userdomain;
attribute confined_admindomain;

# all user domains
attribute userdomain;

# unprivileged user domains
attribute unpriv_userdomain;

attribute user_home_content_type;

attribute userdom_home_reader_certs_type;
attribute userdom_home_reader_type;
attribute userdom_home_manager_type;
attribute userdom_filetrans_type;

# unprivileged user domains
attribute user_home_type;
attribute user_tmp_type;
attribute user_tmpfs_type;

type admin_home_t;
files_type(admin_home_t)
files_associate_tmp(admin_home_t)
fs_associate_tmpfs(admin_home_t)
files_mountpoint(admin_home_t)
files_poly_member(admin_home_t)
files_poly_parent(admin_home_t)

type user_home_dir_t alias { staff_home_dir_t sysadm_home_dir_t secadm_home_dir_t auditadm_home_dir_t unconfined_home_dir_t };
fs_associate_tmpfs(user_home_dir_t)
files_type(user_home_dir_t)
files_mountpoint(user_home_dir_t)
files_associate_tmp(user_home_dir_t)
files_poly(user_home_dir_t)
files_poly_member(user_home_dir_t)
files_poly_parent(user_home_dir_t)
ubac_constrained(user_home_dir_t)

type user_home_t alias { staff_home_t sysadm_home_t secadm_home_t auditadm_home_t unconfined_home_t };
typealias user_home_t alias { staff_untrusted_content_t sysadm_untrusted_content_t secadm_untrusted_content_t auditadm_untrusted_content_t unconfined_untrusted_content_t };
typeattribute user_home_t user_home_type;
userdom_user_home_content(user_home_t)
fs_associate_tmpfs(user_home_t)
files_associate_tmp(user_home_t)
files_poly_member(user_home_t)
files_poly_parent(user_home_t)
files_mountpoint(user_home_t)
ubac_constrained(user_home_t)

type user_devpts_t alias { staff_devpts_t sysadm_devpts_t secadm_devpts_t auditadm_devpts_t unconfined_devpts_t };
dev_node(user_devpts_t)
files_type(user_devpts_t)
ubac_constrained(user_devpts_t)

type user_tmp_t, user_tmp_type, user_tmpfs_type;
typealias user_tmp_t alias { screen_tmp_t winbind_tmp_t wine_tmp_t sshd_tmp_t staff_tmp_t sysadm_tmp_t secadm_tmp_t auditadm_tmp_t unconfined_tmp_t };
typealias user_tmp_t alias { staff_untrusted_content_tmp_t sysadm_untrusted_content_tmp_t secadm_untrusted_content_tmp_t auditadm_untrusted_content_tmp_t unconfined_untrusted_content_tmp_t };
typealias user_tmp_t alias { user_tmpfs_t staff_tmpfs_t sysadm_tmpfs_t secadm_tmpfs_t auditadm_tmpfs_t unconfined_tmpfs_t };
typealias user_tmp_t alias xdm_tmp_t;
typealias user_tmp_t alias { xserver_tmp_t user_xserver_tmp_t staff_xserver_tmp_t sysadm_xserver_tmp_t ice_tmp_t };
files_tmp_file(user_tmp_t)
files_tmpfs_file(user_tmp_t)
userdom_user_home_content(user_tmp_t)
files_poly_parent(user_tmp_t)
files_mountpoint(user_tmp_t)

type user_tty_device_t alias { staff_tty_device_t sysadm_tty_device_t secadm_tty_device_t auditadm_tty_device_t unconfined_tty_device_t };
dev_node(user_tty_device_t)
ubac_constrained(user_tty_device_t)

type audio_home_t;
userdom_user_home_content(audio_home_t)
ubac_constrained(audio_home_t)

type texlive_home_t;
userdom_user_home_content(texlive_home_t)
ubac_constrained(texlive_home_t)

type home_bin_t;
userdom_user_home_content(home_bin_t)
ubac_constrained(home_bin_t)

type home_cert_t;
miscfiles_cert_type(home_cert_t)
userdom_user_home_content(home_cert_t)
ubac_constrained(home_cert_t)

tunable_policy(`login_console_enabled',`
	term_use_console(userdomain)
')

allow userdomain userdomain:process signull;
allow userdomain userdomain:fifo_file { map rw_inherited_fifo_file_perms };
dontaudit unpriv_userdomain self:rawip_socket create_socket_perms;

# Allow userdomain to stop systemd user-session
allow userdomain userdomain:system { halt reload };

# Nautilus causes this avc
domain_dontaudit_access_check(unpriv_userdomain)
dontaudit unpriv_userdomain self:dir setattr;
allow unpriv_userdomain self:file manage_file_perms;
allow unpriv_userdomain self:key manage_key_perms;

auth_filetrans_auth_home_content(userdomain)

files_dontaudit_manage_boot_files(unpriv_userdomain)

mount_dontaudit_write_mount_pid(unpriv_userdomain)
mount_entry_type(unpriv_userdomain)

optional_policy(`
	alsa_read_rw_config(unpriv_userdomain)
	alsa_manage_home_files(unpriv_userdomain)
	alsa_relabel_home_files(unpriv_userdomain)
')

optional_policy(`
    cockpit_manage_unix_stream_sockets(userdomain)
')

optional_policy(`
	gssproxy_stream_connect(userdomain)
')

optional_policy(`
	gnome_filetrans_home_content(userdomain)
')

optional_policy(`
    gpg_noatsecure(userdomain)
')

optional_policy(`
	locallogin_filetrans_home_content(userdomain)
')

optional_policy(`
	pcscd_stream_connect(userdomain)
')

optional_policy(`
    policykit_dbus_chat(userdomain)
    dbus_system_bus_client(userdomain)
')

optional_policy(`
    realmd_read_var_lib(userdomain)
')

optional_policy(`
	ssh_filetrans_home_content(userdomain)
	ssh_rw_tcp_sockets(userdomain)
')

optional_policy(`
        stratisd_dbus_chat(userdomain)
')

optional_policy(`
	telepathy_filetrans_home_content(userdomain)
')

optional_policy(`
	xserver_filetrans_home_content(userdomain)
')

optional_policy(`
	systemd_userdbd_stream_connect(userdomain)
')

# rules for types which can read home certs
allow userdom_home_reader_certs_type home_cert_t:dir list_dir_perms;
read_files_pattern(userdom_home_reader_certs_type, home_cert_t, home_cert_t)
read_lnk_files_pattern(userdom_home_reader_certs_type, home_cert_t, home_cert_t)
userdom_search_user_home_content(userdom_home_reader_certs_type)
allow userdom_home_reader_certs_type home_cert_t:file map;

tunable_policy(`use_ecryptfs_home_dirs',`
    fs_read_ecryptfs_files(userdom_home_reader_certs_type)
    fs_read_ecryptfs_symlinks(userdom_home_reader_certs_type)
')

tunable_policy(`use_nfs_home_dirs',`
	fs_list_auto_mountpoints(userdom_home_reader_type)
	fs_read_nfs_files(userdom_home_reader_type)
')

tunable_policy(`use_samba_home_dirs',`
    fs_read_cifs_files(userdom_home_reader_type)
')

tunable_policy(`use_fusefs_home_dirs',`
    fs_read_fusefs_files(userdom_home_reader_type)
')

tunable_policy(`use_ecryptfs_home_dirs',`
        fs_read_ecryptfs_files(userdom_home_reader_type)
        fs_read_ecryptfs_symlinks(userdom_home_reader_type)
')

tunable_policy(`use_nfs_home_dirs',`
    fs_list_auto_mountpoints(userdom_home_manager_type)
    fs_manage_nfs_dirs(userdom_home_manager_type)
    fs_manage_nfs_files(userdom_home_manager_type)
    fs_manage_nfs_symlinks(userdom_home_manager_type)
    fs_mmap_nfs_files(userdom_home_manager_type)
')

tunable_policy(`use_samba_home_dirs',`
    fs_manage_cifs_dirs(userdom_home_manager_type)
    fs_manage_cifs_files(userdom_home_manager_type)
    fs_manage_cifs_symlinks(userdom_home_manager_type)
    fs_map_cifs_files(userdom_home_manager_type)
')

tunable_policy(`use_fusefs_home_dirs',`
    fs_manage_fusefs_dirs(userdom_home_manager_type)
    fs_manage_fusefs_files(userdom_home_manager_type)
    fs_manage_fusefs_symlinks(userdom_home_manager_type)
    fs_mmap_fusefs_files(userdom_home_manager_type)
')

tunable_policy(`use_ecryptfs_home_dirs',`
	fs_manage_ecryptfs_dirs(userdom_home_manager_type)
	fs_manage_ecryptfs_files(userdom_home_manager_type)
    fs_manage_ecryptfs_symlinks(userdom_home_manager_type)
')

# vi /etc/mtab can cause an avc trying to relabel to self.  
dontaudit userdomain self:file relabelto;

userdom_user_home_dir_filetrans_user_home_content(userdom_filetrans_type, { dir file lnk_file fifo_file sock_file })
userdom_user_home_dir_filetrans(userdom_filetrans_type, home_bin_t, dir, "bin")
userdom_user_home_dir_filetrans(userdom_filetrans_type, audio_home_t, dir, "Audio")
userdom_user_home_dir_filetrans(userdom_filetrans_type, audio_home_t, dir, "Music")
userdom_user_home_dir_filetrans(userdom_filetrans_type, home_cert_t, dir, ".cert")
userdom_user_home_dir_filetrans(userdom_filetrans_type, home_cert_t, dir, ".pki")
userdom_user_home_dir_filetrans(userdom_filetrans_type, home_cert_t, dir, "certificates")
userdom_user_home_dir_filetrans(userdom_filetrans_type, texlive_home_t, dir, ".texlive2012")
userdom_user_home_dir_filetrans(userdom_filetrans_type, texlive_home_t, dir, ".texlive2013")
userdom_user_home_dir_filetrans(userdom_filetrans_type, texlive_home_t, dir, ".texlive2014")
userdom_user_home_dir_filetrans(userdom_filetrans_type, user_tmp_t, dir, ".tmp")
userdom_user_home_dir_filetrans(userdom_filetrans_type, user_tmp_t, dir, "tmp")

optional_policy(`
	gnome_config_filetrans(userdom_filetrans_type, home_cert_t, dir, "certificates")
	gnome_config_filetrans(userdom_filetrans_type, auth_home_t, dir, "Yubico")
	#gnome_admin_home_gconf_filetrans(userdom_filetrans_type, home_bin_t, dir, "bin")
')

optional_policy(`
	alsa_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	apache_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	auth_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	cvs_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	gnome_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	gpg_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	irc_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	kerberos_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	mozilla_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	mta_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	pulseaudio_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	spamassassin_filetrans_home_content(userdom_filetrans_type)
	spamassassin_filetrans_admin_home_content(userdom_filetrans_type)
')

optional_policy(`
	ssh_filetrans_admin_home_content(userdom_filetrans_type)
	ssh_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	telepathy_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	thumb_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	tvtime_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	virt_filetrans_home_content(userdom_filetrans_type)
')

optional_policy(`
	xserver_filetrans_home_content(userdom_filetrans_type)
	xserver_filetrans_admin_home_content(userdom_filetrans_type)
')

############################################################
# login_userdomain local policy

corenet_tcp_bind_xmsg_port(login_userdomain)

create_blk_files_pattern(login_userdomain, user_tmp_t, user_tmp_t )
create_chr_files_pattern(login_userdomain, user_tmp_t, user_tmp_t )
create_fifo_files_pattern(login_userdomain, user_tmp_t, user_tmp_t )
create_files_pattern(login_userdomain, user_tmp_t, user_tmp_t )
create_sock_files_pattern(login_userdomain, user_tmp_t, user_tmp_t )

tunable_policy(`deny_bluetooth',`',`
	allow login_userdomain self:bluetooth_socket rw_stream_socket_perms;
')

dev_watch_generic_dirs(login_userdomain)

files_watch_etc_dirs(login_userdomain)
files_watch_usr_dirs(login_userdomain)
files_watch_var_lib_dirs(login_userdomain)

fs_create_cgroup_files(login_userdomain)
fs_watch_cgroup_files(login_userdomain)

miscfiles_watch_localization_symlinks(login_userdomain)

mount_watch_pid_dirs(login_userdomain)
mount_watch_pid_files(login_userdomain)
mount_watch_reads_pid_files(login_userdomain)

optional_policy(`
	init_mmap_read_var_lib_files(login_userdomain)
')

optional_policy(`
	dbus_create_session_tmp_sock_files(login_userdomain)
	dbus_write_session_tmp_sock_files(login_userdomain)
')

optional_policy(`
	gnome_watch_generic_data_home_dirs(login_userdomain)
	gnome_watch_home_config_dirs(login_userdomain)
	gnome_watch_home_config_files(login_userdomain)
')

optional_policy(`
	logging_mmap_journal(login_userdomain)
	logging_read_syslog_pid(login_userdomain)
')

optional_policy(`
	systemd_login_watch_session_dirs(login_userdomain)
')

############################################################
# Local Policy Confined Admin
#
gen_require(`
	class context contains;
    class passwd { passwd chfn chsh rootok };
')

allow confined_admindomain self:capability ~{ sys_module audit_control audit_write };
allow confined_admindomain self:capability2 { block_suspend syslog };
allow confined_admindomain self:cap_userns { setpcap };
allow confined_admindomain self:process { setexec setfscreate };
allow confined_admindomain self:netlink_audit_socket nlmsg_readpriv;
allow confined_admindomain self:tun_socket create_socket_perms;
allow confined_admindomain self:packet_socket create_socket_perms;

# Set password information for other users.
allow confined_admindomain self:passwd { passwd chfn chsh };
# Skip authentication when pam_rootok is specified.
allow confined_admindomain self:passwd rootok;

corecmd_shell_entry_type(confined_admindomain)
corecmd_bin_entry_type(confined_admindomain)

term_user_pty(confined_admindomain, user_devpts_t)
term_user_tty(confined_admindomain, user_tty_device_t)
term_dontaudit_getattr_generic_ptys(confined_admindomain)

allow confined_admindomain self:process { signal_perms getsched setsched share getpgid setpgid getcap setcap getsession getattr };
tunable_policy(`deny_ptrace',`',`
	allow confined_admindomain self:process ptrace;
')
allow confined_admindomain self:fd use;
allow confined_admindomain self:key manage_key_perms;

allow confined_admindomain self:fifo_file rw_fifo_file_perms;
allow confined_admindomain self:unix_dgram_socket { create_socket_perms sendto };
allow confined_admindomain self:unix_stream_socket { create_stream_socket_perms connectto };
allow confined_admindomain self:shm create_shm_perms;
allow confined_admindomain self:sem create_sem_perms;
allow confined_admindomain self:msgq create_msgq_perms;
allow confined_admindomain self:msg { send receive };
allow confined_admindomain self:context contains;
dontaudit confined_admindomain self:socket create;

allow confined_admindomain user_devpts_t:chr_file { setattr rw_chr_file_perms };
term_create_pty(confined_admindomain, user_devpts_t)
term_use_generic_ptys(confined_admindomain)
# avoid annoying messages on terminal hangup on role change
dontaudit confined_admindomain user_devpts_t:chr_file ioctl;

allow confined_admindomain user_tty_device_t:chr_file { setattr rw_chr_file_perms };
# avoid annoying messages on terminal hangup on role change
dontaudit confined_admindomain user_tty_device_t:chr_file ioctl;

application_exec_all(confined_admindomain)

kernel_read_kernel_sysctls(confined_admindomain)
kernel_read_all_sysctls(confined_admindomain)
kernel_dontaudit_list_unlabeled(confined_admindomain)
kernel_dontaudit_getattr_unlabeled_files(confined_admindomain)
kernel_dontaudit_getattr_unlabeled_symlinks(confined_admindomain)
kernel_dontaudit_getattr_unlabeled_pipes(confined_admindomain)
kernel_dontaudit_getattr_unlabeled_sockets(confined_admindomain)
kernel_dontaudit_getattr_unlabeled_blk_files(confined_admindomain)
kernel_dontaudit_getattr_unlabeled_chr_files(confined_admindomain)
kernel_dontaudit_list_proc(confined_admindomain)

dev_dontaudit_getattr_all_blk_files(confined_admindomain)
dev_dontaudit_getattr_all_chr_files(confined_admindomain)
dev_getattr_mtrr_dev(confined_admindomain)

# When the user domain runs ps, there will be a number of access
# denials when ps tries to search /proc. Do not audit these denials.
domain_dontaudit_read_all_domains_state(confined_admindomain)
domain_dontaudit_getattr_all_domains(confined_admindomain)
domain_dontaudit_getsession_all_domains(confined_admindomain)
dev_dontaudit_all_access_check(confined_admindomain)

files_read_etc_files(confined_admindomain)
files_list_mnt(confined_admindomain)
files_list_var(confined_admindomain)
files_read_mnt_files(confined_admindomain)
files_dontaudit_all_access_check(confined_admindomain)
files_read_etc_runtime_files(confined_admindomain)
files_read_usr_files(confined_admindomain)
files_read_usr_src_files(confined_admindomain)
# Read directories and files with the readable_t type.
# This type is a general type for "world"-readable files.
files_list_world_readable(confined_admindomain)
files_read_world_readable_files(confined_admindomain)
files_read_world_readable_symlinks(confined_admindomain)
files_read_world_readable_pipes(confined_admindomain)
files_read_world_readable_sockets(confined_admindomain)
# old broswer_domain():
files_dontaudit_getattr_all_dirs(confined_admindomain)
files_dontaudit_list_non_security(confined_admindomain)
files_dontaudit_getattr_all_files(confined_admindomain)
files_dontaudit_getattr_non_security_symlinks(confined_admindomain)
files_dontaudit_getattr_non_security_pipes(confined_admindomain)
files_dontaudit_getattr_non_security_sockets(confined_admindomain)
files_dontaudit_setattr_etc_runtime_files(confined_admindomain)

files_exec_usr_files(confined_admindomain)

fs_list_cgroup_dirs(confined_admindomain)
fs_dontaudit_rw_cgroup_files(confined_admindomain)

storage_rw_fuse(confined_admindomain)

init_stream_connect(confined_admindomain)
# The library functions always try to open read-write first,
# then fall back to read-only if it fails. 
init_dontaudit_rw_utmp(confined_admindomain)

libs_exec_ld_so(confined_admindomain)

miscfiles_read_generic_certs(confined_admindomain)

miscfiles_read_all_certs(confined_admindomain)
miscfiles_read_public_files(confined_admindomain)

systemd_dbus_chat_logind(confined_admindomain)
systemd_read_logind_sessions_files(confined_admindomain)
systemd_write_inhibit_pipes(confined_admindomain)
systemd_write_inherited_logind_sessions_pipes(confined_admindomain)
systemd_login_read_pid_files(confined_admindomain)
tunable_policy(`deny_execmem',`', `
	# Allow loading DSOs that require executable stack.
	allow confined_admindomain self:process execmem;
')

tunable_policy(`selinuxuser_execstack',`
	# Allow making the stack executable via mprotect.
	allow confined_admindomain self:process execstack;
')

optional_policy(`
	fs_list_cgroup_dirs(confined_admindomain)
')
	
optional_policy(`
	ssh_rw_stream_sockets(confined_admindomain)
	ssh_delete_tmp(confined_admindomain)
	ssh_signal(confined_admindomain)
')
