]> granicus.if.org Git - linux-pam/commitdiff
pam_unix: Add no_pass_expiry option to ignore password expiration.
authorTomas Mraz <tmraz@fedoraproject.org>
Wed, 17 Feb 2016 13:21:41 +0000 (14:21 +0100)
committerTomas Mraz <tmraz@fedoraproject.org>
Wed, 17 Feb 2016 13:21:41 +0000 (14:21 +0100)
* modules/pam_unix/pam_unix.8.xml: Document the no_pass_expiry option.
* modules/pam_unix/pam_unix_acct.c (pam_sm_acct_mgmt): If no_pass_expiry
is on and return value data is not set to PAM_SUCCESS then ignore
PAM_NEW_AUTHTOK_REQD and PAM_AUTHTOK_EXPIRED returns.
* modules/pam_unix/pam_unix_auth.c (pam_sm_authenticate): Always set the
return value data.
(pam_sm_setcred): Test for likeauth option and use the return value data
only if set.
* modules/pam_unix/support.h: Add the no_pass_expiry option.

modules/pam_unix/pam_unix.8.xml
modules/pam_unix/pam_unix_acct.c
modules/pam_unix/pam_unix_auth.c
modules/pam_unix/support.h

index a8b64bb54e195a69a380750d1740ad3f0055013b..6d8e4ba0c2e9c7254432c1823b6f92a6d3b8f84a 100644 (file)
           </para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>
+          <option>no_pass_expiry</option>
+        </term>
+        <listitem>
+          <para>
+            When set ignore password expiration as defined by the
+            <emphasis>shadow</emphasis> entry of the user. The option has an
+            effect only in case <emphasis>pam_unix</emphasis> was not used
+            for the authentication or it returned authentication failure
+            meaning that other authentication source or method succeeded.
+            The example can be public key authentication in
+            <emphasis>sshd</emphasis>. The module will return
+            <emphasis remap='B'>PAM_SUCCESS</emphasis> instead of eventual
+            <emphasis remap='B'>PAM_NEW_AUTHTOK_REQD</emphasis> or
+            <emphasis remap='B'>PAM_AUTHTOK_EXPIRED</emphasis>.
+          </para>
+        </listitem>
+      </varlistentry>
     </variablelist>
     <para>
       Invalid arguments are logged with  <citerefentry>
index 279984514d82441bf29a06d8ec30cd7cc6600e55..f8b39c9157bdd2f153b6e7d6bc97d8318b0ddfe5 100644 (file)
@@ -235,6 +235,19 @@ pam_sm_acct_mgmt(pam_handle_t *pamh, int flags, int argc, const char **argv)
        } else
                retval = check_shadow_expiry(pamh, spent, &daysleft);
 
+       if (on(UNIX_NO_PASS_EXPIRY, ctrl)) {
+               const void *pretval = NULL;
+               int authrv = PAM_AUTHINFO_UNAVAIL; /* authentication not called */
+
+               if (pam_get_data(pamh, "unix_setcred_return", &pretval) == PAM_SUCCESS
+                       && pretval)
+                       authrv = *(const int *)pretval;
+
+               if (authrv != PAM_SUCCESS
+                       && (retval == PAM_NEW_AUTHTOK_REQD || retval == PAM_AUTHTOK_EXPIRED))
+                       retval = PAM_SUCCESS;
+       }
+
        switch (retval) {
        case PAM_ACCT_EXPIRED:
                pam_syslog(pamh, LOG_NOTICE,
index 44573e6c108bd02f035258c15a8a221ac0549219..9a547b3af408fb68483b82e1b4b0d1a8df5fc1ee 100644 (file)
 
 #define AUTH_RETURN                                            \
 do {                                                           \
-       if (on(UNIX_LIKE_AUTH, ctrl) && ret_data) {             \
+       if (ret_data) {                                         \
                D(("recording return code for next time [%d]",  \
                                        retval));               \
                *ret_data = retval;                             \
                pam_set_data(pamh, "unix_setcred_return",       \
                             (void *) ret_data, setcred_free);  \
-       } else if (ret_data)                                    \
-         free (ret_data);                                      \
+       }                                                       \
        D(("done. [%s]", pam_strerror(pamh, retval)));          \
        return retval;                                          \
 } while (0)
@@ -115,9 +114,8 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
        ctrl = _set_ctrl(pamh, flags, NULL, NULL, NULL, argc, argv);
 
        /* Get a few bytes so we can pass our return value to
-          pam_sm_setcred(). */
-       if (on(UNIX_LIKE_AUTH, ctrl))
-               ret_data = malloc(sizeof(int));
+          pam_sm_setcred() and pam_sm_acct_mgmt(). */
+       ret_data = malloc(sizeof(int));
 
        /* get the user'name' */
 
@@ -194,20 +192,24 @@ pam_sm_authenticate(pam_handle_t *pamh, int flags, int argc, const char **argv)
  */
 
 int
-pam_sm_setcred (pam_handle_t *pamh, int flags UNUSED,
-               int argc UNUSED, const char **argv UNUSED)
+pam_sm_setcred (pam_handle_t *pamh, int flags,
+               int argc, const char **argv)
 {
        int retval;
        const void *pretval = NULL;
+       unsigned int ctrl;
 
        D(("called."));
 
+       ctrl = _set_ctrl(pamh, flags, NULL, NULL, NULL, argc, argv);
+
        retval = PAM_SUCCESS;
 
        D(("recovering return code from auth call"));
        /* We will only find something here if UNIX_LIKE_AUTH is set --
           don't worry about an explicit check of argv. */
-       if (pam_get_data(pamh, "unix_setcred_return", &pretval) == PAM_SUCCESS
+       if (on(UNIX_LIKE_AUTH, ctrl)
+           && pam_get_data(pamh, "unix_setcred_return", &pretval) == PAM_SUCCESS
            && pretval) {
                retval = *(const int *)pretval;
                pam_set_data(pamh, "unix_setcred_return", NULL, NULL);
index 3729ce0cc76372045b21d5fc79ea6a669ebb8963..b767c2659f35289d84d4b5c2a5aa91ff2ecf1a95 100644 (file)
@@ -98,9 +98,10 @@ typedef struct {
 #define UNIX_BLOWFISH_PASS       26    /* new password hashes will use blowfish */
 #define UNIX_MIN_PASS_LEN        27    /* min length for password */
 #define UNIX_QUIET              28     /* Don't print informational messages */
-#define UNIX_DES                 29     /* DES, default */
+#define UNIX_NO_PASS_EXPIRY      29     /* Don't check for password expiration if not used for authentication */
+#define UNIX_DES                 30     /* DES, default */
 /* -------------- */
-#define UNIX_CTRLS_              30    /* number of ctrl arguments defined */
+#define UNIX_CTRLS_              31    /* number of ctrl arguments defined */
 
 #define UNIX_DES_CRYPT(ctrl)   (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl))
 
@@ -138,6 +139,7 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
 /* UNIX_BLOWFISH_PASS */   {"blowfish",    _ALL_ON_^(0260420000), 0200000000, 1},
 /* UNIX_MIN_PASS_LEN */    {"minlen=",         _ALL_ON_,         0400000000, 0},
 /* UNIX_QUIET */           {"quiet",           _ALL_ON_,         01000000000, 0},
+/* UNIX_NO_PASS_EXPIRY */  {"no_pass_expiry",  _ALL_ON_,         02000000000, 0},
 /* UNIX_DES */             {"des",             _ALL_ON_^(0260420000),      0, 1},
 };