diff options
author | Stef Walter <stefw@redhat.com> | 2012-08-16 19:38:32 +0200 |
---|---|---|
committer | Stef Walter <stefw@redhat.com> | 2012-08-16 19:38:32 +0200 |
commit | e5e3feab7f12756daf6210477d706e11dbcce720 (patch) | |
tree | 62f9488ed12dfe19323af60d83d2539fdd52590d /src | |
parent | 70ef5a4310268c1264f116efdc70a60c0a0dbb4d (diff) | |
download | libpwquality-git-e5e3feab7f12756daf6210477d706e11dbcce720.tar.gz |
Add local_users_only option to skip the pwquality checks for non-locals.
Diffstat (limited to 'src')
-rw-r--r-- | src/pam_pwquality.c | 55 |
1 files changed, 53 insertions, 2 deletions
diff --git a/src/pam_pwquality.c b/src/pam_pwquality.c index 0a5bd12..0e4e8f8 100644 --- a/src/pam_pwquality.c +++ b/src/pam_pwquality.c @@ -16,6 +16,9 @@ #include <limits.h> #include <syslog.h> #include <libintl.h> +#include <stdio.h> +#include <pwd.h> +#include <errno.h> #include "pwquality.h" /* For Translators: "%s%s" could be replaced with "<service> " or "". */ @@ -43,11 +46,14 @@ struct module_options { int retry_times; int enforce_for_root; + int local_users_only; pwquality_settings_t *pwq; }; #define CO_RETRY_TIMES 1 +#define PATH_PASSWD "/etc/passwd" + static int _pam_parse (pam_handle_t *pamh, struct module_options *opt, int argc, const char **argv) @@ -82,6 +88,8 @@ _pam_parse (pam_handle_t *pamh, struct module_options *opt, 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)) { /* ignored for compatibility with pam_cracklib */ } else if (!strncmp(*argv, "reject_username", 15)) { @@ -105,6 +113,44 @@ _pam_parse (pam_handle_t *pamh, struct module_options *opt, return ctrl; } +static int +check_local_user (pam_handle_t *pamh, + const char *user) +{ + struct passwd pw, *pwp; + char buf[4096]; + int found = 0; + FILE *fp; + int errn; + + fp = fopen(PATH_PASSWD, "r"); + if (fp == NULL) { + pam_syslog(pamh, LOG_ERR, "pam_pwquality: unable to open %s: %s", + PATH_PASSWD, pam_strerror(pamh, errno)); + return -1; + } + + for (;;) { + errn = fgetpwent_r(fp, &pw, buf, sizeof (buf), &pwp); + if (errn != 0) + break; + if (strcmp (pwp->pw_name, user) == 0) { + found = 1; + break; + } + } + + fclose (fp); + + if (errn != 0 && errn != ENOENT) { + pam_syslog(pamh, LOG_ERR, "pam_pwquality: unable to enumerate local accounts: %s", + pam_strerror(pamh, errn)); + return -1; + } else { + return found; + } +} + PAM_EXTERN int pam_sm_chauthtok(pam_handle_t *pamh, int flags, int argc, const char **argv) @@ -169,8 +215,13 @@ pam_sm_chauthtok(pam_handle_t *pamh, int flags, return PAM_AUTHTOK_ERR; } - /* now test this passwd against libpwquality */ - retval = pwquality_check(options.pwq, newtoken, oldtoken, user, &auxerror); + if (options.local_users_only && check_local_user (pamh, user) == 0) { + /* skip the check if a non-local user */ + retval = 0; + } else { + /* now test this passwd against libpwquality */ + retval = pwquality_check(options.pwq, newtoken, oldtoken, user, &auxerror); + } if (retval < 0) { const char *msg; |