Bug 974700

Summary: pam_pwhistory does not work with SELinux
Product: Red Hat Enterprise Linux 6 Reporter: Chad Hanson <chanson>
Component: selinux-policyAssignee: Miroslav Grepl <mgrepl>
Status: CLOSED NOTABUG QA Contact: BaseOS QE Security Team <qe-baseos-security>
Severity: medium Docs Contact:
Priority: medium    
Version: 6.4CC: dwalsh, krai, lvrabec, mgrepl, mmalik, pkis, plautrba, pvrabec, ssekidde, tmraz
Target Milestone: rcKeywords: FutureFeature, SELinux
Target Release: ---   
Hardware: Unspecified   
OS: Unspecified   
Whiteboard:
Fixed In Version: selinux-policy-3.7.19-246.el6 Doc Type: Enhancement
Doc Text:
Story Points: ---
Clone Of:
: 975074 (view as bug list) Environment:
Last Closed: 2015-11-13 07:21:42 UTC Type: Bug
Regression: --- Mount Type: ---
Documentation: --- CRM:
Verified Versions: Category: ---
oVirt Team: --- RHEL 7.3 requirements from Atomic Host:
Cloudforms Team: --- Target Upstream Version:
Embargoed:
Bug Depends On:    
Bug Blocks: 1172231    

Description Chad Hanson 2013-06-14 21:16:34 UTC
Description of problem:
The pam_pwhistory module does not work with SELinux because it is does not utilize the SELinux unix_* helpers.

Version-Release number of selected component (if applicable):
pam-1.1.1-13

How reproducible:
Always

Steps to Reproduce:
1. Enable pam_pwhistory in with SELinux
2. Create a test user and expire the password with chage
3. Attempt to login as user with expired password

Actual results:
User password is changed, but I believe PAM_USER_UNKOWN is being returned to the PAM stack because of the failure to get data from the shadow file. User thinks password change has failed when it has succeeded.

Expected results:
User should change password and then be logged into the login session.

Additional info:
This would seem to be important if the remember functionality of pam_unix is being phased out in favor of pam_pwhistory module.

Comment 1 Tomas Mraz 2013-06-17 14:50:38 UTC
This is by no means simple change. The module would need to have a new helper that would transfer the password hash from /etc/shadow to the /etc/security/opasswd. And the /etc/security/opasswd would have to be handled with the same restrictions as the /etc/shadow, otherwise the helper could be used to leak the hash from the shadow to a file with less stringent access restrictions.

I suppose that for RHEL-6 it would be probably much easier to have a boolean (off by default) that would allow direct access to the /etc/shadow for applications that call PAM password modules.

Comment 2 Daniel Walsh 2013-06-18 15:46:14 UTC
Yuck, that would allow a whole bunch of apps to read the shadow file.

 matchpathcon /etc/security/opasswd 
/etc/security/opasswd	system_u:object_r:shadow_t:s0

We currently treat the /etc/security/opasswd like we treat /etc/shadow.

Comment 3 Chad Hanson 2013-06-18 18:53:00 UTC
pam_unix already correctly saves the this data /etc/security/opasswd already. So I think we have already have SELinux policy for that. There is some SELinux code involved for the handling of opasswd work happily in passverify.c that needs to go into opasswd.c in pam_pwhistory I would think. The unix_helper I believe is needed more for the call to pam_modutil_getspnam() so this doesn't fail and return PAM_USER_UNKNOWN. I have only done some cursory review for this, so I maybe missing something.

Comment 4 Tomas Mraz 2013-06-19 06:41:21 UTC
(In reply to Daniel Walsh from comment #2)
> Yuck, that would allow a whole bunch of apps to read the shadow file.
> 
>  matchpathcon /etc/security/opasswd 
> /etc/security/opasswd	system_u:object_r:shadow_t:s0
> 
> We currently treat the /etc/security/opasswd like we treat /etc/shadow.
Good, but that is not on RHEL-6, but on more current systems like Fedora.

Actually I think that this means that on current Fedora neither the pam_unix remember functionality will work due to the /etc/security/opasswd being shadow_t.

The helper is needed for all access to shadow_t files and we don't have it for the opasswd accesses.

For RHEL-6 I don't really see any other way than to add boolean for shadow_t access - at least for passwd_t. It would still mean that expired password change on login would not be handled but maybe it would suffice. Or we can declare pam_pwhistory unsupported with SELinux on RHEL-6.

For RHEL-7 completely new helper is needed.

Comment 5 Chad Hanson 2013-06-19 14:09:54 UTC
(In reply to Daniel Walsh from comment #2)
> Yuck, that would allow a whole bunch of apps to read the shadow file.
> 
>  matchpathcon /etc/security/opasswd 
> /etc/security/opasswd	system_u:object_r:shadow_t:s0
> 
> We currently treat the /etc/security/opasswd like we treat /etc/shadow.

Everything works for "remember" in pam_unix in RHEL 5 and RHEL 6 because opasswd is actually defined as etc_t.

[root@chad-rh64 ~]# rpm -qa  | grep selinux-policy
selinux-policy-3.7.19-195.el6_4.6.noarch
selinux-policy-targeted-3.7.19-195.el6_4.6.noarch
[root@chad-rh64 ~]# matchpathcon /etc/security/opasswd
/etc/security/opasswd	system_u:object_r:etc_t:s0

I would agree we need a new helper given this fact for RHEL 7 and if the policy is corrected per comment 2. Also, the passverify.c code does a getfilecon() of /etc/passwd to determine the setfscreatecon for the opasswd tmp file which is later renamed to /etc/security/opasswd. This would also be inconsistent with shadow_t which so we really should grab the context from /etc/shadow. That would need to be done in the new helper since we don't have shadow_t policy.

Comment 7 RHEL Program Management 2013-10-14 03:20:57 UTC
This request was not resolved in time for the current release.
Red Hat invites you to ask your support representative to
propose this request, if still desired, for consideration in
the next release of Red Hat Enterprise Linux.

Comment 20 Simon Sekidde 2015-03-07 19:37:35 UTC
selinux-policy-3.7.19-260.el6_6.2.noarch
authlogin_shadow               (off  ,  off)  Allow users login programs to access /etc/shadow.
Found 16 semantic av rules:
   allow sshd_t shadow_t : file { ioctl read getattr lock open } ; 
   allow remote_login_t shadow_t : file { ioctl read getattr lock open } ; 
   allow sshd_t etc_t : dir { ioctl read getattr lock search open } ; 
   allow remote_login_t etc_t : dir { ioctl read getattr lock search open } ; 
   allow xdm_t shadow_t : file { ioctl read write create getattr setattr lock append unlink link rename open } ; 
   allow rshd_t shadow_t : file { ioctl read getattr lock open } ; 
   allow xdm_t etc_t : file { ioctl read write create getattr setattr lock append unlink link rename open } ; 
   allow xdm_t etc_t : dir { ioctl read write getattr lock add_name remove_name search open } ; 
   allow rshd_t etc_t : dir { ioctl read getattr lock search open } ; 
   allow xdm_t etc_t : lnk_file { read getattr } ; 
   allow rlogind_t shadow_t : file { ioctl read getattr lock open } ; 
   allow rlogind_t etc_t : dir { ioctl read getattr lock search open } ; 
   allow local_login_t shadow_t : file { ioctl read write create getattr setattr lock append unlink link rename open } ; 
   allow local_login_t etc_t : file { ioctl read write create getattr setattr lock append unlink link rename open } ; 
   allow local_login_t etc_t : dir { ioctl read write getattr lock add_name remove_name search open } ; 
   allow local_login_t etc_t : lnk_file { read getattr } ;

Comment 23 Miroslav Grepl 2015-11-03 14:20:02 UTC
That's correct. It should work with this boolean.