all messages for Guix-related lists mirrored at yhetil.org
 help / color / mirror / code / Atom feed
From: Ricardo Wurmus <rekado@elephly.net>
To: guix-devel@gnu.org
Subject: LDAP authentication + Configuring PAM
Date: Thu, 22 Aug 2019 16:03:24 +0200	[thread overview]
Message-ID: <87wof5jo0j.fsf@elephly.net> (raw)

Hi Guix,

in the past few days I’ve been playing on and off with configuring a
Guix System where accounts are authenticated against Active Directory
via LDAP.

My findings so far:

* NSCD *must* be extended with caches for “passwd” and “group”
  databases or else applications will make the lookup for user accounts
  directly and will not consult LDAP at all.

* the default PAM rules provided by nslcd-service-type are either
  incomplete or incorrect, because of the many “unix-pam-service”
  defaults.

* as a result awkward PAM configuration is required to make this work.

* it’s a pity that “name-service-switch” is not a system service and has
  to be extended manually.  … Or is this perhaps how we should treat PAM
  configuration as well?

PAM is the mechanism to use if we want to allow applications to
authenticate users that don’t have local accounts.  For local accounts
the “pam_unix.so” authentication module is used, and we say that it is
required for authentication with “unix-pam-service”.

“required” is an important word here, because that’s one of the keywords
for the PAM module stack.  Some terminology:

* there are four resources: “auth” (for authentication of valid
  accounts), “session” (for setting up a user’s session once
  authenticated), “password” (for changing the user’s password), and
  “account” (to determine if a user account is valid).

* there is a file in /etc/pam.d for each application that should use
  PAM, such as “/etc/pam.d/su” for “su”, “/etc/pam.d/sshd” for the SSH
  daemon, etc.

* each of these files specifies a stack of PAM modules that should be
  consulted for each of the four resources.

* each stack is evaluated from top to bottom.

* each module can be “required”, “sufficient”, “optional”, or a
  “requisite”.

The last point is confusing.  Let’s only look at “required” and
“sufficient”.

Here’s a stack for authenticating a user:

  auth required pam_foo.so
  auth sufficient pam_bar.so
  auth sufficient pam_baz.so
  auth required pam_deny.so

Stacks are evaluated top to bottom.  First pam_foo.so is evaluated.  It
is “required” meaning that it must succeed for authentication to be
successful.  If it returns failure the *next module will be evaluated*,
but no matter what happens authentication will *always fail*.  This is
important.

A module that is “sufficient” will be evaluated.  If it fails the next
module will be tried.  If it succeeds, however, no other module in the
stack will be considered.  Authentication will have succeeded.

So in the above stack we need “pam_foo.so” and one of “pam_bar.so” or
“pam_baz.so” to succeed.  If “pam_bar.so” succeeds “pam_baz.so” will not
be considered, nor will “pam_deny.so” be considered.  If both
“pam_bar.so” and “pam_baz.so” fail “pam_deny.so” is evaluated which will
always return failure — so authentication will fail.

As you can see, the order of modules in the stack is of significant
importance.  Even worse, modules can take arguments such as
“try_first_pass” to use the same password that was provided in an
earlier step.  Mixing up the order of modules here could lead to
unexpected, frustrating behaviour.  Debugging this isn’t easy, because
PAM isn’t very chatty even when “debug” is added as an argument to all
modules.

But back to the problem of authenticating users via LDAP.  With our
default unix-pam-service “pam_unix.so” (which checks that a user account
exists locally and checks its password) is required, so LDAP
authentication will always fail.

I extended the pam-root-service-type with a service that matches on all
pam_unix.so modules and makes them use the “sufficient” keyword instead
to overcome this.  This is problematic when nslcd-service-type is
involved because it extends pam-root-service-type to add entries for
pam_ldap.so.  Instead of using a string “pam_ldap.so” it uses a
G-expression to compute the absolute file name of “pam_ldap.so”.  When
extending the service and matching on PAM entries, however, we don’t
have a string of the absolute file name to match on — we have a
G-expression that is really awkward to match against.

I worked around this (by lowering the G-expression first), but it’s
ugly.  And even then I still have the problem that I can’t control the
order of PAM entries at all.

Perhaps we should implement a different mechanism for specifying PAM
entries for the system, perhaps similar to what the name-service-switch
field does?

I also recommend using “sufficient” as the default keyword for
“pam_unix.so” and ending the stack with “required pam_deny.so”.  This
would make it easier to extend the stack without having to rewrite
existing module entries.

What do you think?

--
Ricardo

             reply	other threads:[~2019-08-22 14:03 UTC|newest]

Thread overview: 4+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2019-08-22 14:03 Ricardo Wurmus [this message]
2019-08-23 12:14 ` LDAP authentication + Configuring PAM Ludovic Courtès
2019-08-23 20:08   ` Ricardo Wurmus
2019-09-03 12:14     ` Ludovic Courtès

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=87wof5jo0j.fsf@elephly.net \
    --to=rekado@elephly.net \
    --cc=guix-devel@gnu.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
Code repositories for project(s) associated with this external index

	https://git.savannah.gnu.org/cgit/guix.git

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.