Linux – What SELinux context should the script have to be ran by pam_exec

pamselinux

I just installed Fedora 22 on my VPS and tried to make trivial thing — run my informer script on every ssh login via pam_exec.
But I was confronted with unexpected difficulties: pam_exec failed with exit code 13.

I added habitual line to the end of /etc/pam.d/sshd:

session optional pam_exec.so seteuid /usr/local/bin/loginformer.py

Of course loginformer.py has execution flags:

$ ls -l /usr/local/bin/loginformer.py
-rwxr-xr-x. 1 root root 4254 Jun  8 09:35 /usr/local/bin/loginformer.py

But here is painful extract from journalctl -lb SYSLOG_FACILITY=10:

Jun 08 11:58:49 fedora22 sshd[671]: pam_exec(sshd:session): execve(/usr/local/bin/loginformer.py,...) failed: Permission denied
Jun 08 11:58:49 fedora22 sshd[663]: pam_exec(sshd:session): /usr/local/bin/loginformer.py failed: exit code 13

I'm not sure what's happening, because it always work on my ArchLinux.
I think it may be some SELinux resctriction, but I'm not sure.

What I'm doing wrong?

UPDATE

Well, I tried to go deeply to SELinux and understood I should change SELinux context of my script.

Now SELinux context of it looks so:

$ ls -Z /usr/local/bin/loginformer.py
unconfined_u:object_r:user_home_t:s0 /usr/local/bin/loginformer.py

But which context should I set to the script?

UPDATE 2

Also, I think SELinux AVC logs may be very useful for detection of problem. I'm sorry I didn't give it earlier.
cat /var/log/audit/audit.log | grep loginformer.py return a lot of same strings:

type=AVC msg=audit(1433784991.570:265): avc:  denied  { execute } for  pid=7866 comm="sshd" name="loginfomer.py" dev="vda1" ino=11924 scontext=system_u:system_r:sshd_t:s0-s0:c0.c1023 tcontext=unconfined_u:object_r:user_home_t:s0 tclass=file permissive=0

Best Answer

The order in which pam_exec and pam_selinux are invoked is important. Man page for pam_selinux notes:

Adding pam_selinux into the PAM stack might disrupt behavior of other PAM modules which execute applications. To avoid that, pam_selinux.so open should be placed after such modules in the PAM stack, and pam_selinux.so close should be placed before them. When such a placement is not feasible, pam_selinux.so restore could be used to temporary restore original security contexts.

Similarly, Dan Walsh writes about the topic:

If you are going to add a pam_module that would exec commands that the user would not be allowed to execute, for example pam_mount, it should be added before the pam_selinux.so open command. If you are adding a pam_module that execs command a user could execute, then you probably want these after the pam_selinux.so open line.

Also note that your script currently has security context of user_home_t, which is not likely compatible with the default policy (file contexts are preserved when file is moved; if you created the file in your home directory moving the file will preserve the original context). You probably should use the default bin_t context. To restore the default context:

restorecon  /usr/local/bin/loginformer.py

If your script does not do anything too special, placing pam_exec before pam_selinux and restring the context should be enough to fix your issue.

Related Question