>Number:         154597
>Category:       misc
>Synopsis:       pam_passwdqc incorrectly user their password must be MAX_INT 
>characters long in some cases.
>Confidential:   no
>Severity:       non-critical
>Priority:       low
>Responsible:    freebsd-bugs
>State:          open
>Quarter:        
>Keywords:       
>Date-Required:
>Class:          update
>Submitter-Id:   current-users
>Arrival-Date:   Tue Feb 08 19:30:08 UTC 2011
>Closed-Date:
>Last-Modified:
>Originator:     Ted Stodgell
>Release:        8-STABLE
>Organization:
NASA Marshall Spaceflight Center
>Environment:
FreeBSD groundemu3.fddrlab.msfc.nasa.gov 8.2-RC3 FreeBSD 8.2-RC3 #6: Mon Feb  7 
10:28:26 CST 2011     
r...@groundemu3.fddrlab.msfc.nasa.gov:/usr/obj/usr/src/sys/GROUNDEMU-B  i386

>Description:
pam_passwdqc incorrectly user their password must be MAX_INT characters long in 
some cases. If you want to force users to use all 4 classes of character (i.e. 
uppercase, lowercase, numbers and symbols) the configuration is

min=disabled,disabled,disabled,disabled,[a number]

Unfortunately, pam_passwdc doesn't handle this situation corectly. It would say:

"A valid password should be a mix of upper and lower case letters,
digits and other characters.  You can use a 2147483647 character long
password with characters from at least 3 of these 4 classes, or
a 12 character long password containing characters from all the
classes.  Characters that form a common pattern are discarded by
the check."

We don't want to allow ANY passwords with only 3 classes of character. It's 
kind of dumb to suggest to a user that they could get away with a password 
that's 2147483647 characters long!
>How-To-Repeat:
1) Enable pam_passwdqc. Below is an example /etc/pam.d/passwd you can use:

#
# $FreeBSD: src/etc/pam.d/passwd,v 1.3.34.1.6.1 2010/12/21 17:09:25 kensmith 
Exp $
#
# PAM configuration for the "passwd" service
#

# passwd(1) does not use the auth, account or session services.

# password
password        requisite       pam_passwdqc.so         enforce=users 
min=disabled,disabled,disabled,disabled,12 max=40
password        required        pam_unix.so             no_warn try_first_pass 
nullok

2) Try changing your password with "passwd". You will get this message:

"A valid password should be a mix of upper and lower case letters,
digits and other characters.  You can use a [HUGE_NUMBER]* character long
password with characters from at least 3 of these 4 classes, or
a 12 character long password containing characters from all the
classes.  Characters that form a common pattern are discarded by
the check."

* this is MAX_INT on your architecture.

3) Unrelated problem: pam_passwdqc has 2 grammatical errors. Messages use the 
non-word "noone" instead of "no one". This is also fixed in the submitted patch.
>Fix:
--- pam_passwdqc.c  2002-04-16 17:25:21.000000000 -0500
+++ pam_passwdqc.c.new  2011-02-08 10:33:05.000000000 -0600
@@ -100,15 +100,20 @@
    "a%s %d character long password containing characters from all the\n" \
    "classes.  Characters that form a common pattern are discarded by\n" \
    "the check.\n"
+#define MESSAGE_EXPLAIN_PASSWORD_3 \
+   "A valid password should be a mix of upper and lower case letters,\n" \
+   "digits and other characters.  You must use a%s %d character long\n" \
+   "password containing characters from all 4 classes. Characters that\n" \
+   "form a common pattern are discarded by the check.\n"
 #define MESSAGE_EXPLAIN_PASSPHRASE \
    "A passphrase should be of at least %d words, %d to %d characters\n" \
    "long and contain enough different characters.\n"
 #define MESSAGE_RANDOM \
-   "Alternatively, if noone else can see your terminal now, you can\n" \
+   "Alternatively, if no one else can see your terminal now, you can\n" \
    "pick this as your password: \"%s\".\n"
 #define MESSAGE_RANDOMONLY \
    "This system is configured to permit randomly generated passwords\n" \
-   "only.  If noone else can see your terminal now, you can pick this\n" \
+   "only.  If no one else can see your terminal now, you can pick this\n" \
    "as your password: \"%s\".  Otherwise, come back later.\n"
 #define MESSAGE_RANDOMFAILED \
    "This system is configured to use randomly generated passwords\n" \
@@ -201,6 +206,7 @@
            p = *argv + 4;
            for (i = 0; i < 5; i++) {
                if (!strncmp(p, "disabled", 8)) {
+                   /* disabled fields are set to INT_MAX */
                    v = INT_MAX;
                    p += 8;
                } else {
@@ -434,16 +440,44 @@
        return status;

    if (!randomonly && params.qc.min[3] <= params.qc.min[4])
+   /* Password needs at least 3 different classes of character.
+    * N4 is either larger than N3, or set to "disabled".
+    */
        status = say(pamh, PAM_TEXT_INFO, MESSAGE_EXPLAIN_PASSWORD_1,
            params.qc.min[3] == 8 || params.qc.min[3] == 11 ? "n" : "",
            params.qc.min[3]);
    else
-   if (!randomonly)
+   if (!randomonly && INT_MAX != params.qc.min[3])
+   /* Password needs at least 3 different classes of character.
+    * N3 and N4 were both assigned numeric values.
+    */
        status = say(pamh, PAM_TEXT_INFO, MESSAGE_EXPLAIN_PASSWORD_2,
            params.qc.min[3] == 8 || params.qc.min[3] == 11 ? "n" : "",
            params.qc.min[3],
            params.qc.min[4] == 8 || params.qc.min[4] == 11 ? "n" : "",
            params.qc.min[4]);
+   else
+   if (!randomonly)
+   /* Password must use all 4 different classes of character.
+     * Only N4 has a value.
+    *
+    * Previously, MESSAGE_EXPLAIN_PASSWORD_2 was used in cases
+    * where N3 was disabled and only N4 was defined with a value,
+    * e.g. min=disabled,disabled,disabled,disabled,12.
+    *
+    * When this happens,
+     * params.qc.min[3] gets set to MAX_INT, and
+    * MESSAGE_EXPLAN_PASSWORD_2 tells you that your password must
+    * be MAX_INT characters long if you want to use only 3 different
+    * classes of character!
+    *
+    * We don't want to allow only 3 classes of character... at all.
+    * Thus, MESSAGE_EXPLAIN_PASSWORD_3.
+    */
+       status = say(pamh, PAM_TEXT_INFO, MESSAGE_EXPLAIN_PASSWORD_3,
+           params.qc.min[4] == 8 || params.qc.min[4] == 11 ? "n" : "",
+           params.qc.min[4]);
+
    if (status != PAM_SUCCESS)
        return status;

Patch attached with submission follows:

--- pam_passwdqc.c      2002-04-16 17:25:21.000000000 -0500
+++ pam_passwdqc.c.new  2011-02-08 10:33:05.000000000 -0600
@@ -100,15 +100,20 @@
        "a%s %d character long password containing characters from all the\n" \
        "classes.  Characters that form a common pattern are discarded by\n" \
        "the check.\n"
+#define MESSAGE_EXPLAIN_PASSWORD_3 \
+       "A valid password should be a mix of upper and lower case letters,\n" \
+       "digits and other characters.  You must use a%s %d character long\n" \
+       "password containing characters from all 4 classes. Characters that\n" \
+       "form a common pattern are discarded by the check.\n"
 #define MESSAGE_EXPLAIN_PASSPHRASE \
        "A passphrase should be of at least %d words, %d to %d characters\n" \
        "long and contain enough different characters.\n"
 #define MESSAGE_RANDOM \
-       "Alternatively, if noone else can see your terminal now, you can\n" \
+       "Alternatively, if no one else can see your terminal now, you can\n" \
        "pick this as your password: \"%s\".\n"
 #define MESSAGE_RANDOMONLY \
        "This system is configured to permit randomly generated passwords\n" \
-       "only.  If noone else can see your terminal now, you can pick this\n" \
+       "only.  If no one else can see your terminal now, you can pick this\n" \
        "as your password: \"%s\".  Otherwise, come back later.\n"
 #define MESSAGE_RANDOMFAILED \
        "This system is configured to use randomly generated passwords\n" \
@@ -201,6 +206,7 @@
                        p = *argv + 4;
                        for (i = 0; i < 5; i++) {
                                if (!strncmp(p, "disabled", 8)) {
+                                       /* disabled fields are set to INT_MAX */
                                        v = INT_MAX;
                                        p += 8;
                                } else {
@@ -434,16 +440,44 @@
                return status;
 
        if (!randomonly && params.qc.min[3] <= params.qc.min[4])
+       /* Password needs at least 3 different classes of character.
+        * N4 is either larger than N3, or set to "disabled".
+        */
                status = say(pamh, PAM_TEXT_INFO, MESSAGE_EXPLAIN_PASSWORD_1,
                    params.qc.min[3] == 8 || params.qc.min[3] == 11 ? "n" : "",
                    params.qc.min[3]);
        else
-       if (!randomonly)
+       if (!randomonly && INT_MAX != params.qc.min[3])
+       /* Password needs at least 3 different classes of character.
+        * N3 and N4 were both assigned numeric values.
+        */
                status = say(pamh, PAM_TEXT_INFO, MESSAGE_EXPLAIN_PASSWORD_2,
                    params.qc.min[3] == 8 || params.qc.min[3] == 11 ? "n" : "",
                    params.qc.min[3],
                    params.qc.min[4] == 8 || params.qc.min[4] == 11 ? "n" : "",
                    params.qc.min[4]);
+       else
+       if (!randomonly)
+       /* Password must use all 4 different classes of character.
+     * Only N4 has a value.
+        *
+        * Previously, MESSAGE_EXPLAIN_PASSWORD_2 was used in cases
+        * where N3 was disabled and only N4 was defined with a value,
+        * e.g. min=disabled,disabled,disabled,disabled,12.
+        *
+        * When this happens,
+     * params.qc.min[3] gets set to MAX_INT, and
+        * MESSAGE_EXPLAN_PASSWORD_2 tells you that your password must
+        * be MAX_INT characters long if you want to use only 3 different
+        * classes of character!
+        *
+        * We don't want to allow only 3 classes of character... at all.
+        * Thus, MESSAGE_EXPLAIN_PASSWORD_3.
+        */
+               status = say(pamh, PAM_TEXT_INFO, MESSAGE_EXPLAIN_PASSWORD_3,
+                   params.qc.min[4] == 8 || params.qc.min[4] == 11 ? "n" : "",
+                   params.qc.min[4]);
+
        if (status != PAM_SUCCESS)
                return status;
 


>Release-Note:
>Audit-Trail:
>Unformatted:
_______________________________________________
freebsd-bugs@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/freebsd-bugs
To unsubscribe, send any mail to "freebsd-bugs-unsubscr...@freebsd.org"

Reply via email to