Date: Sat, 20 Jan 2001 02:04:03 -0500 (EST) From: djm@web.us.uu.net (David J. MacKenzie) To: n@nectar.com Cc: djm@web.us.uu.net, freebsd-security@freebsd.org Subject: Re: Fwd: [PAM broken design? pam_setcred] Message-ID: <20010120070403.43D3A12686@jenkins.web.us.uu.net>
next in thread | raw e-mail | index | archive | help
> Is it just me, or is pam_setcred broken? For example, with the > following config file: > > login auth sufficient pam_skey.so > login auth sufficient pam_krb5.so > login auth required pam_unix.so > > Regardless of whether you authenticate with `skey', `krb5', or `unix', > pam_sm_setcred is called in pam_skey.so, i.e. the module search starts > over. By my reading of the Solaris man page, pam_sm_setcred should be > called in the module that successfully authenticated the user. At any > rate this seems infinitely more useful. Note a few complications: 1. That several auth checks could be listed as "required". It would be more common to have several account management functions be required, but it's possible for any module type. 2. The auth info saved can be used by the account management function as well as by the setcred function. This is the case for the pam_krb5 module. I checked against the reference implementation of PAM, Sun's, by creating a pam_echo module that is like pam_permit but it also prints a line when it enters each of its functions. Then I duplicated it into a pam_echo2 module that's the same except for the name and the messages it prints. Then I duplicated it again into a pam_echodeny module that's the same except its auth function always fails instead of always succeeding. I duplicated it again to create pam_echodeny2, where both the auth and setcred functions fail. I ran a few tests on Solaris 8 and on FreeBSD 4.2-stable, using my PAM-patched su. I also ran them on Linux-Mandrake 7.0, using Linux-PAM 0.72 just in case it's changed since FreeBSD imported it. 1: Everything required for both modules: Solaris: djm@rampart 21 $ su pam_echo pam_sm_authenticate pam_echo2 pam_sm_authenticate pam_echo pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echo pam_sm_setcred pam_echo2 pam_sm_setcred bash-2.03# grep '^su' /etc/pam.conf su auth required /usr/lib/security/$ISA/pam_echo.so.1 su auth required /usr/lib/security/$ISA/pam_echo2.so.1 su account required /usr/lib/security/$ISA/pam_echo.so.1 su account required /usr/lib/security/$ISA/pam_echo2.so.1 su session required /usr/lib/security/$ISA/pam_echo.so.1 su session required /usr/lib/security/$ISA/pam_echo2.so.1 FreeBSD: djm@gaius 27 $ su pam_echo pam_sm_authenticate pam_echo2 pam_sm_authenticate pam_echo pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echo pam_sm_open_session pam_echo2 pam_sm_open_session pam_echo pam_sm_setcred pam_echo2 pam_sm_setcred ~ root@gaius 31 $ grep '^su' /etc/pam.conf su auth required pam_echo.so su auth required pam_echo2.so su account required pam_echo.so su account required pam_echo2.so su session required pam_echo.so su session required pam_echo2.so ~ root@gaius 32 $ Linux: djm@dagger 2 $ su pam_echo pam_sm_authenticate pam_echo2 pam_sm_authenticate pam_echo pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echo pam_sm_open_session pam_echo2 pam_sm_open_session pam_echo pam_sm_setcred pam_echo2 pam_sm_setcred ~ root@dagger 1 $ cat /etc/pam.d/su auth required /lib/security/pam_echo.so auth required /lib/security/pam_echo2.so account required /lib/security/pam_echo.so account required /lib/security/pam_echo2.so session required /lib/security/pam_echo.so session required /lib/security/pam_echo2.so 2: First module auth sufficient: Solaris: djm@rampart 22 $ su pam_echo pam_sm_authenticate pam_echo pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echo pam_sm_setcred pam_echo2 pam_sm_setcred bash-2.03# grep '^su' /etc/pam.conf su auth sufficient /usr/lib/security/$ISA/pam_echo.so.1 su auth required /usr/lib/security/$ISA/pam_echo2.so.1 su account required /usr/lib/security/$ISA/pam_echo.so.1 su account required /usr/lib/security/$ISA/pam_echo2.so.1 su session required /usr/lib/security/$ISA/pam_echo.so.1 su session required /usr/lib/security/$ISA/pam_echo2.so.1 FreeBSD: djm@gaius 28 $ su pam_echo pam_sm_authenticate pam_echo pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echo pam_sm_open_session pam_echo2 pam_sm_open_session pam_echo pam_sm_setcred ~ root@gaius 31 $ grep '^su' /etc/pam.conf su auth sufficient pam_echo.so su auth required pam_echo2.so su account required pam_echo.so su account required pam_echo2.so su session required pam_echo.so su session required pam_echo2.so Linux: djm@dagger 3 $ su pam_echo pam_sm_authenticate pam_echo pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echo pam_sm_open_session pam_echo2 pam_sm_open_session pam_echo pam_sm_setcred ~ root@dagger 1 $ cat /etc/pam.d/su auth sufficient /lib/security/pam_echo.so auth required /lib/security/pam_echo2.so account required /lib/security/pam_echo.so account required /lib/security/pam_echo2.so session required /lib/security/pam_echo.so session required /lib/security/pam_echo2.so 3. First auth is sufficient but fails, every setcred succeeds (this is your case): Solaris: djm@rampart 28 $ su pam_echodeny pam_sm_authenticate pam_echo2 pam_sm_authenticate pam_echodeny pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echodeny pam_sm_setcred pam_echo2 pam_sm_setcred bash-2.03# grep '^su' /etc/pam.conf su auth sufficient /usr/lib/security/$ISA/pam_echodeny.so.1 su auth required /usr/lib/security/$ISA/pam_echo2.so.1 su account required /usr/lib/security/$ISA/pam_echodeny.so.1 su account required /usr/lib/security/$ISA/pam_echo2.so.1 su session required /usr/lib/security/$ISA/pam_echodeny.so.1 su session required /usr/lib/security/$ISA/pam_echo2.so.1 FreeBSD: djm@gaius 55 $ su pam_echodeny pam_sm_authenticate pam_echo2 pam_sm_authenticate pam_echodeny pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echodeny pam_sm_open_session pam_echo2 pam_sm_open_session pam_echodeny pam_sm_setcred ~ root@gaius 31 $ grep '^su' /etc/pam.conf su auth sufficient pam_echodeny.so su auth required pam_echo2.so su account required pam_echodeny.so su account required pam_echo2.so su session required pam_echodeny.so su session required pam_echo2.so Linux: djm@dagger 4 $ su pam_echodeny pam_sm_authenticate pam_echo2 pam_sm_authenticate pam_echodeny pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echodeny pam_sm_open_session pam_echo2 pam_sm_open_session pam_echodeny pam_sm_setcred ~ root@dagger 1 $ cat /etc/pam.d/su auth sufficient /lib/security/pam_echodeny.so auth required /lib/security/pam_echo2.so account required /lib/security/pam_echodeny.so account required /lib/security/pam_echo2.so session required /lib/security/pam_echodeny.so session required /lib/security/pam_echo2.so 4. First auth is sufficient, first auth and first setcred fail (similar to your case): Solaris: pam_echodeny2 pam_sm_authenticate pam_echo2 pam_sm_authenticate pam_echodeny2 pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echodeny2 pam_sm_setcred pam_echo2 pam_sm_setcred bash-2.03# grep '^su' /etc/pam.conf su auth sufficient /usr/lib/security/$ISA/pam_echodeny2.so.1 su auth required /usr/lib/security/$ISA/pam_echo2.so.1 su account required /usr/lib/security/$ISA/pam_echodeny2.so.1 su account required /usr/lib/security/$ISA/pam_echo2.so.1 su session required /usr/lib/security/$ISA/pam_echodeny2.so.1 su session required /usr/lib/security/$ISA/pam_echo2.so.1 FreeBSD: pam_echodeny2 pam_sm_authenticate pam_echo2 pam_sm_authenticate pam_echodeny2 pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echodeny2 pam_sm_open_session pam_echo2 pam_sm_open_session pam_echodeny2 pam_sm_setcred pam_echo2 pam_sm_setcred ~ root@gaius 31 $ grep '^su' /etc/pam.conf su auth sufficient pam_echodeny2.so su auth required pam_echo2.so su account required pam_echodeny2.so su account required pam_echo2.so su session required pam_echodeny2.so su session required pam_echo2.so Linux: djm@dagger 5 $ su pam_echodeny2 pam_sm_authenticate pam_echo2 pam_sm_authenticate pam_echodeny2 pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echodeny2 pam_sm_open_session pam_echo2 pam_sm_open_session pam_echodeny2 pam_sm_setcred pam_echo2 pam_sm_setcred ~ root@dagger 1 $ cat /etc/pam.d/su auth sufficient /lib/security/pam_echodeny2.so auth required /lib/security/pam_echo2.so account required /lib/security/pam_echodeny2.so account required /lib/security/pam_echo2.so session required /lib/security/pam_echodeny2.so session required /lib/security/pam_echo2.so 5. Only one auth module specified, and everything succeeds: Solaris: djm@rampart 40 $ su pam_echo pam_sm_authenticate pam_echo pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echo pam_sm_setcred bash-2.03# grep '^su' /etc/pam.conf su auth required /usr/lib/security/$ISA/pam_echo.so.1 su account required /usr/lib/security/$ISA/pam_echo.so.1 su account required /usr/lib/security/$ISA/pam_echo2.so.1 su session required /usr/lib/security/$ISA/pam_echo.so.1 su session required /usr/lib/security/$ISA/pam_echo2.so.1 FreeBSD: djm@gaius 73 $ su pam_echo pam_sm_authenticate pam_echo pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echo pam_sm_open_session pam_echo2 pam_sm_open_session pam_echo pam_sm_setcred ~ root@gaius 31 $ grep '^su' /etc/pam.conf su auth required pam_echo.so su account required pam_echo.so su account required pam_echo2.so su session required pam_echo.so su session required pam_echo2.so Linux: djm@dagger 6 $ su pam_echo pam_sm_authenticate pam_echo pam_sm_acct_mgmt pam_echo2 pam_sm_acct_mgmt pam_echo pam_sm_open_session pam_echo2 pam_sm_open_session pam_echo pam_sm_setcred ~ root@dagger 1 $ cat /etc/pam.d/su auth required /lib/security/pam_echo.so account required /lib/security/pam_echo.so account required /lib/security/pam_echo2.so session required /lib/security/pam_echo.so session required /lib/security/pam_echo2.so Conclusions: It looks like su on Solaris doesn't call open/close session; apparently that's just for logins. I wonder how it deletes credentials (e.g., Kerberos ticket file) that it's created, when su exits. I'll have to explore that. My patches for the FreeBSD su do what the Linux su does, and also what the stock MIT krb5 su does in order to delete the ticket file, namely, fork and wait. It looks like su should be using setcred(PAM_DELETE_CRED) when it ends, and not using the session functions. I'll fix that. The main difference is in cases 2 and 3, where Solaris is calling setcred for all modules that have auth entries. It appears to be ignoring the "sufficient" tag for the setcred call. This is arguably a bug in Solaris PAM. The Solaris pam.conf man page does say: An authentication service module provides functionality to authenticate a user and set up user credentials. That indicates that the "auth" line should control the setcred call, and test 5 shows that it does. Linux-PAM (both versions) seems to be starting its loop at the top of the auth list for setcred calls and considering the first setcred to be "sufficient". Neither behavior is what you were hoping for, which would be for libpam to remember which module(s) succeeded in the authenticate call and only call setcred for those modules. I think the philosophy of the PAM config file is that the various entries are considered to be independent, and that the framework does not make assumptions about the needs of the modules. Thus the Linux-PAM behavior can be considered reasonable. This behavior should, however, be documented! I just read through the Linux-PAM HTML documentation and it doesn't specify subtleties such as this, either. To Unsubscribe: send mail to majordomo@FreeBSD.org with "unsubscribe freebsd-security" in the body of the message
Want to link to this message? Use this URL: <https://mail-archive.FreeBSD.org/cgi/mid.cgi?20010120070403.43D3A12686>