[Cc'ing pam-list@redhat.com] On Wed, May 16, 2001 at 03:06:14PM -0500, Stephen Langasek wrote: > On Tue, 15 May 2001, Nicolas Williams wrote: > > > pam_sm_acct_mgmt() (and pam_sm_setcred(), for that matter) MUST return > > PAM_IGNORE if pam_sm_authenticate() returned PAM_IGNORE, and what to > > return if pam_sm_authenticate() was not called is a bit more > > complicated. > > Ok, I can see your point here. pam_sm_acct_mgmt() should not contribute a > success code to the return value of the function if we don't have any data > from pam_sm_authenticate(), but this is not necessarily the same thing as > returning a failure (i.e., we have PAM_IGNORE to work with). When a module returns PAM_IGNORE< it's ignored, EVEN IF it was a required module -- i.e., it's treated as if it hadn't even been on the stack. Certainly this is how Solaris PAM works. I know, not only empirically, but also because I have access to Solaris source code. > However, consider this configuration: > > auth sufficient pam_krb5.so > account requisite pam_krb5.so > account requisite pam_unix.so > > This config specifies that pam_krb5 is used for all authentication, and that > the user must pass /both/ Kerberos /and/ Unix (shadow) authorization checks > in order to gain access. Is this a valid config? If so, what happens when > pam_sm_acct_mgmt() returns PAM_IGNORE because it doesn't /know/ if the user > is authorized? It's ignored, as if it had not even been mentioned in the config. Consider this: rlogin auth sufficient pam_rhosts rlogin auth whatever pam_krb5 rlogin auth whatever pam_unix rlogin account required pam_krb5 rlogin account required pam_unix If pam_rhosts succeeds, then pam_krb5:auth will never be tried, but pam_krb5:account MUST be tried just in case pam_krb5:auth was tried. So pam_krb5:account is tried, but it can't actually *DO* anything, so it MUST return PAM_IGNORE. Trust me, Solaris PAM does the right thing, and I believe Linux-PAM must as well. The right thing is to treat modules returning PAM_IGNORE as if they weren't even on the stack (except that setcred() will be called even if auth() returned PAM_IGNORE -- similarly with open/close). > Keep in mind that an app calling pam_authenticate() on a different handle > than pam_acct_mgmt() is effectively broken, at least with respect to our > module's requirements. I think it's appropriate to expose this brokenness, > rather than silently ignoring it with PAM_IGNORE; this is more likely to > result in the application being fixed, making everyone happier. Nope. See above. Account MUST return PAM_IGNORE if it lacks inputs (e.g., pam data whence a principal name can be obtained that can be fed to krb5_kuserok() and krb5_aname_to_lname()). I know this because I got bitten already by this. Amond the many fixes we'll check in this week is a fix to have setcred() and acct_mgmt() return PAM_IGNORE if there's nothing for them to do. It's needed, else things break. I discovered this when a user who is used to using .rhosts auth could no longer use rlogin when I PAM_KRB5'ed his servers. Ooops. > > I was just bitten by a situation where I'd added pam_krb5 to the rlogin > > service, but pam_rhosts was stacked above it as sufficient, so here > > there was a situation where pam_krb5:pam_sm_authenticate() might not be > > called (if rhosts auth succeeded) and so if pam_sm_setcred() returned > > anything other than PAM_IGNORE or PAM_SUCCESS then rlogin/login would > > fail. > > Yes, this is similar to the problem I have when using pam_krb5 with OpenSSH: > when I use RSA authentication, openssh calls pam_setcred() without ever > calling pam_authenticate(), and of course pam_krb5 returns a failure code. > But whereas it may be more polite for us to return PAM_IGNORE, there is an > actual bug in openssh that needs to be fixed. Nope. It's legal to call pam_setcred() without calling pam_authenticate(), if not as documented, then de facto. Think about /bin/login -f... > Under Solaris w/ rlogin, is pam_krb5's pam_sm_setcred() being called even > though its pam_sm_authenticate() function was never called? Some of your Yes. Andrew Morgan says this would not be the case with Linux-PAM, ALTHOUGH, if PAM_KRB5:pam_sm_authenticate() is called and returns PAM)IGNORE, then PAM_KRB5:pam_sm_setcred() WOULD be called in the Linux-PAM case. > comments on the pam-list suggest that Solaris does this. If so, then it > seems we do need to gracefully handle the case where pam_sm_setcred() is > called before (or without) pam_sm_authenticate(). Yup. > > The problem is: how can PAM_KRB5 detect if pam_sm_authenticate() was not > > called because: > > > a) the app didn't call it (e.g. login -f) > > Hmm... I think the app is allowed to ignore the return value of > pam_authenticate(), but I'm not sure the spec allows the app to not call it. > In this config, pam_krb5 is aware it's configured in 'acceptor' mode, > correct? So it has enough information about the environment to always do > the right thing, whether or not pam_authenticate() was called. How is /bin/login supposed to communicate the -f argument to PAM? So the user is authenticated, but there is still value in doing setcred() and acct_mgmt() and firends... > > or > > > b) a sufficient module, higher up the stack *and* sufficient returned > > PAM_SUCCESS > > In which case, does it matter that pam_krb5 doesn't return success? If > pam_authenticate() didn't need a go-ahead from pam_krb5 in order to succeed, > why should it care about it when calling pam_setcred()? Because Solaris PAM calls ALL auth module's setcred() method, regardless of the return values of the sm_authenticate() calls, or even if some modules' pam_sm_authenticate() did not get called. > > And what can pam_krb5:pam_sm_acct_mgmt() do if > > pam_krb5:pam_sm_authenticate() is not called?! > > > > One answer: nothing, return PAM_IGNORE. In fact, that is the only valid > > answer, because pam_krb5:pam_sm_acct_mgmt() at the very least needs a > > principal name to authorize, and if pam_krb5:pam_sm_authenticate() > > doesn't run then there would be no way for pam_krb5:pam_sm_acct_mgmt() > > to discover the principal name to authorize. > > See above for possible reasons why PAM_IGNORE is not appropriate in this > situation. I consider the above scenario, in which the app cares about > pam_krb5's retval from pam_sm_acct_mgmt() but did not call > pam_authenticate() correctly, to be a bug in either the application or the > PAM configuration. It's always appropriate to return PAM_IGNORE if there's nothing the method can do to satisfy its purpose. This is because PAM_IGNORE cannot contribute to the success of the stack. > Steve Langasek > postmodern programmer Cheers, Nico --