summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorStef Walter <stefw@redhat.com>2012-08-16 19:38:32 +0200
committerStef Walter <stefw@redhat.com>2012-08-16 19:38:32 +0200
commite5e3feab7f12756daf6210477d706e11dbcce720 (patch)
tree62f9488ed12dfe19323af60d83d2539fdd52590d /src
parent70ef5a4310268c1264f116efdc70a60c0a0dbb4d (diff)
downloadlibpwquality-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.c55
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;