summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorGabe <redhatrises@gmail.com>2018-08-23 10:31:35 -0600
committerTomáš Mráz <t8m@users.noreply.github.com>2018-08-24 09:37:50 +0200
commitee8bbeb05d4f2ee929bddf1f268160e767598400 (patch)
tree90ce48728ef2316cc6e991774f44ad54f23e6b10
parentd2ed53ae94b0bc97e5dfac50ffd95c57b5ca92e6 (diff)
downloadlibpwquality-git-ee8bbeb05d4f2ee929bddf1f268160e767598400.tar.gz
Move retry, enforce_for_root, local_users_only options to pwquality.conf
- retry, enforce_for_root, local_users_only options can now be configured in pwquality.conf - Fixes RHBZ#1537240
-rw-r--r--doc/man/pwquality.conf.5.pod20
-rw-r--r--src/pam_pwquality.c33
-rw-r--r--src/pwqprivate.h6
-rw-r--r--src/pwquality.conf12
-rw-r--r--src/pwquality.h3
-rw-r--r--src/settings.c23
6 files changed, 79 insertions, 18 deletions
diff --git a/doc/man/pwquality.conf.5.pod b/doc/man/pwquality.conf.5.pod
index 4d90285..47d6fd0 100644
--- a/doc/man/pwquality.conf.5.pod
+++ b/doc/man/pwquality.conf.5.pod
@@ -129,6 +129,26 @@ not created yet.
Path to the cracklib dictionaries. Default is to use the cracklib default.
+=item B<retry=>I<N>
+
+Prompt user at most I<N> times before returning with error. The default is
+I<1>.
+
+=item B<enforce_for_root>
+
+The module will return error on failed check even if the user changing the
+password is root. This option is off by default which means that just
+the message about the failed check is printed but root can change
+the password anyway. Note that root is not asked for an old password
+so the checks that compare the old and new password are not performed.
+
+=item B<local_users_only>
+
+The module will not test the password quality for users that are not present
+in the F</etc/passwd> file. The module still asks for the password so
+the following modules in the stack can use the B<use_authtok> option.
+This option is off by default.
+
=back
=head1 SEE ALSO
diff --git a/src/pam_pwquality.c b/src/pam_pwquality.c
index 9c9849d..9d210e8 100644
--- a/src/pam_pwquality.c
+++ b/src/pam_pwquality.c
@@ -38,9 +38,6 @@
#define PAM_DEBUG_ARG 0x0001
struct module_options {
- int retry_times;
- int enforce_for_root;
- int local_users_only;
pwquality_settings_t *pwq;
};
@@ -76,15 +73,7 @@ _pam_parse (pam_handle_t *pamh, struct module_options *opt,
ctrl |= PAM_DEBUG_ARG;
else if (!strncmp(*argv, "type=", 5))
pam_set_item (pamh, PAM_AUTHTOK_TYPE, *argv+5);
- else if (!strncmp(*argv, "retry=", 6)) {
- opt->retry_times = strtol(*argv+6, &ep, 10);
- if (!ep || (opt->retry_times < 1))
- opt->retry_times = CO_RETRY_TIMES;
- } else if (!strncmp(*argv, "enforce_for_root", 16)) {
- opt->enforce_for_root = 1;
- } else if (!strncmp(*argv, "local_users_only", 16)) {
- opt->local_users_only = 1;
- } else if (!strncmp(*argv, "difignore=", 10)) {
+ else if (!strncmp(*argv, "difignore=", 10)) {
/* ignored for compatibility with pam_cracklib */
} else if (!strncmp(*argv, "reject_username", 15)) {
/* ignored for compatibility with pam_cracklib */
@@ -157,14 +146,19 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
{
int ctrl;
struct module_options options;
+ int retry_times = CO_RETRY_TIMES;
memset(&options, 0, sizeof(options));
- options.retry_times = CO_RETRY_TIMES;
ctrl = _pam_parse(pamh, &options, argc, argv);
if (ctrl < 0)
return PAM_BUF_ERR;
+ pwquality_get_int_value(options.pwq, PWQ_SETTING_RETRY_TIMES, &retry_times);
+ if (retry_times < 1)
+ retry_times = CO_RETRY_TIMES;
+
+
if (flags & PAM_PRELIM_CHECK) {
/* Check for passwd dictionary
* We cannot do that, since the original path is compiled
@@ -194,9 +188,10 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
}
tries = 0;
- while (tries < options.retry_times) {
+ while (tries < retry_times) {
void *auxerror;
const char *newtoken = NULL;
+ int local_users_only = 0;
tries++;
@@ -218,8 +213,9 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
pwquality_free_settings(options.pwq);
return PAM_AUTHTOK_ERR;
}
+ pwquality_get_int_value(options.pwq, PWQ_SETTING_LOCAL_USERS, &local_users_only);
- if (options.local_users_only && check_local_user (pamh, user) == 0) {
+ if (local_users_only && check_local_user (pamh, user) == 0) {
/* skip the check if a non-local user */
retval = 0;
} else {
@@ -231,13 +227,16 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
const char *msg;
char buf[PWQ_MAX_ERROR_MESSAGE_LEN];
int enforcing = 1;
+ int enforce_for_root = 0;
+
msg = pwquality_strerror(buf, sizeof(buf), retval, auxerror);
if (ctrl & PAM_DEBUG_ARG)
pam_syslog(pamh, LOG_DEBUG, "bad password: %s", msg);
pam_error(pamh, _("BAD PASSWORD: %s"), msg);
pwquality_get_int_value(options.pwq, PWQ_SETTING_ENFORCING, &enforcing);
+ pwquality_get_int_value(options.pwq, PWQ_SETTING_ENFORCE_ROOT, &enforce_for_root);
- if (enforcing && (getuid() || options.enforce_for_root ||
+ if (enforcing && (getuid() || enforce_for_root ||
(flags & PAM_CHANGE_EXPIRED_AUTHTOK))) {
pam_set_item(pamh, PAM_AUTHTOK, NULL);
retval = PAM_AUTHTOK_ERR;
@@ -271,7 +270,7 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags,
/* if we have only one try, we can use the real reason,
* else say that there were too many tries. */
- if (options.retry_times > 1)
+ if (retry_times > 1)
return PAM_MAXTRIES;
else
return PAM_AUTHTOK_ERR;
diff --git a/src/pwqprivate.h b/src/pwqprivate.h
index 4ac96a7..38fc93f 100644
--- a/src/pwqprivate.h
+++ b/src/pwqprivate.h
@@ -27,6 +27,9 @@ struct pwquality_settings {
int dict_check;
int user_check;
int enforcing;
+ int retry_times;
+ int enforce_for_root;
+ int local_users_only;
char *bad_words;
char *dict_path;
};
@@ -46,6 +49,9 @@ struct setting_mapping {
#define PWQ_DEFAULT_DICT_CHECK 1
#define PWQ_DEFAULT_USER_CHECK 1
#define PWQ_DEFAULT_ENFORCING 1
+#define PWQ_DEFAULT_RETRY_TIMES 1
+#define PWQ_DEFAULT_ENFORCE_ROOT 0
+#define PWQ_DEFAULT_LOCAL_USERS 0
#define PWQ_TYPE_INT 1
#define PWQ_TYPE_STR 2
diff --git a/src/pwquality.conf b/src/pwquality.conf
index 550036d..1b05cb4 100644
--- a/src/pwquality.conf
+++ b/src/pwquality.conf
@@ -61,3 +61,15 @@
#
# Path to the cracklib dictionaries. Default is to use the cracklib default.
# dictpath =
+#
+# Prompt user at most N times before returning with error. The default is 1.
+# retry = 3
+#
+# Enforces pwquality checks on the root user password.
+# Enabled if the option is present.
+# enforce_for_root
+#
+# Skip testing the password quality for users that are not present in the
+# /etc/passwd file.
+# Enabled if the option is present.
+# local_users_only
diff --git a/src/pwquality.h b/src/pwquality.h
index 0666735..3d61fd6 100644
--- a/src/pwquality.h
+++ b/src/pwquality.h
@@ -30,6 +30,9 @@ extern "C" {
#define PWQ_SETTING_DICT_CHECK 15
#define PWQ_SETTING_USER_CHECK 16
#define PWQ_SETTING_ENFORCING 17
+#define PWQ_SETTING_RETRY_TIMES 18
+#define PWQ_SETTING_ENFORCE_ROOT 19
+#define PWQ_SETTING_LOCAL_USERS 20
#define PWQ_MAX_ENTROPY_BITS 256
#define PWQ_MIN_ENTROPY_BITS 56
diff --git a/src/settings.c b/src/settings.c
index 4b026b1..4f11537 100644
--- a/src/settings.c
+++ b/src/settings.c
@@ -36,6 +36,9 @@ pwquality_default_settings(void)
pwq->dict_check = PWQ_DEFAULT_DICT_CHECK;
pwq->user_check = PWQ_DEFAULT_USER_CHECK;
pwq->enforcing = PWQ_DEFAULT_ENFORCING;
+ pwq->retry_times = PWQ_DEFAULT_RETRY_TIMES;
+ pwq->enforce_for_root = PWQ_DEFAULT_ENFORCE_ROOT;
+ pwq->local_users_only = PWQ_DEFAULT_LOCAL_USERS;
return pwq;
}
@@ -68,7 +71,10 @@ static const struct setting_mapping s_map[] = {
{ "usercheck", PWQ_SETTING_USER_CHECK, PWQ_TYPE_INT},
{ "enforcing", PWQ_SETTING_ENFORCING, PWQ_TYPE_INT},
{ "badwords", PWQ_SETTING_BAD_WORDS, PWQ_TYPE_STR},
- { "dictpath", PWQ_SETTING_DICT_PATH, PWQ_TYPE_STR}
+ { "dictpath", PWQ_SETTING_DICT_PATH, PWQ_TYPE_STR},
+ { "retry", PWQ_SETTING_RETRY_TIMES, PWQ_TYPE_INT},
+ { "enforce_for_root", PWQ_SETTING_ENFORCE_ROOT, PWQ_TYPE_SET},
+ { "local_users_only", PWQ_SETTING_LOCAL_USERS, PWQ_TYPE_SET}
};
/* set setting name with value */
@@ -344,6 +350,12 @@ pwquality_set_int_value(pwquality_settings_t *pwq, int setting, int value)
case PWQ_SETTING_ENFORCING:
pwq->enforcing = value;
break;
+ case PWQ_SETTING_RETRY_TIMES:
+ pwq->retry_times = value;
+ case PWQ_SETTING_ENFORCE_ROOT:
+ pwq->enforce_for_root = value;
+ case PWQ_SETTING_LOCAL_USERS:
+ pwq->local_users_only = value;
default:
return PWQ_ERROR_NON_INT_SETTING;
}
@@ -430,6 +442,15 @@ pwquality_get_int_value(pwquality_settings_t *pwq, int setting, int *value)
case PWQ_SETTING_ENFORCING:
*value = pwq->enforcing;
break;
+ case PWQ_SETTING_RETRY_TIMES:
+ *value = pwq->retry_times;
+ break;
+ case PWQ_SETTING_ENFORCE_ROOT:
+ *value = pwq->enforce_for_root;
+ break;
+ case PWQ_SETTING_LOCAL_USERS:
+ *value = pwq->local_users_only;
+ break;
default:
return PWQ_ERROR_NON_INT_SETTING;
}