User:SwifT/selinux-tutorials/2

Linux services and the system_u SELinux user
So now we know that the security context of a process contains a part called the SELinux user, one SELinux role and the SELinux domain that the process runs in. We have also talked a bit about SELinux users and that they are somewhat immutable (the user cannot change the SELinux user). Well, in this tutorial we'll talk about an exception to this rule, mainly when managing Linux services.

Linux service scripts
Most Linux service scripts are, as you know, located in (I will not talk about systemd yet as I have no experience with it). These service scripts are launched by the init system upon boot (or runlevel change), but can also be called directly by administrators.

For the standard SELinux policies, these scripts are either labeled initrc_exec_t or  _initrc_exec_t:

The idea is that, when init or the administrator runs those scripts, the script itself runs in the initrc_t domain. However, if you double-check, you will notice that only the system_r role is allowed the initrc_t domain - so a regular user domain should not be able to transition towards the initrc_t domain.

So what is happening when you do start the script? After all, everything seems to run, right?

The process to transition to initrc_t
What happens is that, upon executing the init script, a transition occurs to the run_init_t domain (Gentoo). Then, OpenRC (Gentoo's init system) calls the run_init command. This command will invoke the script (again) but with a transition, not only to the target initrc_t domain, but also with the system_u:system_r related context (so it switches SELinux user and role).

The run_init_t domain is one of the few domains that are allowed (by policy) to do this.

Domain-specific init scripts
Some services have a domain-specific init script. For instance, the script has the system_u:object_r:nscd_initrc_exec_t context.

In this case, if the system administrator executes this script, no such transition occurs. This is because the nscd_initrc_exec_t script is not defined as an entrypoint for the run_init_t domain. Instead, it is only known as an entrypoint for the initrc_t domain itself. When trying to execute it directly, SELinux attempts to transition to the initrc_t domain but, as there is no switch in user/role, it fails. In the audit logs (or messages file) you then find an error like the following: type=SELINUX_ERR msg=audit(1363638369.361:144): security_compute_sid: invalid context staff_u:system_r:initrc_t for scontext=staff_u:sysadm_r:sysadm_t tcontext=system_u:object_r:nscd_initrc_exec_t tclass=process

To force the change in user/role, you need to call the run_init command for this (if you are allowed this command), like so:

Purpose of domain-specific init scripts
The purpose of this distinction is to allow specific users (or roles) to execute the domain-specific init scripts, while not granting privileges to execute the other scripts. In this case, users that are not allowed to execute run_init_t can be allowed to execute the mentioned domain-specific init script. In this case, the policy will automatically (i.e. without using run_init_t) switch the role towards system_r (but mind you, this requires that the user is allowed the system_r role).

When this occurs however, no change in SELinux user happens. As a result, these services will then run under the SELinux user of the user that (re)started the service. As the process runs in the system_r and proper domain however, this has no additional impact on the system.

What you need to remember
What you should remember from this tutorial is that
 * calling linux service scripts (init scripts) causes a change in SELinux user, role and domain
 * some service scripts are not labeled the regular initrc_exec_t and require a different approach for calling them
 * it is the SELinux policy that governs changes in roles