The Pluggable Authentication Modules (PAM) integrate several
authentication schemes into an API which is used on several platforms,
including Linux, to perform authentication and authorization for services
such as login, ssh access, etc. One of these modules is Novell’s
pam_nam.so which authenticates against eDirectory and caches users’
credentials locally. This module is available on Suse Linux Enterprise Desktop
(SLED) and is enabled with its Linux User Management (LUM) modules. A PAM
configuration for such an installation starts off with
auth sufficient pam_nam.so
account sufficient pam_nam.so
password sufficient pam_nam.so
session optional pam_nam.so
...
Wanting to get hold of the credentials entered by a user, in order to
subsequently mount a remote file system with them, I found a nifty little set
of tools written by John Newbigin; Linux Enhanced SMBFS describes a PAM
module avec a small daemon which can be used to do just that (I’m only
interested in John’s pam_smbpw.so and smbpwman code; the rest I don’t
use). pam_smbpw.so retrieves the user’s credentials from the PAM stack and
passes them to a small daemon (smbpwman) via a Unix domain socket. The
daemon is forked and executed if it isn’t running, and it keeps the
credentials in core, allowing them to be retrieved by a process allowed to
open said socket. A sample is located in the smbpwtest program. Stacking
pam_smbpw.so into PAM is easy enough and well documented on John’s
page. Unfortunately, the pam_nam.so needs a sufficient
to operate,
meaning, that if it succeeds, the auth stack terminates; I tried using
optional
or required
twice, once before and once after pam_smbpw.so
which works, but it has a side effect of taking excessively long if and when a
user mistypes her password. John was kind enough to answer my query, but his
solution didn’t seem to help me, so I hacked in some code to have
pam_smbpw.so prompt for credentials; it then passes them down the stack,
enabling subsequent modules to retrieve them. My PAM stack now specifies
auth required pam_smbpw.so
auth sufficient pam_nam.so use_first_pass
...
pam_smbpw.so queries the credentials and stores them, even if they are incorrect. Following that, pam_nam.so checks them, and it either succeeds or fails as before. I’m attaching my tiny patch here, but I make no guarantees as to its safety for general consumption.
*** pam_smbpw.c.original 2007-04-26 10:59:30.000000000 +0200
--- pam_smbpw.c 2007-04-26 11:24:08.000000000 +0200
***************
*** 11,16 ****
--- 11,18 ----
#include <security/pam_modules.h>
+ #include <security/_pam_macros.h>
+ #include <security/pam_ext.h>
#include "../smbpw.h"
***************
*** 69,74 ****
--- 71,94 ----
pam_get_user(pamh, &user, NULL);
_pam_log(LOG_DEBUG, "The user is %s\n", user);
+ /* JPM */
+ {
+ char *resp = NULL;
+ char *token;
+
+ r = pam_prompt(pamh, PAM_PROMPT_ECHO_OFF, &resp,
+ "Password.", user);
+
+ if (r != PAM_SUCCESS) {
+ _pam_drop(r);
+ return ((r == PAM_CONV_AGAIN)
+ ? PAM_INCOMPLETE : PAM_AUTHINFO_UNAVAIL);
+
+ }
+ pam_set_item(pamh, PAM_AUTHTOK, resp);
+ _pam_log(LOG_DEBUG, "JPJP: %s", resp);
+ }
+ /* JPM */
r = pam_get_item(pamh, PAM_AUTHTOK, (const void **)&authtok);
if(r != PAM_SUCCESS)
{
It seems to work, but I haven’t as yet scrutinized it for bugs and other evil thingies. Use at your own risk. :-)