On Wed, May 16, 2001 at 04:10:23PM -0500, Steve Langasek wrote: > On Wed, 16 May 2001, Nicolas Williams wrote: > > > It's ignored, as if it had not even been mentioned in the config. > > Exactly, and this is /wrong/. PAM_IGNORE means "I have nothing useful to > contribute". Returning an error when we don't know who the principal is is > not only useful, it's imperative in the case of configs such as the above. If > we want admins to be able to turn this behavior off with a module option, > that's fine, but returning PAM_IGNORE here is not sane default behavior. I disagree. It's always appropriate to return PAM_IGNORE because it cannot contribute to success of the stack. > If I list two authorization modules as 'requisite' or 'required' in my PAM > config, then by God, I don't want that user to be allowed access to the > service unless both of those modules are *sure* that he should be. Well, this is PAM. It's how it works. Perhaps Andrew Morgan can settle this. > > 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. > > Only if you accept that the above config is reasonable. This is /not/ a > reasonable config; you've just said that the applicant must pass It's perfectly reasonable. I said that pam_rhosts is SUFFICIENT for authentication. That means that if pam_rhosts:auth succeeds then the other auth modules are NOT even tried. > authorization checks with both pam_krb5 and pam_unix, but you're allowing them > to authenticate using only pam_rhosts -- so they're not authenticated to the > Kerberos realm, and they /can't/ pass the authorization checks. This is an > inconsistent PAM config, and the config needs to be fixed, not the modules. Which is why PAM_KRB5:account MUST return PAM_IGNORE in such cases. > rlogin auth sufficient pam_rhosts > rlogin auth whatever pam_krb5 > rlogin auth whatever pam_unix > rlogin account optional pam_krb5 > rlogin account optional pam_unix > > Isn't this what you're really trying to say? Isn't it more straightforward to > simply say this in the config file, rather than opening security holes in the > module that will let crippled apps get by with behavior that shouldn't be > allowed? Nope. There's no security hole there. Case 1: a) pam_rhosts:auth succeeds, short-circuiting the remainder of the auth stack b) pam_krb5:account returns PAM_IGNORE and is ignored c) pam_unix:account is a pretty simple module and it works as expected, even though pam_unix:auth was not tried The other cases also have no bug, but I'd have to pick a value for "whatever" above to run through all the possibilities. > > 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). > > Yes, the PAM libraries handle a PAM_IGNORE retval correctly. What's at issue > is whether it's appropriate for a module to return PAM_IGNORE when we have > reason to believe there's an error which should not be ignored. But it's not an error to have no inputs! > > > 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. > > Ok, then pam_krb5 will need to handle this Solaris case. Yes. But there's no reason to treat this differently on Linux-PAM either. > > 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... > > >From your descriptions of kerberized login in the past, I understood that this > is communicated to PAM by means of the service name -- login will invoke PAM > with a different service name for an already-authenticated user than for one > that still needs to be authenticated. No that was just Sun's SEAM login.krb5/PAM_KRB5 stuff. Plain old /bin/login has always (well, for a very, very long time anyways) had a -f argument, and the only way to implement that with PAM is to either skip pam_authenticate() OR use a service name whose auth stack is known to contain ONLY pam_permit (or the equivalent). > In which case there's no harm to the application in calling pam_authenticate() > before pam_setcred() and ignoring the result, and there's no harm to the > modules if it's not called; either way, the only things you can do in > pam_setcred() in this scenario are those which /don't/ require > pam_authenticate() to be called successfully, which in fact rules out most > credential-setting activities except for those like 'pam_krb5.so acceptor'. There may be harm because the auth modules may desire to prompt the user/ converse with the app, but there's no valid semantics at that point in handling such prompts when the user is already authenticated. And the acceptor thing in Sun's SEAM is a perfect example of why there can be value to calling setcred() when authenticate() is skipped. > > 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. > > Ok, so it calls pam_krb5's pam_sm_setcred() function, and this function > returns an error. So what? If that error was insubstantial in > pam_authenticate(), why does it matter now in pam_setcred(), given that > the flow of both function calls is governed by the same PAM config lines? Because /bin/login will fail if pam_setcred() fails and I can't have pam_krb5:setcred() treated differently from pam_krb5:authenticate() as far as required/requisite/... is concerned. > > 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. > > The authorization module's purpose is to guarantee that the applicant is > authorized. Returning PAM_IGNORE when we know the applicant is /not/ > authorized is inconsistent with this goal. Why? Returning PAM_IGNORE *cannot* contribute to success of the stack. It cannot contribute to allowing the user to login. If not one module in a stack returns PAM_SUCCESS then the stack will not return PAM_SUCCESS either. > Steve Langasek > postmodern programmer Cheers, Nico --