From bfd51b6bff4df2c6e78b1718fa11623d249841e8 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Michal=20=C5=BDidek?= Date: Tue, 22 Mar 2016 14:09:34 +0100 Subject: [PATCH] confdb: Make it possible to use config snippets Resolves: https://fedorahosted.org/sssd/ticket/2247 Signed-off-by: Lukas Slebodnik --- Makefile.am | 4 ++- contrib/sssd.spec.in | 1 + src/confdb/confdb.h | 1 + src/confdb/confdb_setup.c | 44 +++++------------------ src/confdb/confdb_setup.h | 1 + src/external/libini_config.m4 | 12 +++++++ src/monitor/monitor.c | 6 ++-- src/tools/common/sss_tools.c | 4 ++- src/util/sss_ini.c | 81 +++++++++++++++++++++++++++++++++++++++---- src/util/sss_ini.h | 3 +- 10 files changed, 109 insertions(+), 48 deletions(-) diff --git a/Makefile.am b/Makefile.am index 152fdbfc435179dfaf2dec1c248bd83a037e2420..d87896df403147acb69b7b50db779af6ad6e6162 100644 --- a/Makefile.am +++ b/Makefile.am @@ -3849,6 +3849,7 @@ SSSD_USER_DIRS = \ $(DESTDIR)$(pubconfpath)/krb5.include.d \ $(DESTDIR)$(gpocachepath) \ $(DESTDIR)$(sssdconfdir) \ + $(DESTDIR)$(sssdconfdir)/conf.d \ $(DESTDIR)$(sssddefaultconfdir) \ $(DESTDIR)$(logpath) \ $(NULL) @@ -3883,7 +3884,8 @@ endif $(INSTALL) -d -m 0755 $(DESTDIR)$(mcpath) $(DESTDIR)$(pipepath) \ $(DESTDIR)$(pubconfpath) \ $(DESTDIR)$(pubconfpath)/krb5.include.d $(DESTDIR)$(gpocachepath) - $(INSTALL) -d -m 0711 $(DESTDIR)$(sssdconfdir) + $(INSTALL) -d -m 0711 $(DESTDIR)$(sssdconfdir) \ + $(DESTDIR)$(sssdconfdir)/conf.d if HAVE_DOXYGEN docs: diff --git a/contrib/sssd.spec.in b/contrib/sssd.spec.in index 769a074848257e9e407d6e544496f6f14a6ea602..1c2c593dae9ae7ad7c73f7821d635c060e3954b9 100644 --- a/contrib/sssd.spec.in +++ b/contrib/sssd.spec.in @@ -782,6 +782,7 @@ done %attr(755,sssd,sssd) %dir %{gpocachepath} %attr(750,sssd,sssd) %dir %{_var}/log/%{name} %attr(711,sssd,sssd) %dir %{_sysconfdir}/sssd +%attr(711,sssd,sssd) %dir %{_sysconfdir}/sssd/conf.d %ghost %attr(0600,sssd,sssd) %config(noreplace) %{_sysconfdir}/sssd/sssd.conf %if (0%{?use_systemd} == 1) %attr(755,root,root) %dir %{_sysconfdir}/systemd/system/sssd.service.d diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h index 0a3d6a035ca53e7e5563138b5d8daf5a0770a693..2cd75b9e8b7d81261774303ad48fcec4112e3ae4 100644 --- a/src/confdb/confdb.h +++ b/src/confdb/confdb.h @@ -42,6 +42,7 @@ #define CONFDB_FILE "config.ldb" #define SSSD_DEFAULT_CONFIG_FILE SSSD_DEFAULT_CONF_DIR"/sssd.conf" #define SSSD_CONFIG_FILE SSSD_CONF_DIR"/sssd.conf" +#define CONFDB_DEFAULT_CONFIG_DIR SSSD_CONF_DIR"/conf.d" #define SSSD_MIN_ID 1 #define SSSD_LOCAL_MINID 1000 #define CONFDB_DEFAULT_SHELL_FALLBACK "/bin/sh" diff --git a/src/confdb/confdb_setup.c b/src/confdb/confdb_setup.c index c1db9965ffe3b13fce88e09b01777f5d686bce06..42b24f70877462a59b7b2b96b79e5900035df931 100644 --- a/src/confdb/confdb_setup.c +++ b/src/confdb/confdb_setup.c @@ -126,14 +126,14 @@ static int confdb_create_base(struct confdb_ctx *cdb) return EOK; } -static int confdb_init_db(const char *config_file, struct confdb_ctx *cdb) +static int confdb_init_db(const char *config_file, const char *config_dir, + struct confdb_ctx *cdb) { TALLOC_CTX *tmp_ctx; int ret; int sret = EOK; int version; char timestr[21]; - char *lasttimestr; bool in_transaction = false; const char *config_ldif; const char *vals[2] = { timestr, NULL }; @@ -205,41 +205,12 @@ static int confdb_init_db(const char *config_file, struct confdb_ctx *cdb) goto done; } - /* Determine if the conf file has changed since we last updated - * the confdb + /* FIXME: Determine if the conf file or any snippet has changed + * since we last updated the confdb or if some snippet was + * added or removed. */ - ret = sss_ini_get_stat(init_data); - if (ret != EOK) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Status check on config file failed.\n"); - ret = errno; - goto done; - } - errno = 0; - - ret = sss_ini_get_mtime(init_data, sizeof(timestr), timestr); - if (ret <= 0 || ret >= sizeof(timestr)) { - DEBUG(SSSDBG_FATAL_FAILURE, - "Failed to convert time_t to string ??\n"); - ret = errno ? errno : EFAULT; - } - ret = confdb_get_string(cdb, tmp_ctx, "config", "lastUpdate", - NULL, &lasttimestr); - if (ret == EOK) { - - /* check if we lastUpdate and last file modification change differ*/ - if ((lasttimestr != NULL) && (strcmp(lasttimestr, timestr) == 0)) { - /* not changed, get out, nothing more to do */ - ret = EOK; - goto done; - } - } else { - DEBUG(SSSDBG_FATAL_FAILURE, "Failed to get lastUpdate attribute.\n"); - goto done; - } - - ret = sss_ini_get_config(init_data, config_file); + ret = sss_ini_get_config(init_data, config_file, config_dir); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to load configuration\n"); goto done; @@ -357,6 +328,7 @@ done: errno_t confdb_setup(TALLOC_CTX *mem_ctx, const char *cdb_file, const char *config_file, + const char *config_dir, struct confdb_ctx **_cdb) { TALLOC_CTX *tmp_ctx; @@ -412,7 +384,7 @@ errno_t confdb_setup(TALLOC_CTX *mem_ctx, goto done; } - ret = confdb_init_db(config_file, cdb); + ret = confdb_init_db(config_file, config_dir, cdb); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "ConfDB initialization has failed " "[%d]: %s\n", ret, sss_strerror(ret)); diff --git a/src/confdb/confdb_setup.h b/src/confdb/confdb_setup.h index d995fc98cf3cf109fcbe08b44e25908b81ac5bd4..a348b29739cab4a2f0008fdbe0b84ed68351bb32 100644 --- a/src/confdb/confdb_setup.h +++ b/src/confdb/confdb_setup.h @@ -48,6 +48,7 @@ errno_t confdb_setup(TALLOC_CTX *mem_ctx, const char *cdb_file, const char *config_file, + const char *config_dir, struct confdb_ctx **_cdb); diff --git a/src/external/libini_config.m4 b/src/external/libini_config.m4 index 9e5c69fbde6f64ddfdffd276fb9c5a21d96f6a01..a2bba4243b86996bdfc81e894ca8bdc489a9c4e6 100644 --- a/src/external/libini_config.m4 +++ b/src/external/libini_config.m4 @@ -19,6 +19,18 @@ PKG_CHECK_MODULES(INI_CONFIG_V0, [ INI_CONFIG_LIBS="$INI_CONFIG_V1_1_LIBS" HAVE_LIBINI_CONFIG_V1_1=1 AC_DEFINE_UNQUOTED(HAVE_LIBINI_CONFIG_V1_1, 1, [libini_config version 1.1.0 or greater]) + PKG_CHECK_MODULES(INI_CONFIG_V1_3, [ + ini_config >= 1.3.0], [ + + INI_CONFIG_CFLAGS="$INI_CONFIG_V1_3_CFLAGS" + INI_CONFIG_LIBS="$INI_CONFIG_V1_3_LIBS" + HAVE_LIBINI_CONFIG_V1_3=1 + AC_DEFINE_UNQUOTED(HAVE_LIBINI_CONFIG_V1_3, 1, + [libini_config version 1.3.0 or greater]) + ], [ + AC_MSG_WARN([libini_config-devel >= 1.3.0 not available, using older version]) + ] + ) ], [ AC_MSG_WARN([libini_config-devel >= 1.1.0 not available, using older version]) ] diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c index 8aec39656046bb4a2e6be0bf01f3c66d82414c6d..7ea0ce6b548329915aa8000eaa16ab16c7dd50cd 100644 --- a/src/monitor/monitor.c +++ b/src/monitor/monitor.c @@ -1872,6 +1872,7 @@ static int monitor_ctx_destructor(void *mem) */ errno_t load_configuration(TALLOC_CTX *mem_ctx, const char *config_file, + const char *config_dir, struct mt_ctx **monitor) { errno_t ret; @@ -1892,7 +1893,7 @@ errno_t load_configuration(TALLOC_CTX *mem_ctx, goto done; } - ret = confdb_setup(ctx, cdb_file, config_file, &ctx->cdb); + ret = confdb_setup(ctx, cdb_file, config_file, config_dir, &ctx->cdb); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to setup ConfDB [%d]: %s\n", ret, sss_strerror(ret)); @@ -3147,7 +3148,8 @@ int main(int argc, const char *argv[]) } /* Parse config file, fail if cannot be done */ - ret = load_configuration(tmp_ctx, config_file, &monitor); + ret = load_configuration(tmp_ctx, config_file, CONFDB_DEFAULT_CONFIG_DIR, + &monitor); if (ret != EOK) { switch (ret) { case ERR_MISSING_CONF: diff --git a/src/tools/common/sss_tools.c b/src/tools/common/sss_tools.c index 6080bb0ac3c6dff5cc6159139d5a8fd01d6ce133..182b66e1e57ec8c9b007094dc793fbc8078d1839 100644 --- a/src/tools/common/sss_tools.c +++ b/src/tools/common/sss_tools.c @@ -103,7 +103,9 @@ static errno_t sss_tool_confdb_init(TALLOC_CTX *mem_ctx, return ENOMEM; } - ret = confdb_setup(mem_ctx, path, SSSD_CONFIG_FILE, &confdb); + ret = confdb_setup(mem_ctx, path, + SSSD_CONFIG_FILE, CONFDB_DEFAULT_CONFIG_DIR, + &confdb); talloc_zfree(path); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Unable to setup ConfDB [%d]: %s\n", diff --git a/src/util/sss_ini.c b/src/util/sss_ini.c index 766a75ea6730b3a8f5fbec5f2086075fbcb2d81b..75f84183e3daeba2fe3c773d106ed95d7f558be2 100644 --- a/src/util/sss_ini.c +++ b/src/util/sss_ini.c @@ -46,7 +46,10 @@ struct sss_ini_initdata { char **error_list; + struct ref_array *ra_success_list; + struct ref_array *ra_error_list; struct ini_cfgobj *sssd_config; + struct ini_cfgobj *orig_sssd_config; struct value_obj *obj; const struct stat *cstat; struct ini_cfgfile *file; @@ -205,13 +208,31 @@ void sss_ini_config_print_errors(char **error_list) /* Load configuration */ int sss_ini_get_config(struct sss_ini_initdata *init_data, - const char *config_file) + const char *config_file, + const char *config_dir) { int ret; #ifdef HAVE_LIBINI_CONFIG_V1 +#ifdef HAVE_LIBINI_CONFIG_V1_3 + const char *patterns[] = { "^[^\\.].*\\.conf", NULL }; + const char *sections[] = { ".*", NULL }; + uint32_t i = 0; + char *msg = NULL; + struct access_check snip_check; + + snip_check.flags = INI_ACCESS_CHECK_MODE | INI_ACCESS_CHECK_UID + | INI_ACCESS_CHECK_GID; + snip_check.uid = 0; /* owned by root */ + snip_check.gid = 0; /* owned by root */ + snip_check.mode = S_IRUSR; /* r**------ */ + snip_check.mask = ALLPERMS & ~(S_IWUSR|S_IXUSR); +#endif /* HAVE_LIBINI_CONFIG_V1_3 */ + + init_data->sssd_config = NULL; + init_data->ra_success_list = NULL; /* Create config object */ - ret = ini_config_create(&(init_data->sssd_config)); + ret = ini_config_create(&(init_data->orig_sssd_config)); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to create config object. Error %d.\n", ret); @@ -223,27 +244,73 @@ int sss_ini_get_config(struct sss_ini_initdata *init_data, INI_STOP_ON_ANY, INI_MV1S_OVERWRITE, INI_PARSE_NOWRAP, - init_data->sssd_config); + init_data->orig_sssd_config); if (ret != EOK) { DEBUG(SSSDBG_FATAL_FAILURE, "Failed to parse configuration. Error %d.\n", ret); - if (ini_config_error_count(init_data->sssd_config)) { + if (ini_config_error_count(init_data->orig_sssd_config)) { DEBUG(SSSDBG_FATAL_FAILURE, "Errors detected while parsing: %s\n", ini_config_get_filename(init_data->file)); - ini_config_get_errors(init_data->sssd_config, + ini_config_get_errors(init_data->orig_sssd_config, &init_data->error_list); sss_ini_config_print_errors(init_data->error_list); ini_config_free_errors(init_data->error_list); } - ini_config_destroy(init_data->sssd_config); - init_data->sssd_config = NULL; + ini_config_destroy(init_data->orig_sssd_config); + init_data->orig_sssd_config = NULL; return ret; } + /* Create config object */ + ret = ini_config_create(&(init_data->sssd_config)); + if (ret != EOK) { + DEBUG(SSSDBG_FATAL_FAILURE, + "Failed to create config object. Error %d.\n", ret); + return ret; + } + +#ifdef HAVE_LIBINI_CONFIG_V1_3 + ret = ini_config_augment(init_data->orig_sssd_config, + config_dir, + patterns, + sections, + &snip_check, + INI_STOP_ON_ANY, + INI_MV1S_OVERWRITE, + INI_PARSE_NOWRAP, + INI_MV2S_OVERWRITE, + &init_data->sssd_config, + &init_data->ra_error_list, + &init_data->ra_success_list); + if (ret != EOK) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Failed to augment configuration [%d]: %s", + ret, sss_strerror(ret)); + } + + while (ref_array_get(init_data->ra_error_list, i, &msg) != NULL) { + DEBUG(SSSDBG_CRIT_FAILURE, + "Config merge error: %s\n", msg); + i++; + } + + i = 0; + while (ref_array_get(init_data->ra_success_list, i, &msg) != NULL) { + DEBUG(SSSDBG_TRACE_FUNC, + "Config merge success: %s\n", msg); + i++; + } +#endif + + if (init_data->sssd_config == NULL) { + /* Fall back to original configuration */ + init_data->sssd_config = init_data->orig_sssd_config; + } + return ret; #else diff --git a/src/util/sss_ini.h b/src/util/sss_ini.h index 3beaca15ba87ad12a016a3295371a56239165683..f5b36deb9cacfecbd68dd2a4d37a4398ce280c3c 100644 --- a/src/util/sss_ini.h +++ b/src/util/sss_ini.h @@ -58,7 +58,8 @@ int sss_ini_get_mtime(struct sss_ini_initdata *init_data, /* Load configuration */ int sss_ini_get_config(struct sss_ini_initdata *init_data, - const char *config_file); + const char *config_file, + const char *config_dir); /* Get configuration object */ int sss_ini_get_cfgobj(struct sss_ini_initdata *init_data, const char *section, const char *name); -- 2.4.11