e30408c5d9
- report failed logins from btmp in pam_lastlog - allow larger groups in modutil functions - fix leaked file descriptor in pam_tally
258 lines
7.8 KiB
Diff
258 lines
7.8 KiB
Diff
diff -up Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.8.xml.pwquality Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.8.xml
|
|
--- Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.8.xml.pwquality 2007-11-06 15:58:54.000000000 +0100
|
|
+++ Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.8.xml 2008-09-23 15:06:40.000000000 +0200
|
|
@@ -59,7 +59,7 @@
|
|
<term>Palindrome</term>
|
|
<listitem>
|
|
<para>
|
|
- Is the new password a palindrome of the old one?
|
|
+ Is the new password a palindrome?
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
@@ -120,6 +120,23 @@
|
|
</para>
|
|
</listitem>
|
|
</varlistentry>
|
|
+ <varlistentry>
|
|
+ <term>Same consecutive characters</term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ Optional check for same consecutive characters.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+ <varlistentry>
|
|
+ <term>Contains user name</term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ Optional check whether the password contains the user's name
|
|
+ in some form.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
</variablelist>
|
|
<para>
|
|
This module with no arguments will work well for standard unix
|
|
@@ -281,7 +298,7 @@
|
|
than 10.
|
|
</para>
|
|
<para>
|
|
- (N > 0) This is the minimum number of upper
|
|
+ (N < 0) This is the minimum number of upper
|
|
case letters that must be met for a new password.
|
|
</para>
|
|
</listitem>
|
|
@@ -349,6 +366,50 @@
|
|
|
|
<varlistentry>
|
|
<term>
|
|
+ <option>minclass=<replaceable>N</replaceable></option>
|
|
+ </term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ The minimum number of required classes of characters for
|
|
+ the new password. The default number is zero. The four
|
|
+ classes are digits, upper and lower letters and other
|
|
+ characters.
|
|
+ The difference to the <option>credit</option> check is
|
|
+ that a specific class if of characters is not required.
|
|
+ Instead <replaceable>N</replaceable> out of four of the
|
|
+ classes are required.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+
|
|
+ <varlistentry>
|
|
+ <term>
|
|
+ <option>maxrepeat=<replaceable>N</replaceable></option>
|
|
+ </term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ Reject passwords which contain more than N same consecutive
|
|
+ characters. The default is 0 which means that this check
|
|
+ is disabled.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+
|
|
+ <varlistentry>
|
|
+ <term>
|
|
+ <option>reject_username</option>
|
|
+ </term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ Check whether the name of the user in straight or reversed
|
|
+ form is contained in the new password. If it is found the
|
|
+ new password is rejected.
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+
|
|
+ <varlistentry>
|
|
+ <term>
|
|
<option>use_authtok</option>
|
|
</term>
|
|
<listitem>
|
|
@@ -495,7 +556,7 @@ password required pam_unix.so use_autht
|
|
<refentrytitle>pam.conf</refentrytitle><manvolnum>5</manvolnum>
|
|
</citerefentry>,
|
|
<citerefentry>
|
|
- <refentrytitle>pam.d</refentrytitle><manvolnum>8</manvolnum>
|
|
+ <refentrytitle>pam.d</refentrytitle><manvolnum>5</manvolnum>
|
|
</citerefentry>,
|
|
<citerefentry>
|
|
<refentrytitle>pam</refentrytitle><manvolnum>8</manvolnum>
|
|
diff -up Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.c.pwquality Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.c
|
|
--- Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.c.pwquality 2008-09-23 15:06:40.000000000 +0200
|
|
+++ Linux-PAM-1.0.2/modules/pam_cracklib/pam_cracklib.c 2008-09-23 15:10:14.000000000 +0200
|
|
@@ -99,6 +99,8 @@ struct cracklib_options {
|
|
int min_class;
|
|
int use_authtok;
|
|
int try_first_pass;
|
|
+ int max_repeat;
|
|
+ int reject_user;
|
|
char prompt_type[BUFSIZ];
|
|
const char *cracklib_dictpath;
|
|
};
|
|
@@ -166,8 +168,14 @@ _pam_parse (pam_handle_t *pamh, struct c
|
|
opt->min_class = strtol(*argv+9,&ep,10);
|
|
if (!ep)
|
|
opt->min_class = 0;
|
|
- if (opt->min_class > 4)
|
|
- opt->min_class = 4 ;
|
|
+ if (opt->min_class > 4)
|
|
+ opt->min_class = 4;
|
|
+ } else if (!strncmp(*argv,"maxrepeat=",10)) {
|
|
+ opt->max_repeat = strtol(*argv+10,&ep,10);
|
|
+ if (!ep)
|
|
+ opt->max_repeat = 0;
|
|
+ } else if (!strncmp(*argv,"reject_username",15)) {
|
|
+ opt->reject_user = 1;
|
|
} else if (!strncmp(*argv,"use_authtok",11)) {
|
|
opt->use_authtok = 1;
|
|
} else if (!strncmp(*argv,"use_first_pass",14)) {
|
|
@@ -418,6 +426,58 @@ static int simple(struct cracklib_option
|
|
return 1;
|
|
}
|
|
|
|
+static int consecutive(struct cracklib_options *opt, const char *new)
|
|
+{
|
|
+ char c;
|
|
+ int i;
|
|
+ int same;
|
|
+
|
|
+ if (opt->max_repeat == 0)
|
|
+ return 0;
|
|
+
|
|
+ for (i = 0; new[i]; i++) {
|
|
+ if (i > 0 && new[i] == c) {
|
|
+ ++same;
|
|
+ if (same > opt->max_repeat)
|
|
+ return 1;
|
|
+ } else {
|
|
+ c = new[i];
|
|
+ same = 1;
|
|
+ }
|
|
+ }
|
|
+ return 0;
|
|
+}
|
|
+
|
|
+static int usercheck(struct cracklib_options *opt, const char *new,
|
|
+ char *user)
|
|
+{
|
|
+ char *f, *b;
|
|
+
|
|
+ if (!opt->reject_user)
|
|
+ return 0;
|
|
+
|
|
+ if (strstr(new, user) != NULL)
|
|
+ return 1;
|
|
+
|
|
+ /* now reverse the username, we can do that in place
|
|
+ as it is strdup-ed */
|
|
+ f = user;
|
|
+ b = user+strlen(user)-1;
|
|
+ while (f < b) {
|
|
+ char c;
|
|
+
|
|
+ c = *f;
|
|
+ *f = *b;
|
|
+ *b = c;
|
|
+ --b;
|
|
+ ++f;
|
|
+ }
|
|
+
|
|
+ if (strstr(new, user) != NULL)
|
|
+ return 1;
|
|
+ return 0;
|
|
+}
|
|
+
|
|
static char * str_lower(char *string)
|
|
{
|
|
char *cp;
|
|
@@ -428,10 +488,12 @@ static char * str_lower(char *string)
|
|
}
|
|
|
|
static const char *password_check(struct cracklib_options *opt,
|
|
- const char *old, const char *new)
|
|
+ const char *old, const char *new,
|
|
+ const char *user)
|
|
{
|
|
const char *msg = NULL;
|
|
char *oldmono = NULL, *newmono, *wrapped = NULL;
|
|
+ char *usermono = NULL;
|
|
|
|
if (old && strcmp(new, old) == 0) {
|
|
msg = _("is the same as the old one");
|
|
@@ -439,6 +501,7 @@ static const char *password_check(struct
|
|
}
|
|
|
|
newmono = str_lower(x_strdup(new));
|
|
+ usermono = str_lower(x_strdup(user));
|
|
if (old) {
|
|
oldmono = str_lower(x_strdup(old));
|
|
wrapped = malloc(strlen(oldmono) * 2 + 1);
|
|
@@ -464,8 +527,15 @@ static const char *password_check(struct
|
|
if (!msg && minclass (opt, new))
|
|
msg = _("not enough character classes");
|
|
|
|
+ if (!msg && consecutive(opt, new))
|
|
+ msg = _("contains too many same characters consecutively");
|
|
+
|
|
+ if (!msg && usercheck(opt, newmono, usermono))
|
|
+ msg = _("contains the user name in some form");
|
|
+
|
|
memset(newmono, 0, strlen(newmono));
|
|
free(newmono);
|
|
+ free(usermono);
|
|
if (old) {
|
|
memset(oldmono, 0, strlen(oldmono));
|
|
memset(wrapped, 0, strlen(wrapped));
|
|
@@ -532,18 +602,18 @@ static int _pam_unix_approve_pass(pam_ha
|
|
return PAM_AUTHTOK_ERR;
|
|
}
|
|
|
|
+ retval = pam_get_item(pamh, PAM_USER, &user);
|
|
+ if (retval != PAM_SUCCESS || user == NULL) {
|
|
+ if (ctrl & PAM_DEBUG_ARG)
|
|
+ pam_syslog(pamh,LOG_ERR,"Can not get username");
|
|
+ return PAM_AUTHTOK_ERR;
|
|
+ }
|
|
/*
|
|
* if one wanted to hardwire authentication token strength
|
|
* checking this would be the place
|
|
*/
|
|
- msg = password_check(opt, pass_old, pass_new);
|
|
+ msg = password_check(opt, pass_old, pass_new, user);
|
|
if (!msg) {
|
|
- retval = pam_get_item(pamh, PAM_USER, &user);
|
|
- if (retval != PAM_SUCCESS || user == NULL) {
|
|
- if (ctrl & PAM_DEBUG_ARG)
|
|
- pam_syslog(pamh,LOG_ERR,"Can not get username");
|
|
- return PAM_AUTHTOK_ERR;
|
|
- }
|
|
msg = check_old_password(user, pass_new);
|
|
}
|
|
|