summaryrefslogtreecommitdiff
path: root/server/confdb
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
parentc1d6bffe9ba81c265042859dddf3b39be87c161b (diff)
downloadsssd-4626af1ad1141291f226382f3569e4dd0486cd08.tar.gz
sssd-4626af1ad1141291f226382f3569e4dd0486cd08.tar.bz2
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')
-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 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, &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 b366d60d..ae66807a 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 c632f97d..f3791953 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"