Author: gd
Date: 2006-01-13 11:11:23 +0000 (Fri, 13 Jan 2006)
New Revision: 12900

WebSVN: 
http://websvn.samba.org/cgi-bin/viewcvs.cgi?view=rev&root=samba&rev=12900

Log:
Merge from trunk:

Correctly handle the case where users logon with an expired password. 

In that case pam_sm_authenticate has to return PAM_SUCESS instead of
PAM_NEW_AUTHTOK_REQD or PAM_AUTHTOK_EXPIRED and pam_sm_acct_mgmt has to
take care of requesting an immediate password change. (see the Linux PAM
documentation).

Fixes Bugzilla #1524, #3205. Tested with login, sshd, kdm and gdm on
Linux.

Thanks to Scott Barker <[EMAIL PROTECTED]>.

Guenther

Modified:
   branches/SAMBA_3_0/source/nsswitch/pam_winbind.c
   branches/SAMBA_3_0/source/nsswitch/pam_winbind.h


Changeset:
Modified: branches/SAMBA_3_0/source/nsswitch/pam_winbind.c
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/pam_winbind.c    2006-01-13 10:37:14 UTC 
(rev 12899)
+++ branches/SAMBA_3_0/source/nsswitch/pam_winbind.c    2006-01-13 11:11:23 UTC 
(rev 12900)
@@ -57,6 +57,11 @@
        return ctrl;
 }
 
+static void _pam_winbind_cleanup_func(pam_handle_t *pamh, void *data, int 
error_status)
+{
+       SAFE_FREE(data);
+}
+
 /* --- authentication management functions --- */
 
 /* Attempt a conversation */
@@ -508,7 +513,22 @@
      }
 
      /* Now use the username to look up password */
-     return winbind_auth_request(username, password, member, ctrl);
+     retval = winbind_auth_request(username, password, member, ctrl);
+     if (retval == PAM_NEW_AUTHTOK_REQD ||
+        retval == PAM_AUTHTOK_EXPIRED) {
+       
+       char *buf;
+                       
+       if (!asprintf(&buf, "%d", retval)) {
+               return PAM_BUF_ERR;
+       }
+
+       pam_set_data( pamh, PAM_WINBIND_NEW_AUTHTOK_REQD, (void *)buf, 
_pam_winbind_cleanup_func);
+
+       return PAM_SUCCESS;
+     }
+     
+     return retval;
 }
 
 PAM_EXTERN
@@ -527,6 +547,8 @@
                   int argc, const char **argv)
 {
     const char *username;
+    void *tmp = NULL;
+
     int retval = PAM_USER_UNKNOWN;
 
     /* parse arguments */
@@ -555,6 +577,26 @@
                return PAM_IGNORE;
            return PAM_USER_UNKNOWN;
        case 0:
+           pam_get_data( pamh, PAM_WINBIND_NEW_AUTHTOK_REQD, (const void 
**)&tmp);
+
+           if (tmp != NULL) {
+               retval = atoi(tmp);
+               switch (retval) {
+               case PAM_AUTHTOK_EXPIRED:
+                    /* fall through, since new token is required in this case 
*/
+               case PAM_NEW_AUTHTOK_REQD:
+                    _pam_log(LOG_WARNING, "pam_sm_acct_mgmt success but %s is 
set",
+                             PAM_WINBIND_NEW_AUTHTOK_REQD);
+                    _pam_log(LOG_NOTICE, "user '%s' needs new password", 
username);
+                    /* PAM_AUTHTOKEN_REQD does not exist, but is documented in 
the manpage */
+                    return PAM_NEW_AUTHTOK_REQD;
+               default:
+                    _pam_log(LOG_WARNING, "pam_sm_acct_mgmt success");
+                    _pam_log(LOG_NOTICE, "user '%s' granted access", username);
+                    return PAM_SUCCESS;
+               }
+           }
+
            /* Otherwise, the authentication looked good */
            _pam_log(LOG_NOTICE, "user '%s' granted access", username);
            return PAM_SUCCESS;

Modified: branches/SAMBA_3_0/source/nsswitch/pam_winbind.h
===================================================================
--- branches/SAMBA_3_0/source/nsswitch/pam_winbind.h    2006-01-13 10:37:14 UTC 
(rev 12899)
+++ branches/SAMBA_3_0/source/nsswitch/pam_winbind.h    2006-01-13 11:11:23 UTC 
(rev 12900)
@@ -84,6 +84,8 @@
 #define WINBIND__OLD_PASSWORD (1<<5)
 #define WINBIND_REQUIRED_MEMBERSHIP (1<<6)
 
+#define PAM_WINBIND_NEW_AUTHTOK_REQD "PAM_WINBIND_NEW_AUTHTOK_REQD"
+
 /*
  * here is the string to inform the user that the new passwords they
  * typed were not the same.

Reply via email to