[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