Bug 688 - PAM modules relying on module-private data (pam_dhkeys, pam_krb5, AFS) fail
Summary: PAM modules relying on module-private data (pam_dhkeys, pam_krb5, AFS) fail
Status: ASSIGNED
Alias: None
Product: Portable OpenSSH
Classification: Unclassified
Component: PAM support (show other bugs)
Version: -current
Hardware: UltraSparc Solaris
: P2 major
Assignee: OpenSSH Bugzilla mailing list
URL:
Keywords:
: 717 768 (view as bug list)
Depends on:
Blocks: 874
  Show dependency treegraph
 
Reported: 2003-09-19 20:19 EST by Paul Bolton
Modified: 2015-10-05 22:24 EST (History)
8 users (show)

See Also:


Attachments
pam_dhkeys debug option (703 bytes, text/plain)
2003-09-19 20:23 EST, Paul Bolton
no flags Details
Forces Storage of Kerberos Credentials right after authentication via PAM (2.67 KB, patch)
2004-05-28 19:31 EST, Christian Pfaffel
no flags Details | Diff
Enables storage of forwarded GSSAPI credentials (1.14 KB, patch)
2004-05-28 19:40 EST, Christian Pfaffel
no flags Details | Diff
uset setjmp/longjmp instead of pthreads or fork (6.52 KB, patch)
2007-09-13 13:46 EST, David Leonard
no flags Details | Diff

Note You need to log in before you can comment on or make changes to this bug.
Description Paul Bolton 2003-09-19 20:19:31 EST
Tested on Solaris 8 HW02/02 SPARC fully patched with latest recommended set.

On 3.6.1p2 openssh would correctly authenticate via the PAM framework against
all modules. 3.7p1 and 3.7.1p1 logins do not successfully perform a keylogin via
the pam_dhkeys.so.1 module.

This results in the users not having correctly set creds in the keyserv and
therefore cannot authenticate against "sec=dh" shares or other services
requiring DH authentication.
Comment 1 Paul Bolton 2003-09-19 20:23:52 EST
Created attachment 434 [details]
pam_dhkeys debug option

This shows that the module is not finding any keys from NIS+.
Comment 2 Paul Bolton 2003-09-22 01:09:09 EST
After looking at the problem today, I believe I have found the source of the
problem.

auth-pam.c spawns processes in order to perform the authentication and
credential setting in sub-processes. The workaround I have used is to force the
use of USE_POSIX_THREADS and use -lpthread.

As an example. in.telnetd will call pam_sm_authenticate() and then fork. Using
the same PAM handle, the child will then perform a pam_sm_setcred() and then
exec to the shell.

What sshd is doing is the main process (A) initializes the PAM framework, then
by simulating "pthreads" process A spawns a process B. Process B performs the
pam_sm_authenticate(). Sometime later A spawns a process C. Process C performs
the pam_sm_setcred(). Then A spawns D to exec and become the shell.
pam_sm_setcred (according to truss) seems to also be called in D. The problem is
that any module specific data set calling pam_sm_authenticate() and
pam_sm_setcred() are in separate copies of the PAM handle (i.e. in B,C,D). It
seems that there is something that is set at each stage that the other
components rely upon. Most likely it is becuase the password is stored in B (via
pam_set_item(...,PAM_AUTHTOK,...)), and hence C or D cannot perform the keylogin
(in pam_sm_setcred) as the password is not present in the module data defined
via the PAM handle.
Comment 3 Darren Tucker 2004-03-30 12:42:16 EST
Here's my understanding of what's going on.  Currently this is only known to
affect Solaris, but it's possible the problem exists on other PAM-using systems.

During pam_authenticate, the modules in question (pam_dhkeys, pam_krb5) stash
some private data using the pam_set_data() calls.  In the normal case, this data
is present in a separate process (the "authentication thread") and is lost when
that process exits after completing the authentication.

Later, when pam_setcred is called to establish the process credentials (eg a PAG
for AFS or the stored DH keys, however they are stored), that private data is
not available to module, so the credentials are not established.

The data stored by pam_set_data is completely inacessible to the application (ie
sshd).  If is was stored via pam_set_item, pam_putenv or the normal environment
space, it can be copied to the main sshd process (and in 3.8 and up, it is).

Currently, the only known workaround is to enable the use of POSIX threads, as
Paul discovered.  This is because the module-private data is stored in the same
address space as the main sshd, and thus survives the termination of the
"authentication thread".  It is then copied to the child forked to run the
user's shell an is available to the pam_setcred() calls in session.c.

Note that enabling threads opens up sshd to any number of races with any PAM
module, so is not recommended unless absolutely necessary and you better hope
your PAM modules are thread-safe.  Thread support in sshd is currently a
necessary evil for these cases.  Once there is a better solution, thread support
becomes an *unnecessary* evil, and will be removed.
Comment 4 Darren Tucker 2004-03-30 12:42:58 EST
*** Bug 768 has been marked as a duplicate of this bug. ***
Comment 5 Darren Tucker 2004-03-30 12:44:32 EST
*** Bug 717 has been marked as a duplicate of this bug. ***
Comment 6 Christian Pfaffel 2004-05-28 19:31:49 EST
Created attachment 642 [details]
Forces Storage of Kerberos Credentials right after authentication via PAM

This is useful for situations where the password is validated through Kerberos
via a PAM module and the credentials obtained during authentication need to be
stored.
Comment 7 Christian Pfaffel 2004-05-28 19:40:51 EST
Created attachment 643 [details]
Enables storage of forwarded GSSAPI credentials

Storage of forwarded GSSAPI credentials when privilege separation is enabled
fails. The pam_session part is reexecuted after the delegated GSSAPI
credentials are stored.
Comment 8 Darren Tucker 2004-05-28 20:24:50 EST
Re-adding PAM+password authentication support is one possible solution to this
(see bug #874).
Comment 9 Darren Tucker 2004-08-17 19:08:03 EST
Note that the patch in bug #874, which will be in the release, provides a
solution to this if you're using password authentications.
Comment 10 Damien Miller 2004-12-20 10:47:42 EST
pre-3.7p1 style PAM password auth was in 3.9p1. Does this solve your problem?
Comment 11 Darren Tucker 2005-02-16 16:13:19 EST
Given that no practical solution to this exists for the general case right now,
this is not going to be in the next release.
Comment 12 Lamont Granquist 2005-09-24 05:17:37 EST
The "use_shmem=sshd" option of pam_krb5-2.2.0-0.5 (or later?) from the RedHat
CVS tree appears to work around this bug, without needing to disable
challenge-response in openssh.
Comment 13 Pieter Hollants 2005-12-19 23:57:47 EST
I would like to know what the viewpoint on the problem faced here is: is this still considered an OpenSSH-specific bug or a general problem of PAM implementations and fork()ing applications such as OpenSSH? Or is it even the wisest thing to advocate PAM module writers to use own mechanisms instead of pam_set_data, like pam_krb5 does with shared memory?
Comment 14 David Leonard 2007-09-13 13:46:53 EST
Created attachment 1347 [details]
uset setjmp/longjmp instead of pthreads or fork

Here's a patch for this problem that I have started using on Solaris for pam_dhkeys. It avoids pthreads and fork by using setjmp/longjmp and sigaltstack and cooperatively yielding only when reading from the IPC socket.

(https://bugsrc.quest.com/show_bug.cgi?id=280)