diff options
Diffstat (limited to 'server/confdb/confdb.c')
-rw-r--r-- | server/confdb/confdb.c | 314 |
1 files changed, 256 insertions, 58 deletions
diff --git a/server/confdb/confdb.c b/server/confdb/confdb.c index 88700e30..4256418a 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, §ion_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; |