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

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

 



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





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

  Powered by Linux