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

sufficient account management checking for locally defined users



I'd like to ask a question about system administration policy and PAM.
First, I'll phrase the question as briefly as I can.  Then, for the
curious, I'll provide more detail, including a description of
available solutions and the problems I see with those solutions.  I'll
suggest some alternative solutions and summarise by concluding why I
think a certain PAM development has taken things in the wrong
direction...

I have 2 sets of users:

* Locally defined users in /etc/{passwd,shadow}.

* Remotely defined users in an LDAP directory.

For the locally defined users, I want to use standard flat files.
This means that the only PAM module available to me is pam_unix (I'm
running Debian GNU/Linux, so pam_pwdb is no longer available).  For the
remotely defined users I want to use pam_ldap.

Therefore, I want to do this:

  account    sufficient   pam_unix.so
  account    required     pam_ldap.so

The reason I want to do this is that I don't want pam_ldap to be used
at all when my locally defined users are logging in.  I see this as a
sensible policy that promotes reliabily.  For example, I will always
be able to login as root, without delay, even if my network is down,
pam_ldap is broken or, worse still, if there's a bug in libdap* that
causes a SIGSEGV.  I don't want to run code that is irrelevant to my
locally defined users, particularly root.

If you don't believe that this is a sensible policy, then please stop
reading, hit your reply button and explain what is wrong with this
policy.  Note that, at this stage, I'm not interested in hearing that
you have a different policy that can be successfully implemented or
that "sufficient account modules don't seem like a useful or well
defined idea".  I want to know why my policy is unreasonable!

If you believe that my policy is reasonable, then you probably think
that PAM ought to support my policy.  Thank you!  :-)

The above configuration doesn't work.  Since I'm using libnss-ldap,
pam_unix sees the LDAP users (via getpwnam()), and happily does the
account management checking and returns PAM_SUCCESS.  Any account
management checking expected of pam_ldap (such as host access
checking) doesn't happen.  This is not unreasonable behaviour.  I
can't find this behaviour documented anywhere, but it is not
unreasonable.  The users that pam_unix knows about are defined by NSS
(the Name Service Switch), so pam_unix has the right to assume that it
can act on behalf of those users.

There are (at least) 2 workarounds for this problem...

The first workaround is to say:

  account    requisite    pam_unix.so
  account    sufficient   pam_local.so
  account    required     pam_ldap.so

pam_local is a custom PAM module that returns PAM_SUCCESS if the user
is present in /etc/passwd, or a failure (such as PAM_USER_UNKNOWN)
otherwise.  A problem with this is that 2 complete traversals of
/etc/passwd will be required for LDAP users.  This works and satisfies
the policy I have outlined above.  However, it introduces an
unnecessary inefficiency.

[Someone has contributed a pam_localuser module via the SourceForge
 bug tracking system.  If this code is accepted, can someone please
 change it to use fgetpwent() to read and parse /etc/passwd instead of
 the current fgets() and custom "parsing" code?  I think this change
 would make the code much clearer.  I'd obviously be willing to
 contribute my version...]

Another workaround is to simply say:

  account    required     pam_unix.so
  account    required     pam_ldap.so

This means that for my LDAP users, the account management checking
will take place.  However, for locally defined users, pam_ldap will be
invoked and will fail.  Therefore, a further workaround is to say
something like:

  account    required     pam_unix.so
  account    [default=die success=ok authinfo_unavail=ignore user_unknown=ignore] pam_ldap.so

This means that pam_ldap can happily return PAM_USER_UNKNOWN, and PAM
can then ignore this return value.  This works, but doesn't satisfy
the policy I've outlined above.

There are (at least) 2 solutions that satisfy my chosen policy:

* Add a "local_only" option to pam_unix; by default pam_unix would
  maintain its current behaviour.  If the "local_only" option is
  passed in the configuration file, pam_unix would use functions that
  look in the local /etc/{passwd,shadow} files, instead of the NSS
  equivalents, to perform lookups at various decision points.  This is
  essentially an optimised combination of pam_unix and pam_local.

  This would allow me to make pam_unix "sufficient".

* Implement a PAM module that works only with local files.  This would
  be based on pam_unix.  Ideally, it would be compiled from the
  pam_unix source by setting a preprocessor macro, so the "new" module
  would have all of the useful features and could share a minimal set
  of bugs.  :-)

  One option is to resurrect pam_pwdb and configure it to only look at
  local files.

  This would allow me to have a "sufficient" module to do my account
  management checking for locally defined accounts.

Some people I've spoken to about this are reluctant to consider either
of these 2 options.  I suspect the main reason is that the
[value=action, ...]  PAM configuration capability makes it easy to
take a short path through modules that are irrelevant to whole classes
of users (in this case, a short path through pam_ldap, which is
irrelevant to my locally defined users).  I think that promoting this
type of configuration is a bad idea.

Thanks for any comments...

peace & happiness,
martin





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