summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am2
-rw-r--r--src/confdb/confdb_setup.c347
-rw-r--r--src/external/libini_config.m424
-rw-r--r--src/monitor/monitor.c2
-rw-r--r--src/responder/nss/nsssrv_netgroup.c2
-rw-r--r--src/responder/nss/nsssrv_services.c1
-rw-r--r--src/util/sss_ini.c488
-rw-r--r--src/util/sss_ini.h81
8 files changed, 709 insertions, 238 deletions
diff --git a/Makefile.am b/Makefile.am
index ef180224..c6dfcb2c 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -391,6 +391,7 @@ dist_noinst_HEADERS = \
src/util/sss_selinux.h \
src/util/sss_utf8.h \
src/util/sss_ssh.h \
+ src/util/sss_ini.h \
src/util/refcount.h \
src/util/find_uid.h \
src/util/user_info_msg.h \
@@ -552,6 +553,7 @@ libsss_util_la_SOURCES = \
src/util/domain_info_utils.c \
src/util/util_lock.c \
src/util/util_errors.c \
+ src/util/sss_ini.c \
src/util/io.c
libsss_util_la_LIBADD = \
$(SSSD_LIBS) \
diff --git a/src/confdb/confdb_setup.c b/src/confdb/confdb_setup.c
index 6c68461f..b13553ea 100644
--- a/src/confdb/confdb_setup.c
+++ b/src/confdb/confdb_setup.c
@@ -26,9 +26,7 @@
#include "confdb.h"
#include "confdb_private.h"
#include "confdb_setup.h"
-#include "collection.h"
-#include "collection_tools.h"
-#include "ini_config.h"
+#include "util/sss_ini.h"
int confdb_test(struct confdb_ctx *cdb)
@@ -126,280 +124,159 @@ int confdb_create_base(struct confdb_ctx *cdb)
return EOK;
}
-static int confdb_create_ldif(TALLOC_CTX *mem_ctx,
- struct collection_item *sssd_config,
- const char **config_ldif)
+int confdb_init_db(const char *config_file, struct confdb_ctx *cdb)
{
- int ret, i, j;
- char *ldif;
- char *tmp_ldif;
- char **sections;
- int section_count;
- char *dn;
- char *tmp_dn;
- char *sec_dn;
- char **attrs;
- int attr_count;
- char *ldif_attr;
- struct collection_item *attr;
TALLOC_CTX *tmp_ctx;
- size_t dn_size;
- size_t ldif_len;
- size_t attr_len;
+ 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 };
+ struct ldb_ldif *ldif;
+ struct sss_ini_initdata *init_data;
- ldif_len = strlen(CONFDB_INTERNAL_LDIF);
- ldif = talloc_array(mem_ctx, char, ldif_len+1);
- if (!ldif) return ENOMEM;
- tmp_ctx = talloc_new(ldif);
- if (!tmp_ctx) {
- ret = ENOMEM;
- goto error;
+ tmp_ctx = talloc_new(cdb);
+ if (tmp_ctx == NULL) {
+ DEBUG(SSSDBG_FATAL_FAILURE, ("Out of memory.\n"));
+ return ENOMEM;
}
- memcpy(ldif, CONFDB_INTERNAL_LDIF, ldif_len);
-
- /* Read in the collection and convert it to an LDIF */
- /* Get the list of sections */
- sections = get_section_list(sssd_config, &section_count, &ret);
- if (ret != EOK) {
- goto error;
+ init_data = sss_ini_initdata_init(tmp_ctx);
+ if (!init_data) {
+ DEBUG(SSSDBG_FATAL_FAILURE, ("Out of memory.\n"));
+ ret = ENOMEM;
+ goto done;
}
- for(i = 0; i < section_count; i++) {
- const char *rdn = NULL;
- DEBUG(6,("Processing config section [%s]\n", sections[i]));
- ret = parse_section(tmp_ctx, sections[i], &sec_dn, &rdn);
- if (ret != EOK) {
- goto error;
- }
-
- dn = talloc_asprintf(tmp_ctx,
- "dn: %s,cn=config\n"
- "cn: %s\n",
- sec_dn, rdn);
- if(!dn) {
- ret = ENOMEM;
- free_section_list(sections);
- goto error;
- }
- dn_size = strlen(dn);
-
- /* Get all of the attributes and their values as LDIF */
- attrs = get_attribute_list(sssd_config, sections[i],
- &attr_count, &ret);
- if (ret != EOK) {
- free_section_list(sections);
- goto error;
- }
-
- for(j = 0; j < attr_count; j++) {
- DEBUG(6, ("Processing attribute [%s]\n", attrs[j]));
- ret = get_config_item(sections[i], attrs[j], sssd_config,
- &attr);
- if (ret != EOK) goto error;
-
- const char *value = get_const_string_config_value(attr, &ret);
- if (ret != EOK) goto error;
- if (value && value[0] == '\0') {
- DEBUG(1, ("Attribute '%s' has empty value, ignoring\n", attrs[j]));
- continue;
- }
-
- ldif_attr = talloc_asprintf(tmp_ctx,
- "%s: %s\n", attrs[j], value);
- DEBUG(9, ("%s", ldif_attr));
-
- attr_len = strlen(ldif_attr);
-
- tmp_dn = talloc_realloc(tmp_ctx, dn, char,
- dn_size+attr_len+1);
- if(!tmp_dn) {
- ret = ENOMEM;
- free_attribute_list(attrs);
- free_section_list(sections);
- goto error;
- }
- dn = tmp_dn;
- memcpy(dn+dn_size, ldif_attr, attr_len+1);
- dn_size += attr_len;
- }
-
- dn_size ++;
- tmp_dn = talloc_realloc(tmp_ctx, dn, char,
- dn_size+1);
- if(!tmp_dn) {
- ret = ENOMEM;
- free_attribute_list(attrs);
- free_section_list(sections);
- goto error;
- }
- dn = tmp_dn;
- dn[dn_size-1] = '\n';
- dn[dn_size] = '\0';
-
- DEBUG(9, ("Section dn\n%s", dn));
-
- tmp_ldif = talloc_realloc(mem_ctx, ldif, char,
- ldif_len+dn_size+1);
- if(!tmp_ldif) {
- ret = ENOMEM;
- free_attribute_list(attrs);
- free_section_list(sections);
- goto error;
- }
- ldif = tmp_ldif;
- memcpy(ldif+ldif_len, dn, dn_size);
- ldif_len += dn_size;
-
- free_attribute_list(attrs);
- talloc_free(dn);
+ /* Open config file */
+ ret = sss_ini_config_file_open(init_data, config_file);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to open configuration file.\n"));
+ ret = EIO;
+ goto done;
}
- ldif[ldif_len] = '\0';
-
- free_section_list(sections);
-
- *config_ldif = (const char *)ldif;
- talloc_free(tmp_ctx);
- return EOK;
-
-error:
- talloc_free(ldif);
- return ret;
-}
-
-int confdb_init_db(const char *config_file, struct confdb_ctx *cdb)
-{
- int ret;
- int fd = -1;
- struct collection_item *sssd_config = NULL;
- struct collection_item *error_list = NULL;
- struct collection_item *item = NULL;
- const char *config_ldif;
- struct ldb_ldif *ldif;
- TALLOC_CTX *tmp_ctx;
- char *lasttimestr, timestr[21];
- const char *vals[2] = { timestr, NULL };
- struct stat cstat;
- int version;
-
- tmp_ctx = talloc_new(cdb);
- if (tmp_ctx == NULL) return ENOMEM;
-
- ret = check_and_open_readonly(config_file, &fd, 0, 0, (S_IRUSR|S_IWUSR),
- CHECK_REG);
+ ret = sss_ini_config_access_check(init_data);
if (ret != EOK) {
- DEBUG(1, ("Permission check on config file failed.\n"));
- talloc_zfree(tmp_ctx);
- return EPERM;
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Permission check on config file failed.\n"));
+ ret = EPERM;
+ goto done;
}
/* Determine if the conf file has changed since we last updated
* the confdb
*/
- ret = fstat(fd, &cstat);
- if (ret != 0) {
- DEBUG(0, ("Unable to stat config file [%s]! (%d [%s])\n",
- config_file, errno, strerror(errno)));
- close(fd);
- talloc_zfree(tmp_ctx);
- return errno;
- }
- ret = snprintf(timestr, 21, "%llu", (long long unsigned)cstat.st_mtime);
- if (ret <= 0 || ret >= 21) {
- DEBUG(0, ("Failed to convert time_t to string ??\n"));
- close(fd);
- talloc_zfree(tmp_ctx);
- return errno ? errno: EFAULT;
+ 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;
}
- /* check if we need to re-init the db */
- ret = confdb_get_string(cdb, tmp_ctx, "config", "lastUpdate", NULL, &lasttimestr);
- if (ret == EOK && lasttimestr != NULL) {
+ errno = 0;
- /* now check if we lastUpdate and last file modification change differ*/
- if (strcmp(lasttimestr, timestr) == 0) {
- /* not changed, get out, nothing more to do */
- close(fd);
- talloc_zfree(tmp_ctx);
- return EOK;
- }
+ 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) {
- /* Set up a transaction to replace the configuration */
- ret = ldb_transaction_start(cdb->ldb);
- if (ret != LDB_SUCCESS) {
- DEBUG(0, ("Failed to start a transaction for updating the configuration\n"));
- talloc_zfree(tmp_ctx);
- close(fd);
- return sysdb_error_to_errno(ret);
- }
-
- /* Purge existing database */
- ret = confdb_purge(cdb);
- if (ret != EOK) {
- DEBUG(0, ("Could not purge existing configuration\n"));
- close(fd);
+ /* 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;
}
- /* Read the configuration into a collection */
- ret = config_from_fd("sssd", fd, config_file, &sssd_config,
- INI_STOP_ON_ANY, &error_list);
- close(fd);
+ ret = sss_ini_get_config(init_data, config_file);
if (ret != EOK) {
- DEBUG(0, ("Parse error reading configuration file [%s]\n",
- config_file));
- print_file_parsing_errors(stderr, error_list);
- free_ini_config_errors(error_list);
- free_ini_config(sssd_config);
+ DEBUG(SSSDBG_FATAL_FAILURE, ("Failed to load configuration\n"));
goto done;
}
/* Make sure that the config file version matches the confdb version */
- ret = get_config_item("sssd", "config_file_version",
- sssd_config, &item);
+ ret = sss_ini_get_cfgobj(init_data, "sssd", "config_file_version");
if (ret != EOK) {
- DEBUG(0, ("Internal error determining config_file_version\n"));
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ ("Internal error determining config_file_version\n"));
goto done;
}
- if (item == NULL) {
+
+ ret = sss_ini_check_config_obj(init_data);
+ if (ret != EOK) {
/* No known version. Assumed to be version 1 */
- DEBUG(0, ("Config file is an old version. "
- "Please run configuration upgrade script.\n"));
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ ("Config file is an old version. "
+ "Please run configuration upgrade script.\n"));
ret = EINVAL;
goto done;
}
- version = get_int_config_value(item, 1, -1, &ret);
+
+ version = sss_ini_get_int_config_value(init_data, 1, -1, &ret);
if (ret != EOK) {
- DEBUG(0, ("Config file version could not be determined\n"));
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ ("Config file version could not be determined\n"));
goto done;
} else if (version < CONFDB_VERSION_INT) {
- DEBUG(0, ("Config file is an old version. "
- "Please run configuration upgrade script.\n"));
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ ("Config file is an old version. "
+ "Please run configuration upgrade script.\n"));
ret = EINVAL;
goto done;
} else if (version > CONFDB_VERSION_INT) {
- DEBUG(0, ("Config file version is newer than confdb\n"));
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ ("Config file version is newer than confdb\n"));
ret = EINVAL;
goto done;
}
- ret = confdb_create_ldif(tmp_ctx, sssd_config, &config_ldif);
- free_ini_config(sssd_config);
+ /* Set up a transaction to replace the configuration */
+ ret = ldb_transaction_start(cdb->ldb);
+ if (ret != LDB_SUCCESS) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ ("Failed to start a transaction for "
+ "updating the configuration\n"));
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+ in_transaction = true;
+
+ /* Purge existing database */
+ ret = confdb_purge(cdb);
if (ret != EOK) {
- DEBUG(0, ("Could not create LDIF for confdb\n"));
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ ("Could not purge existing configuration\n"));
goto done;
}
- DEBUG(7, ("LDIF file to import: \n%s", config_ldif));
+ ret = sss_confdb_create_ldif(tmp_ctx, init_data, &config_ldif);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE, ("Could not create LDIF for confdb\n"));
+ goto done;
+ }
+
+ DEBUG(SSSDBG_TRACE_LIBS, ("LDIF file to import: \n%s", config_ldif));
while ((ldif = ldb_ldif_read_string(cdb->ldb, &config_ldif))) {
ret = ldb_add(cdb->ldb, ldif->msg);
if (ret != LDB_SUCCESS) {
- DEBUG(0, ("Failed to initialize DB (%d,[%s]), aborting!\n",
- ret, ldb_errstring(cdb->ldb)));
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ ("Failed to initialize DB (%d,[%s]), aborting!\n",
+ ret, ldb_errstring(cdb->ldb)));
ret = EIO;
goto done;
}
@@ -411,15 +288,31 @@ int confdb_init_db(const char *config_file, struct confdb_ctx *cdb)
ret = confdb_add_param(cdb, true, "config", "lastUpdate", vals);
if (ret != EOK) {
- DEBUG(1, ("Failed to set last update time on db!\n"));
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ ("Failed to set last update time on db!\n"));
+ goto done;
+ }
+
+ ret = ldb_transaction_commit(cdb->ldb);
+ if (ret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to commit transaction\n"));
+ goto done;
}
+ in_transaction = false;
ret = EOK;
done:
- ret == EOK ?
- ldb_transaction_commit(cdb->ldb) :
- ldb_transaction_cancel(cdb->ldb);
+ if (in_transaction) {
+ sret = ldb_transaction_cancel(cdb->ldb);
+ if (sret != EOK) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("Failed to cancel transaction\n"));
+ }
+ }
+
+ sss_ini_config_destroy(init_data);
+ sss_ini_close_file(init_data);
+
talloc_zfree(tmp_ctx);
return ret;
}
diff --git a/src/external/libini_config.m4 b/src/external/libini_config.m4
index f41f3191..93a4bd94 100644
--- a/src/external/libini_config.m4
+++ b/src/external/libini_config.m4
@@ -1,10 +1,20 @@
+PKG_CHECK_MODULES(INI_CONFIG, [
+ ini_config >= 1.0.0], [
+
+ AC_DEFINE_UNQUOTED(HAVE_LIBINI_CONFIG_V1, 1, [libini_config version greater than 1.0.0])
+ ], [
+ AC_MSG_WARN([libini_config-devel >= 1.0.0 not available, trying older version])
+ PKG_CHECK_MODULES(INI_CONFIG, [
+ ini_config >= 0.6.1], [
+
+ AC_DEFINE_UNQUOTED(HAVE_LIBINI_CONFIG_V0, 1, [libini_config version lesser than 1.0.0])
+ ], [
+ AC_MSG_ERROR([Please install libini_config-devel])
+ ]
+ )
+ ]
+)
+
AC_SUBST(INI_CONFIG_OBJ)
AC_SUBST(INI_CONFIG_CFLAGS)
AC_SUBST(INI_CONFIG_LIBS)
-
-PKG_CHECK_MODULES(INI_CONFIG,
- ini_config >= 0.6.1,
- ,
- AC_MSG_ERROR("Please install libini_config-devel")
- )
-
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
index 4e81f559..bd22a951 100644
--- a/src/monitor/monitor.c
+++ b/src/monitor/monitor.c
@@ -44,8 +44,6 @@
#include "tevent.h"
#include "confdb/confdb.h"
#include "confdb/confdb_setup.h"
-#include "collection.h"
-#include "ini_config.h"
#include "db/sysdb.h"
#include "monitor/monitor.h"
#include "dbus/dbus.h"
diff --git a/src/responder/nss/nsssrv_netgroup.c b/src/responder/nss/nsssrv_netgroup.c
index 30459bea..36792365 100644
--- a/src/responder/nss/nsssrv_netgroup.c
+++ b/src/responder/nss/nsssrv_netgroup.c
@@ -22,7 +22,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
-#include <collection.h>
+
#include "util/util.h"
#include "responder/nss/nsssrv.h"
#include "responder/nss/nsssrv_private.h"
diff --git a/src/responder/nss/nsssrv_services.c b/src/responder/nss/nsssrv_services.c
index 7b76cad8..c9907423 100644
--- a/src/responder/nss/nsssrv_services.c
+++ b/src/responder/nss/nsssrv_services.c
@@ -21,7 +21,6 @@
*/
-#include <collection.h>
#include <arpa/inet.h>
#include "util/util.h"
#include "responder/nss/nsssrv.h"
diff --git a/src/util/sss_ini.c b/src/util/sss_ini.c
new file mode 100644
index 00000000..32e06781
--- /dev/null
+++ b/src/util/sss_ini.c
@@ -0,0 +1,488 @@
+/*
+ SSSD
+
+ sss_ini.c
+
+ Authors:
+ Ondrej Kos <okos@redhat.com>
+
+ Copyright (C) 2013 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 <stdio.h>
+#include <errno.h>
+#include <talloc.h>
+
+#include "config.h"
+#include "util/util.h"
+#include "util/sss_ini.h"
+#include "confdb/confdb_setup.h"
+#include "confdb/confdb_private.h"
+
+#ifdef HAVE_LIBINI_CONFIG_V1
+#include "ini_configobj.h"
+#elif HAVE_LIBINI_CONFIG_V0
+#include "collection.h"
+#include "collection_tools.h"
+#else
+#error "Unsupported libini version"
+#endif
+
+#include "ini_config.h"
+
+
+#ifdef HAVE_LIBINI_CONFIG_V1
+
+struct sss_ini_initdata {
+ char **error_list;
+ struct ini_cfgobj *sssd_config;
+ struct value_obj *obj;
+ const struct stat *cstat;
+ struct ini_cfgfile *file;
+};
+
+#define sss_ini_get_sec_list ini_get_section_list
+#define sss_ini_get_attr_list ini_get_attribute_list
+#define sss_ini_get_const_string_config_value ini_get_const_string_config_value
+#define sss_ini_get_config_obj ini_get_config_valueobj
+
+
+
+#elif HAVE_LIBINI_CONFIG_V0
+
+struct sss_ini_initdata {
+ struct collection_item *error_list;
+ struct collection_item *sssd_config;
+ struct collection_item *obj;
+ struct stat cstat;
+ int file;
+};
+
+#define sss_ini_get_sec_list get_section_list
+#define sss_ini_get_attr_list get_attribute_list
+#define sss_ini_get_const_string_config_value get_const_string_config_value
+#define sss_ini_get_config_obj(secs,attrs,cfg,flag,attr) \
+ get_config_item(secs,attrs,cfg,attr)
+
+#endif
+
+
+/* Initialize data structure */
+
+struct sss_ini_initdata* sss_ini_initdata_init(TALLOC_CTX *mem_ctx)
+{
+ return talloc_zero(mem_ctx, struct sss_ini_initdata);
+}
+
+
+
+/* Close file descriptor */
+
+void sss_ini_close_file(struct sss_ini_initdata *init_data)
+{
+ if (init_data == NULL) return;
+#ifdef HAVE_LIBINI_CONFIG_V1
+ if (init_data->file != NULL) {
+ ini_config_file_destroy(init_data->file);
+ init_data->file = NULL;
+ }
+#elif HAVE_LIBINI_CONFIG_V0
+ if (init_data->file != -1) {
+ close(init_data->file);
+ init_data->file = -1;
+ }
+#endif
+}
+
+
+
+/* Open configuration file */
+
+int sss_ini_config_file_open(struct sss_ini_initdata *init_data,
+ const char *config_file)
+{
+#ifdef HAVE_LIBINI_CONFIG_V1
+ return ini_config_file_open(config_file,
+ INI_META_STATS,
+ &init_data->file);
+#elif HAVE_LIBINI_CONFIG_V0
+ return check_and_open_readonly(config_file, &init_data->file, 0, 0,
+ (S_IRUSR|S_IWUSR), CHECK_REG);
+#endif
+}
+
+
+
+/* Check configuration file permissions */
+
+int sss_ini_config_access_check(struct sss_ini_initdata *init_data)
+{
+#ifdef HAVE_LIBINI_CONFIG_V1
+ return ini_config_access_check(init_data->file,
+ INI_ACCESS_CHECK_MODE |
+ INI_ACCESS_CHECK_UID |
+ INI_ACCESS_CHECK_GID,
+ 0, /* owned by root */
+ 0, /* owned by root */
+ (S_IRUSR|S_IWUSR), /* rw------- */
+ 0); /* check all there parts */
+#elif HAVE_LIBINI_CONFIG_V0
+ return EOK;
+#endif
+}
+
+
+
+/* Get cstat */
+
+int sss_ini_get_stat(struct sss_ini_initdata *init_data)
+{
+#ifdef HAVE_LIBINI_CONFIG_V1
+ init_data->cstat = ini_config_get_stat(init_data->file);
+
+ if (!init_data->cstat) return EIO;
+
+ return EOK;
+#elif HAVE_LIBINI_CONFIG_V0
+
+ return fstat(init_data->file, &init_data->cstat);
+#endif
+}
+
+
+
+/* Get mtime */
+
+int sss_ini_get_mtime(struct sss_ini_initdata *init_data,
+ size_t timestr_len,
+ char *timestr)
+{
+#ifdef HAVE_LIBINI_CONFIG_V1
+ return snprintf(timestr, timestr_len, "%llu",
+ (long long unsigned)init_data->cstat->st_mtime);
+#elif HAVE_LIBINI_CONFIG_V0
+ return snprintf(timestr, timestr_len, "%llu",
+ (long long unsigned)init_data->cstat.st_mtime);
+#endif
+}
+
+
+
+/* Print ini_config errors */
+
+void sss_ini_config_print_errors(char **error_list)
+{
+#ifdef HAVE_LIBINI_CONFIG_V1
+ unsigned count = 0;
+
+ if (!error_list) {
+ return;
+ }
+
+ while (error_list[count]) {
+ DEBUG(SSSDBG_CRIT_FAILURE, ("%s\n", error_list[count]));
+ count++;
+ }
+#endif
+
+ return;
+}
+
+
+
+/* Load configuration */
+
+int sss_ini_get_config(struct sss_ini_initdata *init_data,
+ const char *config_file)
+{
+ int ret;
+#ifdef HAVE_LIBINI_CONFIG_V1
+
+ /* 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;
+ }
+
+ /* Parse file */
+ ret = ini_config_parse(init_data->file,
+ INI_STOP_ON_ANY,
+ INI_MV1S_OVERWRITE,
+ 0,
+ init_data->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)) {
+ 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,
+ &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);
+ return ret;
+ }
+
+ return ret;
+
+#elif HAVE_LIBINI_CONFIG_V0
+
+ /* Read the configuration into a collection */
+ ret = config_from_fd("sssd",
+ init_data->file,
+ config_file,
+ &init_data->sssd_config,
+ INI_STOP_ON_ANY,
+ &init_data->error_list);
+ close(init_data->file);
+
+ if (ret != EOK) {
+ DEBUG(SSSDBG_FATAL_FAILURE,
+ ("Parse error reading configuration file [%s]\n",
+ config_file));
+
+ print_file_parsing_errors(stderr, init_data->error_list);
+
+ free_ini_config_errors(init_data->error_list);
+ free_ini_config(init_data->sssd_config);
+
+ return ret;
+ }
+
+ return EOK;
+
+#endif
+}
+
+
+
+/* Get configuration object */
+
+int sss_ini_get_cfgobj(struct sss_ini_initdata *init_data,
+ const char *section, const char *name)
+{
+ return sss_ini_get_config_obj(section,name, init_data->sssd_config,
+ INI_GET_FIRST_VALUE, &init_data->obj);
+}
+
+
+
+/* Check configuration object */
+
+int sss_ini_check_config_obj(struct sss_ini_initdata *init_data)
+{
+ if (init_data->obj == NULL) {
+ return ENOENT;
+ }
+
+ return EOK;
+}
+
+
+
+/* Get integer value */
+
+int sss_ini_get_int_config_value(struct sss_ini_initdata *init_data,
+ int strict, int def, int *error)
+{
+#ifdef HAVE_LIBINI_CONFIG_V1
+ return ini_get_int_config_value(init_data->obj, strict, def, error);
+#elif HAVE_LIBINI_CONFIG_V0
+ return get_int_config_value(init_data->obj, strict, def, error);
+#endif
+}
+
+
+
+/* Destroy ini config (v1) */
+
+void sss_ini_config_destroy(struct sss_ini_initdata *init_data)
+{
+ if (init_data == NULL) return;
+#ifdef HAVE_LIBINI_CONFIG_V1
+ if (init_data->sssd_config != NULL) {
+ ini_config_destroy(init_data->sssd_config);
+ init_data->sssd_config = NULL;
+ }
+#elif HAVE_LIBINI_CONFIG_V0
+ free_ini_config(init_data->sssd_config);
+#endif
+}
+
+
+
+/* Create LDIF */
+
+int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx,
+ struct sss_ini_initdata *init_data,
+ const char **config_ldif)
+{
+ int ret, i, j;
+ char *ldif;
+ char *tmp_ldif;
+ char **sections;
+ int section_count;
+ char *dn;
+ char *tmp_dn;
+ char *sec_dn;
+ char **attrs;
+ int attr_count;
+ char *ldif_attr;
+ TALLOC_CTX *tmp_ctx;
+ size_t dn_size;
+ size_t ldif_len;
+ size_t attr_len;
+#ifdef HAVE_LIBINI_CONFIG_V1
+ struct value_obj *obj = NULL;
+#elif HAVE_LIBINI_CONFIG_V0
+ struct collection_item *obj = NULL;
+#endif
+
+ ldif_len = strlen(CONFDB_INTERNAL_LDIF);
+ ldif = talloc_array(mem_ctx, char, ldif_len+1);
+ if (!ldif) return ENOMEM;
+
+ tmp_ctx = talloc_new(ldif);
+ if (!tmp_ctx) {
+ ret = ENOMEM;
+ goto error;
+ }
+
+ memcpy(ldif, CONFDB_INTERNAL_LDIF, ldif_len);
+
+ /* Read in the collection and convert it to an LDIF */
+ /* Get the list of sections */
+ sections = sss_ini_get_sec_list(init_data->sssd_config,
+ &section_count, &ret);
+ if (ret != EOK) {
+ goto error;
+ }
+
+ for (i = 0; i < section_count; i++) {
+ const char *rdn = NULL;
+ DEBUG(SSSDBG_TRACE_FUNC,
+ ("Processing config section [%s]\n", sections[i]));
+ ret = parse_section(tmp_ctx, sections[i], &sec_dn, &rdn);
+ if (ret != EOK) {
+ goto error;
+ }
+
+ dn = talloc_asprintf(tmp_ctx,
+ "dn: %s,cn=config\n"
+ "cn: %s\n",
+ sec_dn, rdn);
+ if (!dn) {
+ ret = ENOMEM;
+ free_section_list(sections);
+ goto error;
+ }
+ dn_size = strlen(dn);
+
+ /* Get all of the attributes and their values as LDIF */
+ attrs = sss_ini_get_attr_list(init_data->sssd_config, sections[i],
+ &attr_count, &ret);
+ if (ret != EOK) {
+ free_section_list(sections);
+ goto error;
+ }
+
+ for (j = 0; j < attr_count; j++) {
+ DEBUG(SSSDBG_TRACE_FUNC,
+ ("Processing attribute [%s]\n", attrs[j]));
+ ret = sss_ini_get_config_obj(sections[i], attrs[j],
+ init_data->sssd_config,
+ INI_GET_FIRST_VALUE, &obj);
+ if (ret != EOK) goto error;
+
+ const char *value = sss_ini_get_const_string_config_value(obj, &ret);
+ if (ret != EOK) goto error;
+ if (value && value[0] == '\0') {
+ DEBUG(SSSDBG_CRIT_FAILURE,
+ ("Attribute '%s' has empty value, ignoring\n",
+ attrs[j]));
+ continue;
+ }
+
+ ldif_attr = talloc_asprintf(tmp_ctx,
+ "%s: %s\n", attrs[j], value);
+ DEBUG(SSSDBG_TRACE_ALL, ("%s", ldif_attr));
+
+ attr_len = strlen(ldif_attr);
+
+ tmp_dn = talloc_realloc(tmp_ctx, dn, char,
+ dn_size+attr_len+1);
+ if (!tmp_dn) {
+ ret = ENOMEM;
+ free_attribute_list(attrs);
+ free_section_list(sections);
+ goto error;
+ }
+ dn = tmp_dn;
+ memcpy(dn+dn_size, ldif_attr, attr_len+1);
+ dn_size += attr_len;
+ }
+
+ dn_size ++;
+ tmp_dn = talloc_realloc(tmp_ctx, dn, char,
+ dn_size+1);
+ if (!tmp_dn) {
+ ret = ENOMEM;
+ free_attribute_list(attrs);
+ free_section_list(sections);
+ goto error;
+ }
+ dn = tmp_dn;
+ dn[dn_size-1] = '\n';
+ dn[dn_size] = '\0';
+
+ DEBUG(SSSDBG_TRACE_ALL, ("Section dn\n%s", dn));
+
+ tmp_ldif = talloc_realloc(mem_ctx, ldif, char,
+ ldif_len+dn_size+1);
+ if (!tmp_ldif) {
+ ret = ENOMEM;
+ free_attribute_list(attrs);
+ free_section_list(sections);
+ goto error;
+ }
+ ldif = tmp_ldif;
+ memcpy(ldif+ldif_len, dn, dn_size);
+ ldif_len += dn_size;
+
+ free_attribute_list(attrs);
+ talloc_free(dn);
+ }
+
+ ldif[ldif_len] = '\0';
+
+ free_section_list(sections);
+
+ *config_ldif = (const char *)ldif;
+ talloc_free(tmp_ctx);
+ return EOK;
+
+error:
+ talloc_free(ldif);
+ return ret;
+}
diff --git a/src/util/sss_ini.h b/src/util/sss_ini.h
new file mode 100644
index 00000000..3beaca15
--- /dev/null
+++ b/src/util/sss_ini.h
@@ -0,0 +1,81 @@
+/*
+ SSSD
+
+ sss_ini.c
+
+ Authors:
+ Ondrej Kos <okos@redhat.com>
+
+ Copyright (C) 2013 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_INI_H__
+#define __SSS_INI_H__
+
+/* Structure declarations */
+
+/* INI data structure */
+struct sss_ini_initdata;
+
+
+/* Function declarations */
+
+/* Initialize data structure */
+struct sss_ini_initdata* sss_ini_initdata_init(TALLOC_CTX *tmp_ctx);
+
+/* Close file descriptor */
+void sss_ini_close_file(struct sss_ini_initdata *init_data);
+
+/* Open config file */
+int sss_ini_config_file_open(struct sss_ini_initdata *init_data,
+ const char *config_file);
+
+/* Check file permissions */
+int sss_ini_config_access_check(struct sss_ini_initdata *init_data);
+
+/* Cstat */
+int sss_ini_get_stat(struct sss_ini_initdata *init_data);
+
+/* Get mtime */
+int sss_ini_get_mtime(struct sss_ini_initdata *init_data,
+ size_t timestr_len,
+ char *timestr);
+
+/* Load configuration */
+int sss_ini_get_config(struct sss_ini_initdata *init_data,
+ const char *config_file);
+/* Get configuration object */
+int sss_ini_get_cfgobj(struct sss_ini_initdata *init_data,
+ const char *section, const char *name);
+
+/* Check configuration object */
+int sss_ini_check_config_obj(struct sss_ini_initdata *init_data);
+
+/* Get int value */
+int sss_ini_get_int_config_value(struct sss_ini_initdata *init_data,
+ int strict, int def, int *error);
+
+/* Destroy ini config */
+void sss_ini_config_destroy(struct sss_ini_initdata *init_data);
+
+/* Create LDIF */
+int sss_confdb_create_ldif(TALLOC_CTX *mem_ctx,
+ struct sss_ini_initdata *init_data,
+ const char **config_ldif);
+
+#endif /* __SSS_INI_H__ */