List Info

Thread: weird PAM chauthtok behaviour




weird PAM chauthtok behaviour
user name
2007-08-25 12:51:38
I just spent most of the day trying to find out why a PAM  
configuration a la (I'm omitting .so, /usr/pkg/lib/security
and all  
the options here)

password sufficient pam_ldap
password required   pam_unix

or

password sufficient pam_ldap
password sufficient pam_unix
password required   pam_deny

would work on Linux, but not in NetBSD.

Having found blunder in nss_ldap before, I suspected
pam_ldap to be  
the culprit, but not so.

The problem arises from a strange behaviour of OpenPAM's
chauthtok  
handling. The whole module chain is run twice, once with  
PAM_PRELIM_CHECK and a second time without. But on that
first pass,  
OpenPAM explicitly treats a control flag of sufficient as
optional  
(openpam_dispatch.c:137):

  /*
   * For pam_setcred() and pam_chauthtok() with the
   * PAM_PRELIM_CHECK flag, treat "sufficient" as
   * "optional".
   */
  if ((chain->flag == PAM_SUFFICIENT ||
      chain->flag == PAM_BINDING) && !fail
&&
      primitive != PAM_SM_SETCRED &&
      !(primitive == PAM_SM_CHAUTHTOK &&
          (flags & PAM_PRELIM_CHECK)))
          break;

So, the only ways I can think of to make password changes
work with  
both LDAP and non-LDAP accounts is to either modify pam_deny
so it  
will (optionally) not fail for the preliminary phase of
chauthtok or  
end the chain with pam_allow. I am however, not sure of the 

implications the latter solution may have on the case of
someone  
trying to log in with an expired password. This will force
an  
immediate password change, and one might wish to know if it
failed or  
not.

Two questions on this:

1. Can someone think on a more elegant way of handling
that?

2. Can someone explain to me why OpenPAM handles sufficient
as  
optional on the first pass in the first place?


Re: weird PAM chauthtok behaviour
country flaguser name
Germany
2007-08-29 09:32:44
> So, the only ways I can think of to make password
changes work with  
> both LDAP and non-LDAP accounts is to either modify
pam_deny so it  
> will (optionally) not fail for the preliminary phase of
chauthtok
I've implemented this and it pretends to work.
I've also adjusted the various return values to those
permitted by _openpam_check_error_code
(dist/openpam/lib/openpam_dispatch.c). Does this look OK to
any PAM experts round here? Should I file a PR for this?

--- pam_deny.c.orig	2004-12-12 09:18:44.000000000 +0100
+++ pam_deny.c	2007-08-29 16:13:04.000000000 +0200
 -34,6
+34,8 
 #endif
 
 #include <stddef.h>
+#include <string.h>
+#include <syslog.h>
 
 #define PAM_SM_AUTH
 #define PAM_SM_ACCOUNT
 -61,7
+63,7 
     int argc __unused, const char *argv[] __unused)
 {
 
-	return (PAM_AUTH_ERR);
+	return (PAM_CRED_ERR);
 }
 
 PAM_EXTERN int
 -73,11
+75,25 
 }
 
 PAM_EXTERN int
-pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags
__unused,
-    int argc __unused, const char *argv[] __unused)
+pam_sm_chauthtok(pam_handle_t *pamh __unused, int flags,
+    int argc, const char *argv[])
 {
+	int prelim_ignore = 0, debug = 0;
+	int i;
 
-	return (PAM_AUTH_ERR);
+	for (i = 0; i < argc; i++) {
+		if (strcmp(argv[i], "prelim_ignore") == 0)
+			prelim_ignore = 1;
+		else if (strcmp(argv[i], "debug") == 0)
+			debug = 1;
+		else
+			syslog(LOG_ERR, "illegal option %s",
argv[i]);
+	}
+
+	if (flags & PAM_PRELIM_CHECK &&
prelim_ignore)
+		return (PAM_IGNORE);
+	else
+		return (PAM_AUTHTOK_ERR);
 }
 
 PAM_EXTERN int
 -85,7
+101,7 
     int argc __unused, const char *argv[] __unused)
 {
 
-	return (PAM_AUTH_ERR);
+	return (PAM_SESSION_ERR);
 }
 
 PAM_EXTERN int
 -93,7
+109,7 
     int argc __unused, const char *argv[] __unused)
 {
 
-	return (PAM_AUTH_ERR);
+	return (PAM_SESSION_ERR);
 }
 
 PAM_MODULE_ENTRY("pam_deny");
--- pam_deny.8.orig	2005-02-26 15:54:25.000000000 +0100
+++ pam_deny.8	2007-08-29 16:06:34.000000000 +0200
 -73,6
+73,17 
 These messages include
 reasons why the user's
 authentication attempt was declined.
+.It Cm prelim_ignore
+for password management (
+.Dq Li password
+feature), return PAM_IGNORE
+in the preliminary phase.
+This allows the module to be used (with the
+.Dq Li required
+flag) at the end of a chain of
+.Dq Li sufficient
+modules with this service
+(where the entire chain is in fact run twice).
 .El
 .Sh SEE ALSO
 .Xr syslog 3 ,


Re: weird PAM chauthtok behaviour
user name
2007-08-29 13:42:42
Edgar,

On Sat, 25 Aug 2007 19:51:38 +0200
Edgar Fuß <efmath.uni-bonn.de> wrote:

> I just spent most of the day trying to find out why a
PAM  
> configuration a la (I'm omitting .so,
/usr/pkg/lib/security and all  
> the options here)
> 
> password sufficient pam_ldap
> password required   pam_unix

> The problem arises from a strange behaviour of
OpenPAM's chauthtok  
> handling. The whole module chain is run twice, once
with  
> PAM_PRELIM_CHECK and a second time without. But on that
first pass,  
> OpenPAM explicitly treats a control flag of sufficient
as optional  

> Two questions on this:
> 
> 1. Can someone think on a more elegant way of handling
that?

Does your config have the use_first_pass (or try_first_pass)
option?

> 2. Can someone explain to me why OpenPAM handles
sufficient as  
> optional on the first pass in the first place?

I may be wrong here (I haven't looked at the code), but
isn't it just a
pass to check whether all modules used in the config are
present and
are loadable?


Kind regards,
dieter

[1-3]

about | contact  Other archives ( Real Estate discussion Medical topics )