diff options
author | Thorsten Kukuk <kukuk@thkukuk.de> | 2010-08-17 11:15:32 +0000 |
---|---|---|
committer | Thorsten Kukuk <kukuk@thkukuk.de> | 2010-08-17 11:15:32 +0000 |
commit | fa29cc2697e1627650eeedf1ba300ad7377e11c3 (patch) | |
tree | 58348bf50e94f489a66eaa4c875da69a635e740d /modules | |
parent | 07b5f4ce482ef22270a6c18ba01d108c065b9de2 (diff) | |
download | pam-fa29cc2697e1627650eeedf1ba300ad7377e11c3.tar.gz pam-fa29cc2697e1627650eeedf1ba300ad7377e11c3.tar.bz2 pam-fa29cc2697e1627650eeedf1ba300ad7377e11c3.zip |
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')
-rw-r--r-- | modules/pam_unix/pam_unix.8.xml | 12 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_acct.c | 2 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_auth.c | 2 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_passwd.c | 16 | ||||
-rw-r--r-- | modules/pam_unix/pam_unix_sess.c | 4 | ||||
-rw-r--r-- | modules/pam_unix/support.c | 28 | ||||
-rw-r--r-- | modules/pam_unix/support.h | 10 |
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); |