Re: PAM_IGNORE (was Re: Why should setcred be called after sessionopen?)

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

 



On Wed, 16 May 2001, Nicolas Williams wrote:

> 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.

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.

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.

> 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
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.

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?

> 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.

> > 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.

> > > 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...

>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.

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'.

> > 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.

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?

> > 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.

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.

Steve Langasek
postmodern programmer





[Index of Archives]     [Fedora Users]     [Kernel]     [Red Hat Install]     [Linux for the blind]     [Gimp]

  Powered by Linux