summaryrefslogtreecommitdiffstats
path: root/server/confdb/confdb.c
diff options
context:
space:
mode:
authorStephen Gallagher <sgallagh@redhat.com>2009-04-11 10:20:48 -0400
committerSimo Sorce <ssorce@redhat.com>2009-04-13 09:06:49 -0400
commit4626af1ad1141291f226382f3569e4dd0486cd08 (patch)
treef35309c400cd028482750e0469db218e6eb02d49 /server/confdb/confdb.c
parentc1d6bffe9ba81c265042859dddf3b39be87c161b (diff)
downloadsssd-4626af1ad1141291f226382f3569e4dd0486cd08.tar.gz
sssd-4626af1ad1141291f226382f3569e4dd0486cd08.tar.xz
sssd-4626af1ad1141291f226382f3569e4dd0486cd08.zip
Allow configuration of the SSSD through /etc/sssd/sssd.conf
The SSSD now links with the ini_config and collection libraries in the common directory. The monitor will track changes to the /etc/sssd/sssd.conf file using inotify on platforms that support it, or polled every 5 seconds on platforms that do not. At startup or modification of the conf file, the monitor will purge the existing confdb and reread it completely from the conf file, to ensure that there are no lingering entries. It does this in a transaction, so there should be no race condition with the client services. A new option has been added to the startup options for the SSSD. It is now possible to specify an alternate config file with the -c <file> at the command line.
Diffstat (limited to 'server/confdb/confdb.c')
-rw-r--r--server/confdb/confdb.c314
1 files changed, 256 insertions, 58 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;