diff options
Diffstat (limited to 'debian/patches-applied/007_modules_pam_unix')
-rw-r--r-- | debian/patches-applied/007_modules_pam_unix | 712 |
1 files changed, 712 insertions, 0 deletions
diff --git a/debian/patches-applied/007_modules_pam_unix b/debian/patches-applied/007_modules_pam_unix new file mode 100644 index 00000000..a0c1857a --- /dev/null +++ b/debian/patches-applied/007_modules_pam_unix @@ -0,0 +1,712 @@ +Index: pam.deb/modules/pam_unix/pam_unix_passwd.c +=================================================================== +--- pam.deb.orig/modules/pam_unix/pam_unix_passwd.c ++++ pam.deb/modules/pam_unix/pam_unix_passwd.c +@@ -87,6 +87,9 @@ + unsigned long versnum, unsigned int proto); + #endif /* GNU libc 2.1 */ + ++extern const char *obscure_msg(const char *, const char *, const struct passwd *, ++ unsigned int); ++ + /* + How it works: + Gets in username (has to be done) from the calling program +@@ -457,7 +460,8 @@ + 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,7 +492,7 @@ + } + } + if (off(UNIX__IAMROOT, ctrl)) { +- if (strlen(pass_new) < 6) ++ 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)) { +@@ -500,6 +504,11 @@ + return retval; + } + } ++ if (!remark && pass_old != NULL) { /* only check if we don't already have a failure */ ++ struct passwd *pwd; ++ pwd = pam_modutil_getpwnam(pamh, user); ++ remark = (char *)obscure_msg(pass_old,pass_new,pwd,ctrl); /* do obscure checks */ ++ } + } + if (remark) { + _make_remark(pamh, ctrl, PAM_ERROR_MSG, remark); +@@ -516,6 +525,7 @@ + int retval; + int remember = -1; + int rounds = -1; ++ int pass_min_len = 6; + + /* <DO NOT free() THESE> */ + const char *user; +@@ -524,7 +534,8 @@ + + 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 +@@ -724,7 +735,8 @@ + 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); +@@ -757,7 +769,8 @@ + 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: pam.deb/modules/pam_unix/pam_unix_acct.c +=================================================================== +--- pam.deb.orig/modules/pam_unix/pam_unix_acct.c ++++ pam.deb/modules/pam_unix/pam_unix_acct.c +@@ -191,7 +191,7 @@ + + 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: pam.deb/modules/pam_unix/support.c +=================================================================== +--- pam.deb.orig/modules/pam_unix/support.c ++++ pam.deb/modules/pam_unix/support.c +@@ -55,7 +55,7 @@ + */ + + 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; + +@@ -81,6 +81,7 @@ + D(("SILENT")); + set(UNIX__QUIET, ctrl); + } ++ + /* now parse the arguments to this module */ + + while (argc-- > 0) { +@@ -90,7 +91,8 @@ + + for (j = 0; j < UNIX_CTRLS_; ++j) { + if (unix_args[j].token +- && !strncmp(*argv, unix_args[j].token, strlen(unix_args[j].token))) { ++ && !strncmp(*argv, unix_args[j].token, strlen(unix_args[j].token))) ++ { + break; + } + } +@@ -102,15 +104,16 @@ + 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 + 4); ++ } + if (rounds != NULL && j == UNIX_ALGO_ROUNDS) + *rounds = strtol(*argv + 7, NULL, 10); + } +@@ -118,6 +121,10 @@ + ++argv; /* step to next argument */ + } + ++ if (off(UNIX_HASH_MASK,ctrl) ++ && pass_min_len && *pass_min_len > 8) ++ *pass_min_len = 8; ++ + if (flags & PAM_DISALLOW_NULL_AUTHTOK) { + D(("DISALLOW_NULL_AUTHTOK")); + set(UNIX__NONULL, ctrl); +Index: pam.deb/modules/pam_unix/support.h +=================================================================== +--- pam.deb.orig/modules/pam_unix/support.h ++++ pam.deb/modules/pam_unix/support.h +@@ -89,41 +89,49 @@ + #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_MAX_PASS_LEN 27 /* internal, for compatibility only */ ++#define UNIX_MIN_PASS_LEN 28 /* min length for password */ ++#define UNIX_OBSCURE_CHECKS 29 /* enable obscure checks on passwords */ + /* -------------- */ +-#define UNIX_CTRLS_ 27 /* number of ctrl arguments defined */ ++#define UNIX_CTRLS_ 30 /* number of ctrl arguments defined */ ++ ++#define UNIX_HASH_MASK (UNIX_MD5_PASS|UNIX_BIGCRYPT|UNIX_SHA256_PASS|UNIX_SHA512_PASS|UNIX_BLOWFISH_PASS) + + static const UNIX_Ctrls unix_args[UNIX_CTRLS_] = + { + /* symbol token name ctrl mask ctrl * + * ----------------------- ------------------- --------------------- -------- */ + +-/* UNIX__OLD_PASSWD */ {NULL, _ALL_ON_, 01}, +-/* UNIX__VERIFY_PASSWD */ {NULL, _ALL_ON_, 02}, +-/* UNIX__IAMROOT */ {NULL, _ALL_ON_, 04}, +-/* UNIX_AUDIT */ {"audit", _ALL_ON_, 010}, +-/* UNIX_USE_FIRST_PASS */ {"use_first_pass", _ALL_ON_^(060), 020}, +-/* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(060), 040}, +-/* UNIX_NOT_SET_PASS */ {"not_set_pass", _ALL_ON_, 0100}, +-/* UNIX__PRELIM */ {NULL, _ALL_ON_^(0600), 0200}, +-/* UNIX__UPDATE */ {NULL, _ALL_ON_^(0600), 0400}, +-/* UNIX__NONULL */ {NULL, _ALL_ON_, 01000}, +-/* UNIX__QUIET */ {NULL, _ALL_ON_, 02000}, +-/* UNIX_USE_AUTHTOK */ {"use_authtok", _ALL_ON_, 04000}, +-/* UNIX_SHADOW */ {"shadow", _ALL_ON_, 010000}, +-/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(0260420000), 020000}, +-/* UNIX__NULLOK */ {"nullok", _ALL_ON_^(01000), 0}, +-/* UNIX_DEBUG */ {"debug", _ALL_ON_, 040000}, +-/* UNIX_NODELAY */ {"nodelay", _ALL_ON_, 0100000}, +-/* UNIX_NIS */ {"nis", _ALL_ON_, 0200000}, +-/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(0260420000), 0400000}, +-/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 01000000}, +-/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 02000000}, +-/* UNIX_NOREAP */ {"noreap", _ALL_ON_, 04000000}, +-/* UNIX_BROKEN_SHADOW */ {"broken_shadow", _ALL_ON_, 010000000}, +-/* UNIX_SHA256_PASS */ {"sha256", _ALL_ON_^(0260420000), 020000000}, +-/* UNIX_SHA512_PASS */ {"sha512", _ALL_ON_^(0260420000), 040000000}, +-/* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0100000000}, +-/* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(0260420000), 0200000000}, ++/* UNIX__OLD_PASSWD */ {NULL, _ALL_ON_, 0x1}, ++/* UNIX__VERIFY_PASSWD */ {NULL, _ALL_ON_, 0x2}, ++/* UNIX__IAMROOT */ {NULL, _ALL_ON_, 0x4}, ++/* UNIX_AUDIT */ {"audit", _ALL_ON_, 0x8}, ++/* UNIX_USE_FIRST_PASS */ {"use_first_pass", _ALL_ON_^(0x30), 0x10}, ++/* UNIX_TRY_FIRST_PASS */ {"try_first_pass", _ALL_ON_^(0x30), 0x20}, ++/* UNIX_NOT_SET_PASS */ {"not_set_pass", _ALL_ON_, 0x40}, ++/* UNIX__PRELIM */ {NULL, _ALL_ON_^(0x180), 0x80}, ++/* UNIX__UPDATE */ {NULL, _ALL_ON_^(0x180), 0x100}, ++/* UNIX__NONULL */ {NULL, _ALL_ON_, 0x200}, ++/* UNIX__QUIET */ {NULL, _ALL_ON_, 0x400}, ++/* UNIX_USE_AUTHTOK */ {"use_authtok", _ALL_ON_, 0x800}, ++/* UNIX_SHADOW */ {"shadow", _ALL_ON_, 0x1000}, ++/* UNIX_MD5_PASS */ {"md5", _ALL_ON_^(0x2C22000), 0x2000}, ++/* UNIX__NULLOK */ {"nullok", _ALL_ON_^(0x200), 0}, ++/* UNIX_DEBUG */ {"debug", _ALL_ON_, 0x4000}, ++/* UNIX_NODELAY */ {"nodelay", _ALL_ON_, 0x8000}, ++/* UNIX_NIS */ {"nis", _ALL_ON_, 0x10000}, ++/* UNIX_BIGCRYPT */ {"bigcrypt", _ALL_ON_^(0x2C22000), 0x20000}, ++/* UNIX_LIKE_AUTH */ {"likeauth", _ALL_ON_, 0x40000}, ++/* UNIX_REMEMBER_PASSWD */ {"remember=", _ALL_ON_, 0x80000}, ++/* UNIX_NOREAP */ {"noreap", _ALL_ON_, 0x100000}, ++/* UNIX_BROKEN_SHADOW */ {"broken_shadow", _ALL_ON_, 0x200000}, ++/* UNIX_SHA256_PASS */ {"sha256", _ALL_ON_^(0x2C22000), 0x400000}, ++/* UNIX_SHA512_PASS */ {"sha512", _ALL_ON_^(0x2C22000), 0x800000}, ++/* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0x1000000}, ++/* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(0x2C22000),0x2000000}, ++/* UNIX_MAX_PASS_LEN */ {"max=", _ALL_ON_, 0}, ++/* UNIX_MIN_PASS_LEN */ {"min=", _ALL_ON_, 0x4000000}, ++/* UNIX_OBSCURE_CHECKS */ {"obscure", _ALL_ON_, 0x8000000}, + }; + + #define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag) +@@ -141,7 +149,7 @@ + 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); +Index: pam.deb/modules/pam_unix/pam_unix.8.xml +=================================================================== +--- pam.deb.orig/modules/pam_unix/pam_unix.8.xml ++++ pam.deb/modules/pam_unix/pam_unix.8.xml +@@ -326,6 +326,90 @@ + </para> + </listitem> + </varlistentry> ++ <varlistentry> ++ <term> ++ <option>min=<replaceable>n</replaceable></option> ++ </term> ++ <listitem> ++ <para> ++ Set a minimum password length of <replaceable>n</replaceable> ++ characters. The default value is 6. ++ </para> ++ </listitem> ++ </varlistentry> ++ <varlistentry> ++ <term> ++ <option>obscure</option> ++ </term> ++ <listitem> ++ <para> ++ Enable some extra checks on password strength. These checks ++ are based on the "obscure" checks in the original shadow ++ package. The behavior is similar to the pam_cracklib ++ module, but for non-dictionary-based checks. The following ++ checks are implemented: ++ <variablelist> ++ <varlistentry> ++ <term> ++ <option>Palindrome</option> ++ </term> ++ <listitem> ++ <para> ++ Verifies that the new password is not a palindrome ++ of (i.e., the reverse of) the previous one. ++ </para> ++ </listitem> ++ </varlistentry> ++ <varlistentry> ++ <term> ++ <option>Case Change Only</option> ++ </term> ++ <listitem> ++ <para> ++ Verifies that the new password isn't the same as the ++ old one with a change of case. ++ </para> ++ </listitem> ++ </varlistentry> ++ <varlistentry> ++ <term> ++ <option>Similar</option> ++ </term> ++ <listitem> ++ <para> ++ Verifies that the new password isn't too much like ++ the previous one. ++ </para> ++ </listitem> ++ </varlistentry> ++ <varlistentry> ++ <term> ++ <option>Simple</option> ++ </term> ++ <listitem> ++ <para> ++ Is the new password too simple? This is based on ++ the length of the password and the number of ++ different types of characters (alpha, numeric, etc.) ++ used. ++ </para> ++ </listitem> ++ </varlistentry> ++ <varlistentry> ++ <term> ++ <option>Rotated</option> ++ </term> ++ <listitem> ++ <para> ++ Is the new password a rotated version of the old ++ password? (E.g., "billy" and "illyb") ++ </para> ++ </listitem> ++ </varlistentry> ++ </variablelist> ++ </para> ++ </listitem> ++ </varlistentry> + </variablelist> + <para> + Invalid arguments are logged with <citerefentry> +Index: pam.deb/modules/pam_unix/obscure.c +=================================================================== +--- /dev/null ++++ pam.deb/modules/pam_unix/obscure.c +@@ -0,0 +1,198 @@ ++/* ++ * Copyright 1989 - 1994, Julianne Frances Haugh ++ * All rights reserved. ++ * ++ * Redistribution and use in source and binary forms, with or without ++ * modification, are permitted provided that the following conditions ++ * are met: ++ * 1. Redistributions of source code must retain the above copyright ++ * notice, this list of conditions and the following disclaimer. ++ * 2. Redistributions in binary form must reproduce the above copyright ++ * notice, this list of conditions and the following disclaimer in the ++ * documentation and/or other materials provided with the distribution. ++ * 3. Neither the name of Julianne F. Haugh nor the names of its contributors ++ * may be used to endorse or promote products derived from this software ++ * without specific prior written permission. ++ * ++ * THIS SOFTWARE IS PROVIDED BY JULIE HAUGH AND CONTRIBUTORS ``AS IS'' AND ++ * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE ++ * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ++ * ARE DISCLAIMED. IN NO EVENT SHALL JULIE HAUGH OR CONTRIBUTORS BE LIABLE ++ * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL ++ * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS ++ * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) ++ * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT ++ * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY ++ * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF ++ * SUCH DAMAGE. ++ */ ++ ++#include "config.h" ++ ++#include <ctype.h> ++#include <stdio.h> ++#include <unistd.h> ++#include <string.h> ++#include <stdlib.h> ++#include <pwd.h> ++#include <security/pam_modules.h> ++#include <security/_pam_macros.h> ++ ++ ++#include "support.h" ++ ++/* can't be a palindrome - like `R A D A R' or `M A D A M' */ ++static int palindrome(const char *old, const char *new) { ++ int i, j; ++ ++ i = strlen (new); ++ ++ for (j = 0;j < i;j++) ++ if (new[i - j - 1] != new[j]) ++ return 0; ++ ++ return 1; ++} ++ ++/* more than half of the characters are different ones. */ ++static int similar(const char *old, const char *new) { ++ int i, j; ++ ++ /* ++ * XXX - sometimes this fails when changing from a simple password ++ * to a really long one (MD5). For now, I just return success if ++ * the new password is long enough. Please feel free to suggest ++ * something better... --marekm ++ */ ++ if (strlen(new) >= 8) ++ return 0; ++ ++ for (i = j = 0; new[i] && old[i]; i++) ++ if (strchr(new, old[i])) ++ j++; ++ ++ if (i >= j * 2) ++ return 0; ++ ++ return 1; ++} ++ ++/* a nice mix of characters. */ ++static int simple(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 is this - a password of only one character type ++ * must be 8 letters long. Two types, 7, and so on. ++ */ ++ ++ size = 9; ++ if (digits) size--; ++ if (uppers) size--; ++ if (lowers) size--; ++ if (others) size--; ++ ++ if (size <= i) ++ return 0; ++ ++ return 1; ++} ++ ++static char *str_lower(char *string) { ++ char *cp; ++ ++ for (cp = string; *cp; cp++) ++ *cp = tolower(*cp); ++ return string; ++} ++ ++static const char * password_check(const char *old, const char *new, ++ const struct passwd *pwdp) { ++ const char *msg = NULL; ++ char *oldmono, *newmono, *wrapped; ++ ++ if (strcmp(new, old) == 0) ++ return _("Bad: new password must be different than the old one"); ++ ++ newmono = str_lower(strdup(new)); ++ oldmono = str_lower(strdup(old)); ++ wrapped = (char *)malloc(strlen(oldmono) * 2 + 1); ++ strcpy (wrapped, oldmono); ++ strcat (wrapped, oldmono); ++ ++ if (palindrome(oldmono, newmono)) { ++ msg = _("Bad: new password cannot be a palindrome"); ++ } else if (strcmp(oldmono, newmono) == 0) { ++ msg = _("Bad: new and old password must differ by more than just case"); ++ } else if (similar(oldmono, newmono)) { ++ msg = _("Bad: new and old password are too similar"); ++ } else if (simple(old, new)) { ++ msg = _("Bad: new password is too simple"); ++ } else if (strstr(wrapped, newmono)) { ++ msg = _("Bad: new password is just a wrapped version of the old one"); ++ } ++ ++ _pam_delete(newmono); ++ _pam_delete(oldmono); ++ _pam_delete(wrapped); ++ ++ return msg; ++} ++ ++const char *obscure_msg(const char *old, const char *new, ++ const struct passwd *pwdp, unsigned int ctrl) { ++ int oldlen, newlen; ++ char *new1, *old1; ++ const char *msg; ++ ++ if (old == NULL) ++ return NULL; /* no check if old is NULL */ ++ ++ oldlen = strlen(old); ++ newlen = strlen(new); ++ ++ /* Remaining checks are optional. */ ++ if (off(UNIX_OBSCURE_CHECKS,ctrl)) ++ return NULL; ++ ++ if ((msg = password_check(old, new, pwdp)) != NULL) ++ return msg; ++ ++ /* The traditional crypt() truncates passwords to 8 chars. It is ++ possible to circumvent the above checks by choosing an easy ++ 8-char password and adding some random characters to it... ++ Example: "password$%^&*123". So check it again, this time ++ truncated to the maximum length. Idea from npasswd. --marekm */ ++ ++ if (on(UNIX_HASH_MASK,ctrl)) ++ return NULL; /* unlimited password length */ ++ ++ if (oldlen <= 8 && newlen <= 8) ++ return NULL; ++ ++ new1 = strndup(new,8); ++ old1 = strndup(old,8); ++ ++ msg = password_check(old1, new1, pwdp); ++ ++ _pam_delete(new1); ++ _pam_delete(old1); ++ ++ return msg; ++} +Index: pam.deb/modules/pam_unix/Makefile.am +=================================================================== +--- pam.deb.orig/modules/pam_unix/Makefile.am ++++ pam.deb/modules/pam_unix/Makefile.am +@@ -41,7 +41,7 @@ + + pam_unix_la_SOURCES = bigcrypt.c pam_unix_acct.c \ + pam_unix_auth.c pam_unix_passwd.c pam_unix_sess.c support.c \ +- passverify.c yppasswd_xdr.c md5_good.c md5_broken.c ++ passverify.c yppasswd_xdr.c md5_good.c md5_broken.c obscure.c + + bigcrypt_SOURCES = bigcrypt.c bigcrypt_main.c + bigcrypt_CFLAGS = $(AM_CFLAGS) +Index: pam.deb/modules/pam_unix/pam_unix_auth.c +=================================================================== +--- pam.deb.orig/modules/pam_unix/pam_unix_auth.c ++++ pam.deb/modules/pam_unix/pam_unix_auth.c +@@ -109,7 +109,7 @@ + + 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: pam.deb/modules/pam_unix/pam_unix_sess.c +=================================================================== +--- pam.deb.orig/modules/pam_unix/pam_unix_sess.c ++++ pam.deb/modules/pam_unix/pam_unix_sess.c +@@ -73,7 +73,7 @@ + + 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 @@ + + 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: pam.deb/modules/pam_unix/pam_unix.8 +=================================================================== +--- pam.deb.orig/modules/pam_unix/pam_unix.8 ++++ pam.deb/modules/pam_unix/pam_unix.8 +@@ -166,13 +166,11 @@ + .\" ----------------------------------------------------------------- + .\" * MAIN CONTENT STARTS HERE * + .\" ----------------------------------------------------------------- +-.SH "Name" ++.SH "NAME" + pam_unix \- Module for traditional password authentication +-.SH "Synopsis" +-.fam C ++.SH "SYNOPSIS" + .HP \w'\fBpam_unix\&.so\fR\ 'u + \fBpam_unix\&.so\fR [\&.\&.\&.] +-.fam + .SH "DESCRIPTION" + .PP + This is the standard Unix authentication module\&. It uses standard calls from the system\'s libraries to retrieve and set account information as well as authentication\&. Usually this is obtained from the /etc/passwd and the /etc/shadow file as well if shadow is enabled\&. +@@ -264,7 +262,7 @@ + The last + \fIn\fR + passwords for each user are saved in +-\FC/etc/security/opasswd\F[] ++/etc/security/opasswd + in order to force password change history and keep the user from alternating between the same password too frequently\&. + .RE + .PP +@@ -315,6 +313,44 @@ + Ignore errors reading shadow information for users in the account management module\&. + .RE + .PP ++\fBmin=\fR\fB\fIn\fR\fR ++.RS 4 ++Set a minimum password length of ++\fIn\fR ++characters\&. The default value is 6\&. ++.RE ++.PP ++\fBobscure\fR ++.RS 4 ++Enable some extra checks on password strength\&. These checks are based on the "obscure" checks in the original shadow package\&. The behavior is similar to the pam_cracklib module, but for non\-dictionary\-based checks\&. The following checks are implemented: ++.PP ++\fBPalindrome\fR ++.RS 4 ++Verifies that the new password is not a palindrome of (i\&.e\&., the reverse of) the previous one\&. ++.RE ++.PP ++\fBCase Change Only\fR ++.RS 4 ++Verifies that the new password isn\'t the same as the old one with a change of case\&. ++.RE ++.PP ++\fBSimilar\fR ++.RS 4 ++Verifies that the new password isn\'t too much like the previous one\&. ++.RE ++.PP ++\fBSimple\fR ++.RS 4 ++Is the new password too simple? This is based on the length of the password and the number of different types of characters (alpha, numeric, etc\&.) used\&. ++.RE ++.PP ++\fBRotated\fR ++.RS 4 ++Is the new password a rotated version of the old password? (E\&.g\&., "billy" and "illyb") ++.RE ++.sp ++.RE ++.PP + Invalid arguments are logged with + \fBsyslog\fR(3)\&. + .SH "MODULE TYPES PROVIDED" +@@ -333,21 +369,13 @@ + .SH "EXAMPLES" + .PP + An example usage for +-\FC/etc/pam\&.d/login\F[] ++/etc/pam\&.d/login + would be: + .sp + .if n \{\ + .RS 4 + .\} +-.fam C +-.ps -1 + .nf +-.if t \{\ +-.sp -1 +-.\} +-.BB lightgray adjust-for-leading-newline +-.sp -1 +- + # Authenticate the user + auth required pam_unix\&.so + # Ensure users account and password are still active +@@ -358,13 +386,7 @@ + password required pam_unix\&.so use_authtok nullok md5 + session required pam_unix\&.so + +-.EB lightgray adjust-for-leading-newline +-.if t \{\ +-.sp 1 +-.\} + .fi +-.fam +-.ps +1 + .if n \{\ + .RE + .\} |