changeset b4f44d75bcba in /srv/hg/libpwquality
details:
http://hg.fedorahosted.org/hg/srv/hg/libpwquality?cmd=changeset;node=b4f4...
summary: Add implicit support for <cfgfile>.d/*.conf file parsing.
diffstat:
doc/man/pwquality.conf.5 | 4 ++
src/pwquality.h | 5 ++-
src/settings.c | 69 ++++++++++++++++++++++++++++++++++++++++++++++++
3 files changed, 77 insertions(+), 1 deletions(-)
diffs (131 lines):
diff -r 4e5931455631 -r b4f44d75bcba doc/man/pwquality.conf.5
--- a/doc/man/pwquality.conf.5 Fri Jul 17 14:20:51 2015 +0200
+++ b/doc/man/pwquality.conf.5 Fri Jul 17 17:08:43 2015 +0200
@@ -9,6 +9,7 @@
pwquality.conf \- configuration for the libpwquality library
.SH SYNOPSIS
\fB/etc/security/pwquality.conf\fR
+\fB/etc/security/pwquality.conf.d/*.conf\fR
.SH DESCRIPTION
\fBpwquality.conf\fR provides a way to configure the default password
quality requirements for the system passwords. This file is read by the
@@ -19,6 +20,9 @@
starting with \fB#\fR character. The whitespace at the beginning of line, end
of line, and around the \fB=\fR sign is ignored.
+The libpwquality library also first reads all \fB*.conf\fR files from the
+\fB/etc/security/pwquality.conf.d\fR directory in ASCII sorted order. The
+values of the same settings are overriden in the order the files are parsed.
.PD
.SH OPTIONS
The possible options in the file are:
diff -r 4e5931455631 -r b4f44d75bcba src/pwquality.h
--- a/src/pwquality.h Fri Jul 17 14:20:51 2015 +0200
+++ b/src/pwquality.h Fri Jul 17 17:08:43 2015 +0200
@@ -77,7 +77,10 @@
/* Parse the configuration file (if cfgfile is NULL then the default one).
* If auxerror is not NULL it also possibly returns auxiliary error information
- * that must be passed into pwquality_strerror() function. */
+ * that must be passed into pwquality_strerror() function.
+ * New in 1.3.0: First tries to parse all *.conf configuration files from
+ * <cfgfile>.d directory if it exists. Order of parsing determines what
+ values will be in effect - the latest wins. */
int
pwquality_read_config(pwquality_settings_t *pwq, const char *cfgfile,
void **auxerror);
diff -r 4e5931455631 -r b4f44d75bcba src/settings.c
--- a/src/settings.c Fri Jul 17 14:20:51 2015 +0200
+++ b/src/settings.c Fri Jul 17 17:08:43 2015 +0200
@@ -12,6 +12,7 @@
#include <limits.h>
#include <ctype.h>
#include <errno.h>
+#include <dirent.h>
#include "pwquality.h"
#include "pwqprivate.h"
@@ -181,15 +182,83 @@
return rv;
}
+static int
+filter_conf(const struct dirent *d)
+{
+ const char *p;
+
+ if ((p = strstr(d->d_name, ".conf")) == NULL)
+ return 0;
+
+ if (p[5] != '\0')
+ return 0;
+
+ return 1;
+}
+
+static int
+comp_func(const struct dirent **a, const struct dirent **b)
+{
+ return strcmp ((*a)->d_name, (*b)->d_name);
+}
+
/* parse the configuration file (if NULL then the default one) */
int
pwquality_read_config(pwquality_settings_t *pwq, const char *cfgfile, void **auxerror)
{
+ char *dirname;
+ struct dirent **namelist;
+ int n;
+ int i;
+ int rv = 0;
+
if (auxerror)
*auxerror = NULL;
if (cfgfile == NULL)
cfgfile = PWQUALITY_DEFAULT_CFGFILE;
+ /* read "*.conf" files from "<cfgfile>.d" directory
first */
+
+ if (asprintf(&dirname, "%s.d", cfgfile) < 0)
+ return PWQ_ERROR_MEM_ALLOC;
+
+ /* we do not care about scandir races here so we use scandir */
+ n = scandir(dirname, &namelist, filter_conf, comp_func);
+
+ if (n < 0) {
+ namelist = NULL;
+
+ if (errno == ENOMEM) {
+ free(dirname);
+ return PWQ_ERROR_MEM_ALLOC;
+ } /* other errors are ignored */
+ }
+
+ for (i = 0; i < n; i++) {
+ char *subcfg;
+
+ if (rv) {
+ free(namelist[i]);
+ continue;
+ }
+
+ if (asprintf(&subcfg, "%s/%s", dirname,
namelist[i]->d_name) < 0)
+ rv = PWQ_ERROR_MEM_ALLOC;
+ else {
+ rv = read_config_file(pwq, subcfg, auxerror);
+ if (rv == PWQ_ERROR_CFGFILE_OPEN)
+ rv = 0; /* ignore, this one does not modify auxerror */
+ free(subcfg);
+ }
+
+ free(namelist[i]);
+ }
+ free(dirname);
+ free(namelist);
+
+ if (rv)
+ return rv;
+
return read_config_file(pwq, cfgfile, auxerror);
}