]> granicus.if.org Git - linux-pam/commitdiff
Relevant BUGIDs:
authorThorsten Kukuk <kukuk@thkukuk.de>
Tue, 17 Aug 2010 11:15:32 +0000 (11:15 +0000)
committerThorsten Kukuk <kukuk@thkukuk.de>
Tue, 17 Aug 2010 11:15:32 +0000 (11:15 +0000)
Purpose of commit: new feature

Commit summary:
---------------

2010-08-17  Thorsten Kukuk  <kukuk@thkukuk.de>

        * modules/pam_unix/pam_unix_passwd.c: Implement minlen option.
        * modules/pam_unix/support.c: Likewise.
        * modules/pam_unix/support.h: Likewise.

        * modules/pam_unix/pam_unix_acct.c (pam_sm_acct_mgmt): Adjust
        arguments for _set_ctrl call.
        * modules/pam_unix/pam_unix_auth.c (pam_sm_authenticate): Likewise.
        * modules/pam_unix/pam_unix_session.c: Likewise.

        * modules/pam_unix/pam_unix.8.xml: Document minlen option.
        Based on patch by Steve Langasek.

ChangeLog
modules/pam_unix/pam_unix.8.xml
modules/pam_unix/pam_unix_acct.c
modules/pam_unix/pam_unix_auth.c
modules/pam_unix/pam_unix_passwd.c
modules/pam_unix/pam_unix_sess.c
modules/pam_unix/support.c
modules/pam_unix/support.h

index da8193ddecc76f5458e86b11a2a1753f32988486..6fbdb4e090ac773fa9dd27b5f787081ea3505aa8 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,3 +1,17 @@
+2010-08-17  Thorsten Kukuk  <kukuk@thkukuk.de>
+
+       * modules/pam_unix/pam_unix_passwd.c: Implement minlen option.
+       * modules/pam_unix/support.c: Likewise.
+       * modules/pam_unix/support.h: Likewise.
+
+       * modules/pam_unix/pam_unix_acct.c (pam_sm_acct_mgmt): Adjust
+       arguments for _set_ctrl call.
+       * modules/pam_unix/pam_unix_auth.c (pam_sm_authenticate): Likewise.
+       * modules/pam_unix/pam_unix_session.c: Likewise.
+
+       * modules/pam_unix/pam_unix.8.xml: Document minlen option.
+       Based on patch by Steve Langasek.
+
 2010-08-12  Thorsten Kukuk  <kukuk@thkukuk.de>
 
        * modules/pam_mail/pam_mail.c: Check for mail only with user
index 6b860f7f648358ec1832896ce77de31e18450d7f..c272e3cea93079971047954d5c84571e65dea169 100644 (file)
           </para>
         </listitem>
       </varlistentry>
+      <varlistentry>
+        <term>
+          <option>minlen=<replaceable>n</replaceable></option>
+        </term>
+        <listitem>
+          <para>
+            Set a minimum password length of <replaceable>n</replaceable>
+            characters. The max. for DES crypt based passwords are 8
+            characters.
+          </para>
+        </listitem>
+      </varlistentry>
     </variablelist>
     <para>
       Invalid arguments are logged with  <citerefentry>
index 08cc750f81585e55114a04aa224d490b757f9257..2731b8bcd75efcf7410b8a3f2c7fe04c3a3909e8 100644 (file)
@@ -191,7 +191,7 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags,
 
        D(("called."));
 
-       ctrl = _set_ctrl(pamh, flags, NULL, NULL, argc, argv);
+       ctrl = _set_ctrl(pamh, flags, NULL, NULL, NULL, argc, argv);
 
        retval = pam_get_item(pamh, PAM_USER, &void_uname);
        uname = void_uname;
index c2f79b10028ac876587cd5357fb29a6f1cef0c2a..d9c4ea5583f42499b47d0e81880581be1d5429f1 100644 (file)
@@ -109,7 +109,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags
 
        D(("called."));
 
-       ctrl = _set_ctrl(pamh, flags, NULL, NULL, argc, 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(). */
index f137570abdd2d5bf9af6c0d750bd1692d1f61e45..320bc54772a6b0d8297d1cc45ab1a90d5f8a852c 100644 (file)
@@ -457,7 +457,8 @@ static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned in
 static int _pam_unix_approve_pass(pam_handle_t * pamh
                                  ,unsigned int ctrl
                                  ,const char *pass_old
-                                 ,const char *pass_new)
+                                 ,const char *pass_new,
+                                  int pass_min_len)
 {
        const void *user;
        const char *remark = NULL;
@@ -488,6 +489,9 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh
                }
        }
        if (off(UNIX__IAMROOT, ctrl)) {
+               if (strlen(pass_new) < pass_min_len)
+                 remark = _("You must choose a longer password");
+               D(("length check [%s]", remark));
                if (on(UNIX_REMEMBER_PASSWD, ctrl)) {
                        if ((retval = check_old_password(user, pass_new)) == PAM_AUTHTOK_ERR)
                          remark = _("Password has been already used. Choose another.");
@@ -513,6 +517,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
        int retval;
        int remember = -1;
        int rounds = -1;
+       int pass_min_len = 0;
 
        /* <DO NOT free() THESE> */
        const char *user;
@@ -521,7 +526,8 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
 
        D(("called."));
 
-       ctrl = _set_ctrl(pamh, flags, &remember, &rounds, argc, argv);
+       ctrl = _set_ctrl(pamh, flags, &remember, &rounds, &pass_min_len,
+                        argc, argv);
 
        /*
         * First get the name of a user
@@ -721,7 +727,8 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                        if (*(const char *)pass_new == '\0') {  /* "\0" password = NULL */
                                pass_new = NULL;
                        }
-                       retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new);
+                       retval = _pam_unix_approve_pass(pamh, ctrl, pass_old,
+                                                       pass_new, pass_min_len);
 
                        if (retval != PAM_SUCCESS && off(UNIX_NOT_SET_PASS, ctrl)) {
                                pam_set_item(pamh, PAM_AUTHTOK, NULL);
@@ -754,7 +761,8 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
                        return retval;
                }
 
-               retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new);
+               retval = _pam_unix_approve_pass(pamh, ctrl, pass_old, pass_new,
+                                               pass_min_len);
                if (retval != PAM_SUCCESS) {
                        pam_syslog(pamh, LOG_NOTICE,
                                 "new password not acceptable 2");
index e984578c56ab1255fc129fd29bc717e5ea76fb4c..778062e406e291c23993a6e9348a6a1226b3c694 100644 (file)
@@ -73,7 +73,7 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t * pamh, int flags,
 
        D(("called."));
 
-       ctrl = _set_ctrl(pamh, flags, NULL, NULL, argc, argv);
+       ctrl = _set_ctrl(pamh, flags, NULL, NULL, NULL, argc, argv);
 
        retval = pam_get_item(pamh, PAM_USER, (void *) &user_name);
        if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) {
@@ -107,7 +107,7 @@ PAM_EXTERN int pam_sm_close_session(pam_handle_t * pamh, int flags,
 
        D(("called."));
 
-       ctrl = _set_ctrl(pamh, flags, NULL, NULL, argc, argv);
+       ctrl = _set_ctrl(pamh, flags, NULL, NULL, NULL, argc, argv);
 
        retval = pam_get_item(pamh, PAM_USER, (void *) &user_name);
        if (user_name == NULL || *user_name == '\0' || retval != PAM_SUCCESS) {
index 2a47d157e4da3ed2df829fa35c1b6b227de761da..898d1ea5e5f9dff6d9f47415ccc5ef2532d21d69 100644 (file)
@@ -55,7 +55,7 @@ int _make_remark(pam_handle_t * pamh, unsigned int ctrl,
  */
 
 int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds,
-             int argc, const char **argv)
+             int *pass_min_len, int argc, const char **argv)
 {
        unsigned int ctrl;
 
@@ -102,15 +102,16 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds,
                        ctrl &= unix_args[j].mask;      /* for turning things off */
                        ctrl |= unix_args[j].flag;      /* for turning things on  */
 
-                       if (remember != NULL) {
-                               if (j == UNIX_REMEMBER_PASSWD) {
-                                       *remember = strtol(*argv + 9, NULL, 10);
-                                       if ((*remember == INT_MIN) || (*remember == INT_MAX))
-                                               *remember = -1;
-                                       if (*remember > 400)
-                                               *remember = 400;
-                               }
-                       }
+                       /* special cases */
+                       if (remember != NULL && j == UNIX_REMEMBER_PASSWD) {
+                               *remember = strtol(*argv + 9, NULL, 10);
+                               if ((*remember == INT_MIN) || (*remember == INT_MAX))
+                                       *remember = -1;
+                               if (*remember > 400)
+                                       *remember = 400;
+                       } else if (pass_min_len && j == UNIX_MIN_PASS_LEN) {
+                               *pass_min_len = atoi(*argv + 7);
+                       }
                        if (rounds != NULL && j == UNIX_ALGO_ROUNDS)
                                *rounds = strtol(*argv + 7, NULL, 10);
                }
@@ -118,6 +119,13 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds,
                ++argv;         /* step to next argument */
        }
 
+       if (UNIX_DES_CRYPT(ctrl)
+           && pass_min_len && *pass_min_len > 8)
+         {
+           pam_syslog (pamh, LOG_NOTICE, "Password minlen reset to 8 characters");
+           *pass_min_len = 8;
+         }
+
        if (flags & PAM_DISALLOW_NULL_AUTHTOK) {
                D(("DISALLOW_NULL_AUTHTOK"));
                set(UNIX__NONULL, ctrl);
index dfee2daebe055e031aa0141114f9855c146f6615..db4cd9537f56cc6f1a6372bf92681aa909dcca13 100644 (file)
@@ -86,11 +86,14 @@ typedef struct {
                                         * information during acct management */
 #define UNIX_SHA256_PASS         23    /* new password hashes will use SHA256 */
 #define UNIX_SHA512_PASS         24    /* new password hashes will use SHA512 */
-#define UNIX_ALGO_ROUNDS         25    /* optional number of rounds for new 
+#define UNIX_ALGO_ROUNDS         25    /* optional number of rounds for new
                                           password hash algorithms */
 #define UNIX_BLOWFISH_PASS       26    /* new password hashes will use blowfish */
+#define UNIX_MIN_PASS_LEN        27    /* min length for password */
 /* -------------- */
-#define UNIX_CTRLS_              27    /* number of ctrl arguments defined */
+#define UNIX_CTRLS_              28    /* 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))
 
 static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
 {
@@ -124,6 +127,7 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
 /* UNIX_SHA512_PASS */     {"sha512",       _ALL_ON_^(0260420000), 040000000},
 /* UNIX_ALGO_ROUNDS */     {"rounds=",         _ALL_ON_,          0100000000},
 /* UNIX_BLOWFISH_PASS */   {"blowfish",    _ALL_ON_^(0260420000), 0200000000},
+/* UNIX_MIN_PASS_LEN */    {"minlen=",         _ALL_ON_,          0400000000},
 };
 
 #define UNIX_DEFAULTS  (unix_args[UNIX__NONULL].flag)
@@ -141,7 +145,7 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
 extern int _make_remark(pam_handle_t * pamh, unsigned int ctrl
                       ,int type, const char *text);
 extern int _set_ctrl(pam_handle_t * pamh, int flags, int *remember, int *rounds,
-                    int argc, const char **argv);
+                    int *pass_min_len, int argc, const char **argv);
 extern int _unix_getpwnam (pam_handle_t *pamh,
                           const char *name, int files, int nis,
                           struct passwd **ret);