From 98822a2108d900a59f22f2dc0783e825a1a4de3d Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Thu, 7 Dec 2006 12:34:00 +0000 Subject: Relevant BUGIDs: Purpose of commit: new feature Commit summary: --------------- 2006-12-06 Thorsten Kukuk * modules/pam_faildelay/pam_faildelay.c: If no argument is given, try to read FAIL_DELAY from /etc/login.defs. * modules/pam_faildelay/pam_faildelay.8.xml: Document usage of /etc/login.defs. --- modules/pam_faildelay/README | 3 + modules/pam_faildelay/pam_faildelay.8 | 27 ++++---- modules/pam_faildelay/pam_faildelay.8.xml | 5 +- modules/pam_faildelay/pam_faildelay.c | 110 +++++++++++++++++++++++++++++- 4 files changed, 128 insertions(+), 17 deletions(-) (limited to 'modules/pam_faildelay') diff --git a/modules/pam_faildelay/README b/modules/pam_faildelay/README index 80b29d6e..a06d7e3f 100644 --- a/modules/pam_faildelay/README +++ b/modules/pam_faildelay/README @@ -7,6 +7,9 @@ DESCRIPTION pam_faildelay is a PAM module that can be used to set the delay on failure per-application. +If no delay is given, pam_faildelay will use the value of FAIL_DELAY from /etc/ +login.defs. + OPTIONS debug diff --git a/modules/pam_faildelay/pam_faildelay.8 b/modules/pam_faildelay/pam_faildelay.8 index 2c87a3ec..86eb031a 100644 --- a/modules/pam_faildelay/pam_faildelay.8 +++ b/modules/pam_faildelay/pam_faildelay.8 @@ -1,11 +1,11 @@ .\" Title: pam_faildelay .\" Author: -.\" Generator: DocBook XSL Stylesheets v1.71.0 -.\" Date: 11/28/2006 +.\" Generator: DocBook XSL Stylesheets v1.70.1 +.\" Date: 12/06/2006 .\" Manual: Linux\-PAM Manual .\" Source: Linux\-PAM Manual .\" -.TH "PAM_FAILDELAY" "8" "11/28/2006" "Linux\-PAM Manual" "Linux\-PAM Manual" +.TH "PAM_FAILDELAY" "8" "12/06/2006" "Linux\-PAM Manual" "Linux\-PAM Manual" .\" disable hyphenation .nh .\" disable justification (adjust text to left margin only) @@ -18,33 +18,30 @@ pam_faildelay \- Change the delay on failure per\-application .SH "DESCRIPTION" .PP pam_faildelay is a PAM module that can be used to set the delay on failure per\-application. -.SH "OPTIONS" .PP +If no +\fBdelay\fR +is given, pam_faildelay will use the value of FAIL_DELAY from +\fI/etc/login.defs\fR. +.SH "OPTIONS" +.TP 3n \fBdebug\fR -.RS 3n Turns on debugging messages sent to syslog. -.RE -.PP +.TP 3n \fBdelay=\fR\fB\fIN\fR\fR -.RS 3n Set the delay on failure to N microseconds. -.RE .SH "MODULE SERVICES PROVIDED" .PP Only the \fBauth\fR service is supported. .SH "RETURN VALUES" -.PP +.TP 3n PAM_IGNORE -.RS 3n Delay was successful adjusted. -.RE -.PP +.TP 3n PAM_SYSTEM_ERR -.RS 3n The specified delay was not valid. -.RE .SH "EXAMPLES" .PP The following example will set the delay on failure to 10 seconds: diff --git a/modules/pam_faildelay/pam_faildelay.8.xml b/modules/pam_faildelay/pam_faildelay.8.xml index 9e3b9ef9..d2dfd266 100644 --- a/modules/pam_faildelay/pam_faildelay.8.xml +++ b/modules/pam_faildelay/pam_faildelay.8.xml @@ -35,7 +35,10 @@ pam_faildelay is a PAM module that can be used to set the delay on failure per-application. - + + If no is given, pam_faildelay will + use the value of FAIL_DELAY from /etc/login.defs. + diff --git a/modules/pam_faildelay/pam_faildelay.c b/modules/pam_faildelay/pam_faildelay.c index 0fa910b7..16cb7458 100644 --- a/modules/pam_faildelay/pam_faildelay.c +++ b/modules/pam_faildelay/pam_faildelay.c @@ -11,10 +11,16 @@ * auth required pam_faildelay.so delay=10000000 * will set the delay on failure to 10 seconds. * + * If no delay option was given, pam_faildelay.so will use the + * FAIL_DELAY value of /etc/login.defs. * * Based on pam_rootok and parts of pam_unix both by Andrew Morgan * * + * Copyright (c) 2006 Thorsten Kukuk + * - Rewrite to use extended PAM functions + * - Add /etc/login.defs support + * * Portions Copyright (c) 2005 Darren Tucker . * * Redistribution and use in source and binary forms of, with @@ -55,10 +61,14 @@ #include "config.h" +#include +#include #include +#include #include #include #include +#include #define PAM_SM_AUTH @@ -67,6 +77,79 @@ #include +#define BUF_SIZE 8192 +#define LOGIN_DEFS "/etc/login.defs" + +static char * +search_key (const char *filename) +{ + FILE *fp; + char *buf = NULL; + size_t buflen = 0; + char *retval = NULL; + + fp = fopen (filename, "r"); + if (NULL == fp) + return NULL; + + while (!feof (fp)) + { + char *tmp, *cp; +#if defined(HAVE_GETLINE) + ssize_t n = getline (&buf, &buflen, fp); +#elif defined (HAVE_GETDELIM) + ssize_t n = getdelim (&buf, &buflen, '\n', fp); +#else + ssize_t n; + + if (buf == NULL) + { + buflen = BUF_SIZE; + buf = malloc (buflen); + } + buf[0] = '\0'; + if (fgets (buf, buflen - 1, fp) == NULL) + break; + else if (buf != NULL) + n = strlen (buf); + else + n = 0; +#endif /* HAVE_GETLINE / HAVE_GETDELIM */ + cp = buf; + + if (n < 1) + break; + + tmp = strchr (cp, '#'); /* remove comments */ + if (tmp) + *tmp = '\0'; + while (isspace ((int)*cp)) /* remove spaces and tabs */ + ++cp; + if (*cp == '\0') /* ignore empty lines */ + continue; + + if (cp[strlen (cp) - 1] == '\n') + cp[strlen (cp) - 1] = '\0'; + + tmp = strsep (&cp, " \t="); + if (cp != NULL) + while (isspace ((int)*cp) || *cp == '=') + ++cp; + + if (strcasecmp (tmp, "FAIL_DELAY") == 0) + { + retval = strdup (cp); + break; + } + } + fclose (fp); + + free (buf); + + return retval; +} + + /* --- authentication management functions (only) --- */ PAM_EXTERN @@ -74,7 +157,7 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, int argc, const char **argv) { int i, debug_flag = 0; - long int delay = 0; + long int delay = -1; /* step through arguments */ for (i = 0; i < argc; i++) { @@ -86,6 +169,31 @@ int pam_sm_authenticate(pam_handle_t *pamh, int flags UNUSED, pam_syslog (pamh, LOG_ERR, "unknown option; %s", argv[i]); } + if (delay == -1) + { + char *endptr; + char *val = search_key (LOGIN_DEFS); + const char *val_orig = val; + + if (val == NULL) + return PAM_IGNORE; + + errno = 0; + delay = strtol (val, &endptr, 10) & 0777; + if (((delay == 0) && (val_orig == endptr)) || + ((delay == LONG_MIN || delay == LONG_MAX) && (errno == ERANGE))) + { + pam_syslog (pamh, LOG_ERR, "FAIL_DELAY=%s in %s not valid", + val, LOGIN_DEFS); + free (val); + return PAM_IGNORE; + } + + free (val); + /* delay is in seconds, convert to microseconds. */ + delay *= 1000000; + } + if (debug_flag) pam_syslog (pamh, LOG_DEBUG, "setting fail delay to %ld", delay); -- cgit v1.2.3