Follow Techotopia on Twitter

On-line Guides
All Guides
eBook Store
iOS / Android
Linux for Beginners
Office Productivity
Linux Installation
Linux Security
Linux Utilities
Linux Virtualization
Linux Kernel
System/Network Admin
Scripting Languages
Development Tools
Web Development
GUI Toolkits/Desktop
Mail Systems
Eclipse Documentation

How To Guides
General System Admin
Linux Security
Linux Filesystems
Web Servers
Graphics & Desktop
PC Hardware
Problem Solutions
Privacy Policy




The Guide to Writing SELinux Policy
Prev Home Next

5. User related files

This section will discuss policy files related to actual users on the system, and where you can determine their level of access. In "Getting Started with SE Linux HOWTO" we saw that "an identity under SE Linux is not the same as the traditional Unix uid (user id). They can coexist together on the same system, but are quite different. identities under SE Linux form part of a security context which will affect what domains can be entered, i.e. what essentially can be done. An SE Linux identity and a standard Unix login name may have the same textual representation (and in most cases they do), however it is important to understand that they are two different things."

5.1 The users file

The users file, found in your policy source directory for your distribution, such as /etc/selinux/users under Debian, contains definitions for each user that is to be recognised by your SE Linux system. If a user identity is explicitly named in this file, their user identity will form the first part of their security context. A security context is made up of the identity, role and domain or type. You can check your own current security context by running the id command under SE Linux. If a user identity is not named in the users file, they will be assigned the user_u identity.

Following are some example entries in a users file.

user root roles { staff_r sysadm_r };
This entry defines user identity root, and allows root to enter the staff_r and sysadm_r roles. The newrole command can be used to change user roles, or root (in this example) can choose to enter one of the roles above when logging in at the console.

user faye roles { staff_r sysadm_r };
Again, this entry defines the user identity faye. As with root, faye is also able to enter the sysadm_r role, which is the system administrator role. These two examples show you that the traditional root user does not necessarily have to have sysadm_r privileges just because they are user root, and that another user (such as faye) can have access to the system administrator role. If the roles definition for user root did not have sysadm_r, faye would be more powerful than root.

user foo roles { user_r };
User foo is defined, and they only have access to the user_r role, which is the general unprivileged user role.

user system_u roles system_r;

The system_u identity is the user identity for processes and objects such as files, directories, sockets and so on. You should not assign the system_u identity to a user process, as system_u is for daemons. If a user has system_u, they may potentially have access to the system_r role and any daemon domains.

5.2 The user.te file

This file is found in the subdirectory "domains" under your policy source directory, such as /etc/selinux/domains on Debian. user.te contains the unprivileged domains for the users on your SE Linux system. In this file you will see the line
This line allows all access necessary for the user role to do standard things such as run bin_t programs in their home directory, assign user_home_dir_t to the user's home directory and user_home_t to directories under that. The lines
allow staff_t unpriv_userdomain:process signal_perms;
can_ps(staff_t, unpriv_userdomain)
allow staff_t { ttyfile ptyfile tty_device_t }:chr_file getattr;
defines the domain staff_t. The second line allows the staff_t domain to send signals to processes running in unprivileged domains such as user_t and staff_t. The third line allows staff_t to run ps and see processes in the unprivileged user domains. staff_t is able to run ps and see everything in user_t and other user domains if any, whereas user_t can not. The fourth line allows staff_t to access the attributes of any terminal device.
dontaudit unpriv_userdomain sysadm_home_dir_t:dir { getattr search };
This line says not to audit unprivileged user domain (such as user_t) attempts to acces the /root directory by doing something like a ls -l or cd /root command, or trying to access a file under the /root directory. The line can also be read as "dontaudit source destination:destination class {what was attempted }".
# change from role $1_r to $2_r and relabel tty appropriately
define(`role_tty_type_change', `
allow $1_r $2_r;
type_change $2_t $1_devpts_t:chr_file $2_devpts_t;
type_change $2_t $1_tty_device_t:chr_file $2_tty_device_t;
The first (uncommented) line defines the macro role_tty_type_change. This macro allows you to change roles and then relabel the tty you're using (such as when you use the newrole command to get from staff_r to sysadm_r and your tty changes). The second line says that $1_r is allowed to transition to $2_r (so $1_r might be staff_r and $2_r is sysadm_r). The relabelling of the tty is handled by the third and fourth lines.
ifdef(`newrole.te', `
# Allow the user roles to transition
# into each other.
role_tty_type_change(sysadm, user)
role_tty_type_change(staff, sysadm)
role_tty_type_change(sysadm, staff)
This block says that if newrole.te is defined (i.e. if the file exists) then allow the roles shown to transition to eachother. These statements are the invocations of the role_tty_type_change macro as defined previously.

5.3 The user_macros.te file

This file contains macros for user login domains which are domains users get upon logging in, as opposed to the domain of something like a cron job. Other non-login domains include those for gpg and irc, among others. I am using extracts of my own user_macros.te file as the example here (not the whole file). This file is located under the macros subdirectory of your policy source. I will break this file up in to little chunks for ease of explanation. Before I do that, I'd like to provide a brief definition of "capabilities": the ability to perform certain privileged operations.

5.3.1 Macros for user login domains


 # user_domain() is also called by the admin_domain() macro
The above extract defines the macro user_domain


# Use capabilities
allow $1_t self:capability { setgid chown fowner };
dontaudit $1_t self:capability { sys_nice fsetid };
"Capabilities" in this snippet means the capability to change the group id (setgid). A program can call setgid() to change its group id, but only if it has the capability to do so in the first place, as well as not having given up the capability previously. A program can't call setgid() if this capability isn't granted. An in-depth discussion of capabilities is beyond the scope of this document, however please see /usr/include/linux/capability.h for more information. The first line allows the $1_t type the capability to setgid. $1 is the first parameter passed from the calling code (the code that called the macros). The second line says not to audit sys_nice (the ability to increase scheduling priority) or fsetid (related to controlling setuid and setgid files). These are capabilities requested repeatedly, so this line says not to audit the fact they're being requested.


# Type for home directory.
ifelse($1, sysadm, `
type $1_home_dir_t, file_type, sysadmfile, home_dir_type, home_type;
type $1_home_t, file_type, sysadmfile, home_type;
', `
type $1_home_dir_t, file_type, sysadmfile, home_dir_type, user_home_dir_type, home_
type, user_home_type;
type $1_home_t, file_type, sysadmfile, home_type, user_home_type;
The above says that if $1 is sysadm then do the first block, otherwise do the second block, where both define types for home directories and tmp_domain (the macro for /tmp file access). So, the first block relates to sysadm stuff, and the second relates to the rest.
 # do not allow privhome access to sysadm_home_dir_t
file_type_auto_trans(privhome, $1_home_dir_t, $1_home_t)
tmp_domain($1, `, user_tmpfile')
Here, we don't want privhome domains to access sysadm_home_dir_t. Take procmail for example. When procmail delivers mail it creates a file in a user's home directory. We don't want that happening to a sysadm directory (/root). "file_type_auto_trans" is the way to set the default type for a new file, otherwise it will be the same type as the directory it is created in. Normally when you create a file, it will have the same type as the directory it is created in. There are two ways to have a different type to that of the directory at creation time. The first is through open_secure() and the second is through file_type_auto_trans. For the first to be allowed, you need to have a file_type_trans rule that permits it, and then file_type_auto_trans makes it the default.


# allow ptrace
can_ptrace($1_t, $1_t)
This allows the first parameter ($1_t) to ptrace, or trace the process of the second parameter (also $1_t). This line therefore allows $1_t to ptrace itself.


# Create, access, and remove files in home directory.
file_type_auto_trans($1_t, $1_home_dir_t, $1_home_t)
allow $1_t $1_home_t:dir_file_class_set { relabelfrom relabelto };
Here, a process in domain $1_t creates a file under a directory of type $1_home_dir_t and by default the created file is of type $1_home_t. The second line allows $1_t to relabel a file of type $1_home_t to something else, and to change the type from something else to $1_home_t.


# Bind to a Unix domain socket in /tmp.
allow $1_t $1_tmp_t:unix_stream_socket name_bind;
This allows $1_t to bind to a Unix domain socket, so it can then receive connections from other processes. $1_tmp_t is the type of the tmp_domain. name_bind allows $1_t to bind to a name under /tmp.

5.3.2 Macros for ordinary user domains

Everything below refers to user_t.


define(`full_user_role', `

# user_t/$1_t is an unprivileged users domain.
type $1_t, domain, userdomain, unpriv_userdomain, web_client_domain;

# $1_r is authorized for $1_t for the initial login domain.
role $1_r types $1_t;
allow system_r $1_r;

# Grant permissions within the domain.
Define the macro full_user_role. Define the type $1_t/user_t and give it the four attributes listed. $1_r/user_r is able to have $1_t/user_t. system_r is then allowed access to $1_r/user_r. general_domain_access allows $1_t to see process in $1_t, see files in /proc/# among others (check the file core_macros.te).


# Read /etc.
allow $1_t etc_t:dir r_dir_perms;
allow $1_t etc_t:notdevfile_class_set r_file_perms;
allow $1_t etc_runtime_t:{ file lnk_file } r_file_perms;
Allow user_t to read etc_t (the type of /etc). You can see and read files under /etc and do things such as ls -l commands on /etc. If you look at the file core_macros.te you will see that notdevfile_class_set related to non-device file classes such as files, symlinks, socket files and fifo files. etc_runtime_t is the type for certain files in /etc (grep for "etc_runtime_t" in the file file_contexts).


define(`in_user_role', `
role user_r types $1;
role staff_r types $1;
Define the macro in_user_role. A domain can be used in any of the user roles. The macro must be called in the .te file of the domain concerned. Look at the file passwd.te (for the passwd program). The in_user_role macro is invoked and has the passwd_t parameter passed to it. Going back to the above snippet, we can now say
role user_r types passwd_t;
role staff_r types passwd_t;
meaning that user_r and staff_r can run the passwd program. Remember that if you add a new role, you must edit the in_user_role macro here.

The Guide to Writing SELinux Policy
Prev Home Next

  Published with kind permission of Faye Coker Design by Interspire