0

I have an autofs program-based map which I wrote, which auto-mounts CIFS shares, taking credentials from a file which is located within the ~/.smb folder of any given user. There can be multiple credential files, where each filename matches the domain name of the target CIFS server.

Autofs mounts are run by automounter(8), which is defined as a systemd service in my Centos 7 build. Automounter runs as root, the autofs map script is owned by root and is set to 0700 permissions, and there is a credential file living under /root/.smb with 0600 perms. By rights, I'd have thought that automounter should be able to read the credentials file.

That is, until SELinux gets in the way; whereupon it logs in audit.log (linebreaks added for readability):

type=AVC msg=audit(1508458225.901:143): avc:  
    denied  { read } for  
    pid=4786 
    comm="auto.smb-user" 
    name="mydomain.credentials" 
    dev="sda1" 
    ino=10180973 
    scontext=system_u:system_r:automount_t:s0
    tcontext=unconfined_u:object_r:admin_home_t:s0 
    tclass=file

The automount process runs fine with setenforce 0, of course, but I'd rather get used to SELinux than disable it all the time

I guess that audit record means that my script auto.smb-user cannot access mydomain.credentials because the file is tagged admin_home_t, and processes tagged automount_t can't access these?

Firstly, am I reading that right? If not, how better to interpret?

Secondly, how does one sanely add a minimal SELinux 'exception' such that this script could access any credentials files under ~/.smb, for any user including root (preferably only if run by automount); that survives reboot, yum update, etc.?

2

Yes - you are reading the output correctly.

The source context is automount_t and the target context is admin_home_t, and it is denied because automount_t does not have read permission on admin_home_t.

To verify this, you can use the following command:

sesearch -d -A -s autmount_t -t admin_home_t

And you will notice that it does returns an empty line - which means that automount_t has no permissions on admin_home_t.

Now you have two options:

  • Changing the file context of the file to automount_var_run_t, which is an easier and saner solution, one that makes SELinux think that the file is owned by automount, thus it will allow it mostly everything, including reading and writing (however, keep in mind that the effective outcome can still be overridden by normal file permissions or ACLs!)
  • Adding a policy package, which is a more sweeping, somewhat more insane solution, as it will give automount_t read access to admin_home_t,... but it will give only read access to it, as opposed to "owner" access.
  • (There's a third option as well, combining the two previous two and complicating them a bit more - making your own context type, applying it to those files, and then making a policy module that allows automount_t to access to that type. I won't go into detail on this one.)

Changing file context to automount_var_run_t

This is the easier option, and involves simply you changing the filecontext of the file /root/.smb to automount_var_run_t - thus any process running with the type automount_t will be able to access it. In this case, however, it will also have other permissions. Checking sesearch -d -A -s autmount_t -c file will tell you which:

allow automount_t automount_var_run_t : file { ioctl read write getattr lock add_name remove_name search open } ;

If you are fine with automount having those permissions on these files, you can go ahead and actually change the context of the file to automount_var_run_t, you do the following:

semanage fcontext -a -t automount_var_run_t "/root/.smb"
restorecon /root/.smb

This should enable automount to access the file for root. Now to add access for all other users (assuming they have the default home location,...) do the following:

semanage fcontext -a -t autmount_var_run_t "/home/(.*)+/.smb"
restorecon -R /home

This should enable autmount to work as you've described.

Giving automount_t permission to read admin_home_t

This will give automount_t permission to read all files with the context admin_home_t. Probably not really what you want - but for the sake of completeness

Get the relevant audit.log line(s) and put them in a file, for instance automount-audit.log. Then run the following:

audit2allow -i automount-audit.log -m automount > automount-audit.te

That will generate a type enforcement file from the audit log line, and it will look something like this:

module automount-smb 1.0;

require {
    type admin_home_t;
    type automount_t;
    class file read;
}

#============== autmount_t ==============
allow automount_t admin_home_t:file read;

If you also want it to allow access to user_home_t (for normal, non-root users) you can add the following line to the end:

allow automount_t user_home_t:file read;

Then you need to compile the module with:

checkmodule -M -m -o automount-smb.mod automount-smb.te

Make the policy package from the module:

semodule_package -o automount-smb.pp -m automount-smb.mod

And finally (whew!) insert the policy package into the kernel:

semodule -i automount-smb.pp

That should now allow processes with the label automount_t read access to all files with the admin_home_t or user_home_t context.

  • Thanks for this @Rabban. If I were to take the first approach, does/can the file end up with both automount_var_run_t and admin_home_t or do the protections of admin_home_t get removed from the file? I am concious of other applications accessing the credential file. – jimbobmcgee Oct 20 '17 at 11:17
  • Also, if I were to go the second approach, do kernel updates (e.g. via yum update) revert my added policies? Do I need to keep the .mod, .te and .pp files somewhere specific to avoid this? – jimbobmcgee Oct 20 '17 at 11:18
  • Any file can only have one single context applied to it - so yes, if you were to relabel it to automount_var_run_t, f admin_home_t would not apply to it any longer. As for the policy, they will survive both a reboot and a yum update - in fact, what semodule -i module-name.pp does, is install it under /etc/selinux/targeted/active/modules/400/module-name/, where 400 is the default priority of new modules. This also assumes you are using the targeted policy. – Rabban Oct 21 '17 at 7:56

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.