From 37d90b6343a7f89480158427c24c53f65239c1e5 Mon Sep 17 00:00:00 2001 From: Kenton Groombridge Date: Sun, 30 Jun 2024 10:39:43 -0400 Subject: [PATCH] kanidm: initial policy Signed-off-by: Kenton Groombridge --- policy/modules/kernel/files.if | 18 +++ policy/modules/services/kanidm.fc | 16 +++ policy/modules/services/kanidm.if | 201 +++++++++++++++++++++++++++ policy/modules/services/kanidm.te | 197 ++++++++++++++++++++++++++ policy/modules/system/selinuxutil.if | 20 +++ policy/modules/system/userdomain.if | 18 +++ 6 files changed, 470 insertions(+) create mode 100644 policy/modules/services/kanidm.fc create mode 100644 policy/modules/services/kanidm.if create mode 100644 policy/modules/services/kanidm.te diff --git a/policy/modules/kernel/files.if b/policy/modules/kernel/files.if index b82a03db5..2a967b85a 100644 --- a/policy/modules/kernel/files.if +++ b/policy/modules/kernel/files.if @@ -4116,6 +4116,24 @@ interface(`files_watch_home',` allow $1 home_root_t:dir watch; ') +######################################## +## +## Manage user home root symlinks. +## +## +## +## Domain allowed access. +## +## +# +interface(`files_manage_home_symlinks',` + gen_require(` + type home_root_t; + ') + + allow $1 home_root_t:lnk_file manage_lnk_file_perms; +') + ######################################## ## ## Create objects in /home. diff --git a/policy/modules/services/kanidm.fc b/policy/modules/services/kanidm.fc new file mode 100644 index 000000000..fcafffbd5 --- /dev/null +++ b/policy/modules/services/kanidm.fc @@ -0,0 +1,16 @@ +/usr/bin/kanidmd -- gen_context(system_u:object_r:kanidmd_exec_t,s0) +/usr/bin/kanidm_unixd -- gen_context(system_u:object_r:kanidm_unixd_exec_t,s0) +/usr/bin/kanidm_unixd_tasks -- gen_context(system_u:object_r:kanidm_unixd_tasks_exec_t,s0) + +/usr/sbin/kanidmd -- gen_context(system_u:object_r:kanidmd_exec_t,s0) +/usr/sbin/kanidm_unixd -- gen_context(system_u:object_r:kanidm_unixd_exec_t,s0) +/usr/sbin/kanidm_unixd_tasks -- gen_context(system_u:object_r:kanidm_unixd_tasks_exec_t,s0) + +/etc/kanidm(/.*)? gen_context(system_u:object_r:kanidm_config_t,s0) + +/run/kanidm-unixd(/.*)? gen_context(system_u:object_r:kanidm_unixd_runtime_t,s0) + +/var/cache/kanidm-unixd(/.*)? gen_context(system_u:object_r:kanidm_unixd_cache_t,s0) + +/var/lib/kanidmd(/.*)? gen_context(system_u:object_r:kanidm_var_lib_t,s0) +/var/lib/kanidm-unixd(/.*)? gen_context(system_u:object_r:kanidm_unixd_var_lib_t,s0) diff --git a/policy/modules/services/kanidm.if b/policy/modules/services/kanidm.if new file mode 100644 index 000000000..83ac37cc3 --- /dev/null +++ b/policy/modules/services/kanidm.if @@ -0,0 +1,201 @@ +## A simple, secure and fast identity management platform + +######################################## +## +## Execute kanidmd in the kanidmd domain. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`kanidm_domtrans_server',` + gen_require(` + type kanidmd_t, kanidmd_exec_t; + ') + + corecmd_search_bin($1) + domtrans_pattern($1, kanidmd_exec_t, kanidmd_t) +') + +######################################## +## +## Execute kanidmd in the kanidmd domain, and +## allow the specified role the kanidmd domain. +## +## +## +## Domain allowed to transition. +## +## +## +## +## Role allowed access. +## +## +## +# +interface(`kanidm_run_server',` + gen_require(` + type kanidmd_t; + ') + + kanidm_domtrans_server($1) + role $2 types kanidmd_t; +') + +######################################## +## +## Execute kanidmd-unixd in the +## kanidmd-unixd domain. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`kanidm_domtrans_unixd',` + gen_require(` + type kanidm_unixd_t, kanidm_unixd_exec_t; + ') + + corecmd_search_bin($1) + domtrans_pattern($1, kanidm_unixd_exec_t, kanidm_unixd_t) +') + +######################################## +## +## Execute kanidm-unixd in the kanidm-unixd +## domain, and allow the specified role the +## kanidm-unixd domain. +## +## +## +## Domain allowed to transition. +## +## +## +## +## Role allowed access. +## +## +## +# +interface(`kanidm_run_unixd',` + gen_require(` + type kanidm_unixd_t; + ') + + kanidm_domtrans_unixd($1) + role $2 types kanidm_unixd_t; +') + +######################################## +## +## Read kanidm config files. +## +## +## +## Domain allowed access. +## +## +# +interface(`kanidm_read_config',` + gen_require(` + type kanidm_config_t; + ') + + files_search_etc($1) + read_files_pattern($1, kanidm_config_t, kanidm_config_t) +') + +######################################## +## +## Set attributes on kanidm-unixd cache directories. +## +## +## +## Domain allowed access. +## +## +# +interface(`kanidm_setattr_unixd_cache_dirs',` + gen_require(` + type kanidm_unixd_cache_t; + ') + + allow $1 kanidm_unixd_cache_t:dir setattr_dir_perms; +') + +####################################### +## +## Connect to kanidm-unixd with a +## domain stream socket. +## +## +## +## Domain allowed access. +## +## +# +interface(`kanidm_unixd_stream_connect',` + gen_require(` + type kanidm_unixd_t, kanidm_unixd_runtime_t; + ') + + files_search_runtime($1) + stream_connect_pattern($1, kanidm_unixd_runtime_t, kanidm_unixd_runtime_t, kanidm_unixd_t) +') + +######################################## +## +## All of the rules required to +## administrate a Kanidm environment. +## +## +## +## Domain allowed access. +## +## +## +## +## Role allowed access. +## +## +## +# +interface(`kanidm_admin',` + gen_require(` + type kanidmd_t; + type kanidm_unixd_t; + type kanidm_config_t; + type kanidm_unixd_cache_t; + type kanidm_unixd_runtime_t; + type kanidm_var_lib_t; + ') + + kanidm_run_server($1, $2) + kanidm_run_unixd($1, $2) + + allow $1 kanidmd_t:process { ptrace signal_perms }; + ps_process_pattern($1, kanidmd_t) + + allow $1 kanidm_unixd_t:process { ptrace signal_perms }; + ps_process_pattern($1, kanidm_unixd_t) + + stream_connect_pattern($1, kanidm_unixd_runtime_t, kanidm_unixd_runtime_t, kanidm_unixd_t) + + files_search_etc($1) + admin_pattern($1, kanidm_config_t) + + files_search_runtime($1) + admin_pattern($1, kanidm_unixd_runtime_t) + + files_search_var($1) + admin_pattern($1, kanidm_unixd_cache_t) + + files_search_var_lib($1) + admin_pattern($1, kanidm_var_lib_t) +') diff --git a/policy/modules/services/kanidm.te b/policy/modules/services/kanidm.te new file mode 100644 index 000000000..7294ac9f6 --- /dev/null +++ b/policy/modules/services/kanidm.te @@ -0,0 +1,197 @@ +policy_module(kanidm) + +######################################## +# +# Declarations +# + +## +##

+## Determine whether kanidm-unixd-tasks can +## create home directories via pam. +##

+##
+gen_tunable(kanidm_unixd_create_home_dirs, false) + +## +##

+## Determine whether kanidm-unixd-tasks can +## modify the SELinux policy. This is to create +## local equivalence file context rules which map +## usernames to their UUID, SPN, or other identifier. +##

+##
+gen_tunable(kanidm_unixd_modify_policy, false) + +type kanidmd_t; +type kanidmd_exec_t; +init_daemon_domain(kanidmd_t, kanidmd_exec_t) + +type kanidm_unixd_t; +type kanidm_unixd_exec_t; +init_daemon_domain(kanidm_unixd_t, kanidm_unixd_exec_t) + +type kanidm_unixd_tasks_t; +type kanidm_unixd_tasks_exec_t; +init_daemon_domain(kanidm_unixd_tasks_t, kanidm_unixd_tasks_exec_t) + +type kanidm_config_t; +files_config_file(kanidm_config_t) + +type kanidmd_runtime_t; +files_runtime_file(kanidmd_runtime_t) + +type kanidm_unixd_cache_t; +files_type(kanidm_unixd_cache_t) + +type kanidm_unixd_runtime_t; +files_runtime_file(kanidm_unixd_runtime_t) + +type kanidm_var_lib_t; +files_type(kanidm_var_lib_t) + +type kanidm_unixd_var_lib_t; +files_type(kanidm_unixd_var_lib_t) + +######################################## +# +# kanidmd local policy +# + +allow kanidmd_t self:process getsched; +allow kanidmd_t self:tcp_socket create_stream_socket_perms; +allow kanidmd_t self:unix_dgram_socket create_socket_perms; + +read_files_pattern(kanidmd_t, kanidm_config_t, kanidm_config_t) + +manage_sock_files_pattern(kanidmd_t, kanidmd_runtime_t, kanidmd_runtime_t) +files_runtime_filetrans(kanidmd_t, kanidmd_runtime_t, sock_file) + +manage_dirs_pattern(kanidmd_t, kanidm_var_lib_t, kanidm_var_lib_t) +mmap_manage_files_pattern(kanidmd_t, kanidm_var_lib_t, kanidm_var_lib_t) + +corenet_tcp_bind_generic_node(kanidmd_t) +corenet_tcp_bind_http_port(kanidmd_t) +corenet_tcp_bind_servistaitsm_port(kanidmd_t) + +domain_use_interactive_fds(kanidmd_t) + +files_read_usr_files(kanidmd_t) +files_search_var_lib(kanidmd_t) +files_read_var_lib_symlinks(kanidmd_t) + +fs_read_cgroup_files(kanidmd_t) + +kernel_read_vm_overcommit_sysctl(kanidmd_t) + +logging_send_syslog_msg(kanidmd_t) + +miscfiles_read_generic_certs(kanidmd_t) + +userdom_use_user_terminals(kanidmd_t) + +optional_policy(` + certbot_read_lib(kanidmd_t) +') + +######################################## +# +# kanidm-unixd local policy +# + +allow kanidm_unixd_t self:process getsched; +allow kanidm_unixd_t self:udp_socket create_socket_perms; +allow kanidm_unixd_t self:unix_dgram_socket create_socket_perms; + +read_files_pattern(kanidm_unixd_t, kanidm_config_t, kanidm_config_t) + +manage_files_pattern(kanidm_unixd_t, kanidm_unixd_cache_t, kanidm_unixd_cache_t) + +manage_dirs_pattern(kanidm_unixd_t, kanidm_unixd_runtime_t, kanidm_unixd_runtime_t) +manage_sock_files_pattern(kanidm_unixd_t, kanidm_unixd_runtime_t, kanidm_unixd_runtime_t) +files_runtime_filetrans(kanidm_unixd_t, kanidm_unixd_runtime_t, { dir sock_file }) + +files_search_var_lib(kanidm_unixd_t) +manage_files_pattern(kanidm_unixd_t, kanidm_unixd_var_lib_t, kanidm_unixd_var_lib_t) + +corenet_tcp_bind_generic_node(kanidm_unixd_t) +corenet_tcp_connect_http_port(kanidm_unixd_t) + +corecmd_exec_shell(kanidm_unixd_t) + +domain_use_interactive_fds(kanidm_unixd_t) + +# watch /etc/passwd +files_watch_etc_files(kanidm_unixd_t) + +fs_read_cgroup_files(kanidm_unixd_t) + +kernel_read_system_state(kanidm_unixd_t) + +auth_use_nsswitch(kanidm_unixd_t) + +miscfiles_read_generic_certs(kanidm_unixd_t) +miscfiles_read_localization(kanidm_unixd_t) + +logging_send_syslog_msg(kanidm_unixd_t) + +userdom_use_user_terminals(kanidm_unixd_t) + +######################################## +# +# kanidm-unixd-tasks local policy +# + +allow kanidm_unixd_tasks_t self:process { getsched setfscreate }; +# needed for running as root reading /run/kanidm-unixd +allow kanidm_unixd_tasks_t self:capability dac_override; + +read_files_pattern(kanidm_unixd_tasks_t, kanidm_config_t, kanidm_config_t) +stream_connect_pattern(kanidm_unixd_tasks_t, kanidm_unixd_runtime_t, kanidm_unixd_runtime_t, kanidm_unixd_t) + +corecmd_exec_bin(kanidm_unixd_tasks_t) + +domain_obj_id_change_exemption(kanidm_unixd_tasks_t) + +files_search_home(kanidm_unixd_tasks_t) + +kernel_read_kernel_sysctls(kanidm_unixd_tasks_t) +kernel_read_system_state(kanidm_unixd_tasks_t) + +auth_use_nsswitch(kanidm_unixd_tasks_t) + +logging_send_syslog_msg(kanidm_unixd_tasks_t) + +selinux_get_fs_mount(kanidm_unixd_tasks_t) +selinux_get_enforce_mode(kanidm_unixd_tasks_t) + +seutil_libselinux_linked(kanidm_unixd_tasks_t) + +tunable_policy(`kanidm_unixd_create_home_dirs',` + allow kanidm_unixd_tasks_t self:capability { chown dac_read_search }; + userdom_create_user_home_dirs(kanidm_unixd_tasks_t) + userdom_setattr_user_home_dirs(kanidm_unixd_tasks_t) + userdom_home_filetrans_user_home_dir(kanidm_unixd_tasks_t) + + # create alias symlinks + files_manage_home_symlinks(kanidm_unixd_tasks_t) + + # populate new home dirs from /etc/skel + userdom_manage_user_home_content_dirs(kanidm_unixd_tasks_t) + userdom_manage_user_home_content_files(kanidm_unixd_tasks_t) + userdom_manage_user_home_content_symlinks(kanidm_unixd_tasks_t) + userdom_user_home_dir_filetrans_user_home_content(kanidm_unixd_tasks_t, { dir file lnk_file sock_file fifo_file }) + + seutil_exec_setfiles(kanidm_unixd_tasks_t) +') + +tunable_policy(`kanidm_unixd_create_home_dirs && kanidm_unixd_modify_policy',` + # create equivalence rules for home dirs + seutil_nnp_domtrans_semanage(kanidm_unixd_tasks_t) + seutil_read_file_contexts(kanidm_unixd_tasks_t) + seutil_read_default_contexts(kanidm_unixd_tasks_t) +',` + seutil_dontaudit_exec_semanage(kanidm_unixd_tasks_t) + seutil_dontaudit_exec_setfiles(kanidm_unixd_tasks_t) + seutil_dontaudit_read_file_contexts(kanidm_unixd_tasks_t) +') diff --git a/policy/modules/system/selinuxutil.if b/policy/modules/system/selinuxutil.if index f4464cc5c..338d40836 100644 --- a/policy/modules/system/selinuxutil.if +++ b/policy/modules/system/selinuxutil.if @@ -1040,6 +1040,26 @@ interface(`seutil_domtrans_semanage',` domtrans_pattern($1, semanage_exec_t, semanage_t) ') +######################################## +## +## Transition to the semanage domain when +## NNP has been set. +## +## +## +## Domain allowed to transition. +## +## +# +interface(`seutil_nnp_domtrans_semanage',` + gen_require(` + type semanage_t; + ') + + seutil_domtrans_semanage($1) + allow $1 semanage_t:process2 nnp_transition; +') + ######################################## ## ## Execute semanage in the semanage domain, and diff --git a/policy/modules/system/userdomain.if b/policy/modules/system/userdomain.if index 7755e753c..cdbba832d 100644 --- a/policy/modules/system/userdomain.if +++ b/policy/modules/system/userdomain.if @@ -1851,6 +1851,24 @@ interface(`userdom_dontaudit_getattr_user_home_dirs',` dontaudit $1 user_home_dir_t:dir getattr_dir_perms; ') +######################################## +## +## Set the attributes of user home directories. +## +## +## +## Domain allowed access. +## +## +# +interface(`userdom_setattr_user_home_dirs',` + gen_require(` + type user_home_dir_t; + ') + + allow $1 user_home_dir_t:dir setattr_dir_perms; +') + ######################################## ## ## Search user home directories.