[SSSD] [PATCH] sss_config: alter configuration file
Lukas Slebodnik
lslebodn at redhat.com
Tue Apr 22 09:21:26 UTC 2014
On (22/04/14 10:29), Pavel Březina wrote:
>Hi,
>I'm sending some patches that I'll use for OpenLMI provider. It
>supports few modifications of sssd.conf through augeas.
>
>For the moment, I think we should not bound to any particular API so
>even though I made it a separate object, I don't have any intentions
>to make it publicly usable library.
>
>This code will be used from D-Bus responder. I may extend the API if needed.
>
>Unit tests are attached.
>From 29b998ed4b98b43a815023f32413442c01ecf92a Mon Sep 17 00:00:00 2001
>From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina at redhat.com>
>Date: Fri, 18 Apr 2014 17:23:16 +0200
>Subject: [PATCH 1/3] sss_config: the code
>
>---
> src/util/sss_config.c | 507 ++++++++++++++++++++++++++++++++++++++++++++++++++
> src/util/sss_config.h | 71 +++++++
> 2 files changed, 578 insertions(+)
> create mode 100644 src/util/sss_config.c
> create mode 100644 src/util/sss_config.h
>
>diff --git a/src/util/sss_config.c b/src/util/sss_config.c
>new file mode 100644
>index 0000000000000000000000000000000000000000..6a6216da1b90adc2628cbdae692228121162fb3e
>--- /dev/null
>+++ b/src/util/sss_config.c
>@@ -0,0 +1,507 @@
>+/*
>+ Authors:
>+ Pavel Březina <pbrezina at redhat.com>
>+
>+ Copyright (C) 2014 Red Hat
>+
>+ This program is free software; you can redistribute it and/or modify
>+ it under the terms of the GNU General Public License as published by
>+ the Free Software Foundation; either version 3 of the License, or
>+ (at your option) any later version.
>+
>+ This program is distributed in the hope that it will be useful,
>+ but WITHOUT ANY WARRANTY; without even the implied warranty of
>+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>+ GNU General Public License for more details.
>+
>+ You should have received a copy of the GNU General Public License
>+ along with this program. If not, see <http://www.gnu.org/licenses/>.
>+*/
>+
>+#include <augeas.h>
>+#include <talloc.h>
>+#include <string.h>
>+#include "util/sss_config.h"
>+
>+#define PATH_SECTION "/files/%s/target[. = \"%s\"]"
>+#define PATH_OPTION PATH_SECTION "/%s"
>+
>+#define build_section_path(mem_ctx, config_ctx, section) \
>+ talloc_asprintf(mem_ctx, PATH_SECTION, config_ctx->file, section)
>+
>+#define build_option_path(mem_ctx, config_ctx, section, option) \
>+ talloc_asprintf(mem_ctx, PATH_OPTION, config_ctx->file, section, option)
>+
>+struct sss_config_ctx
>+{
>+ augeas *auges_ctx;
>+ const char *file;
>+};
>+
>+static errno_t
>+sss_config_set_option(struct sss_config_ctx *ctx,
>+ const char *section,
>+ const char *option,
>+ const char *value)
>+{
>+ TALLOC_CTX *tmp_ctx = NULL;
>+ char *target_path = NULL;
>+ char *option_path = NULL;
>+ errno_t ret;
>+ int aug_ret;
>+
>+ tmp_ctx = talloc_new(NULL);
>+ if (tmp_ctx == NULL) {
>+ return ENOMEM;
>+ }
>+
>+ target_path = build_section_path(tmp_ctx, ctx, section);
>+ if (target_path == NULL) {
>+ ret = ENOMEM;
>+ goto done;
>+ }
>+
>+ option_path = build_option_path(tmp_ctx, ctx, section, option);
>+ if (option_path == NULL) {
>+ ret = ENOMEM;
>+ goto done;
>+ }
>+
>+ /* Set configuration option:
>+ *
>+ * # make sure the section exists
>+ * set /files/$file/target[. = "$section"] $section
>+ *
>+ * # set value
>+ * set /files/$file/target[. = "$section"]/$option $value
>+ */
>+
>+ aug_ret = aug_set(ctx->auges_ctx, target_path, section);
>+ if (aug_ret != 0) {
>+ ret = EIO;
>+ goto done;
>+ }
>+
>+ aug_ret = aug_set(ctx->auges_ctx, option_path, value);
>+ if (aug_ret != 0) {
>+ ret = EIO;
>+ goto done;
>+ }
>+
>+ ret = EOK;
>+
>+done:
>+ talloc_free(tmp_ctx);
>+ return ret;
>+}
>+
>+static errno_t
>+sss_config_rm_option(struct sss_config_ctx *ctx,
>+ const char *section,
>+ const char *option)
>+{
>+ TALLOC_CTX *tmp_ctx = NULL;
>+ char *option_path = NULL;
>+ errno_t ret;
>+ int aug_ret;
>+
>+ tmp_ctx = talloc_new(NULL);
>+ if (tmp_ctx == NULL) {
>+ return ENOMEM;
>+ }
>+
>+ option_path = build_option_path(tmp_ctx, ctx, section, option);
>+ if (option_path == NULL) {
>+ ret = ENOMEM;
>+ goto done;
>+ }
>+
>+ /* Remove configuration option:
>+ *
>+ * rm /files/$file/target[. = "$section"]/$option
>+ */
>+
>+ aug_ret = aug_rm(ctx->auges_ctx, option_path);
>+ if (aug_ret != 1) {
>+ ret = EIO;
>+ goto done;
>+ }
>+
>+ ret = EOK;
>+
>+done:
>+ talloc_free(tmp_ctx);
>+ return ret;
>+}
>+
>+static errno_t
>+sss_config_set_list(struct sss_config_ctx *ctx,
>+ const char *section,
>+ const char *option,
>+ char **list)
>+{
>+ TALLOC_CTX *tmp_ctx = NULL;
>+ char *value = NULL;
>+ errno_t ret;
>+ int i;
>+
>+ if (list == NULL) {
>+ return EOK;
>+ }
>+
>+ tmp_ctx = talloc_new(NULL);
>+ if (tmp_ctx == NULL) {
>+ return ENOMEM;
>+ }
>+
>+ if (list[0] == NULL) {
>+ ret = sss_config_rm_option(ctx, section, option);
>+ goto done;
>+ }
>+
>+ value = talloc_strdup(tmp_ctx, list[0]);
>+ if (value == NULL) {
>+ ret = ENOMEM;
>+ goto done;
>+ }
>+
>+ for (i = 1; list[i] != NULL; i++) {
>+ value = talloc_asprintf_append(value, ", %s", list[i]);
>+ if (value == NULL) {
>+ ret = ENOMEM;
>+ goto done;
>+ }
>+ }
>+
>+ ret = sss_config_set_option(ctx, section, option, value);
>+
>+done:
>+ talloc_free(tmp_ctx);
>+ return ret;
>+}
>+
>+static errno_t
>+sss_config_get_list(TALLOC_CTX *mem_ctx,
>+ struct sss_config_ctx *ctx,
>+ const char *section,
>+ const char *option,
>+ char ***_list)
>+{
>+ TALLOC_CTX *tmp_ctx = NULL;
>+ char *option_path = NULL;
>+ const char *value = NULL;
>+ char **list = NULL;
>+ errno_t ret;
>+ int aug_ret;
>+
>+ tmp_ctx = talloc_new(NULL);
>+ if (tmp_ctx == NULL) {
>+ return ENOMEM;
>+ }
>+
>+ option_path = build_option_path(tmp_ctx, ctx, section, option);
>+ if (option_path == NULL) {
ret = EINVAL???
src/util/sss_config.c:203:9: error: variable 'ret' is used uninitialized whenever 'if' condition
is true [-Werror,-Wsometimes-uninitialized]
if (option_path == NULL) {
^~~~~~~~~~~~~~~~~~~
src/util/sss_config.c:233:12: note: uninitialized use occurs here
return ret;
^~~
>+ goto done;
>+ }
>+
>+ aug_ret = aug_get(ctx->auges_ctx, option_path, &value);
>+ if (aug_ret == 0 || (aug_ret == 1 && (value == NULL || *value == '\0'))) {
>+ /* option is not present, return empty list */
>+ list = talloc_zero_array(tmp_ctx, char*, 1);
>+ if (list == NULL) {
>+ ret = ENOMEM;
>+ }
>+
>+ ret = EOK;
>+ goto done;
>+ } else if (aug_ret != 1) {
>+ /* error: more than one value found */
>+ ret = EINVAL;
>+ goto done;
>+ }
>+
>+ ret = split_on_separator(tmp_ctx, value, ',', true, true, &list, NULL);
>+ if (ret != EOK) {
>+ goto done;
>+ }
>+
>+ *_list = talloc_steal(mem_ctx, list);
>+ ret = EOK;
>+
>+done:
>+ talloc_free(tmp_ctx);
>+ return ret;
>+}
>+
>+static errno_t
>+sss_config_is_in_list(struct sss_config_ctx *ctx,
>+ const char *section,
>+ const char *option,
>+ const char *value,
>+ bool *_result)
>+{
>+ char **list = NULL;
>+ errno_t ret;
>+
>+ ret = sss_config_get_list(ctx, ctx, section, option, &list);
>+ if (ret != EOK) {
>+ goto done;
>+ }
>+
>+ *_result = string_in_list(value, list, true);
>+
>+done:
>+ talloc_free(list);
>+ return ret;
>+}
>+
>+static errno_t
>+sss_config_add_to_list(struct sss_config_ctx *ctx,
>+ const char *section,
>+ const char *option,
>+ const char *value)
>+{
>+ TALLOC_CTX *tmp_ctx = NULL;
>+ char **list = NULL;
>+ errno_t ret;
>+ bool result = false;
>+
>+ tmp_ctx = talloc_new(NULL);
>+ if (tmp_ctx == NULL) {
>+ return ENOMEM;
>+ }
>+
>+ ret = sss_config_get_list(tmp_ctx, ctx, section, option, &list);
>+ if (ret != EOK) {
>+ goto done;
>+ }
>+
>+ result = string_in_list(value, list, true);
>+ if (result == true) {
>+ ret = EOK;
>+ goto done;
>+ }
>+
>+ ret = add_string_to_list(tmp_ctx, value, &list);
>+ if (ret != EOK) {
>+ goto done;
>+ }
>+
>+ ret = sss_config_set_list(ctx, section, option, list);
>+
>+done:
>+ talloc_free(tmp_ctx);
>+ return ret;
>+}
>+
>+static errno_t
>+sss_config_del_from_list(struct sss_config_ctx *ctx,
>+ const char *section,
>+ const char *option,
>+ const char *value)
>+{
>+ TALLOC_CTX *tmp_ctx = NULL;
>+ char **list = NULL;
>+ errno_t ret;
>+ bool found;
>+ int i;
>+
>+ tmp_ctx = talloc_new(NULL);
>+ if (tmp_ctx == NULL) {
>+ return ENOMEM;
>+ }
>+
>+ ret = sss_config_get_list(tmp_ctx, ctx, section, option, &list);
>+ if (ret != EOK) {
>+ goto done;
>+ }
>+
>+ if (list == NULL) {
>+ goto done;
>+ }
>+
>+ found = false;
>+ for (i = 0; list[i] != NULL; i++) {
>+ if (strcmp(list[i], value) == 0) {
>+ found = true;
>+ }
>+
>+ if (found) {
>+ list[i] = list[i + 1];
>+ }
>+ }
>+
>+ ret = sss_config_set_list(ctx, section, option, list);
>+
>+done:
>+ talloc_free(tmp_ctx);
>+ return ret;
>+}
>+
>+static int sss_config_ctx_destructor(struct sss_config_ctx *ctx)
>+{
>+ if (ctx->auges_ctx != NULL) {
>+ aug_close(ctx->auges_ctx);
>+ ctx->auges_ctx = NULL;
>+ }
>+
>+ return 0;
>+}
>+
>+struct sss_config_ctx *
>+sss_config_open(TALLOC_CTX *mem_ctx,
>+ const char *root,
>+ const char *file)
>+{
>+ struct sss_config_ctx *ctx = NULL;
>+ errno_t ret;
>+ int aug_ret;
>+
>+ ctx = talloc_zero(mem_ctx, struct sss_config_ctx);
>+ if (ctx == NULL) {
>+ return NULL;
>+ }
>+
>+ talloc_set_destructor(ctx, sss_config_ctx_destructor);
>+
>+ ctx->auges_ctx = aug_init(root, NULL, AUG_NO_LOAD | AUG_NO_MODL_AUTOLOAD
>+ | AUG_SAVE_BACKUP);
>+ if (ctx->auges_ctx == NULL) {
>+ ret = ENOMEM;
>+ goto done;
>+ }
>+
>+ ctx->file = talloc_strdup(ctx, file);
>+ if (ctx->file == NULL) {
>+ ret = ENOMEM;
>+ goto done;
>+ }
>+
>+ /* Load configuration file
>+ *
>+ * set /augeas/load/sssd/lens sssd.lns
>+ * set /augeas/load/sssd/incl $file
>+ * load
>+ */
>+
>+ aug_ret = aug_set(ctx->auges_ctx, "/augeas/load/sssd/lens", "sssd.lns");
>+ if (aug_ret != 0) {
>+ ret = EIO;
>+ goto done;
>+ }
>+
>+ aug_ret = aug_set(ctx->auges_ctx, "/augeas/load/sssd/incl", ctx->file);
>+ if (aug_ret != 0) {
>+ ret = EIO;
>+ goto done;
>+ }
>+
>+ aug_ret = aug_load(ctx->auges_ctx);
>+ if (aug_ret != 0) {
>+ ret = EIO;
>+ goto done;
>+ }
>+
>+ ret = EOK;
>+
>+done:
>+ if (ret != EOK) {
>+ talloc_free(ctx);
>+ }
>+
>+ return ctx;
>+}
>+
>+errno_t
>+sss_config_save(struct sss_config_ctx *ctx)
>+{
>+ int aug_ret;
>+
>+ aug_ret = aug_save(ctx->auges_ctx);
>+ if (aug_ret != 0) {
>+ return EIO;
>+ }
>+
>+ return EOK;
>+}
>+
>+void
>+sss_config_close(struct sss_config_ctx **_ctx)
>+{
>+ if (_ctx == NULL || *_ctx == NULL) {
>+ return;
>+ }
>+
>+ talloc_free(*_ctx);
>+ *_ctx = NULL;
>+}
>+
>+errno_t
>+sss_config_set_debug_level(struct sss_config_ctx *ctx,
>+ const char *section,
>+ uint32_t level)
>+{
>+ char *level_str = NULL;
>+ errno_t ret;
>+
>+ level_str = talloc_asprintf(ctx, "%#.4x", level);
>+ if (level_str == NULL) {
>+ return ENOMEM;
>+ }
>+
>+ ret = sss_config_set_option(ctx, section, CONFDB_SERVICE_DEBUG_LEVEL,
>+ level_str);
>+
>+ talloc_free(level_str);
>+ return ret;
>+}
>+
>+errno_t
>+sss_config_service_is_enabled(struct sss_config_ctx *ctx,
>+ const char *service,
>+ bool *_result)
>+{
>+ return sss_config_is_in_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_SERVICES,
>+ service, _result);
>+}
>+
>+errno_t
>+sss_config_service_enable(struct sss_config_ctx *ctx,
>+ const char *service)
>+{
>+ return sss_config_add_to_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_SERVICES,
>+ service);
>+}
>+
>+errno_t
>+sss_config_service_disable(struct sss_config_ctx *ctx,
>+ const char *service)
>+{
>+ return sss_config_del_from_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_SERVICES,
>+ service);
>+}
>+
>+errno_t
>+sss_config_domain_is_enabled(struct sss_config_ctx *ctx,
>+ const char *domain,
>+ bool *_result)
>+{
>+ return sss_config_is_in_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_DOMAINS,
>+ domain, _result);
>+}
>+
>+errno_t
>+sss_config_domain_enable(struct sss_config_ctx *ctx,
>+ const char *domain)
>+{
>+ return sss_config_add_to_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_DOMAINS,
>+ domain);
>+}
>+
>+errno_t
>+sss_config_domain_disable(struct sss_config_ctx *ctx,
>+ const char *domain)
>+{
>+ return sss_config_del_from_list(ctx, "sssd", CONFDB_MONITOR_ACTIVE_DOMAINS,
>+ domain);
>+}
>diff --git a/src/util/sss_config.h b/src/util/sss_config.h
>new file mode 100644
>index 0000000000000000000000000000000000000000..b59f5fcf0e23e7a6c8543346c52fa06ae6041a3d
>--- /dev/null
>+++ b/src/util/sss_config.h
>@@ -0,0 +1,71 @@
>+/*
>+ Authors:
>+ Pavel Březina <pbrezina at redhat.com>
>+
>+ Copyright (C) 2014 Red Hat
>+
>+ This program is free software; you can redistribute it and/or modify
>+ it under the terms of the GNU General Public License as published by
>+ the Free Software Foundation; either version 3 of the License, or
>+ (at your option) any later version.
>+
>+ This program is distributed in the hope that it will be useful,
>+ but WITHOUT ANY WARRANTY; without even the implied warranty of
>+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
>+ GNU General Public License for more details.
>+
>+ You should have received a copy of the GNU General Public License
>+ along with this program. If not, see <http://www.gnu.org/licenses/>.
>+*/
>+
>+#ifndef SSS_CONFIG_H_
>+#define SSS_CONFIG_H_
>+
>+#include <talloc.h>
>+#include "util/util.h"
>+
>+struct sss_config_ctx;
>+
>+struct sss_config_ctx *
>+sss_config_open(TALLOC_CTX *mem_ctx,
>+ const char *root,
>+ const char *file);
>+
>+errno_t
>+sss_config_save(struct sss_config_ctx *ctx);
>+
>+void
>+sss_config_close(struct sss_config_ctx **_ctx);
>+
>+errno_t
>+sss_config_set_debug_level(struct sss_config_ctx *ctx,
>+ const char *section,
>+ uint32_t level);
>+
>+errno_t
>+sss_config_service_is_enabled(struct sss_config_ctx *ctx,
>+ const char *service,
>+ bool *_result);
>+
>+errno_t
>+sss_config_service_enable(struct sss_config_ctx *ctx,
>+ const char *service);
>+
>+errno_t
>+sss_config_service_disable(struct sss_config_ctx *ctx,
>+ const char *service);
>+
>+errno_t
>+sss_config_domain_is_enabled(struct sss_config_ctx *ctx,
>+ const char *domain,
>+ bool *_result);
>+
>+errno_t
>+sss_config_domain_enable(struct sss_config_ctx *ctx,
>+ const char *domain);
>+
>+errno_t
>+sss_config_domain_disable(struct sss_config_ctx *ctx,
>+ const char *domain);
>+
>+#endif /* SSS_CONFIG_H_ */
>--
>1.7.11.7
>
>From 38a199b55608cf42ff3879a9aaa168ef619a42d1 Mon Sep 17 00:00:00 2001
>From: =?UTF-8?q?Pavel=20B=C5=99ezina?= <pbrezina at redhat.com>
>Date: Mon, 21 Apr 2014 12:17:53 +0200
>Subject: [PATCH 2/3] sss_config: build
>
>---
> Makefile.am | 12 ++++++++++++
> configure.ac | 1 +
> src/external/libaugeas.m4 | 10 ++++++++++
> 3 files changed, 23 insertions(+)
> create mode 100644 src/external/libaugeas.m4
>
>diff --git a/Makefile.am b/Makefile.am
>index 0ce377a03f0b606f18b4e1524de375744096eb09..58b4159b0d1a47ef98a2b88dd751f75f5dc54e18 100644
>--- a/Makefile.am
>+++ b/Makefile.am
>@@ -435,6 +435,7 @@ dist_noinst_HEADERS = \
> src/util/sss_ssh.h \
> src/util/sss_ini.h \
> src/util/sss_format.h \
>+ src/util/sss_config.h \
> src/util/refcount.h \
> src/util/find_uid.h \
> src/util/user_info_msg.h \
>@@ -577,6 +578,17 @@ pkglib_LTLIBRARIES += libsss_child.la
> libsss_child_la_SOURCES = src/util/child_common.c
> libsss_child_la_LDFLAGS = -avoid-version
>
^^^^
trailing spaces.
sh$ git am ~/000*
Applying: sss_config: the code
Applying: sss_config: build
/dev/shm/sssd/.git/rebase-apply/patch:65: new blank line at EOF.
+
warning: 1 line adds whitespace errors.
Applying: sss_config: unit tests
/dev/shm/sssd/.git/rebase-apply/patch:25: trailing whitespace.
warning: 1 line adds whitespace errors.
>+pkglib_LTLIBRARIES += libsss_config.la
^^^^^^
libsss_config.so will be installed in private directory /usr/lib64/sssd
If augeas opens this library with dlopen it should be installed in different
directory.
>+libsss_config_la_SOURCES = \
>+ src/util/sss_config.c
>+libsss_config_la_CFLAGS = \
>+ $(AM_CFLAGS) \
^^^^
'\t' instead of spaces.
>+ $(AUGEAS_CFLAGS)
>+libsss_config_la_LIBADD = \
>+ $(AUGEAS_LIBS)
./.libs/libsss_config.so: undefined reference to `string_in_list'
./.libs/libsss_config.so: undefined reference to `split_on_separator'
./.libs/libsss_config.so: undefined reference to `add_string_to_list'
add $(SSSD_INTERNAL_LTLIBS) to LIBADD
>+libsss_config_la_LDFLAGS = \
>+ -avoid-version
>+
> pkglib_LTLIBRARIES += libsss_util.la
> libsss_util_la_SOURCES = \
> src/confdb/confdb.c \
>diff --git a/configure.ac b/configure.ac
>index 41fa6496553336c73338459eaff639f10fde74f1..11bb0874bdf913070fc2f7509523a3f0b3982c42 100644
>--- a/configure.ac
>+++ b/configure.ac
>@@ -129,6 +129,7 @@ WITH_CRYPTO
> WITH_SYSLOG
>
> m4_include([src/external/pkg.m4])
>+m4_include([src/external/libaugeas.m4])
> m4_include([src/external/libpopt.m4])
> m4_include([src/external/libtalloc.m4])
> m4_include([src/external/libtdb.m4])
>diff --git a/src/external/libaugeas.m4 b/src/external/libaugeas.m4
>new file mode 100644
>index 0000000000000000000000000000000000000000..813d1067804f45b2b6f593f3bb2c3bc32112bb24
>--- /dev/null
>+++ b/src/external/libaugeas.m4
>@@ -0,0 +1,10 @@
>+AC_SUBST(AUGEAS_OBJ)
>+AC_SUBST(AUGEAS_CFLAGS)
>+AC_SUBST(AUGEAS_LIBS)
>+
>+PKG_CHECK_MODULES(AUGEAS,
>+ augeas >= 1.0.0,
>+ ,
>+ AC_MSG_ERROR("Please install augeas-devel")
>+ )
>+
>--
>1.7.11.7
>
You added new build time dependency, but spec file was not change.
Could be this optional dependency like a cifs-idmap-plugin?
src/external/cifsidmap.m4
You created new dynamic library(module) but it was not added into dlopen tests.
LS
More information about the sssd-devel
mailing list