]> git.ipfire.org Git - thirdparty/util-linux.git/commitdiff
Add support for libeconf
authorThorsten Kukuk <kukuk@suse.com>
Tue, 3 Sep 2019 13:04:43 +0000 (15:04 +0200)
committerThorsten Kukuk <kukuk@suse.com>
Tue, 3 Sep 2019 13:04:43 +0000 (15:04 +0200)
configure.ac
login-utils/Makemodule.am
login-utils/logindefs.c
login-utils/su-common.c

index d4cf46fea08ba2c16b3c5b8659c72dfde2a2613f..a3881ab8c3a1e704ece8506e9d3c04b7efb4672a 100644 (file)
@@ -2232,6 +2232,31 @@ AS_IF([test "x$with_smack" = xyes], [
   AC_DEFINE([HAVE_SMACK], [1], [Add SMACK support])
 ])
 
+AC_ARG_WITH([econf],
+  AS_HELP_STRING([--without-econf], [do not use libeconf]),
+  [], [with_econf=check]
+)
+
+have_econf=no
+AS_IF([test "x$with_econf" != xno], [
+  # new version -- all libsystemd-* libs merged into libsystemd
+  PKG_CHECK_MODULES([ECONF], [libeconf], [have_econf=yes], [have_econf=no])
+    AS_CASE([$with_econf:$have_econf],
+    [yes:no],
+      [AC_MSG_ERROR([libeconf expected but libeconf not found])],
+    [*:yes],
+       AC_DEFINE([HAVE_LIBECONF], [1], [Define if libeconf is available])
+  )
+])
+AM_CONDITIONAL([HAVE_ECONF], [test "x$have_econf" = xyes])
+
+AC_ARG_ENABLE([vendordir],
+  AS_HELP_STRING([--enable-vendordir=DIR], [Direcotry for istribution provided configuration files]),,
+  []
+)
+AC_SUBST([vendordir], [$enable_vendordir])
+AM_CONDITIONAL([HAVE_VENDORDIR], [test "x$enable_vendordir" != x])
+
 
 AC_ARG_WITH([bashcompletiondir],
   AS_HELP_STRING([--with-bashcompletiondir=DIR], [Bash completions directory]),
@@ -2461,6 +2486,7 @@ AC_MSG_RESULT([
        usrbin_execdir:    ${usrbin_execdir}
        usrsbin_execdir:   ${usrsbin_execdir}
        usrlib_execdir:    ${usrlib_execdir}
+        vendordir:         ${enable_vendordir}
 
        compiler:          ${CC}
        cflags:            ${CFLAGS}
@@ -2476,6 +2502,7 @@ AC_MSG_RESULT([
        Bash completions:  ${with_bashcompletiondir}
        Systemd support:   ${have_systemd}
        Systemd unitdir:   ${with_systemdsystemunitdir}
+       libeconf support:  ${have_econf}
        Btrfs support:     ${have_btrfs}
        Wide-char support: ${build_widechar}
 
index aafbea307778fd3d808083503e1d6967fd3214eb..22a6c867e8c9a0cf78488da294811d99ab9eb0fb 100644 (file)
@@ -44,6 +44,9 @@ login_SOURCES = \
        login-utils/logindefs.c \
        login-utils/logindefs.h
 login_LDADD = $(LDADD) libcommon.la -lpam
+if HAVE_VENDORDIR
+login_CFLAGS = $(AM_CFLAGS) -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\"
+endif
 if HAVE_LINUXPAM
 login_LDADD += -lpam_misc
 endif
@@ -53,6 +56,9 @@ endif
 if HAVE_SELINUX
 login_LDADD += -lselinux
 endif
+if HAVE_ECONF
+login_LDADD += -leconf
+endif
 endif # BUILD_LOGIN
 
 
@@ -121,8 +127,14 @@ chfn_SOURCES = \
        login-utils/logindefs.h \
        $(chfn_chsh_sources)
 chfn_CFLAGS = $(chfn_chsh_cflags)
+if HAVE_VENDORDIR
+chfn_CFLAGS += -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\"
+endif
 chfn_LDFLAGS = $(chfn_chsh_ldflags)
 chfn_LDADD = $(LDADD) $(chfn_chsh_ldadd)
+if HAVE_ECONF
+chfn_LDADD += -leconf
+endif
 
 chsh_SOURCES = login-utils/chsh.c $(chfn_chsh_sources)
 chsh_CFLAGS = $(chfn_chsh_cflags)
@@ -141,6 +153,9 @@ su_SOURCES = \
        login-utils/logindefs.c \
        login-utils/logindefs.h
 su_CFLAGS = $(SUID_CFLAGS) $(AM_CFLAGS)
+if HAVE_VENDORDIR
+su_CFLAGS += -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\"
+endif
 su_LDFLAGS = $(SUID_LDFLAGS) $(AM_LDFLAGS)
 su_LDADD = $(LDADD) libcommon.la -lpam
 if HAVE_LINUXPAM
@@ -149,6 +164,9 @@ endif
 if HAVE_UTIL
 su_LDADD += -lutil
 endif
+if HAVE_ECONF
+su_LDADD += -leconf
+endif
 endif # BUILD_SU
 
 
@@ -168,6 +186,12 @@ endif
 if HAVE_UTIL
 runuser_LDADD += -lutil
 endif
+if HAVE_ECONF
+runuser_LDADD += -leconf
+endif
+if HAVE_VENDORDIR
+runuser_CFLAGS = $(AM_CFLAGS) -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\"
+endif
 endif # BUILD_RUNUSER
 
 
@@ -192,6 +216,9 @@ lslogins_SOURCES = \
        login-utils/logindefs.h
 lslogins_LDADD = $(LDADD) libcommon.la libsmartcols.la
 lslogins_CFLAGS = $(AM_CFLAGS) -I$(ul_libsmartcols_incdir)
+if HAVE_VENDORDIR
+lslogins_CFLAGS += -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\"
+endif
 if HAVE_SELINUX
 lslogins_LDADD += -lselinux
 endif
@@ -199,6 +226,9 @@ if HAVE_SYSTEMD
 lslogins_LDADD += $(SYSTEMD_LIBS) $(SYSTEMD_JOURNAL_LIBS)
 lslogins_CFLAGS += $(SYSTEMD_CFLAGS) $(SYSTEMD_JOURNAL_CFLAGS)
 endif
+if HAVE_ECONF
+lslogins_LDADD += -leconf
+endif
 endif # BUILD_LSLOGINS
 
 if BUILD_VIPW
@@ -231,6 +261,12 @@ test_logindefs_SOURCES = \
        login-utils/logindefs.c \
        login-utils/logindefs.h
 test_logindefs_CPPFLAGS = -DTEST_PROGRAM $(AM_CPPFLAGS)
+if HAVE_VENDORDIR
+test_logindefs_CPPFLAGS += -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\"
+endif
+if HAVE_ECONF
+test_logindefs_LDADD = -leconf
+endif
 
 
 install-exec-hook:
index 2b505d255d564be365bbb812677e1f918a5778e9..9075ad9e75d8a062fa068ab1943cb9250c8f296b 100644 (file)
 #include "pathnames.h"
 #include "xalloc.h"
 
+
+static void (*logindefs_loader)(void *) = NULL;
+static void *logindefs_loader_data = NULL;
+
+void logindefs_set_loader(void (*loader)(void *data), void *data)
+{
+       logindefs_loader = loader;
+       logindefs_loader_data = data;
+}
+
+#ifndef HAVE_LIBECONF
+
 struct item {
        char *name;             /* name of the option.  */
        char *value;            /* value of the option.  */
@@ -48,9 +60,6 @@ struct item {
 
 static struct item *list = NULL;
 
-static void (*logindefs_loader)(void *) = NULL;
-static void *logindefs_loader_data = NULL;
-
 void free_getlogindefs_data(void)
 {
        struct item *ptr;
@@ -145,12 +154,6 @@ void logindefs_load_file(const char *filename)
        fclose(f);
 }
 
-void logindefs_set_loader(void (*loader)(void *data), void *data)
-{
-       logindefs_loader = loader;
-       logindefs_loader_data = data;
-}
-
 static void load_defaults(void)
 {
        if (logindefs_loader)
@@ -232,6 +235,156 @@ const char *getlogindefs_str(const char *name, const char *dflt)
        return ptr->value;
 }
 
+#else
+
+#include <libeconf.h>
+
+static econf_file *file = NULL;
+
+void free_getlogindefs_data(void)
+{
+       econf_free (file);
+       file = NULL;
+}
+
+#ifndef VENDORDIR
+#define VENDORDIR NULL
+#endif
+
+static void load_defaults(void)
+{
+       econf_err error;
+
+       if (file != NULL)
+               free_getlogindefs_data();
+
+       if ((error = econf_readDirs(&file, VENDORDIR, "/etc",
+                                   "login", "defs", "= \t", "#")))
+         syslog(LOG_NOTICE, _("Error reading login.defs: %s"),
+                econf_errString(error));
+
+       if (logindefs_loader)
+               logindefs_loader(logindefs_loader_data);
+
+}
+
+void logindefs_load_file(const char *filename)
+{
+       econf_file *file_l, *file_m;
+       char *path;
+
+       logindefs_loader = NULL; /* No recursion */
+
+#if HAVE_VENDORDIR
+       if (asprintf (&path, VENDORDIR"/%s", filename) == -1)
+               return;
+       if (!econf_readFile(&file_l, path, "= \t", "#")) {
+               if (file == NULL)
+                       file = file_l;
+               else if (!econf_mergeFiles(&file_m, file, file_l)) {
+                       econf_free(file);
+                       file = file_m;
+                       econf_free(file_l);
+               }
+       }
+       free (path);
+#endif
+
+       if (asprintf (&path, "/etc/%s", filename) == -1)
+               return;
+       if (!econf_readFile(&file_l, path, "= \t", "#")) {
+               if (file == NULL)
+                       file = file_l;
+               else if (!econf_mergeFiles(&file_m, file, file_l)) {
+                       econf_free(file);
+                       file = file_m;
+                       econf_free(file_l);
+               }
+       } else {
+         /* Try original filename, could be relative */
+               if (!econf_readFile(&file_l, filename, "= \t", "#")) {
+                       if (file == NULL)
+                               file = file_l;
+                       else if (!econf_mergeFiles(&file_m, file, file_l)) {
+                               econf_free(file);
+                               file = file_m;
+                               econf_free(file_l);
+                       }
+               }
+       }
+       free (path);
+}
+
+int getlogindefs_bool(const char *name, int dflt)
+{
+        bool value;
+       econf_err error;
+
+       if (!file)
+               load_defaults();
+
+       if (!file)
+               return dflt;
+
+       if ((error = econf_getBoolValue(file, NULL, name, &value))) {
+               if (error != ECONF_NOKEY)
+                       syslog(LOG_NOTICE, _("couldn't fetch %s: %s"), name,
+                              econf_errString(error));
+               return dflt;
+       }
+       if (value == true)
+               return 0;
+       else
+               return 1;
+}
+
+unsigned long getlogindefs_num(const char *name, unsigned long dflt)
+{
+       unsigned long value;
+       econf_err error;
+
+       if (!file)
+               load_defaults();
+
+       if (!file)
+               return dflt;
+
+       if ((error = econf_getUInt64Value(file, NULL, name, &value))) {
+               if (error != ECONF_NOKEY)
+                       syslog(LOG_NOTICE, _("couldn't fetch %s: %s"), name,
+                              econf_errString(error));
+               return dflt;
+       }
+       return value;
+}
+
+/*
+ * Returns:
+ *     @dflt           if @name not found
+ *     ""              (empty string) if found, but value not defined
+ *     "string"        if found
+ */
+const char *getlogindefs_str(const char *name, const char *dflt)
+{
+        char *value;
+       econf_err error;
+
+       if (!file)
+               load_defaults();
+
+       if (!file)
+               return dflt;
+
+       if ((error = econf_getStringValue(file, NULL, name, &value))) {
+               if (error != ECONF_NOKEY)
+                 syslog(LOG_NOTICE, _("couldn't fetch %s: %s"), name,
+                        econf_errString(error));
+               return dflt;
+       }
+       return value;
+}
+#endif /* !HAVE_LIBECONF */
+
 /*
  * For compatibility with shadow-utils we have to support additional
  * syntax for environment variables in login.defs(5) file. The standard
@@ -283,7 +436,6 @@ int effective_access(const char *path, int mode)
        return fd == -1 ? -1 : 0;
 }
 
-
 /*
  * Check the per-account or the global hush-login setting.
  *
@@ -412,12 +564,33 @@ int main(int argc, char *argv[])
        logindefs_load_file(argv[1]);
 
        if (argc != 4) {        /* list all */
+#ifdef HAVE_LIBECONF
+               econf_err error;
+               size_t key_number;
+               char **keys;
+
+               if ((error = econf_getKeys(file, NULL, &key_number, &keys)))
+                       errx(EXIT_FAILURE, "Couldn't list all keys: %s",
+                            econf_errString(error));
+
+               for (size_t i = 0; i < key_number; i++) {
+                       char *value = NULL;
+
+                       econf_getStringValue(file, NULL, keys[i], &value);
+                       printf ("%s: $%s: '%s'\n", "logindefs.data",
+                               keys[i], value);
+               }
+
+               econf_free (keys);
+               econf_free (file);
+
+#else
                struct item *ptr;
 
                for (ptr = list; ptr; ptr = ptr->next)
                        printf("%s: $%s: '%s'\n", ptr->path, ptr->name,
                               ptr->value);
-
+#endif
                return EXIT_SUCCESS;
        }
 
index 4d91b22e44b28e4d63a76a33e3e3ed329c09e77b..57d584e550ef15b1a579cfe9da9d1316bf5d705b 100644 (file)
@@ -90,8 +90,13 @@ UL_DEBUG_DEFINE_MASKNAMES(su) = UL_DEBUG_EMPTY_MASKNAMES;
 #define PAM_SRVNAME_RUNUSER "runuser"
 #define PAM_SRVNAME_RUNUSER_L "runuser-l"
 
+#ifdef HAVE_LIBECONF
+#define _PATH_LOGINDEFS_SU     "default/su"
+#define _PATH_LOGINDEFS_RUNUSER "default/runuser"
+#else
 #define _PATH_LOGINDEFS_SU     "/etc/default/su"
 #define _PATH_LOGINDEFS_RUNUSER "/etc/default/runuser"
+#endif
 
 #define is_pam_failure(_rc)    ((_rc) != PAM_SUCCESS)
 
@@ -1231,7 +1236,9 @@ static void load_config(void *data)
        struct su_context *su = (struct su_context *) data;
 
        DBG(MISC, ul_debug("loading logindefs"));
+#ifndef HAVE_LIBECONF
        logindefs_load_file(_PATH_LOGINDEFS);
+#endif
        logindefs_load_file(su->runuser ? _PATH_LOGINDEFS_RUNUSER : _PATH_LOGINDEFS_SU);
 }