summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAndrew G. Morgan <morgan@kernel.org>2001-06-24 22:54:05 +0000
committerAndrew G. Morgan <morgan@kernel.org>2001-06-24 22:54:05 +0000
commitf97d55b623cd851283a42b9807292ce751029218 (patch)
treeb8718a50eb322afbd65b142ec16f541dc840536d
parentd9f17b20fb20658e3eb3ff74a9eb635f14ba2d06 (diff)
Relevant BUGIDs: 413162
Purpose of commit: new feature Commit summary: --------------- pam_cracklib enhancements to make use of negative limits. Werner Puschitz gets brownie points for submitting documentation to match!
-rw-r--r--CHANGELOG5
-rw-r--r--doc/modules/pam_cracklib.sgml57
-rw-r--r--modules/pam_cracklib/pam_cracklib.c111
3 files changed, 118 insertions, 55 deletions
diff --git a/CHANGELOG b/CHANGELOG
index 8308853d..b4956813 100644
--- a/CHANGELOG
+++ b/CHANGELOG
@@ -49,8 +49,11 @@ bug report - outstanding bugs are listed here:
0.76: please submit patches for this section with actual code/doc
patches!
+* made a pam_cracklib enhancement to interpret -ve limits in a
+ sensible fashion contributed by Werner Puschitz (Bug 413162 -
+ agmorgan)
* another fix for the latest number of rlimits available to pam_limits
-(Bug 424060 - agmorgan)
+ (Bug 424060 - agmorgan)
* removed stale link from pam_pwdb documentation (Bug 433460 - agmorgan)
* pam_appl.sgml change - more discussion of choosing a service name
(Bug 417512 - agmorgan)
diff --git a/doc/modules/pam_cracklib.sgml b/doc/modules/pam_cracklib.sgml
index 97b284de..061a8a21 100644
--- a/doc/modules/pam_cracklib.sgml
+++ b/doc/modules/pam_cracklib.sgml
@@ -169,8 +169,9 @@ are different then the new password will be accepted anyway.
<item> <tt/minlen=N/ -
-The minimum acceptable size for the new password plus one. In
-addition to the number of characters in the new password, credit (of
+The minimum acceptable size for the new password (plus one if credits
+are not disabled which is the default).
+In addition to the number of characters in the new password, credit (of
+1 in length) is given for each different kind of character (<em>other,
upper, lower</em> and <em/digit/). The default for this parameter is
9 which is good for a old style UNIX password all of the same type of
@@ -184,34 +185,39 @@ the crack library and then recompile this module.
<item> <tt/dcredit=N/ -
-This is the maximum credit for having digits in the new password. If
+(N >= 0) This is the maximum credit for having digits in the new password. If
you have less than or <tt/N/ digits, each digit will count +1 towards
meeting the current <tt/minlen/ value. The default for <tt/dcredit/
is 1 which is the recommended value for <tt/minlen/ less than 10.
+(N < 0) This is the minimum number of digits that must be met for a new
+password.
<item> <tt/ucredit=N/ -
-This is the maximum credit for having upper case letters in the new
+(N >= 0) This is the maximum credit for having upper case letters in the new
password. If you have less than or <tt/N/ upper case letters each
letter will count +1 towards meeting the current <tt/minlen/ value.
The default for <tt/ucredit/ is 1 which is the recommended value for
-<tt/minlen/ less than 10.
+<tt/minlen/ less than 10. (N < 0) This is the minimum number of upper
+case letters that must be met for a new password.
<item> <tt/lcredit=N/ -
-This is the maximum credit for having lower case letters in the new
+(N >= 0) This is the maximum credit for having lower case letters in the new
password. If you have less than or <tt/N/ lower case letters, each
letter will count +1 towards meeting the current <tt/minlen/ value.
The default for <tt/lcredit/ is 1 which is the recommended value for
-<tt/minlen/ less than 10.
+<tt/minlen/ less than 10. (N < 0) This is the minimum number of lower
+case letters that must be met for a new password.
<item> <tt/ocredit=N/ -
-This is the maximum credit for having other characters in the new
+(N >= 0) This is the maximum credit for having other characters in the new
password. If you have less than or <tt/N/ other characters, each
character will count +1 towards meeting the current <tt/minlen/ value.
The default for <tt/ocredit/ is 1 which is the recommended value for
-<tt/minlen/ less than 10.
+<tt/minlen/ less than 10. (N < 0) This is the minimum number of other
+characters that must be met for a new password.
<item> <tt/use_authtok/ -
@@ -258,6 +264,39 @@ password required pam_pwdb.so use_authtok nullok md5
</verb>
</tscreen>
+<p>
+And here is another example in case you don't want to use credits:
+<tscreen>
+<verb>
+#%PAM-1.0
+#
+# These lines require the user to select a password with a minimum
+# length of 8 and with at least 1 digit number, 1 upper case letter,
+# and 1 other character
+#
+password required pam_cracklib.so \
+ dcredit=-1 ucredit=-1 ocredit=-1 lcredit=0 minlen=8
+password required pam_pwdb.so use_authtok nullok md5
+</verb>
+</tscreen>
+
+<p>
+In this example we simply say that the password must have a minimum
+length of 8:
+<tscreen>
+<verb>
+#%PAM-1.0
+#
+# These lines require the user to select a password with a mimimum
+# length of 8. He gets no credits and he is not forced to use
+# digit numbers, upper case letters etc.
+#
+password required pam_cracklib.so \
+ dcredit=0 ucredit=0 ocredit=0 lcredit=0 minlen=8
+password required pam_pwdb.so use_authtok nullok md5
+</verb>
+</tscreen>
+
</descrip>
<!--
diff --git a/modules/pam_cracklib/pam_cracklib.c b/modules/pam_cracklib/pam_cracklib.c
index 07725db7..1277619e 100644
--- a/modules/pam_cracklib/pam_cracklib.c
+++ b/modules/pam_cracklib/pam_cracklib.c
@@ -1,6 +1,11 @@
-/* pam_cracklib module */
+/*
+ * pam_cracklib module
+ * $Id$
+ */
/*
+ * 0.86. added support for setting minimum numbers of digits, uppers,
+ * lowers, and others
* 0.85. added six new options to use this with long passwords.
* 0.8. tidied output and improved D(()) usage for debugging.
* 0.7. added support for more obscure checks for new passwd.
@@ -142,19 +147,19 @@ static int _pam_parse(struct cracklib_options *opt, int argc, const char **argv)
opt->min_length = CO_MIN_LENGTH_BASE;
} else if (!strncmp(*argv,"dcredit=",8)) {
opt->dig_credit = strtol(*argv+8,&ep,10);
- if (!ep || (opt->dig_credit < 0))
+ if (!ep)
opt->dig_credit = 0;
} else if (!strncmp(*argv,"ucredit=",8)) {
opt->up_credit = strtol(*argv+8,&ep,10);
- if (!ep || (opt->up_credit < 0))
+ if (!ep)
opt->up_credit = 0;
} else if (!strncmp(*argv,"lcredit=",8)) {
opt->low_credit = strtol(*argv+8,&ep,10);
- if (!ep || (opt->low_credit < 0))
+ if (!ep)
opt->low_credit = 0;
} else if (!strncmp(*argv,"ocredit=",8)) {
opt->oth_credit = strtol(*argv+8,&ep,10);
- if (!ep || (opt->oth_credit < 0))
+ if (!ep)
opt->oth_credit = 0;
} else if (!strncmp(*argv,"use_authtok",11)) {
opt->use_authtok = 1;
@@ -268,54 +273,70 @@ static int similar(struct cracklib_options *opt,
*/
static int simple(struct cracklib_options *opt, const char *old, const char *new)
{
- int digits = 0;
- int uppers = 0;
- int lowers = 0;
- int others = 0;
- int size;
- int i;
-
- for (i = 0;new[i];i++) {
- if (isdigit (new[i]))
- digits++;
- else if (isupper (new[i]))
- uppers++;
- else if (islower (new[i]))
- lowers++;
- else
- others++;
- }
-
- /*
- * The scam was this - a password of only one character type
- * must be 8 letters long. Two types, 7, and so on.
- * This is now changed, the base size and the credits or defaults
- * see the docs on the module for info on these parameters, the
- * defaults cause the effect to be the same as before the change
- */
+ int digits = 0;
+ int uppers = 0;
+ int lowers = 0;
+ int others = 0;
+ int size;
+ int i;
+
+ for (i = 0;new[i];i++) {
+ if (isdigit (new[i]))
+ digits++;
+ else if (isupper (new[i]))
+ uppers++;
+ else if (islower (new[i]))
+ lowers++;
+ else
+ others++;
+ }
- if (digits > opt->dig_credit)
- digits = opt->dig_credit;
+ /*
+ * The scam was this - a password of only one character type
+ * must be 8 letters long. Two types, 7, and so on.
+ * This is now changed, the base size and the credits or defaults
+ * see the docs on the module for info on these parameters, the
+ * defaults cause the effect to be the same as before the change
+ */
- if (uppers > opt->up_credit)
- uppers = opt->up_credit;
+ if ((opt->dig_credit >= 0) && (digits > opt->dig_credit))
+ digits = opt->dig_credit;
- if (lowers > opt->low_credit)
- lowers = opt->low_credit;
+ if ((opt->up_credit >= 0) && (uppers > opt->up_credit))
+ uppers = opt->up_credit;
- if (others > opt->oth_credit)
- others = opt->oth_credit;
+ if ((opt->low_credit >= 0) && (lowers > opt->low_credit))
+ lowers = opt->low_credit;
- size = opt->min_length;
- size -= digits;
- size -= uppers;
- size -= lowers;
- size -= others;
+ if ((opt->oth_credit >= 0) && (others > opt->oth_credit))
+ others = opt->oth_credit;
- if (size <= i)
- return 0;
+ size = opt->min_length;
+ if (opt->dig_credit >= 0)
+ size -= digits;
+ else if (digits < opt->dig_credit * -1)
return 1;
+
+ if (opt->up_credit >= 0)
+ size -= uppers;
+ else if (uppers < opt->up_credit * -1)
+ return 1;
+
+ if (opt->low_credit >= 0)
+ size -= lowers;
+ else if (lowers < opt->low_credit * -1)
+ return 1;
+
+ if (opt->oth_credit >= 0)
+ size -= others;
+ else if (others < opt->oth_credit * -1)
+ return 1;
+
+ if (size <= i)
+ return 0;
+
+ return 1;
}
static char * str_lower(char *string)