From 9e584ff32428b9832470d19a54bba4838f3a6c34 Mon Sep 17 00:00:00 2001 From: Thorsten Kukuk Date: Tue, 3 Sep 2019 15:04:43 +0200 Subject: [PATCH 1/2] Add support for libeconf --- configure.ac | 27 ++++++ login-utils/Makemodule.am | 36 +++++++ login-utils/logindefs.c | 195 +++++++++++++++++++++++++++++++++++--- login-utils/su-common.c | 7 ++ 4 files changed, 254 insertions(+), 11 deletions(-) Index: util-linux-2.35.1/configure.ac =================================================================== --- util-linux-2.35.1.orig/configure.ac +++ util-linux-2.35.1/configure.ac @@ -2274,6 +2274,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]), @@ -2527,6 +2552,7 @@ AC_MSG_RESULT([ usrbin_execdir: ${usrbin_execdir} usrsbin_execdir: ${usrsbin_execdir} usrlib_execdir: ${usrlib_execdir} + vendordir: ${enable_vendordir} compiler: ${CC} cflags: ${CFLAGS} @@ -2542,6 +2568,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: util-linux-2.35.1/login-utils/Makemodule.am =================================================================== --- util-linux-2.35.1.orig/login-utils/Makemodule.am +++ util-linux-2.35.1/login-utils/Makemodule.am @@ -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 @@ -152,6 +167,9 @@ su_SOURCES += lib/pty-session.c \ lib/monotonic.c su_LDADD += -lutil $(REALTIME_LIBS) endif +if HAVE_ECONF +su_LDADD += -leconf +endif endif # BUILD_SU @@ -174,6 +192,12 @@ runuser_SOURCES += lib/pty-session.c \ lib/monotonic.c runuser_LDADD += -lutil $(REALTIME_LIBS) endif +if HAVE_ECONF +runuser_LDADD += -leconf +endif +if HAVE_VENDORDIR +runuser_CFLAGS = $(AM_CFLAGS) -DHAVE_VENDORDIR -DVENDORDIR=\"@vendordir@\" +endif endif # BUILD_RUNUSER @@ -198,6 +222,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 @@ -205,6 +232,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 @@ -237,6 +267,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: util-linux-2.35.1/login-utils/logindefs.c =================================================================== --- util-linux-2.35.1.orig/login-utils/logindefs.c +++ util-linux-2.35.1/login-utils/logindefs.c @@ -38,6 +38,18 @@ #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 *fil 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 return ptr->value; } +#else + +#include + +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 = NULL, *file_m = NULL; + 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; + } + return value; +} + +unsigned long getlogindefs_num(const char *name, unsigned long dflt) +{ + uint64_t 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; + } + if (value) + return value; + else + return strdup(""); +} +#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, i return fd == -1 ? -1 : 0; } - /* * Check the per-account or the global hush-login setting. * @@ -412,12 +564,28 @@ int main(int argc, char *argv[]) logindefs_load_file(argv[1]); if (argc != 4) { /* list all */ +#ifdef HAVE_LIBECONF + int i; + char *keys[] = {"END", "EMPTY", "CRAZY3", "CRAZY2", "CRAZY1", + "BOOLEAN", "NUMBER", "STRING", "HELLO_WORLD", + NULL}; + + for (i = 0; keys[i] != NULL; i++) { + char *value = NULL; + + econf_getStringValue(file, NULL, keys[i], &value); + printf ("%s: $%s: '%s'\n", argv[1], keys[i], value); + } + + 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: util-linux-2.35.1/login-utils/su-common.c =================================================================== --- util-linux-2.35.1.orig/login-utils/su-common.c +++ util-linux-2.35.1/login-utils/su-common.c @@ -90,8 +90,13 @@ UL_DEBUG_DEFINE_MASKNAMES(su) = UL_DEBUG #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) @@ -1038,7 +1043,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); }