summaryrefslogtreecommitdiffstats
path: root/server/confdb
diff options
context:
space:
mode:
Diffstat (limited to 'server/confdb')
-rw-r--r--server/confdb/confdb.c314
-rw-r--r--server/confdb/confdb.h12
-rw-r--r--server/confdb/confdb_private.h42
3 files changed, 270 insertions, 98 deletions
diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c
index 88700e301..4256418a6 100644
--- a/server/confdb/confdb.c
+++ b/server/confdb/confdb.c
@@ -20,6 +20,10 @@
*/
#define _GNU_SOURCE
+
+#include "talloc.h"
+#include "tevent.h"
+#include "config.h"
#include "ldb.h"
#include "ldb_errors.h"
#include "util/util.h"
@@ -27,8 +31,13 @@
#include "confdb/confdb_private.h"
#include "util/btreemap.h"
#include "db/sysdb.h"
-#define CONFDB_VERSION "0.1"
-#define CONFDB_DOMAIN_BASEDN "cn=domains,cn=config"
+#include "collection.h"
+#include "collection_tools.h"
+#include "ini_config.h"
+
+#define CONFDB_VERSION "1"
+#define CONFDB_BASEDN "cn=config"
+#define CONFDB_DOMAIN_BASEDN "cn=domains,"CONFDB_BASEDN
#define CONFDB_DOMAIN_ATTR "cn"
#define CONFDB_MPG "magicPrivateGroups"
#define CONFDB_FQ "useFullyQualifiedNames"
@@ -487,7 +496,7 @@ failed:
return ret;
}
-static int confdb_test(struct confdb_ctx *cdb)
+int confdb_test(struct confdb_ctx *cdb)
{
char **values;
int ret;
@@ -522,23 +531,254 @@ static int confdb_test(struct confdb_ctx *cdb)
return EOK;
}
-static int confdb_init_db(struct confdb_ctx *cdb)
+static int confdb_purge(struct confdb_ctx *cdb)
+{
+ int ret, i;
+ TALLOC_CTX *tmp_ctx;
+ struct ldb_result *res;
+ struct ldb_dn *dn;
+ const char *attrs[] = { "dn", NULL };
+
+ tmp_ctx = talloc_new(NULL);
+
+ dn = ldb_dn_new(tmp_ctx, cdb->ldb, "cn=config");
+
+ /* Get the list of all DNs */
+ ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn,
+ LDB_SCOPE_SUBTREE, attrs, NULL);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+
+ for(i=0; i<res->count; i++) {
+ /* Delete this DN */
+ ret = ldb_delete(cdb->ldb, res->msgs[i]->dn);
+ if (ret != LDB_SUCCESS) {
+ ret = sysdb_error_to_errno(ret);
+ goto done;
+ }
+ }
+
+done:
+ talloc_free(tmp_ctx);
+ return ret;
+}
+
+int confdb_create_base(struct confdb_ctx *cdb)
{
- const char *base_ldif;
- struct ldb_ldif *ldif;
- const char *val[2] = {NULL, NULL};
int ret;
+ struct ldb_ldif *ldif;
+
+ const char *base_ldif = CONFDB_BASE_LDIF;
+
+ while ((ldif = ldb_ldif_read_string(cdb->ldb, &base_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)));
+ return EIO;
+ }
+ ldb_ldif_read_free(cdb->ldb, ldif);
+ }
+
+ return EOK;
+}
+
+static int confdb_create_ldif(TALLOC_CTX *mem_ctx,
+ struct collection_item *sssd_config,
+ char **config_ldif)
+{
+ int ret, i, j;
+ char *ldif;
+ char *tmp_ldif;
+ char *writer;
+ 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;
+
+ 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);
+ writer = 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;
+ }
+
+ 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;
+
+ 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);
+ }
+
+ ldif[ldif_len] = '\0';
+
+ free_section_list(sections);
+
+ *config_ldif = 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, i;
+ struct collection_item *sssd_config = NULL;
+ struct collection_item *error_list = NULL;
+ char *config_ldif;
+ struct ldb_ldif *ldif;
TALLOC_CTX *tmp_ctx;
tmp_ctx = talloc_new(cdb);
if(tmp_ctx == NULL) return ENOMEM;
- /* cn=confdb does not exists, means db is empty, populate */
- base_ldif = CONFDB_BASE_LDIF;
- while ((ldif = ldb_ldif_read_string(cdb->ldb, &base_ldif))) {
+ /* 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_free(tmp_ctx);
+ return sysdb_error_to_errno(ret);
+ }
+
+ /* Purge existing database */
+ ret = confdb_purge(cdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Could not purge existing configuration\n"));
+ goto done;
+ }
+
+ /* Read the configuration into a collection */
+ ret = config_from_file("sssd", config_file, &sssd_config,
+ INI_STOP_ON_ANY, &error_list);
+ if (ret != EOK) {
+ DEBUG(0, ("Parse error reading configuration file [%s]\n",
+ config_file));
+ print_file_parsing_errors(stderr, error_list);
+ destroy_collection(error_list);
+ destroy_collection(sssd_config);
+ goto done;
+ }
+
+ ret = confdb_create_ldif(tmp_ctx, sssd_config, &config_ldif);
+ destroy_collection(sssd_config);
+ if (ret != EOK) {
+ DEBUG(0, ("Could not create LDIF for confdb\n"));
+ goto done;
+ }
+
+ DEBUG(7, ("LDIF file to import: \n%s", config_ldif));
+
+ i=0;
+ while ((ldif = ldb_ldif_read_string(cdb->ldb, (const char **)&config_ldif))) {
ret = ldb_add(cdb->ldb, ldif->msg);
if (ret != LDB_SUCCESS) {
- DEBUG(0, ("Failed to inizialiaze DB (%d,[%s]), aborting!\n",
+ DEBUG(0, ("Failed to initialize DB (%d,[%s]), aborting!\n",
ret, ldb_errstring(cdb->ldb)));
ret = EIO;
goto done;
@@ -546,45 +786,12 @@ static int confdb_init_db(struct confdb_ctx *cdb)
ldb_ldif_read_free(cdb->ldb, ldif);
}
-/* InfoPipe */
-#ifdef HAVE_INFOPIPE
- /* Set the sssd_info description */
- val[0] = "InfoPipe Configuration";
- ret = confdb_add_param(cdb, false, "config/services/info", "description", val);
- if (ret != EOK) goto done;
-
- /* Set the sssd_info command path */
- val[0] = talloc_asprintf(tmp_ctx, "%s/sssd_info", SSSD_LIBEXEC_PATH);
- CONFDB_ZERO_CHECK_OR_JUMP(val[0], ret, ENOMEM, done);
- ret = confdb_add_param(cdb, false, "config/services/info", "command", val);
- if (ret != EOK) goto done;
-
- /* Add the InfoPipe to the list of active services */
- val[0] = "info";
- ret = confdb_add_param(cdb, false, "config/services", "activeServices", val);
- if (ret != EOK) goto done;
-#endif
-
-/* PolicyKit */
-#ifdef HAVE_POLICYKIT
- /* Set the sssd_pk description */
- val[0] = "PolicyKit Backend Configuration";
- ret = confdb_add_param(cdb, false, "config/services/pk", "description", val);
- if (ret != EOK) goto done;
-
- /* Set the sssd_info command path */
- val[0] = talloc_asprintf(tmp_ctx, "%s/sssd_pk", SSSD_LIBEXEC_PATH);
- CONFDB_ZERO_CHECK_OR_JUMP(val[0], ret, ENOMEM, done);
- ret = confdb_add_param(cdb, false, "config/services/pk", "command", val);
- if (ret != EOK) goto done;
-
- /* Add the InfoPipe to the list of active services */
- val[0] = "pk";
- ret = confdb_add_param(cdb, false, "config/services", "activeServices", val);
- if (ret != EOK) goto done;
-#endif
+ ret = EOK;
done:
+ ret == EOK ?
+ ldb_transaction_commit(cdb->ldb) :
+ ldb_transaction_cancel(cdb->ldb);
talloc_free(tmp_ctx);
return ret;
}
@@ -595,7 +802,7 @@ int confdb_init(TALLOC_CTX *mem_ctx,
char *confdb_location)
{
struct confdb_ctx *cdb;
- int ret;
+ int ret = EOK;
cdb = talloc_zero(mem_ctx, struct confdb_ctx);
if (!cdb)
@@ -626,15 +833,6 @@ int confdb_init(TALLOC_CTX *mem_ctx,
return EIO;
}
- ret = confdb_test(cdb);
- if (ret == ENOENT) {
- ret = confdb_init_db(cdb);
- }
- if (ret != EOK) {
- talloc_free(cdb);
- return ret;
- }
-
*cdb_ctx = cdb;
return EOK;
diff --git a/server/confdb/confdb.h b/server/confdb/confdb.h
index b366d60d5..ae66807ae 100644
--- a/server/confdb/confdb.h
+++ b/server/confdb/confdb.h
@@ -26,10 +26,16 @@
#include "talloc.h"
#include "tevent.h"
#include "util/btreemap.h"
+#include "config.h"
#define CONFDB_FILE "config.ldb"
+#define CONFDB_DEFAULT_CONFIG_FILE SSSD_CONF_DIR"/sssd.conf"
#define SSSD_MIN_ID 1000
+struct confdb_ctx;
+
+typedef int (*confdb_reconf_fn) (struct confdb_ctx *cdb, void *pvt);
+
struct sss_domain_info {
char *name;
char *provider;
@@ -44,8 +50,6 @@ struct sss_domain_info {
struct sss_domain_info *next;
};
-struct confdb_ctx;
-
int confdb_add_param(struct confdb_ctx *cdb,
bool replace,
const char *section,
@@ -80,4 +84,8 @@ int confdb_get_domains(struct confdb_ctx *cdb,
TALLOC_CTX *mem_ctx,
struct sss_domain_info **domains);
+int confdb_create_base(struct confdb_ctx *cdb);
+int confdb_test(struct confdb_ctx *cdb);
+int confdb_init_db(const char *config_file, struct confdb_ctx *cdb);
+
#endif
diff --git a/server/confdb/confdb_private.h b/server/confdb/confdb_private.h
index c632f97de..f37919537 100644
--- a/server/confdb/confdb_private.h
+++ b/server/confdb/confdb_private.h
@@ -12,43 +12,9 @@
"\n" \
"dn: @MODULES\n" \
"@LIST: server_sort\n" \
- "\n" \
+ "\n"
+
+#define CONFDB_INTERNAL_LDIF \
"dn: cn=config\n" \
- "cn: config\n" \
- "version: 0.1\n" \
- "description: base object\n" \
- "\n" \
- "dn: cn=services,cn=config\n" \
- "cn: services\n" \
- "description: Local service configuration\n" \
- "activeServices: dp\n" \
- "activeServices: nss\n" \
- "activeServices: pam\n" \
- "\n" \
- "dn: cn=monitor,cn=services,cn=config\n" \
- "cn: monitor\n" \
- "description: Monitor Configuration\n" \
- "\n" \
- "dn: cn=dp,cn=services,cn=config\n" \
- "cn: dp\n" \
- "description: Data Provider Configuration\n" \
- "\n" \
- "dn: cn=nss,cn=services,cn=config\n" \
- "cn: nss\n" \
- "description: NSS Responder Configuration\n" \
- "\n" \
- "dn: cn=pam,cn=services,cn=config\n" \
- "cn: pam\n" \
- "description: PAM Responder Configuration\n" \
- "\n" \
- "dn: cn=domains,cn=config\n" \
- "cn: domains\n" \
- "description: Domains served by SSSD\n" \
- "domains: LOCAL\n" \
- "\n" \
- "dn: cn=LOCAL,cn=domains,cn=config\n" \
- "cn: LOCAL\n" \
- "description: LOCAL domain\n" \
- "enumerate: 3\n" \
- "magicPrivateGroups: TRUE\n" \
+ "version: 1\n" \
"\n"