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(a)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(a)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(a)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(a)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