On Wed, May 16, 2001 at 06:18:29PM -0500, Steve Langasek wrote: > Nico, > > On Wed, 16 May 2001, Nicolas Williams wrote: > > > I disagree. It's always appropriate to return PAM_IGNORE because it > > cannot contribute to success of the stack. > > It also will not contribute to the failure of the stack, which is where the > problem lies. Sure it does! PAM stacks fail by default. Here's another way to put it: - PAM_IGNORE is a device to help cope with lack of expressibility in pam.conf and the PAM SPI - some modules present auth, account and other facilities which can be used separately (e.g., pam_unix). - some modules' various facilities cannot be used separately (e.g., PAM_KRB5) - there is no way to tie execution of modules in the account stack to events in the auth stack (and so on) - so, sometimes you need to be able to neither contribute nor hinder authentication, authorization, and so on -- thus PAM_IGNORE > > 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. > > So in this context, what do the lines > > rlogin account required pam_krb5 > rlogin account required pam_unix > > mean? I believe this should mean that both pam_krb5 and pam_unix must > *approve* the applicant for access. If pam_krb5 is going to punt whenever it > doesn't know what to do, then I have no way to achieve the semantics I'm > looking for.[1] Conversely, there are ways to structure the PAM config to > give you the results you desire without making use of a PAM_IGNORE return code > from pam_krb5. If the authors of PAM_KRB5 document that PAM_KRB5:account will return PAM_IGNORE if there is no pam data from PAM_KRB5:auth or PAM_KRB5:setcred which can be used to perform the authorization check, then it's ok to return PAM_IGNORE in such circumstances. Here's what the example you give means: - if Kerberos password validation was performed, then also perform Kerberos principal->username authorization - if no Kerberos password validation was done (e.g., a sufficient auth module short-circuited the auth stack before pam_krb5), then no Kerberos authorization check can be performed either BUT, - because the admin specified that some other module was sufficient for auth, that means - and because we can't kerberos-authorize a principal name we don't know - kerberos authorization MUST be skipped BUT, PAM gives us no way to do this *other than* by returning PAM_IGNORE. So it's ok for PAM_KRB5:account to return PAM_IGNORE in this case. Consider this stack: rlogin auth sufficient pam_rhosts rlogin auth required pam_unix rlogin account required pam_unix rlogin account required pam_nologin And now: rlogin auth sufficient pam_rhosts rlogin auth required pam_krb5 rlogin auth required pam_unix rlogin account required pam_krb5 rlogin account required pam_unix rlogin account required pam_nologin We've added Kerberos, but we say pam_rhosts is sufficient, so what happens when pam_rhosts succeeds? The answer: the user should get in, unless pam_unix or pam_nologin say otherwiise. Kerberos is out of the picture. But if pam_rhosts auth fails, then it's another story. If it were not ok for PAM_KRB5:account to return PAM_IGNORE when it can't do anything, then the above would NEVER work with rhosts authentication (that may be a good thing, if you think rhosts is a bad thing, but that's another story!). > There's no security hole in your example config, because you're assigning a > different meaning to 'required' than I am. If I have a config of I'm making a legal use of PAM_IGNORE to modify required, yes, but only because you cannot use pam_krb5 to do account checks if you don't use pam_krb5 to authenticate the user or get his/her credentials. > auth required pam_krb5 > account required pam_krb5 > account required pam_unix > I have an expectation that the users who are granted access to this service > have valid, non-expired Kerberos accounts *and* valid, non-expired Unix > accounts. If the application calls pam_acct_mgmt() on a different handle than > was used when calling pam_authenticate(), and this triggers pam_krb5 to return > PAM_IGNORE, the user will be granted access. Now, think about what this means > if the user's password expired, and pam_sm_authenticate() stored a token that > should have been passed to pam_sm_acct_mgmt(). If pam_sm_acct_mgmt() says > 'no news is good news' and returns PAM_IGNORE, a user with an expired > principal will get access to the service -- something I've explicitly tried to > prevent in my configuration! Not only that, but because we don't have a TGT > for the user (can't get one, the user's password is expired), we don't have > cryptographic proof of the user's identity (the KDC's response could've been > spoofed), but we'd be granting him access to the service anyway! No, no, here pam_krb5:auth is not skipped, therefore pam_krb5:account will NOT return PAM_IGNORE. > And because this all traces back to brokenness on the part of the application, > I as an admin may never know about the problem until it's too late. No, no, no. Please, step back. PAM_KRB5:account would only return PAM_IGNORE if PAM_KRB5:auth was not called. That can only happen if: a) the sysadmin did not put pam_krb5 in the auth stack (stupid) or b) something higher and suficient in the auth stack caused pam_krb5:auth to be skipped. In the (b) case pam_krb5:account should not and cannot get in the way of the other modules in the account stack. > > But it's not an error to have no inputs! > > Yes, it /is/. :) Asking pam_krb5 to authorize a user when she has not first > been authenticated against the Kerberos realm is meaningless, and represents > an error in either the PAM config or the application. If the error should not > be considered fatal, let the admin spell that out in the config. Don't > override the PAM config by denying that there's an error. But it's meaningful to make pam_rhosts sufficient ahead of pam_krb5! [...] [this is on a different note] > Unless we're talking again about the 'login -f' case, and the problem is > that you have a single PAM config being used both with and without > pam_authenticate(). Honestly, I don't think this can be made to work reliably > without seriously botching things for other applications. login needs to have > two different configurations, with two different service names, because the > configuration requirements when pam_authenticate() is used are different than > those when it is not used. I was talking about -f. > Cheers, > Steve Langasek > postmodern programmer > > > [1] Ok, with Linux-PAM, this isn't exactly true. Using Linux-PAM's extended > config syntax, I can map the 'ignore' return code to a failure, but this is > prohibitively complex. I want a solution that works for more than the dozen > Linux admins on the planet who know about this extended config file syntax. :) If NO module in a stack returns PAM_SUCCESS, the stack fails. Cheers, Nico --