SELinux user mapping
Manage mapping of users stored in IPA to SELinux users.
IPA will store one new type of entry and two new pieces of configuration.
attributeTypes: (2.16.840.1.113722.214.171.124.10 NAME 'ipaSELinuxUser' DESC 'An SELinux user' EQUALITY caseIgnoreMatch ORDERING caseIgnoreOrderingMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 126.96.36.199.4.1.14188.8.131.52.15 SINGLE-VALUE X-ORIGIN 'IPA v3' )
objectClasses: (2.16.840.1.1137184.108.40.206.5 NAME 'ipaSELinuxUserMap' SUP ipaAssociation STRUCTURAL MUST SELinuxUser MAY ( accessTime $ seeAlso ) X-ORIGIN 'IPA v3' )
- SELinuxUser is the SELinux user this rule maps to.
- accessTime is a FutureFeature.
- seeAlso is the dn of an HBAC rule defining the users and hosts for this map
We will store these rules in cn=selinux,$SUFFIX
dn: ipauniqueid=d4d97a3a-1167-11e1-9dea-0050562c8d82,cn=selinux,dc=example,dc=com cn: Staff on rawhide ipaenabledflag: TRUE memberhost: fqdn=rawhide.example.com,cn=computers,cn=accounts,dc=example,dc=com memberuser: uid=joe.user,cn=users,cn=accounts,dc=example,dc=com accessruletype: allow ipaselinuxuser: staff_u:s0-s0:c0.c1023 ipauniqueid: d4d97a3a-1167-11e1-9dea-0050562c8d82 objectclass: ipaassociation objectclass: ipaselinuxusermap
dn: ipauniqueid=d4d97a3a-1167-11e1-9dea-0050562c8d82,cn=selinux,dc=example,dc=com cn: User using hbac ipaenabledflag: TRUE seeAlso: ipauniqueid=79a60542-1168-11e1-851d-0050562c8d82,cn=hbac,dc=example,dc=com ipaselinuxuser: user_u:s0-s0:c0.c1023 ipauniqueid: d4d97a3a-1167-11e1-9dea-0050562c8d82 objectclass: ipaassociation objectclass: ipaselinuxusermap
The other two values will be stored in cn=ipaConfig.
The first value is the order list of SELinux users we can map to in ascending order of priority. This list will use $ as a separator.
attributeTypes: ( 2.16.840.1.1137220.127.116.11.27 NAME 'ipaSELinuxUserMapOrder' DESC 'Available SELinux user context ordering' EQUALITY caseIgnoreMatch ORDERING caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 18.104.22.168.4.1.1422.214.171.124.15 SINGLE-VALUE X-ORIGIN 'IPA v3' )
This table will look like:
The second value is the default SELinux user, e.g. guest_u:s0
attributeTypes: ( 2.16.840.1.1137126.96.36.199.26 NAME 'ipaSELinuxUserMapDefault' DESC 'Default SELinux user' EQUALITY caseIgnoreMatch ORDERING caseIgnoreMatch SUBSTR caseIgnoreSubstringsMatch SYNTAX 188.8.131.52.4.1.14184.108.40.206.15 SINGLE-VALUE X-ORIGIN 'IPA v3' )
An HBAC rule pointed to by an SELinux mapping may not be removed until the mapping rule is removed. The HBAC rule does not store a pointer, rather it will need to search the maps to see if it is being referenced.
An SELinux user may not be removed from the ordered list if it appears in any of the mapping rules.
An SELinux user may not be removed from the order list if it is the default.
The default value must always be a member of the list.
The default user context may be blank/empty. An empty member tells sssd to use the system default context.
The default user context in IPA is unconfined_u.
A map must contain both a (user/group or usercat) and (host/hostgroup or hostcat).
If it points to an HBAC rule then that rule must conform to the above. Otherwise the mapping rule is ignored.
seeAlso may not be defined if a user, usercat, host or hostcat is defined. The use must either link to an HBAC rule or define everything in the SELinux map.
SELinux user syntax
An SELinux user has 3 components: user:MLS:MCS. user and MLS are mandatory, so user:MLS:MCS or only user:MLS are also valid (relevant Bugzilla).
User traditionally ends with _u but this is not mandatory. It may contain letters or underscores, but must start with a letter.
The MLS part can only be s[0-15] (a single level), or s[0-15]-s[0-15] (a range of levels).
Then MCS could be c[0-1023] (a single category), c[0-1023].c[0-0123] (a range of categories), or any number of these separated by commas.
For example, the following are valid:
user_u:s0 user_u:s0-s1 user_u:s0-s15:c0.c1023 user_u:s0-s1:c0,c2,c15.c26 user_u:s0-s0:c0.c1023
See SELinux documentation for more details on MCS/MLS levels. Note that IPA only does a rudimentary sanity check, so it may allow illegal values in some cases.
IPA stores the maps, the ordered list of SELinux contexts and the default context.
SSSD evaluates the maps to determine the correct context based on the user and machine.
Order of operation
The maps are a triple of (host, user, selinuxuser)
host can be a single host, a hostgroup, or hostcat=all user can be a single user, a group, or usercat=all selinuxuser is a single value
Matching is done from most to least-specific. You can think of this as levels where user > group > usercat=all and host > hostgroup > hostcat=all.
The host is checked first, then user.
If two matches on the same level are found then the ordered list of selinux users is used to determine the winner. The last (highest priority) in the list wins.
If after all this no match is found the default selinux user is used.
Since we can potentially point to another association (HBAC) which has its own enabled flag both will need to be evaluated. If either is disabled then the rule is ignored.
When a user attempts to log in we'll know two things: the uid of the user logging in and the name of the host we're on.
For determining which rules apply to the user you have to check two things:
1. Pull the user's entry and find any memberof in the SELinux user map container, it will look like:
2. Find all the SELinux rules with seeAlso set and see if that DN is in the user's memberof.
Do the same thing with the host, combine the two sets and you have your set of rules.
The next calculation is more complex as we decided that specificity wins (e.g. a rule with a specific user has more weight than a group or *). To determine the correct user context, iterate through the unordered set of candidate rules and comparing current state to the rule.
The initial context is the default SELinux user.
The first rule context gets applied to the user and we also track specificity of host and user (could be an enum: direct, group, wildcard).
In the next rule we look to see if host or user is more specific and if so we get that context, otherwise we punt.
If it is equally specific we take the highest context as defined in the context ordering.
Do this until the list is exhausted. The final state is the context to set.
These rules are in the form (host, user, mapping).
joe.user, is a member of the groups
We have a hostgroup,
webservers, which contains the hosts
(client.example.com, *, staff_u) (*, joe.user, guest_u)
If <code>joe.user logs in from client.example.com he will get
staff_u because hosts are evaluated first.
If joe.user logs in from any other host he gets
(webservers, joe.user, staff_u) (webservers, admins, unconfined_u)
joe.user logs in from web2.example.com he will get
This is because the rule containing his uid is more specific than the group rule.