summaryrefslogtreecommitdiff
path: root/modules/pam_unix
diff options
context:
space:
mode:
authorThorsten Kukuk <kukuk@thkukuk.de>2010-08-17 11:15:32 +0000
committerThorsten Kukuk <kukuk@thkukuk.de>2010-08-17 11:15:32 +0000
commitfa29cc2697e1627650eeedf1ba300ad7377e11c3 (patch)
tree58348bf50e94f489a66eaa4c875da69a635e740d /modules/pam_unix
parent07b5f4ce482ef22270a6c18ba01d108c065b9de2 (diff)
Relevant BUGIDs:
Purpose of commit: new feature Commit summary: --------------- 2010-08-17 Thorsten Kukuk <kukuk@thkukuk.de> * modules/pam_unix/pam_unix_passwd.c: Implement minlen option. * modules/pam_unix/support.c: Likewise. * modules/pam_unix/support.h: Likewise. * modules/pam_unix/pam_unix_acct.c (pam_sm_acct_mgmt): Adjust arguments for _set_ctrl call. * modules/pam_unix/pam_unix_auth.c (pam_sm_authenticate): Likewise. * modules/pam_unix/pam_unix_session.c: Likewise. * modules/pam_unix/pam_unix.8.xml: Document minlen option. Based on patch by Steve Langasek.
Diffstat (limited to 'modules/pam_unix')
-rw-r--r--modules/pam_unix/pam_unix.8.xml12
-rw-r--r--modules/pam_unix/pam_unix_acct.c2
-rw-r--r--modules/pam_unix/pam_unix_auth.c2
-rw-r--r--modules/pam_unix/pam_unix_passwd.c16
-rw-r--r--modules/pam_unix/pam_unix_sess.c4
-rw-r--r--modules/pam_unix/support.c28
-rw-r--r--modules/pam_unix/support.h10
7 files changed, 53 insertions, 21 deletions
diff --git a/modules/pam_unix/pam_unix.8.xml b/modules/pam_unix/pam_unix.8.xml
index 6b860f7f..c272e3ce 100644
--- a/modules/pam_unix/pam_unix.8.xml
+++ b/modules/pam_unix/pam_unix.8.xml
@@ -326,6 +326,18 @@
</para>
</listitem>
</varlistentry>
+ <varlistentry>
+ <term>
+ <option>minlen=<replaceable>n</replaceable></option>
+ </term>
+ <listitem>
+ <para>
+ Set a minimum password length of <replaceable>n</replaceable>
+ characters. The max. for DES crypt based passwords are 8
+ characters.
+ </para>
+ </listitem>
+ </varlistentry>
</variablelist>
<para>
Invalid arguments are logged with <citerefentry>
diff --git a/modules/pam_unix/pam_unix_acct.c b/modules/pam_unix/pam_unix_acct.c
index 08cc750f..2731b8bc 100644
--- a/modules/pam_unix/pam_unix_acct.c
+++ b/modules/pam_unix/pam_unix_acct.c
@@ -191,7 +191,7 @@ PAM_EXTERN int pam_sm_acct_mgmt(pam_handle_t * pamh, int flags,
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;
diff --git a/modules/pam_unix/pam_unix_auth.c b/modules/pam_unix/pam_unix_auth.c
index c2f79b10..d9c4ea55 100644
--- a/modules/pam_unix/pam_unix_auth.c
+++ b/modules/pam_unix/pam_unix_auth.c
@@ -109,7 +109,7 @@ PAM_EXTERN int pam_sm_authenticate(pam_handle_t * pamh, int flags
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(). */
diff --git a/modules/pam_unix/pam_unix_passwd.c b/modules/pam_unix/pam_unix_passwd.c
index f137570a..320bc547 100644
--- a/modules/pam_unix/pam_unix_passwd.c
+++ b/modules/pam_unix/pam_unix_passwd.c
@@ -457,7 +457,8 @@ static int _unix_verify_shadow(pam_handle_t *pamh, const char *user, unsigned in
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,6 +489,9 @@ static int _pam_unix_approve_pass(pam_handle_t * pamh
}
}
if (off(UNIX__IAMROOT, ctrl)) {
+ 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)) {
if ((retval = check_old_password(user, pass_new)) == PAM_AUTHTOK_ERR)
remark = _("Password has been already used. Choose another.");
@@ -513,6 +517,7 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
int retval;
int remember = -1;
int rounds = -1;
+ int pass_min_len = 0;
/* <DO NOT free() THESE> */
const char *user;
@@ -521,7 +526,8 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
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
@@ -721,7 +727,8 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
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);
@@ -754,7 +761,8 @@ PAM_EXTERN int pam_sm_chauthtok(pam_handle_t * pamh, int flags,
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");
diff --git a/modules/pam_unix/pam_unix_sess.c b/modules/pam_unix/pam_unix_sess.c
index e984578c..778062e4 100644
--- a/modules/pam_unix/pam_unix_sess.c
+++ b/modules/pam_unix/pam_unix_sess.c
@@ -73,7 +73,7 @@ PAM_EXTERN int pam_sm_open_session(pam_handle_t * pamh, int flags,
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 @@ PAM_EXTERN int pam_sm_close_session(pam_handle_t * pamh, int flags,
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) {
diff --git a/modules/pam_unix/support.c b/modules/pam_unix/support.c
index 2a47d157..898d1ea5 100644
--- a/modules/pam_unix/support.c
+++ b/modules/pam_unix/support.c
@@ -55,7 +55,7 @@ int _make_remark(pam_handle_t * pamh, unsigned int ctrl,
*/
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;
@@ -102,15 +102,16 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds,
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 + 7);
+ }
if (rounds != NULL && j == UNIX_ALGO_ROUNDS)
*rounds = strtol(*argv + 7, NULL, 10);
}
@@ -118,6 +119,13 @@ int _set_ctrl(pam_handle_t *pamh, int flags, int *remember, int *rounds,
++argv; /* step to next argument */
}
+ if (UNIX_DES_CRYPT(ctrl)
+ && pass_min_len && *pass_min_len > 8)
+ {
+ pam_syslog (pamh, LOG_NOTICE, "Password minlen reset to 8 characters");
+ *pass_min_len = 8;
+ }
+
if (flags & PAM_DISALLOW_NULL_AUTHTOK) {
D(("DISALLOW_NULL_AUTHTOK"));
set(UNIX__NONULL, ctrl);
diff --git a/modules/pam_unix/support.h b/modules/pam_unix/support.h
index dfee2dae..db4cd953 100644
--- a/modules/pam_unix/support.h
+++ b/modules/pam_unix/support.h
@@ -86,11 +86,14 @@ typedef struct {
* information during acct management */
#define UNIX_SHA256_PASS 23 /* new password hashes will use SHA256 */
#define UNIX_SHA512_PASS 24 /* new password hashes will use SHA512 */
-#define UNIX_ALGO_ROUNDS 25 /* optional number of rounds for new
+#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_MIN_PASS_LEN 27 /* min length for password */
/* -------------- */
-#define UNIX_CTRLS_ 27 /* number of ctrl arguments defined */
+#define UNIX_CTRLS_ 28 /* number of ctrl arguments defined */
+
+#define UNIX_DES_CRYPT(ctrl) (off(UNIX_MD5_PASS,ctrl)&&off(UNIX_BIGCRYPT,ctrl)&&off(UNIX_SHA256_PASS,ctrl)&&off(UNIX_SHA512_PASS,ctrl)&&off(UNIX_BLOWFISH_PASS,ctrl))
static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
{
@@ -124,6 +127,7 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
/* UNIX_SHA512_PASS */ {"sha512", _ALL_ON_^(0260420000), 040000000},
/* UNIX_ALGO_ROUNDS */ {"rounds=", _ALL_ON_, 0100000000},
/* UNIX_BLOWFISH_PASS */ {"blowfish", _ALL_ON_^(0260420000), 0200000000},
+/* UNIX_MIN_PASS_LEN */ {"minlen=", _ALL_ON_, 0400000000},
};
#define UNIX_DEFAULTS (unix_args[UNIX__NONULL].flag)
@@ -141,7 +145,7 @@ static const UNIX_Ctrls unix_args[UNIX_CTRLS_] =
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);