- new password quality checks in pam_cracklib
- report failed logins from btmp in pam_lastlog - allow larger groups in modutil functions - fix leaked file descriptor in pam_tally
This commit is contained in:
parent
8955a466b5
commit
e30408c5d9
285
pam-0.99.6.2-lastlog-failed.patch
Normal file
285
pam-0.99.6.2-lastlog-failed.patch
Normal file
@ -0,0 +1,285 @@
|
|||||||
|
diff -up Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.c.failed Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.c
|
||||||
|
--- Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.c.failed 2006-08-24 20:03:44.000000000 +0200
|
||||||
|
+++ Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.c 2008-09-12 21:21:42.000000000 +0200
|
||||||
|
@@ -46,6 +46,10 @@ struct lastlog {
|
||||||
|
};
|
||||||
|
#endif /* hpux */
|
||||||
|
|
||||||
|
+#ifndef _PATH_BTMP
|
||||||
|
+# define _PATH_BTMP "/var/log/btmp"
|
||||||
|
+#endif
|
||||||
|
+
|
||||||
|
/* XXX - time before ignoring lock. Is 1 sec enough? */
|
||||||
|
#define LASTLOG_IGNORE_LOCK_TIME 1
|
||||||
|
|
||||||
|
@@ -75,11 +79,13 @@ struct lastlog {
|
||||||
|
#define LASTLOG_DEBUG 020 /* send info to syslog(3) */
|
||||||
|
#define LASTLOG_QUIET 040 /* keep quiet about things */
|
||||||
|
#define LASTLOG_WTMP 0100 /* log to wtmp as well as lastlog */
|
||||||
|
+#define LASTLOG_BTMP 0200 /* display failed login info from btmp */
|
||||||
|
+#define LASTLOG_UPDATE 0400 /* update the lastlog and wtmp files (default) */
|
||||||
|
|
||||||
|
static int
|
||||||
|
_pam_parse(pam_handle_t *pamh, int flags, int argc, const char **argv)
|
||||||
|
{
|
||||||
|
- int ctrl=(LASTLOG_DATE|LASTLOG_HOST|LASTLOG_LINE|LASTLOG_WTMP);
|
||||||
|
+ int ctrl=(LASTLOG_DATE|LASTLOG_HOST|LASTLOG_LINE|LASTLOG_WTMP|LASTLOG_UPDATE);
|
||||||
|
|
||||||
|
/* does the appliction require quiet? */
|
||||||
|
if (flags & PAM_SILENT) {
|
||||||
|
@@ -105,6 +111,10 @@ _pam_parse(pam_handle_t *pamh, int flags
|
||||||
|
ctrl |= LASTLOG_NEVER;
|
||||||
|
} else if (!strcmp(*argv,"nowtmp")) {
|
||||||
|
ctrl &= ~LASTLOG_WTMP;
|
||||||
|
+ } else if (!strcmp(*argv,"noupdate")) {
|
||||||
|
+ ctrl &= ~(LASTLOG_WTMP|LASTLOG_UPDATE);
|
||||||
|
+ } else if (!strcmp(*argv,"showfailed")) {
|
||||||
|
+ ctrl |= LASTLOG_BTMP;
|
||||||
|
} else {
|
||||||
|
pam_syslog(pamh, LOG_ERR, "unknown option: %s", *argv);
|
||||||
|
}
|
||||||
|
@@ -135,7 +145,7 @@ get_tty(pam_handle_t *pamh)
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-last_login_read(pam_handle_t *pamh, int announce, int last_fd, uid_t uid)
|
||||||
|
+last_login_read(pam_handle_t *pamh, int announce, int last_fd, uid_t uid, time_t *lltime)
|
||||||
|
{
|
||||||
|
struct flock last_lock;
|
||||||
|
struct lastlog last_login;
|
||||||
|
@@ -166,6 +176,7 @@ last_login_read(pam_handle_t *pamh, int
|
||||||
|
last_lock.l_type = F_UNLCK;
|
||||||
|
(void) fcntl(last_fd, F_SETLK, &last_lock); /* unlock */
|
||||||
|
|
||||||
|
+ *lltime = last_login.ll_time;
|
||||||
|
if (!last_login.ll_time) {
|
||||||
|
if (announce & LASTLOG_DEBUG) {
|
||||||
|
pam_syslog(pamh, LOG_DEBUG,
|
||||||
|
@@ -320,13 +331,13 @@ last_login_write(pam_handle_t *pamh, int
|
||||||
|
}
|
||||||
|
|
||||||
|
static int
|
||||||
|
-last_login_date(pam_handle_t *pamh, int announce, uid_t uid, const char *user)
|
||||||
|
+last_login_date(pam_handle_t *pamh, int announce, uid_t uid, const char *user, time_t *lltime)
|
||||||
|
{
|
||||||
|
int retval;
|
||||||
|
int last_fd;
|
||||||
|
|
||||||
|
/* obtain the last login date and all the relevant info */
|
||||||
|
- last_fd = open(_PATH_LASTLOG, O_RDWR);
|
||||||
|
+ last_fd = open(_PATH_LASTLOG, announce&LASTLOG_UPDATE ? O_RDWR : O_RDONLY);
|
||||||
|
if (last_fd < 0) {
|
||||||
|
if (errno == ENOENT) {
|
||||||
|
last_fd = open(_PATH_LASTLOG, O_RDWR|O_CREAT,
|
||||||
|
@@ -353,7 +364,7 @@ last_login_date(pam_handle_t *pamh, int
|
||||||
|
return PAM_SERVICE_ERR;
|
||||||
|
}
|
||||||
|
|
||||||
|
- retval = last_login_read(pamh, announce, last_fd, uid);
|
||||||
|
+ retval = last_login_read(pamh, announce, last_fd, uid, lltime);
|
||||||
|
if (retval != PAM_SUCCESS)
|
||||||
|
{
|
||||||
|
close(last_fd);
|
||||||
|
@@ -361,7 +372,9 @@ last_login_date(pam_handle_t *pamh, int
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
- retval = last_login_write(pamh, announce, last_fd, uid, user);
|
||||||
|
+ if (announce & LASTLOG_UPDATE) {
|
||||||
|
+ retval = last_login_write(pamh, announce, last_fd, uid, user);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
close(last_fd);
|
||||||
|
D(("all done with last login"));
|
||||||
|
@@ -369,6 +382,116 @@ last_login_date(pam_handle_t *pamh, int
|
||||||
|
return retval;
|
||||||
|
}
|
||||||
|
|
||||||
|
+static int
|
||||||
|
+last_login_failed(pam_handle_t *pamh, int announce, const char *user, time_t lltime)
|
||||||
|
+{
|
||||||
|
+ int retval;
|
||||||
|
+ int fd;
|
||||||
|
+ struct utmp ut;
|
||||||
|
+ struct utmp utuser;
|
||||||
|
+ int failed = 0;
|
||||||
|
+ char the_time[256];
|
||||||
|
+ char *date = NULL;
|
||||||
|
+ char *host = NULL;
|
||||||
|
+ char *line = NULL;
|
||||||
|
+
|
||||||
|
+ if (strlen(user) > UT_NAMESIZE) {
|
||||||
|
+ pam_syslog(pamh, LOG_WARNING, "username too long, output might be inaccurate");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* obtain the failed login attempt records from btmp */
|
||||||
|
+ fd = open(_PATH_BTMP, O_RDONLY);
|
||||||
|
+ if (fd < 0) {
|
||||||
|
+ pam_syslog(pamh, LOG_ERR, "unable to open %s: %m", _PATH_BTMP);
|
||||||
|
+ D(("unable to open %s file", _PATH_BTMP));
|
||||||
|
+ return PAM_SERVICE_ERR;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ while ((retval=pam_modutil_read(fd, (void *)&ut,
|
||||||
|
+ sizeof(ut))) == sizeof(ut)) {
|
||||||
|
+ if (ut.ut_tv.tv_sec >= lltime && strncmp(ut.ut_user, user, UT_NAMESIZE) == 0) {
|
||||||
|
+ memcpy(&utuser, &ut, sizeof(utuser));
|
||||||
|
+ failed++;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (failed) {
|
||||||
|
+ /* we want the date? */
|
||||||
|
+ if (announce & LASTLOG_DATE) {
|
||||||
|
+ struct tm *tm, tm_buf;
|
||||||
|
+ time_t lf_time;
|
||||||
|
+
|
||||||
|
+ lf_time = utuser.ut_tv.tv_sec;
|
||||||
|
+ tm = localtime_r (&lf_time, &tm_buf);
|
||||||
|
+ strftime (the_time, sizeof (the_time),
|
||||||
|
+ /* TRANSLATORS: "strftime options for date of last login" */
|
||||||
|
+ _(" %a %b %e %H:%M:%S %Z %Y"), tm);
|
||||||
|
+
|
||||||
|
+ date = the_time;
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* we want & have the host? */
|
||||||
|
+ if ((announce & LASTLOG_HOST)
|
||||||
|
+ && (utuser.ut_host[0] != '\0')) {
|
||||||
|
+ /* TRANSLATORS: " from <host>" */
|
||||||
|
+ if (asprintf(&host, _(" from %.*s"), UT_HOSTSIZE,
|
||||||
|
+ utuser.ut_host) < 0) {
|
||||||
|
+ pam_syslog(pamh, LOG_ERR, "out of memory");
|
||||||
|
+ retval = PAM_BUF_ERR;
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ /* we want and have the terminal? */
|
||||||
|
+ if ((announce & LASTLOG_LINE)
|
||||||
|
+ && (utuser.ut_line[0] != '\0')) {
|
||||||
|
+ /* TRANSLATORS: " on <terminal>" */
|
||||||
|
+ if (asprintf(&line, _(" on %.*s"), UT_LINESIZE,
|
||||||
|
+ utuser.ut_line) < 0) {
|
||||||
|
+ pam_syslog(pamh, LOG_ERR, "out of memory");
|
||||||
|
+ retval = PAM_BUF_ERR;
|
||||||
|
+ goto cleanup;
|
||||||
|
+ }
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ if (announce & (LASTLOG_LINE|LASTLOG_DATE|LASTLOG_HOST)) {
|
||||||
|
+ /* TRANSLATORS: "Last failed login: <date> from <host> on <terminal>" */
|
||||||
|
+ pam_info(pamh, _("Last failed login:%s%s%s"),
|
||||||
|
+ date ? date : "",
|
||||||
|
+ host ? host : "",
|
||||||
|
+ line ? line : "");
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+ _pam_drop(line);
|
||||||
|
+#if defined HAVE_DNGETTEXT && defined ENABLE_NLS
|
||||||
|
+ asprintf (&line, dngettext(PACKAGE,
|
||||||
|
+ "There was %d failed login attempt since the last successful login.",
|
||||||
|
+ "There were %d failed login attempts since the last successful login.",
|
||||||
|
+ failed),
|
||||||
|
+ failed);
|
||||||
|
+#else
|
||||||
|
+ if (daysleft == 1)
|
||||||
|
+ asprintf(&line,
|
||||||
|
+ _("There was %d failed login attempt since the last successful login."),
|
||||||
|
+ failed);
|
||||||
|
+ else
|
||||||
|
+ asprintf(&line,
|
||||||
|
+ /* TRANSLATORS: only used if dngettext is not supported */
|
||||||
|
+ _("There were %d failed login attempts since the last successful login."),
|
||||||
|
+ failed);
|
||||||
|
+#endif
|
||||||
|
+ retval = pam_info(pamh, "%s", line);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
+cleanup:
|
||||||
|
+ free(host);
|
||||||
|
+ free(line);
|
||||||
|
+ close(fd);
|
||||||
|
+ D(("all done with btmp"));
|
||||||
|
+
|
||||||
|
+ return retval;
|
||||||
|
+}
|
||||||
|
+
|
||||||
|
/* --- authentication management functions (only) --- */
|
||||||
|
|
||||||
|
PAM_EXTERN int
|
||||||
|
@@ -379,6 +502,7 @@ pam_sm_open_session(pam_handle_t *pamh,
|
||||||
|
const void *user;
|
||||||
|
const struct passwd *pwd;
|
||||||
|
uid_t uid;
|
||||||
|
+ time_t lltime = 0;
|
||||||
|
|
||||||
|
/*
|
||||||
|
* this module gets the uid of the PAM_USER. Uses it to display
|
||||||
|
@@ -407,7 +531,11 @@ pam_sm_open_session(pam_handle_t *pamh,
|
||||||
|
|
||||||
|
/* process the current login attempt (indicate last) */
|
||||||
|
|
||||||
|
- retval = last_login_date(pamh, ctrl, uid, user);
|
||||||
|
+ retval = last_login_date(pamh, ctrl, uid, user, &lltime);
|
||||||
|
+
|
||||||
|
+ if ((ctrl & LASTLOG_BTMP) && retval == PAM_SUCCESS) {
|
||||||
|
+ retval = last_login_failed(pamh, ctrl, user, lltime);
|
||||||
|
+ }
|
||||||
|
|
||||||
|
/* indicate success or failure */
|
||||||
|
|
||||||
|
diff -up Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.8.xml.failed Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.8.xml
|
||||||
|
--- Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.8.xml.failed 2006-06-09 18:44:07.000000000 +0200
|
||||||
|
+++ Linux-PAM-0.99.6.2/modules/pam_lastlog/pam_lastlog.8.xml 2008-09-12 21:12:35.000000000 +0200
|
||||||
|
@@ -39,6 +39,12 @@
|
||||||
|
<arg choice="opt">
|
||||||
|
nowtmp
|
||||||
|
</arg>
|
||||||
|
+ <arg choice="opt">
|
||||||
|
+ noupdate
|
||||||
|
+ </arg>
|
||||||
|
+ <arg choice="opt">
|
||||||
|
+ showfailed
|
||||||
|
+ </arg>
|
||||||
|
</cmdsynopsis>
|
||||||
|
</refsynopsisdiv>
|
||||||
|
|
||||||
|
@@ -137,6 +143,28 @@
|
||||||
|
</para>
|
||||||
|
</listitem>
|
||||||
|
</varlistentry>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term>
|
||||||
|
+ <option>noupdate</option>
|
||||||
|
+ </term>
|
||||||
|
+ <listitem>
|
||||||
|
+ <para>
|
||||||
|
+ Don't update any file.
|
||||||
|
+ </para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
+ <varlistentry>
|
||||||
|
+ <term>
|
||||||
|
+ <option>showfailed</option>
|
||||||
|
+ </term>
|
||||||
|
+ <listitem>
|
||||||
|
+ <para>
|
||||||
|
+ Display number of failed login attempts and the date of the
|
||||||
|
+ last failed attempt from btmp. The date is not displayed
|
||||||
|
+ when <option>nodate</option> is specified.
|
||||||
|
+ </para>
|
||||||
|
+ </listitem>
|
||||||
|
+ </varlistentry>
|
||||||
|
</variablelist>
|
||||||
|
</refsect1>
|
||||||
|
|
||||||
|
@@ -213,7 +241,7 @@
|
||||||
|
<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>
|
257
pam-1.0.2-cracklib-pwquality.patch
Normal file
257
pam-1.0.2-cracklib-pwquality.patch
Normal file
@ -0,0 +1,257 @@
|
|||||||
|
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);
|
||||||
|
}
|
||||||
|
|
75
pam-1.0.2-many-groups.patch
Normal file
75
pam-1.0.2-many-groups.patch
Normal file
@ -0,0 +1,75 @@
|
|||||||
|
diff -up Linux-PAM-1.0.2/libpam/pam_modutil_getpwnam.c.many-groups Linux-PAM-1.0.2/libpam/pam_modutil_getpwnam.c
|
||||||
|
--- Linux-PAM-1.0.2/libpam/pam_modutil_getpwnam.c.many-groups 2007-08-30 06:00:39.000000000 +0200
|
||||||
|
+++ Linux-PAM-1.0.2/libpam/pam_modutil_getpwnam.c 2008-09-23 15:59:46.000000000 +0200
|
||||||
|
@@ -104,7 +104,7 @@ pam_modutil_getpwnam(pam_handle_t *pamh,
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- length <<= 2;
|
||||||
|
+ length <<= PWD_LENGTH_SHIFT;
|
||||||
|
|
||||||
|
} while (length < PWD_ABSURD_PWD_LENGTH);
|
||||||
|
|
||||||
|
diff -up Linux-PAM-1.0.2/libpam/pam_modutil_getpwuid.c.many-groups Linux-PAM-1.0.2/libpam/pam_modutil_getpwuid.c
|
||||||
|
--- Linux-PAM-1.0.2/libpam/pam_modutil_getpwuid.c.many-groups 2007-08-30 06:00:39.000000000 +0200
|
||||||
|
+++ Linux-PAM-1.0.2/libpam/pam_modutil_getpwuid.c 2008-09-23 15:59:59.000000000 +0200
|
||||||
|
@@ -115,7 +115,7 @@ pam_modutil_getpwuid(pam_handle_t *pamh,
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- length <<= 2;
|
||||||
|
+ length <<= PWD_LENGTH_SHIFT;
|
||||||
|
|
||||||
|
} while (length < PWD_ABSURD_PWD_LENGTH);
|
||||||
|
|
||||||
|
diff -up Linux-PAM-1.0.2/libpam/pam_modutil_getgrnam.c.many-groups Linux-PAM-1.0.2/libpam/pam_modutil_getgrnam.c
|
||||||
|
--- Linux-PAM-1.0.2/libpam/pam_modutil_getgrnam.c.many-groups 2007-08-30 06:00:39.000000000 +0200
|
||||||
|
+++ Linux-PAM-1.0.2/libpam/pam_modutil_getgrnam.c 2008-09-23 15:59:29.000000000 +0200
|
||||||
|
@@ -104,7 +104,7 @@ pam_modutil_getgrnam(pam_handle_t *pamh,
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- length <<= 2;
|
||||||
|
+ length <<= PWD_LENGTH_SHIFT;
|
||||||
|
|
||||||
|
} while (length < PWD_ABSURD_PWD_LENGTH);
|
||||||
|
|
||||||
|
diff -up Linux-PAM-1.0.2/libpam/pam_modutil_getspnam.c.many-groups Linux-PAM-1.0.2/libpam/pam_modutil_getspnam.c
|
||||||
|
--- Linux-PAM-1.0.2/libpam/pam_modutil_getspnam.c.many-groups 2007-08-30 06:00:39.000000000 +0200
|
||||||
|
+++ Linux-PAM-1.0.2/libpam/pam_modutil_getspnam.c 2008-09-23 16:00:11.000000000 +0200
|
||||||
|
@@ -104,7 +104,7 @@ pam_modutil_getspnam(pam_handle_t *pamh,
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- length <<= 2;
|
||||||
|
+ length <<= PWD_LENGTH_SHIFT;
|
||||||
|
|
||||||
|
} while (length < PWD_ABSURD_PWD_LENGTH);
|
||||||
|
|
||||||
|
diff -up Linux-PAM-1.0.2/libpam/pam_modutil_getgrgid.c.many-groups Linux-PAM-1.0.2/libpam/pam_modutil_getgrgid.c
|
||||||
|
--- Linux-PAM-1.0.2/libpam/pam_modutil_getgrgid.c.many-groups 2007-08-30 06:00:39.000000000 +0200
|
||||||
|
+++ Linux-PAM-1.0.2/libpam/pam_modutil_getgrgid.c 2008-09-23 15:59:07.000000000 +0200
|
||||||
|
@@ -115,7 +115,7 @@ pam_modutil_getgrgid(pam_handle_t *pamh,
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
- length <<= 2;
|
||||||
|
+ length <<= PWD_LENGTH_SHIFT;
|
||||||
|
|
||||||
|
} while (length < PWD_ABSURD_PWD_LENGTH);
|
||||||
|
|
||||||
|
diff -up Linux-PAM-1.0.2/libpam/pam_modutil_private.h.many-groups Linux-PAM-1.0.2/libpam/pam_modutil_private.h
|
||||||
|
--- Linux-PAM-1.0.2/libpam/pam_modutil_private.h.many-groups 2005-09-21 12:00:58.000000000 +0200
|
||||||
|
+++ Linux-PAM-1.0.2/libpam/pam_modutil_private.h 2008-09-23 16:00:30.000000000 +0200
|
||||||
|
@@ -13,8 +13,9 @@
|
||||||
|
#include <security/pam_modules.h>
|
||||||
|
#include <security/pam_modutil.h>
|
||||||
|
|
||||||
|
-#define PWD_INITIAL_LENGTH 0x100
|
||||||
|
-#define PWD_ABSURD_PWD_LENGTH 0x8000
|
||||||
|
+#define PWD_INITIAL_LENGTH 0x400
|
||||||
|
+#define PWD_ABSURD_PWD_LENGTH 0x40001
|
||||||
|
+#define PWD_LENGTH_SHIFT 4 /* 2^4 == 16 */
|
||||||
|
|
||||||
|
extern void
|
||||||
|
pam_modutil_cleanup(pam_handle_t *pamh, void *data,
|
36
pam-1.0.2-tally-fdleak.patch
Normal file
36
pam-1.0.2-tally-fdleak.patch
Normal file
@ -0,0 +1,36 @@
|
|||||||
|
Index: pam_tally.c
|
||||||
|
===================================================================
|
||||||
|
RCS file: /cvsroot/pam/Linux-PAM/modules/pam_tally/pam_tally.c,v
|
||||||
|
retrieving revision 1.30
|
||||||
|
diff -u -p -r1.30 pam_tally.c
|
||||||
|
--- pam/modules/pam_tally/pam_tally.c 9 Jul 2008 12:23:23 -0000 1.30
|
||||||
|
+++ pam/modules/pam_tally/pam_tally.c 19 Sep 2008 12:29:21 -0000
|
||||||
|
@@ -350,7 +350,7 @@ get_tally(pam_handle_t *pamh, tally_t *t
|
||||||
|
}
|
||||||
|
|
||||||
|
if ( ! ( *TALLY = fopen(filename,(*tally!=TALLY_HI)?"r+":"r") ) ) {
|
||||||
|
- pam_syslog(pamh, LOG_ALERT, "Error opening %s for update", filename);
|
||||||
|
+ pam_syslog(pamh, LOG_ALERT, "Error opening %s for %s", filename, *tally!=TALLY_HI?"update":"read");
|
||||||
|
|
||||||
|
/* Discovering why account service fails: e/uid are target user.
|
||||||
|
*
|
||||||
|
@@ -504,7 +504,7 @@ tally_check (time_t oldtime, pam_handle_
|
||||||
|
tally_t
|
||||||
|
deny = opts->deny;
|
||||||
|
tally_t
|
||||||
|
- tally = 0; /* !TALLY_HI --> Log opened for update */
|
||||||
|
+ tally = TALLY_HI;
|
||||||
|
long
|
||||||
|
lock_time = opts->lock_time;
|
||||||
|
|
||||||
|
@@ -515,6 +515,10 @@ tally_check (time_t oldtime, pam_handle_
|
||||||
|
i=get_tally(pamh, &tally, uid, opts->filename, &TALLY, fsp);
|
||||||
|
if ( i != PAM_SUCCESS ) { RETURN_ERROR( i ); }
|
||||||
|
|
||||||
|
+ if ( TALLY != NULL ) {
|
||||||
|
+ fclose(TALLY);
|
||||||
|
+ }
|
||||||
|
+
|
||||||
|
if ( !(opts->ctrl & OPT_MAGIC_ROOT) || getuid() ) { /* magic_root skips tally check */
|
||||||
|
|
||||||
|
/* To deny or not to deny; that is the question */
|
16
pam.spec
16
pam.spec
@ -3,7 +3,7 @@
|
|||||||
Summary: A security tool which provides authentication for applications
|
Summary: A security tool which provides authentication for applications
|
||||||
Name: pam
|
Name: pam
|
||||||
Version: 1.0.2
|
Version: 1.0.2
|
||||||
Release: 1%{?dist}
|
Release: 2%{?dist}
|
||||||
# The library is BSD licensed with option to relicense as GPLv2+ - this option is redundant
|
# The library is BSD licensed with option to relicense as GPLv2+ - this option is redundant
|
||||||
# as the BSD license allows that anyway. pam_timestamp and pam_console modules are GPLv2+,
|
# as the BSD license allows that anyway. pam_timestamp and pam_console modules are GPLv2+,
|
||||||
# pam_rhosts_auth module is BSD with advertising
|
# pam_rhosts_auth module is BSD with advertising
|
||||||
@ -27,7 +27,11 @@ Patch21: pam-0.99.10.0-unix-audit-failed.patch
|
|||||||
Patch22: pam-1.0.1-unix-prompts.patch
|
Patch22: pam-1.0.1-unix-prompts.patch
|
||||||
Patch31: pam-1.0.1-cracklib-try-first-pass.patch
|
Patch31: pam-1.0.1-cracklib-try-first-pass.patch
|
||||||
Patch32: pam-1.0.1-tally-fail-close.patch
|
Patch32: pam-1.0.1-tally-fail-close.patch
|
||||||
|
Patch33: pam-1.0.2-tally-fdleak.patch
|
||||||
Patch41: pam-1.0.1-namespace-create.patch
|
Patch41: pam-1.0.1-namespace-create.patch
|
||||||
|
Patch42: pam-1.0.2-cracklib-pwquality.patch
|
||||||
|
Patch43: pam-0.99.6.2-lastlog-failed.patch
|
||||||
|
Patch44: pam-1.0.2-many-groups.patch
|
||||||
|
|
||||||
%define _sbindir /sbin
|
%define _sbindir /sbin
|
||||||
%define _moduledir /%{_lib}/security
|
%define _moduledir /%{_lib}/security
|
||||||
@ -97,7 +101,11 @@ mv pam-redhat-%{pam_redhat_version}/* modules
|
|||||||
%patch22 -p1 -b .prompts
|
%patch22 -p1 -b .prompts
|
||||||
%patch31 -p1 -b .try-first-pass
|
%patch31 -p1 -b .try-first-pass
|
||||||
%patch32 -p1 -b .fail-close
|
%patch32 -p1 -b .fail-close
|
||||||
|
%patch33 -p1 -b .fdleak
|
||||||
%patch41 -p1 -b .create
|
%patch41 -p1 -b .create
|
||||||
|
%patch42 -p1 -b .pwquality
|
||||||
|
%patch43 -p1 -b .failed
|
||||||
|
%patch44 -p1 -b .many-groups
|
||||||
|
|
||||||
autoreconf
|
autoreconf
|
||||||
|
|
||||||
@ -327,6 +335,12 @@ fi
|
|||||||
%doc doc/adg/*.txt doc/adg/html
|
%doc doc/adg/*.txt doc/adg/html
|
||||||
|
|
||||||
%changelog
|
%changelog
|
||||||
|
* Tue Sep 23 2008 Tomas Mraz <tmraz@redhat.com> 1.0.2-2
|
||||||
|
- new password quality checks in pam_cracklib
|
||||||
|
- report failed logins from btmp in pam_lastlog
|
||||||
|
- allow larger groups in modutil functions
|
||||||
|
- fix leaked file descriptor in pam_tally
|
||||||
|
|
||||||
* Mon Sep 8 2008 Tomas Mraz <tmraz@redhat.com> 1.0.2-1
|
* Mon Sep 8 2008 Tomas Mraz <tmraz@redhat.com> 1.0.2-1
|
||||||
- pam_loginuid: uids are unsigned (#460241)
|
- pam_loginuid: uids are unsigned (#460241)
|
||||||
- new minor upstream release
|
- new minor upstream release
|
||||||
|
Loading…
Reference in New Issue
Block a user