diff --git a/refpolicy/policy/modules/kernel/terminal.if b/refpolicy/policy/modules/kernel/terminal.if index c41a065..a9871a0 100644 --- a/refpolicy/policy/modules/kernel/terminal.if +++ b/refpolicy/policy/modules/kernel/terminal.if @@ -48,6 +48,26 @@ define(`term_user_pty',` ') ######################################## +## +## +## Transform specified type into a pty type +## used by login programs, such as sshd. +## +## +## An object type that will applied to a pty. +## +## +# +define(`term_login_pty',` + gen_require(` + attribute server_ptynode; + ') + + term_pty($1) + typeattribute $1 server_ptynode; +') + +######################################## ## ## ## Transform specified type into a tty type. diff --git a/refpolicy/policy/modules/services/ssh.fc b/refpolicy/policy/modules/services/ssh.fc new file mode 100644 index 0000000..e69de29 --- /dev/null +++ b/refpolicy/policy/modules/services/ssh.fc diff --git a/refpolicy/policy/modules/services/ssh.if b/refpolicy/policy/modules/services/ssh.if new file mode 100644 index 0000000..ad7afd5 --- /dev/null +++ b/refpolicy/policy/modules/services/ssh.if @@ -0,0 +1,285 @@ +define(`ssh_per_userdomain_template',` + # Derived domain based on the calling user domain and the program. + type $1_ssh_t; #, privlog, nscd_client_domain; + domain_type($1_ssh_t) + + type $1_home_ssh_t; #, $1_file_type; + files_file_type($1_home_ssh_t) + role $1_r types $1_ssh_t; + + # Transition from the user domain to the derived domain. + domain_auto_trans($1_t, ssh_exec_t, $1_ssh_t) + + libs_use_ld_so($1_ssh_t) + libs_use_shared_libs($1_ssh_t) + + tunable_policy(`use_nfs_home_dirs',` + fs_manage_nfs_dirs($1_ssh_t) + fs_manage_nfs_files($1_ssh_t) + ') + + tunable_policy(`use_samba_home_dirs',` + fs_manage_cifs_dirs($1_ssh_t) + fs_manage_cifs_files($1_ssh_t) + ') + + ifdef(`TODO',` + # Grant permissions within the domain. + general_domain_access($1_ssh_t) + allow $1_ssh_t autofs_t:dir { search getattr }; + + # Use descriptors created by sshd + allow $1_ssh_t privfd:fd use; + + read_locale($1_ssh_t) + + # Get attributes of file systems. + allow $1_ssh_t fs_type:filesystem getattr; + + base_file_read_access($1_ssh_t) + + # Read /var. + allow $1_ssh_t var_t:dir r_dir_perms; + allow $1_ssh_t var_t:notdevfile_class_set r_file_perms; + + # Read /var/run, /var/log. + allow $1_ssh_t var_run_t:dir r_dir_perms; + allow $1_ssh_t var_run_t:{ file lnk_file } r_file_perms; + allow $1_ssh_t var_log_t:dir r_dir_perms; + allow $1_ssh_t var_log_t:{ file lnk_file } r_file_perms; + + # Read /etc. + allow $1_ssh_t etc_t:dir r_dir_perms; + allow $1_ssh_t etc_t:notdevfile_class_set r_file_perms; + allow $1_ssh_t etc_runtime_t:{ file lnk_file } r_file_perms; + + # Read /dev directories and any symbolic links. + allow $1_ssh_t device_t:dir r_dir_perms; + allow $1_ssh_t device_t:lnk_file r_file_perms; + + # Read /dev/urandom. + allow $1_ssh_t urandom_device_t:chr_file r_file_perms; + + # Read and write /dev/null. + allow $1_ssh_t { null_device_t zero_device_t }:chr_file rw_file_perms; + + # Grant permissions needed to create TCP and UDP sockets and + # to access the network. + can_network_client_tcp($1_ssh_t) + can_resolve($1_ssh_t) + can_ypbind($1_ssh_t) + can_kerberos($1_ssh_t) + + # for port forwarding + if (user_tcp_server) { + allow $1_ssh_t port_t:tcp_socket name_bind; + } + + # Use capabilities. + allow $1_ssh_t self:capability { setuid setgid dac_override dac_read_search }; + + # run helper programs - needed eg for x11-ssh-askpass + can_exec($1_ssh_t, { shell_exec_t bin_t }) + + # Read the ssh key file. + allow $1_ssh_t sshd_key_t:file r_file_perms; + + # Access the ssh temporary files. + file_type_auto_trans($1_ssh_t, tmp_t, sshd_tmp_t) + allow $1_ssh_t $1_tmp_t:dir r_dir_perms; + + # for rsync + allow $1_ssh_t $1_t:unix_stream_socket rw_socket_perms; + + # Access the users .ssh directory. + file_type_auto_trans({ sysadm_ssh_t $1_ssh_t }, $1_home_dir_t, $1_home_ssh_t, dir) + file_type_auto_trans($1_ssh_t, $1_home_dir_t, $1_home_ssh_t, sock_file) + allow $1_t $1_home_ssh_t:sock_file create_file_perms; + allow { sysadm_ssh_t $1_ssh_t } $1_home_ssh_t:file create_file_perms; + allow { sysadm_ssh_t $1_ssh_t } $1_home_ssh_t:lnk_file { getattr read }; + dontaudit $1_ssh_t $1_home_t:dir { getattr search }; + r_dir_file({ sshd_t sshd_extern_t }, $1_home_ssh_t) + rw_dir_create_file($1_t, $1_home_ssh_t) + + # for /bin/sh used to execute xauth + dontaudit $1_ssh_t proc_t:dir search; + dontaudit $1_ssh_t proc_t:{ lnk_file file } { getattr read }; + + # Inherit and use descriptors from gnome-pty-helper. + ifdef(`gnome-pty-helper.te', `allow $1_ssh_t $1_gph_t:fd use;') + + # Write to the user domain tty. + access_terminal($1_ssh_t, $1) + + # Allow the user shell to signal the ssh program. + allow $1_t $1_ssh_t:process signal; + # allow ps to show ssh + can_ps($1_t, $1_ssh_t) + + ifdef(`xserver.te', ` + # Communicate with the X server. + ifdef(`startx.te', ` + can_unix_connect($1_ssh_t, $1_xserver_t) + allow $1_ssh_t $1_xserver_tmp_t:sock_file rw_file_perms; + allow $1_ssh_t $1_xserver_tmp_t:dir search; + ')dnl end if startx + ifdef(`xdm.te', ` + allow $1_ssh_t { xdm_xserver_tmp_t xdm_tmp_t }:dir search; + allow $1_ssh_t { xdm_tmp_t }:sock_file write; + ') + ')dnl end if xserver + + ifdef(`ssh-agent.te', ` + ssh_agent_domain($1) + ')dnl end if ssh_agent.te + + #allow ssh to access keys stored on removable media + # Should we have a boolean around this? + allow $1_ssh_t mnt_t:dir search; + r_dir_file($1_ssh_t, removable_t) + + ifdef(`xdm.te', ` + # should be able to remove these two later + allow $1_ssh_t xdm_xserver_tmp_t:sock_file { read write }; + allow $1_ssh_t xdm_xserver_tmp_t:dir search; + allow $1_ssh_t xdm_xserver_t:unix_stream_socket connectto; + allow $1_ssh_t xdm_xserver_t:shm r_shm_perms; + allow $1_ssh_t xdm_xserver_t:fd use; + allow $1_ssh_t xdm_xserver_tmpfs_t:file read; + allow $1_ssh_t xdm_t:fd use; + ')dnl end if xdm.te + ') dnl endif TODO +') + +######################################## +# +# +# +define(`sshd_program_domain', ` + # auth_chkpwd is for running unix_chkpwd and unix_verify. + type $1_t; #, nscd_client_domain; + role system_r types $1_t; + + type $1_devpts_t; + term_login_pty($1_devpts_t) + + type $1_var_run_t; + files_pid_file($1_var_run_t) + + allow $1_t self:capability { kill sys_chroot sys_resource chown dac_override fowner fsetid setgid setuid sys_tty_config }; + allow $1_t self:fifo_file rw_file_perms; + allow $1_t self:process { signal setsched setrlimit setexec }; + + allow $1_t self:tcp_socket { listen accept create connect ioctl read getattr write setattr append bind getopt setopt shutdown }; + allow $1_t self:udp_socket { connect create ioctl read getattr write setattr append bind getopt setopt shutdown }; + + allow $1_t $1_devpts_t:chr_file { rw_file_perms setattr getattr relabelfrom }; + term_create_pty($1_t,$1_devpts_t) + + allow $1_t $1_var_run_t:file create_file_perms; + files_create_pid($1_t,$1_var_run_t,file) + + can_exec($1_t, sshd_exec_t) + + # Access key files + allow $1_t sshd_key_t:file { getattr read }; + + kernel_read_kernel_sysctl($1_t) + + corenet_tcp_sendrecv_all_if($1_t) + corenet_udp_sendrecv_all_if($1_t) + corenet_raw_sendrecv_all_if($1_t) + corenet_tcp_sendrecv_all_nodes($1_t) + corenet_udp_sendrecv_all_nodes($1_t) + corenet_raw_sendrecv_all_nodes($1_t) + corenet_udp_sendrecv_all_ports($1_t) + corenet_tcp_sendrecv_all_ports($1_t) + corenet_tcp_bind_all_nodes($1_t) + corenet_udp_bind_all_nodes($1_t) + + dev_read_urand($1_t) + + selinux_get_fs_mount($1_t) + selinux_validate_context($1_t) + selinux_compute_access_vector($1_t) + selinux_compute_create_context($1_t) + selinux_compute_relabel_context($1_t) + selinux_compute_user_contexts($1_t) + + auth_dontaudit_read_shadow($1_t) + auth_domtrans_chk_passwd($1_t) + auth_rw_login_records($1_t) + auth_rw_lastlog($1_t) + + domain_wide_inherit_fd($1_t) + domain_subj_id_change_exempt($1_t) + domain_role_change_exempt($1_t) + domain_obj_id_change_exempt($1_t) + + files_read_generic_etc_files($1_t) + files_read_etc_runtime_files($1_t) + + init_rw_script_pid($1_t) + + libs_use_ld_so($1_t) + libs_use_shared_libs($1_t) + + logging_search_logs($1_t) + logging_send_syslog_msg($1_t) + + miscfiles_read_localization($1_t) + + seutil_read_default_contexts($1_t) + + sysnet_read_config($1_t) + + tunable_policy(`use_nfs_home_dirs',` + fs_read_nfs_files($1_t) + ') + + tunable_policy(`use_samba_home_dirs',` + fs_read_cifs_files($1_t) + ') + + ifdef(`TODO',` + + # do not allow statfs() + dontaudit $1_t fs_type:filesystem getattr; + + allow $1_t bin_t:dir search; + allow $1_t bin_t:lnk_file read; + + # for sshd subsystems, such as sftp-server. + allow $1_t bin_t:file getattr; + + # Read /var. + allow $1_t var_t:dir getattr; + + ifdef(`mount.te', ` + allow $1_t mount_t:udp_socket rw_socket_perms; + ') + + allow $1_t { home_root_t home_dir_type }:dir { search getattr }; + allow $1_t autofs_t:dir { search getattr }; + + dontaudit sshd_t userpty_type:chr_file relabelfrom; + + optional_policy(`inetd.te',` + if (run_ssh_inetd) { + allow $1_t self:process signal; + allow $1_t inetd_t:tcp_socket rw_socket_perms; + allow $1_t var_run_t:dir { getattr search }; + } else { + corenet_tcp_bind_ssh_port($1_t) + init_use_fd($1_t) + init_use_script_pty($1_t) + } + ',` + # These rules should match the else block + # of the run_ssh_inetd conditional directly above + corenet_tcp_bind_ssh_port($1_t) + init_use_fd($1_t) + init_use_script_pty($1_t) + ') + ') dnl end TODO +') diff --git a/refpolicy/policy/modules/services/ssh.te b/refpolicy/policy/modules/services/ssh.te new file mode 100644 index 0000000..2a0290d --- /dev/null +++ b/refpolicy/policy/modules/services/ssh.te @@ -0,0 +1,229 @@ + +policy_module(ssh,1.0) + +######################################## +# +# Declarations +# + +# Allow ssh logins as sysadm_r:sysadm_t +bool ssh_sysadm_login false; + +# Allow ssh to run from inetd instead of as a daemon. +bool run_ssh_inetd false; + +# Type for the ssh-agent executable. +type ssh_agent_exec_t; +files_file_type(ssh_agent_exec_t) + +# ssh client executable. +type ssh_exec_t; +files_file_type(ssh_exec_t) + +type ssh_keygen_t; +type ssh_keygen_exec_t; +init_daemon_domain(ssh_keygen_t,ssh_keygen_exec_t) +role system_r types ssh_keygen_t; + +# ssh server executable +type sshd_exec_t; +files_file_type(sshd_exec_t) + +type sshd_key_t; +files_file_type(sshd_key_t) + +type sshd_tmp_t; +files_tmp_file(sshd_tmp_t) + +################################# +# +# sshd local policy +# +# sshd_t is the domain for the sshd program. +# + +sshd_program_domain(sshd) + +allow sshd_t sshd_tmp_t:dir create_dir_perms; +allow sshd_t sshd_tmp_t:file create_file_perms; +allow sshd_t sshd_tmp_t:sock_file create_file_perms; +files_create_tmp_files(sshd_t, sshd_tmp_t, { dir file sock_file }) + +# for X forwarding +corenet_tcp_bind_xserver_port(sshd_t) + +auth_exec_pam(sshd_t) + +seutil_read_config(sshd_t) + +ifdef(`TODO',` +if (ssh_sysadm_login) { + userdom_spec_domtrans_all_users(sshd_t) + userdom_signal_all_users(sshd_t) + + ifdef(`xauth.te',` + domain_trans(sshd_t, xauth_exec_t, userdomain) + ') + # Relabel and access ptys created by sshd + # ioctl is necessary for logout() processing for utmp entry and for w to + # display the tty. + # some versions of sshd on the new SE Linux require setattr + allow sshd_t ptyfile:chr_file { relabelto read write getattr ioctl setattr }; + # inheriting stream sockets is needed for "ssh host command" as no pty + # is allocated + allow userdomain sshd_t:unix_stream_socket rw_stream_socket_perms; +} else { + userdom_spec_domtrans_unpriv_users(sshd_t) + userdom_signal_unpriv_users(sshd_t) + + ifdef(`xauth.te',` + domain_trans(sshd_t, xauth_exec_t, unpriv_userdomain) + ') + # Relabel and access ptys created by sshd + # ioctl is necessary for logout() processing for utmp entry and for w to + # display the tty. + # some versions of sshd on the new SE Linux require setattr + allow sshd_t userpty_type:chr_file { relabelto read write getattr ioctl setattr }; + # inheriting stream sockets is needed for "ssh host command" as no pty + # is allocated + allow userdomain sshd_t:unix_stream_socket rw_stream_socket_perms; +} + +# for when the network connection breaks after running newrole -r sysadm_r +dontaudit sshd_t sysadm_devpts_t:chr_file setattr; + +# Allow checking users mail at login +allow sshd_t { var_spool_t mail_spool_t }:dir search; +allow sshd_t mail_spool_t:lnk_file read; +allow sshd_t mail_spool_t:file getattr; +') dnl endif TODO + +################################# +# +# sshd_extern local policy +# +# sshd_extern_t is the domain for ssh from outside our network +# +ifdef(`TODO',` +sshd_program_domain(sshd_extern) + +domain_trans(sshd_extern_t, shell_exec_t, user_mini_domain) +# Signal the user domains. +allow sshd_extern_t user_mini_domain:process signal; + +ifdef(`xauth.te', ` +domain_trans(sshd_extern_t, xauth_exec_t, user_mini_domain) +') + +# Relabel and access ptys created by sshd +# ioctl is necessary for logout() processing for utmp entry and for w to +# display the tty. +# some versions of sshd on the new SE Linux require setattr +allow sshd_extern_t user_mini_domain:chr_file { relabelto read write getattr ioctl setattr }; + +# inheriting stream sockets is needed for "ssh host command" as no pty +# is allocated +allow user_mini_domain sshd_extern_t:unix_stream_socket rw_stream_socket_perms; + +optional_policy(`inetd.te',` + if (run_ssh_inetd) { + allow inetd_t ssh_port_t:tcp_socket name_bind; + domain_auto_trans(inetd_t, sshd_exec_t, sshd_t) + domain_trans(inetd_t, sshd_exec_t, sshd_extern_t) + } else { + domain_auto_trans(initrc_t, sshd_exec_t, sshd_t) + domain_trans(initrc_t, sshd_exec_t, sshd_extern_t) + dontaudit initrc_t sshd_key_t:file { getattr read }; + } +',` + # These rules should match the else block + # of the run_ssh_inetd conditional directly above + domain_auto_trans(initrc_t, sshd_exec_t, sshd_t) + domain_trans(initrc_t, sshd_exec_t, sshd_extern_t) + dontaudit initrc_t sshd_key_t:file { getattr read }; +') + +ifdef(`direct_sysadm_daemon', ` +# Direct execution by sysadm_r. +domain_auto_trans(sysadm_t, sshd_exec_t, sshd_t) +role_transition sysadm_r sshd_exec_t system_r; +') + +# so a tunnel can point to another ssh tunnel... +allow sshd_t self:tcp_socket { acceptfrom connectto recvfrom }; +allow sshd_t kernel_t:tcp_socket recvfrom; +allow sshd_t kernel_t:tcp_socket recvfrom; + +# for port forwarding +allow userdomain sshd_t:tcp_socket { connectto recvfrom }; +allow sshd_t userdomain:tcp_socket { acceptfrom recvfrom }; +allow userdomain kernel_t:tcp_socket recvfrom; +allow sshd_t kernel_t:tcp_socket recvfrom; +') dnl endif TODO + +######################################## +# +# ssh_keygen local policy +# + +# ssh_keygen_t is the type of the ssh-keygen program when run at install time +# and by sysadm_t + +dontaudit ssh_keygen_t self:capability sys_tty_config; +allow ssh_keygen_t self:process { sigchld sigkill sigstop signull signal }; + +allow ssh_keygen_t self:unix_stream_socket create_stream_socket_perms; + +allow ssh_keygen_t sshd_key_t:file create_file_perms; +files_create_etc_config(ssh_keygen_t,sshd_key_t,file) + +kernel_read_kernel_sysctl(ssh_keygen_t) + +dev_read_sysfs(ssh_keygen_t) +dev_read_urand(ssh_keygen_t) + +term_dontaudit_use_console(ssh_keygen_t) + +domain_use_wide_inherit_fd(ssh_keygen_t) + +files_read_generic_etc_files(ssh_keygen_t) + +init_use_fd(ssh_keygen_t) +init_use_script_pty(ssh_keygen_t) + +libs_use_ld_so(ssh_keygen_t) +libs_use_shared_libs(ssh_keygen_t) + +logging_send_syslog_msg(ssh_keygen_t) + +allow ssh_keygen_t proc_t:dir r_dir_perms; +allow ssh_keygen_t proc_t:lnk_file read; + +userdom_use_sysadm_tty(ssh_keygen_t) +userdom_dontaudit_use_unpriv_user_fd(ssh_keygen_t) + +ifdef(`direct_sysadm_daemon',` + userdom_dontaudit_use_sysadm_terms(ssh_keygen_t) +') + +ifdef(`targeted_policy', ` + term_dontaudit_use_unallocated_tty(ssh_keygen_t) + term_dontaudit_use_generic_pty(ssh_keygen_t) + files_dontaudit_read_root_file(ssh_keygen_t) +') + +optional_policy(`rhgb.te', ` + rhgb_domain(ssh_keygen_t) +') + +optional_policy(`selinux.te',` + seutil_newrole_sigchld(ssh_keygen_t) +') + +optional_policy(`udev.te', ` + udev_read_db(ssh_keygen_t) +') + +ifdef(`TODO',` +allow ssh_keygen_t autofs_t:dir { search getattr }; +') diff --git a/refpolicy/policy/modules/system/userdomain.if b/refpolicy/policy/modules/system/userdomain.if index 2f804f7..f129a43 100644 --- a/refpolicy/policy/modules/system/userdomain.if +++ b/refpolicy/policy/modules/system/userdomain.if @@ -869,28 +869,45 @@ define(`userdom_shell_domtrans_sysadm_depend',` ') ######################################## -## +## ## -## Read and write administrative users -## physical and pseudo terminals. +## Read and write sysadm ttys. ## ## ## The type of the process performing this action. ## ## # -define(`userdom_use_sysadm_terms',` - gen_require(`$0'_depend) +define(`userdom_use_sysadm_tty',` + gen_require(` + type sysadm_tty_device_t; + class chr_file { getattr read write ioctl }; + ') dev_list_all_dev_nodes($1) term_list_ptys($1) - allow $1 admin_terminal:chr_file { getattr read write ioctl }; + allow $1 sysadm_tty_device_t:chr_file { getattr read write ioctl }; ') -define(`userdom_use_sysadm_terms_depend',` - attribute admin_terminal; +######################################## +## +## +## Read and write sysadm ttys and ptys. +## +## +## The type of the process performing this action. +## +## +# +define(`userdom_use_sysadm_terms',` + gen_require(` + attribute admin_terminal; + class chr_file { getattr read write ioctl }; + ') - class chr_file { getattr read write ioctl }; + dev_list_all_dev_nodes($1) + term_list_ptys($1) + allow $1 admin_terminal:chr_file { getattr read write ioctl }; ') ######################################## @@ -904,17 +921,14 @@ define(`userdom_use_sysadm_terms_depend',` ## # define(`userdom_dontaudit_use_sysadm_terms',` - gen_require(`$0'_depend) + gen_require(` + attribute admin_terminal; + class chr_file { read write }; + ') dontaudit $1 admin_terminal:chr_file { read write }; ') -define(`userdom_dontaudit_use_sysadm_terms_depend',` - attribute admin_terminal; - - class chr_file { read write }; -') - ######################################## ## ## @@ -926,18 +940,15 @@ define(`userdom_dontaudit_use_sysadm_terms_depend',` ## # define(`userdom_search_all_users_home',` - gen_require(`$0'_depend) + gen_require(` + attribute home_dir_type, home_type; + class dir search; + ') files_list_home($1) allow $1 { home_dir_type home_type }:dir search; ') -define(`userdom_search_all_users_home_depend',` - attribute home_dir_type, home_type; - - class dir search; -') - ######################################## ## ## @@ -949,20 +960,17 @@ define(`userdom_search_all_users_home_depend',` ## # define(`userdom_read_all_user_data',` - gen_require(`$0'_depend) + gen_require(` + attribute home_type; + class dir r_dir_perms; + class file r_file_perms; + ') files_list_home($1) allow $1 home_type:dir r_dir_perms; allow $1 home_type:file r_file_perms; ') -define(`userdom_read_all_user_data_depend',` - attribute home_type; - - class dir r_dir_perms; - class file r_file_perms; -') - ######################################## ## ## @@ -974,17 +982,14 @@ define(`userdom_read_all_user_data_depend',` ## # define(`userdom_use_all_user_fd',` - gen_require(`$0'_depend) + gen_require(` + attribute userdomain; + class fd use; + ') allow $1 userdomain:fd use; ') -define(`userdom_use_all_user_fd_depend',` - attribute userdomain; - - class fd use; -') - ######################################## ## ## @@ -996,15 +1001,31 @@ define(`userdom_use_all_user_fd_depend',` ## # define(`userdom_signal_all_users',` - gen_require(`$0'_depend) + gen_require(` + attribute userdomain; + class process signal; + ') allow $1 userdomain:process signal; ') -define(`userdom_signal_all_users_depend',` - attribute userdomain; +######################################## +## +## +## Send general signals to unprivileged user domains. +## +## +## The type of the process performing this action. +## +## +# +define(`userdom_signal_unpriv_users',` + gen_require(` + attribute unpriv_userdomain; + class process signal; + ') - class process signal; + allow $1 unpriv_userdomain:process signal; ') ######################################## @@ -1018,17 +1039,14 @@ define(`userdom_signal_all_users_depend',` ## # define(`userdom_use_unpriv_users_fd',` - gen_require(`$0'_depend) + gen_require(` + attribute unpriv_userdomain; + class fd use; + ') allow $1 unpriv_userdomain:fd use; ') -define(`userdom_use_unpriv_users_fd_depend',` - attribute unpriv_userdomain; - - class fd use; -') - ######################################## ## ## @@ -1041,15 +1059,12 @@ define(`userdom_use_unpriv_users_fd_depend',` ## # define(`userdom_dontaudit_use_unpriv_user_fd',` - gen_require(`$0'_depend) + gen_require(` + attribute unpriv_userdomain; + class fd use; + ') dontaudit $1 unpriv_userdomain:fd use; ') -define(`userdom_dontaudit_use_unpriv_user_fd_depend',` - attribute unpriv_userdomain; - - class fd use; -') - ##