View Full Version : SELinux new users, new roles , new domains

4th June 2009, 06:32 PM
I'm new to SELinux actually, I've looked and done Fedora SELinux user guide but unfortunatly it did not cover my questions.

Currently working on the targeted policy, I need a help in doing the following things as quick as possible:
1- How to create a totally new SELinux user (not mapping new linux user to SELinux user) I want a new user with no roles or with a maximum of 1 role. I also need how to compile the new user so I can used it for mapping users. At the time, I've tried creating a new file inside /etc/selinux/targeted/contexts/users similar to the other users inside this directory, but it did not actually seem to appear when using the command semanage to list SELinux users : semanage user -l

2- How to create a totally new SELinux role (empty for now) ? and how to make the relation between this new role and domains or types.
3- How to create new domain, actually following some old instructions I created the .fc and .te files, but not the .if file, which is more complicated than the other 2 file.

Hope to hear soon from SELinux experts.


4th June 2009, 06:37 PM
The experts live @ the selinux mailing list.



4th June 2009, 08:40 PM
There are different kind of roles.

I will discuss 4 simple ones: a unprivileged ssh user, a unprivileged gui user, a gui/ssh user that can access other roles (mytestrole). a privileged role (mytestrole):

primairy unpriv ssh user role:

echo "policy_module(myguest, 0.0.1)" > myguest.te
echo "role myguest_r;" >> myguest.te
echo "userdom_restricted_user_template(myguest)" >> myguest.te
echo "gen_user(myguest_u, user, myguest_r, s0, s0)" >> myguest.te
cp /etc/selinux/targeted/contexts/users/guest_u /etc/selinux/targeted/contexts/users/myguest_u
sed -i 's/guest/myguest/g' /etc/selinux/targeted/contexts/users/myguest_u
make -f /usr/share/selinux/devel/Makefile
sudo semodule -i myguest.pp
sudo useradd -Z myguest_u joe

primairy unpriv gui user role:

echo "policy_module(myxguest, 0.0.1)" > myxguest.te
echo "role myxguest_r;" >> myxguest.te
echo "userdom_restricted_xwindows_user_template(myxguest )" >> myxguest.te
echo "gen_user(myxguest_u, user, myxguest_r, s0, s0)" >> myxguest.te
cp /etc/selinux/targeted/contexts/users/xguest_u /etc/selinux/targeted/contexts/users/myxguest_u
sed -i 's/xguest/myxguest/g' /etc/selinux/targeted/contexts/users/myxguest_u
make -f /usr/share/selinux/devel/Makefile
sudo semodule -i myxguest.pp
sudo useradd -Z myxguest_u joe

primairy gui/ssh user role that can access other secundairy privileged roles (example test role) (see below the test role example)

echo "policy_module(mystaff, 0.0.1)" > mystaff.te
echo "role mystaff_r;" >> mystaff.te
echo "userdom_unpriv_user_template(mystaff)" >> mystaff.te
echo "seutil_run_newrole(mystaff_t, mystaff_r)" >> mystaff.te
echo "sudo_role_template(mystaff, mystaff_r, mystaff_t)" >> mystaff.te
echo "this user can access the mytestrole role" >> mystaff..te
echo "mytestrole_role_change(mystaff_r)" >> mystaff.te
echo "gen_user(mystaff_u, user, mystaff_r mytestrole_r system_r, s0, s0)" >> mystaff.te
cp /etc/selinux/targeted/contexts/users/staff_u /etc/selinux/targeted/contexts/users/mystaff_u
sed -i 's/stafft/mystaff/g' /etc/selinux/targeted/contexts/users/mystaff_u

secundairy privileged mytestrole role:

echo "policy_module(mytestrole, 0.0.1)" > mytestrole.te
echo "role mytestrole_r;" >> mytestrole.te
echo "userdom_base_user_template(mytestrole)" >> mytestrole.te
echo "this role can manage the asterisk service" >> mytestrole.te
echo "asterisk_admin(mytestrole_t, mytestrole_r)" >> mytestrole.te
echo " ########################################" > mytestrole.if
echo " ## <summary>" >> mytestrole.if
echo "## Change to the mytestrole role." >> mytestrole.if
echo "## </summary>" >> mytestrole.if
echo "## <param name="role">" >> mytestrole.if
echo "## <summary>" >> mytestrole.if
echo "## Role allowed access." >> mytestrole.if
echo "## </summary>" >> mytestrole.if
echo "## </param>" >> mytestrole.if
echo "## <rolecap/>" >> mytestrole.if
echo "#" >> mytestrole.if
echo "interface(`mytestrole_role_change',`" >> mytestrole.if
echo " gen_require(`" >> mytestrole.if
echo " role mytestrole_r;" >> mytestrole.if
echo "')" >> mytestrole.fc;" >> mytestrole.if
echo " allow $1 mytestrole_r;;" >> mytestrole.if
echo "');" >> mytestrole.if
make -f /usr/share/selinux/devel/Makefile
sudo semodule -i mystaff.pp mytestrole.pp
sudo useradd -Z mystaff_u joe

Note that the echos may not work right since it has weird characters that may need to be escaped
Also note that these policy may or may not work. i left out some policy to keep it as simple and as to the point as possible.
Note above examples my or may not work
Note if you want to see how it is done upstream then download the selinux-policy.src.rpm, extract it extract the included serefpolicy.tgz, apply the included patch and then look into policy/modules/roles (guest, xguest, staff, webadm in particular)

How to create a domain:

This question is too open. what kind of domain?

echo "policy_module(mydomain, 0.0.1)" > mydomain.te
echo "type mydomain_t;" >> mydomain.te
echo "domain_type(mydomain_t)" >> mydomain.te
echo "type mydomain_exec_t) >> mydomain.te
echo "files_type(mydomain_exec_t)" >> mydomain.te
echo "domain_entry_file(mydomain_t. mydomain_exec_t)" >> mydomain.te
echo "/some/place/mydomain.bin -- gen_context(system_u:object_r:mydomain_exec_t, s0)" >> mydomain.fc
make -f /usr/share/selinux/devel/Makefile
sudo semodule -i mydomain.pp
sudo restorecon -v /some/place/mydomain.bin

(this wont allow anything becuase i dont know what kind of domain it has to be) e.g. who/what runs it?

Try this at your own risk

5th June 2009, 03:42 PM
Thanks SlowJet for telling me about the mailing list.

Thanks domg472 for your help, it's really easy to understand.
The thing I'm trying to do is: I've a program (executed file),
I need to create a special SELinux user to run this program, so I need a :
1- SELinux user, say specialuser_u. which has one role, which is: specialuser_r.
2- This rule show contain one domain for the user, which is specialuser_t only to allow the user to run this program.

Currently what I've done is the following:
1- specialuser.te, contains:
policy_module(specialuser, 0.0.1)

## define new role, with new user specialuser
role specialuser_r;
gen_user(specialuser_u, user, specialuser_r, s0, s0)

## define new domain for the user
type specialuser_t;
type specialuser_exec_t;
domain_entry_file(specialuser_t, specialuser_exec_t)

2- file specialuser.fc, contains:
/home/specialuser/program(/.*)? get_context(system_u:object_r:specialuser_exec_t,s 0)

when I try to used the command :
make -f /usr/share/selinux/devel/Makefile

it shows me the following errror:Compiling targeted specialuser module
/usr/bin/checkmodule: loading policy configuration from tmp/specialuser.tmp
specialuser.te":9:ERROR 'syntax error' at token 'type' on line 28502:
type specialuser_t;
## define new domain for the user
/usr/bin/checkmodule: error(s) encountered while parsing configuration
make: *** [tmp/specialuser.mod] Error 1

Hope it's clear what I'm trying to achieve, just by the way I didn't find that good documentation or tutorials of how to develop SELinux policy in Fedora, I've a book but it's speaking about Fedora core 2 which is almost totally different.


5th June 2009, 05:16 PM
Ok with this information let us try again.

step 1. create a unprivileged user (myuser_u, myuser_t, myuser_r) that is based off of user_u:


policy_module(myuser, 0.0.1)
role myuser_r;
gen_user(myuser_u, user, myuser_r, s0, s0)

cp /etc/selinux/targeted/contexts/users/user_u /etc/selinux/targeted/contexts/users/myuser_u
sed -i 's/user/myuser/g' /etc/selinux/targeted/contexts/users/myuser_u

Step 2. create a application domain (myapp_t) for myuser_t


policy_module(myapp, 0.0.1)
type myapp_t;
type myapp_exec_t;
application_domain(myapp_t, myapp_exec_t)
role myuser_r types myapp_t;
require { type myuser_t; }
domain_auto_trans(myuser_t, myapp_exec_t, myapp_t)


HOME_DIR/program.bin -- gen_context(system_u:object_r:myapp_exec_t, s0)

building & installing:

make -f /usr/share/selinux/devel/Makefile
sudo semodule -i myuser.pp myapp.pp

sudo useradd -Z myuser_u joe
sudo restorecon -v /home/joe/program.bin


myuser.te adds policy for myuser_u (myuser_t/myuser_r)
that policy is based off of the existing user_u seuser

myapp.te adds policy for the user application called "program" in /home/*/program.bin
this policy for myapp only has a few declarations to get started. it also has policy that specifies that if myuser_t runs a executable file with type myapp_exec_t that the domain should transition to myapp_t.
this policy module has NO other allow rules yet. You must extend it to meet your requirement
audit2allow can help there.

as a policy author there are some sources of information. i will list some:

the selinux, fedora-selinux and tresys-refpolicy maillists
the selinux websites
the refpolicy and fedora selinux-policy source policy
the book "SELinux by Example"
the #selinux and #fedora-selinux IRC chats

6th June 2009, 03:35 PM
Hello, domg472, thanks for replying again.
Actually I've got a new problem during using the semodule command, this is the error:
sudo semodule -i myuser.pp myapp.pp
libsepol.context_from_record: user get_context(system_u is not defined
libsepol.context_from_record: could not create context structure
libsepol.context_from_string: could not create context structure
libsepol.sepol_context_to_sid: could not convert get_context(system_u:object_r:myapp_exec_t,s0) to sid
invalid context get_context(system_u:object_r:myapp_exec_t,s0)
libsemanage.semanage_install_active: setfiles returned error code 1.
semodule: Failed!

It sounds easy to fix, but didn't get anywhere. Hope you can help in getting this fixed again.


6th June 2009, 05:32 PM
It is a typo i believe: you defined "get_context" but it should be "gen_context"

HOME_DIR/program.bin -- gen_context(system_u:object_r:myapp_exec_t, s0)

7th June 2009, 12:15 PM
Hello domg472,
you're right, it's a silly mistake that I get every so offer.
Thanks for much for help, I'll try the new solution soon.
thanks for the sources for learning SELinux .

8th June 2009, 06:59 PM
Thanks domg472 again.
It does work now but didn't relabel file names using restorecon. It did not work also when using comamnd su - exampleuser to be exampleuser, I mean it did not change the selinux and role.
Just interesting question: how can I find all the option that I can use in the policy( things like application_executable_file, system_r:sysadm_su_t:s0 ) all the possible options? and if possible is there is any documentation for them? this will help me a lot in getting to know what's available there, even if it in selinux files.


8th June 2009, 07:26 PM
By studying/referencing the source policy. These interfaces, macros, templates, patterns and permission sets usually have a small comment describing what they do and what input they expect.

Also their contents (policy) is the best way to see what they do/allow.

I will give you an example:


(line 24 to line 44)

This is a interface. interfaces are shared policy. It is policy that is hosted by module for other domains to use.
The interface names usually hint you about where they are defined.
In this case: application_executable_file is defined in the application module.
The interface name is prepended with the name of the module where it is defined (application)
Shared policy you can find in the .if files or interface files.

So lets have a closer look at the contents:

Interfaces usually have a commented header with a description if its use and they tell you what parameters they expect (input)

line 26 to line 28 has a summary/description
line 30 to line 34 shows what parameter it expects.

line 36 to line 40 show the actual contents of the interface (policy)
This policy may have calls to other interfaces.

for example: line 43 has a call to another interface, which is defined here:

shared policy is like headers that can be included. external policy that can be borrowed.
The concept of sharing policy is so that the amount of policy written can be kept to a minimum
This makes it easier to maintain policy (it is defined in a single central place and from there distributed to other places that may want to use the same policy)(no duplicates/overhead)

Besides interfaces and templates there are also macros, patterns and permission sets:

they serve similar purpose. to make it easier for policy authors to maintain policy and to keep the policy as small as possible.

In a source policy module there are 3 files.
a .te(type enforcement) file has personal policy (policy local to the module)
a .if(interface) file has shared policy (policy that can be shared with other modules)
a .fc(file context) file has file contexts

As a policy author you should get familiar with everything in here:

This is a very important source of information. As it has descriptions of most interfaces/macros etc and also it has many example policy modules.

Another good place to study is:

Well actually everything here:

It does work now but didn't relabel file names using restorecon. It did not work also when using comamnd su - exampleuser to be exampleuser, I mean it did not change the selinux and role.

The su issue is a policy issue. There are two things to consider. A default unconfined user will not transition to confined users (unless you implicitly define that it should). However unconfined users were designed to be exempted from most SELinux and therefore unconfined processes usually stay unconfined rather then transition to confined domains( which would basically defeat the purpose of an unconfined/exempted domain)

Your newly created (confined) user domain can also not use su/sudo and domain transitions because we didnt allow it.

role transitions must be implicitly allowed to work and su does not support domain transitions. sudo or su used together with the newrole command do support domain transitions.

The restorecon command should work if you run it as an unconfined root. The restorecon command does not work if you run it as the new confined user because the new confined user does not have access to relabel file from type user_home_t to myapp_exec_t

You would have to grant your user permission to do so.

for example by adding the following to your myuser.te (and rebuild/reinstall):

require { type myapp_exec_t; }
relabel_files_pattern(myuser_t, myapp_exec_t, myapp_exec_t)

By the way: You can find a prettier lay out of the .if files here:

This can be created if you run 'make html' in the source tree. (it will translate the commented header in the interface files and convert it to html)

10th June 2009, 05:36 PM
Hello domg472
That's nice , it's clear now for me how to find information and how the mechanism work in overall. Now it's time that I start going through these files to find things out myself.

Thank you very much.