summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--server/Makefile.in19
-rw-r--r--server/confdb/confdb.c314
-rw-r--r--server/confdb/confdb.h12
-rw-r--r--server/confdb/confdb_private.h42
-rw-r--r--server/configure.ac2
-rw-r--r--server/examples/config.ldif88
-rw-r--r--server/examples/db.ldif71
-rw-r--r--server/examples/sssd.conf51
-rw-r--r--server/monitor/monitor.c353
-rw-r--r--server/monitor/monitor.h7
-rw-r--r--server/sbus/sssd_dbus_connection.c1
11 files changed, 686 insertions, 274 deletions
diff --git a/server/Makefile.in b/server/Makefile.in
index d7d114c3d..8aabd2f07 100644
--- a/server/Makefile.in
+++ b/server/Makefile.in
@@ -18,6 +18,7 @@ builddir = @builddir@
sharedbuilddir = @sharedbuilddir@
INSTALLCMD = @INSTALL@
EXTRA_OBJ=@EXTRA_OBJ@
+SSSD_CONF_DIR = @sysconfdir@/sssd
SSSD_LIBEXEC_PATH = @libexecdir@/@PACKAGE_NAME@
SSSD_LIBDIR = @pluginpath@
LDB_LIBDIR = @libdir@/ldb
@@ -62,6 +63,12 @@ OPENLDAP_LIBS = @OPENLDAP_LIBS@
LDAP_CFLAGS = $(OPENLDAP_CFLAGS)
LDAP_LIBS = $(OPENLDAP_LIBS)
+COLLECTION_CFLAGS = -I ../common/collection -I../common/trace
+COLLECTION_LIBS = -L ../common/collection/.libs/ -lcollection
+
+INI_CFG_CFLAGS = -I ../common/ini
+INI_CFG_LIBS = -L ../common/ini/.libs/ -lini_config
+
LIBDL = @LIBDL@
SHLIBEXT = @SHLIBEXT@
@@ -72,13 +79,15 @@ SHLD_FLAGS = @SHLD_FLAGS@
SONAMEFLAG = @SONAMEFLAG@
LDFLAGS += @LDFLAGS@ -L$(srcdir)/lib
-LIBS = @LIBS@ $(TALLOC_LIBS) $(TDB_LIBS) $(TEVENT_LIBS) $(POPT_LIBS) $(LDB_LIBS) $(DBUS_LIBS) $(PCRE_LIBS)
+LIBS = @LIBS@ $(TALLOC_LIBS) $(TDB_LIBS) $(TEVENT_LIBS) $(POPT_LIBS) $(LDB_LIBS) $(DBUS_LIBS) $(PCRE_LIBS) $(INI_CFG_LIBS) $(COLLECTION_LIBS)
PICFLAG = @PICFLAG@
CFLAGS := -I$(srcdir)/include -Iinclude -I$(srcdir) -I$(srcdir)/.. \
- $(POPT_CFLAGS) $(TALLOC_CFLAGS) $(TDB_CFLAGS) $(TEVENT_CFLAGS) $(LDB_CFLAGS) $(DBUS_CFLAGS) $(CHECK_CFLAGS) $(PCRE_CFLAGS) \
+ $(POPT_CFLAGS) $(TALLOC_CFLAGS) $(TDB_CFLAGS) $(TEVENT_CFLAGS) \
+ $(LDB_CFLAGS) $(DBUS_CFLAGS) $(CHECK_CFLAGS) $(PCRE_CFLAGS) \
+ $(COLLECTION_CFLAGS) $(INI_CFG_CFLAGS)\
-DLIBDIR=\"$(libdir)\" -DVARDIR=\"$(localstatedir)\" -DSHLIBEXT=\"$(SHLIBEXT)\" -DSSSD_LIBEXEC_PATH=\"$(SSSD_LIBEXEC_PATH)\" \
- -DSSSD_INTROSPECT_PATH=\"$(SSSD_INTROSPECT_PATH)\" -DUSE_MMAP=1 $(CFLAGS)
+ -DSSSD_INTROSPECT_PATH=\"$(SSSD_INTROSPECT_PATH)\" -DSSSD_CONF_DIR=\"$(SSSD_CONF_DIR)\" -DUSE_MMAP=1 $(CFLAGS)
MDLD = @MDLD@
MDLD_FLAGS = @MDLD_FLAGS@
@@ -109,6 +118,7 @@ OBJS = $(SERVER_OBJ) $(EXTRA_OBJ)
headers =
DBUS_SYSBUS_POLICY_DIR = @sysconfdir@/dbus-1/system.d
+SSSD_CONF_FILE = etc/sssd.conf
LIBEXECBINS = sbin/sssd_nss sbin/sssd_dp sbin/sssd_be sbin/sssd_pam
ifneq (x$(HAVE_INFOPIPE), x)
@@ -180,7 +190,8 @@ installdirs::
$(DESTDIR)$(SSSD_INTROSPECT_PATH)/infopipe \
$(DESTDIR)$(SSSD_PIPE_PATH)/private \
$(DESTDIR)$(SSSD_DB_PATH) \
- $(DESTDIR)$(SSSD_PID_PATH)
+ $(DESTDIR)$(SSSD_PID_PATH) \
+ $(DESTDIR)$(SSSD_CONF_DIR)
installheaders:: installdirs
ifneq (x$(headers), x)
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"
diff --git a/server/configure.ac b/server/configure.ac
index b37388027..fade762d4 100644
--- a/server/configure.ac
+++ b/server/configure.ac
@@ -76,4 +76,6 @@ AC_LIBREPLACE_MDLD
AC_LIBREPLACE_MDLD_FLAGS
AC_LIBREPLACE_RUNTIME_LIB_PATH_VAR
+AC_CHECK_HEADERS([sys/inotify.h])
+
AC_OUTPUT(Makefile)
diff --git a/server/examples/config.ldif b/server/examples/config.ldif
deleted file mode 100644
index b9eb33407..000000000
--- a/server/examples/config.ldif
+++ /dev/null
@@ -1,88 +0,0 @@
-# editing 4 records
-# record 1
-dn: cn=config
-cn: config
-version: 0.1
-
-dn: cn=services,cn=config
-cn: services
-description: Local service configuration
-activeServices: nss
-activeServices: dp
-activeServices: pam
-activeServices: info
-
-dn: cn=nss,cn=services,cn=config
-cn: nss
-description: NSS Responder Configuration
-filterGroups: root
-filterGroups: foo@TEST
-filterUsers: root
-filterUsers: bar@TEST
-
-dn: cn=dp,cn=services,cn=config
-cn: dp
-description: Data Provider Configuration
-
-dn: cn=monitor,cn=services,cn=config
-cn: monitor
-description: Monitor Configuration
-sbusTimeout: 10
-servicePingTime: 10
-
-dn: cn=pam,cn=services,cn=config
-cn: pam
-description: PAM Responder Configuration
-
-dn: cn=info,cn=services,cn=config
-cn: info
-description: InfoPipe Configuration
-
-dn: cn=domains,cn=config
-cn: domains
-description: Domains served by SSSD
-domains: LOCAL, EXAMPLE.COM, TEST
-
-dn: cn=LOCAL,cn=domains,cn=config
-cn: LOCAL
-description: Reserved domain for local configurations
-enumerate: 3
-minId: 500
-maxId: 999
-legacy: TRUE
-libName: files
-libPath: /lib64/libnss_files.so.2
-magicPrivateGroups: FALSE
-provider: proxy
-auth-module: proxy
-pam-target: sssdproxylocal
-
-dn: cn=TEST,cn=domains,cn=config
-cn: TEST
-description: TEST Ldap domain
-libName: ldap
-libPath: /usr/lib64/libnss_ldap.so.2
-legacy: TRUE
-enumerate: 3
-useFullyQualifiedNames: TRUE
-minId: 1000
-provider: proxy
-auth-module: proxy
-pam-target: sssdproxytest
-
-dn: cn=LDAPTEST,cn=domains,cn=config
-cn: LDAPTEST
-basedn: cn=LDAPTEST,sn=sysdb
-command: /usr/libexec/sssd/sssd_be --provider ldap --domain LDAPTEST
-description: TEST PAM Ldap domain
-provider: ldap
-userSearchBase: ou=user,dc=my-domain,dc=com
-
-dn: cn=EXAMPLE.COM,cn=domains,cn=config
-cn: EXAMPLE.COM
-description: Example domain served by IPA
-provider: ipa
-server: ipaserver1.example.com
-server: ipabackupserver.example.com
-legacy: FALSE
-enumerate: 0
diff --git a/server/examples/db.ldif b/server/examples/db.ldif
deleted file mode 100644
index 9ded6c794..000000000
--- a/server/examples/db.ldif
+++ /dev/null
@@ -1,71 +0,0 @@
-dn: @ATTRIBUTES
-userPrincipalName: CASE_INSENSITIVE
-cn: CASE_INSENSITIVE
-dc: CASE_INSENSITIVE
-dn: CASE_INSENSITIVE
-name: CASE_INSENSITIVE
-objectclass: CASE_INSENSITIVE
-
-dn: @INDEXLIST
-@IDXATTR: cn
-@IDXATTR: objectclass
-@IDXATTR: member
-@IDXATTR: memberof
-@IDXATTR: memberUid
-@IDXATTR: uid
-@IDXATTR: gid
-@IDXATTR: uidNumber
-@IDXATTR: gidNumber
-@IDXATTR: lastUpdate
-
-dn: @MODULES
-@LIST: asq,memberof
-
-dn: cn=sysdb
-cn: sysdb
-version: 0.1
-description: base object
-
-dn: cn=local,cn=sysdb
-cn: local
-description: Local system data
-
-dn: cn=groups,cn=local,cn=sysdb
-cn: groups
-description: Local POSIX groups
-
-dn: gid=foousers,cn=groups,cn=local,cn=sysdb
-gid: foousers
-description: Local user accounts
-member: uid=foobar,cn=users,cn=local,cn=sysdb
-objectclass: group
-gidNumber: 10101
-
-dn: cn=users,cn=local,cn=sysdb
-cn: users
-description: Local POSIX users
-
-dn: uid=foobar,cn=users,cn=local,cn=sysdb
-uid: foobar
-objectClass: user
-description: User Foo Bar
-uidNumber: 10101
-gidNumber: 10101
-legacy: false
-primaryGroup: cn=foousers,cn=groups,cn=local,cn=sysdb
-userPassword: !@#$%#@#@!FOOBAR
-homeDirectory: /home/foobar
-fullName: Foo Bar
-loginShell: /bin/bash
-accountExpires: 20500101000000Z
-biometricSignature: <binary>
-disabled: false
-failedLoginAttempts: 0
-keyboardLayout: it_IT
-lastPasswordChange: 20080912142034Z
-passwordHint: Favorite pasta sauce
-passwordHistory: foo,bar,baz
-preferredLanguage: IT
-preferredSession: GNOME
-memberOf: cn=foousers,cn=groups,cn=local,cn=sysdb
-
diff --git a/server/examples/sssd.conf b/server/examples/sssd.conf
new file mode 100644
index 000000000..b15e92ff1
--- /dev/null
+++ b/server/examples/sssd.conf
@@ -0,0 +1,51 @@
+[services]
+description = Local Service Configuration
+activeServices = nss, dp, pam, info
+
+[services/nss]
+description = NSS Responder Configuration
+timeout = 10
+filterGroups = root, foo@TEST
+filterUsers = root, bar@TEST
+
+[services/dp]
+description = Data Provider Configuration
+timeout = 10
+
+[services/pam]
+description = PAM Responder Configuration
+timeout = 10
+
+[services/info]
+description = InfoPipe Configuration
+timeout = 10
+
+[services/monitor]
+description = Service Monitor Configuration
+sbusTimeout = 10
+servicePingTime = 10
+
+[domains]
+description = Domains served by SSSD
+domains = LOCAL
+
+[domains/LOCAL]
+description = Reserved domain for local configurations
+enumerate = 3
+minId = 500
+maxId = 999
+legacy = TRUE
+libName = files
+libPath = /lib64/libnss_files.so.2
+magicPrivateGroups = FALSE
+provider = proxy
+auth-module = proxy
+pam-target = sssdproxylocal
+
+[domains/EXAMPLE.COM]
+description = Example LDAP domain
+basedn = dc=example,dc=com
+command = /usr/libexec/sssd/sssd_be --provider ldap --domain EXAMPLE.COM
+provider = ldap
+userSearchBase = ou=user,dc=example,dc=com
+
diff --git a/server/monitor/monitor.c b/server/monitor/monitor.c
index 65664ca61..168112242 100644
--- a/server/monitor/monitor.c
+++ b/server/monitor/monitor.c
@@ -24,6 +24,14 @@
#include <sys/wait.h>
#include <sys/time.h>
#include <time.h>
+#include "config.h"
+#ifdef HAVE_SYS_INOTIFY_H
+#include <sys/inotify.h>
+#endif
+#include <sys/types.h>
+#include <sys/stat.h>
+#include <unistd.h>
+#include <fcntl.h>
#include "util/util.h"
#include "popt.h"
#include "tevent.h"
@@ -79,6 +87,17 @@ struct mt_ctx {
int service_id_timeout;
};
+struct config_file_ctx {
+ TALLOC_CTX *parent_ctx;
+ struct confdb_ctx *cdb;
+ struct tevent_context *ev;
+ int fd;
+ char *filename;
+ time_t modified;
+ confdb_reconf_fn reconf_fn;
+ void *reconf_pvt;
+};
+
static int start_service(struct mt_svc *mt_svc);
static int dbus_service_init(struct sbus_conn_ctx *conn_ctx, void *data);
@@ -97,8 +116,11 @@ static int get_service_config(struct mt_ctx *ctx, const char *name,
struct mt_svc **svc_cfg);
static int get_provider_config(struct mt_ctx *ctx, const char *name,
struct mt_svc **svc_cfg);
-static int add_new_service (struct mt_ctx *ctx, const char *name);
-static int add_new_provider (struct mt_ctx *ctx, const char *name);
+static int add_new_service(struct mt_ctx *ctx, const char *name);
+static int add_new_provider(struct mt_ctx *ctx, const char *name);
+
+static int monitor_signal_reconf(struct confdb_ctx *cdb, void *pvt);
+static int update_monitor_config(struct mt_ctx *ctx);
/* dbus_get_monitor_version
* Return the monitor version over D-BUS */
@@ -474,6 +496,13 @@ done:
dbus_message_unref(reply);
}
+static int monitor_signal_reconf(struct confdb_ctx *cdb, void *pvt)
+{
+ struct mt_ctx *ctx = talloc_get_type(pvt, struct mt_ctx);
+ DEBUG(1, ("Configuration has changed. Reloading.\n"));
+ return update_monitor_config(ctx);
+}
+
static int service_signal_reload(struct mt_svc *svc)
{
DBusMessage *msg;
@@ -513,6 +542,11 @@ static int service_signal_reload(struct mt_svc *svc)
int get_monitor_config(struct mt_ctx *ctx)
{
int ret;
+ size_t svc_count = 0;
+ char *svcs;
+ char *cur, *p, *t;
+ char **svc_list = NULL;
+ char **tmp_list = NULL;
ret = confdb_get_int(ctx->cdb, ctx,
MONITOR_CONF_ENTRY, "sbusTimeout",
@@ -521,22 +555,61 @@ int get_monitor_config(struct mt_ctx *ctx)
return ret;
}
- ret = confdb_get_param(ctx->cdb, ctx,
- "config/services", "activeServices",
- &ctx->services);
+ ret = confdb_get_string(ctx->cdb, ctx,
+ "config/services", "activeServices",
+ NULL, &svcs);
- if (ctx->services[0] == NULL) {
+ if (ret != EOK || svcs == NULL) {
DEBUG(0, ("No services configured!\n"));
return EINVAL;
}
+ cur = p = talloc_strdup(svcs, svcs);
+ while (p && *p) {
+ for (cur = p; (*cur == ' ' || *cur == '\t'); cur++) /* trim */ ;
+ if (!*cur) break;
+
+ p = strchr(cur, ',');
+ if (p) {
+ /* terminate element */
+ *p = '\0';
+ /* trim spaces */
+ for (t = p-1; (*t == ' ' || *t == '\t'); t--) *t = '\0';
+ p++;
+ }
+
+ svc_count++;
+ tmp_list = talloc_realloc(svcs, svc_list, char *, svc_count);
+ if (!tmp_list) {
+ ret = ENOMEM;
+ goto done;
+ }
+ svc_list = tmp_list;
+ svc_list[svc_count-1] = talloc_strdup(svc_list, cur);
+ }
+
+ svc_count++;
+ tmp_list = talloc_realloc(svcs, svc_list, char *, svc_count);
+ if (!tmp_list) {
+ ret = ENOMEM;
+ goto done;
+ }
+ svc_list = tmp_list;
+ svc_list[svc_count-1] = NULL;
+
+ ctx->services = talloc_steal(ctx, svc_list);
+
ret = confdb_get_domains(ctx->cdb, ctx, &ctx->domains);
if (ret != EOK) {
DEBUG(2, ("No domains configured. LOCAL should always exist!\n"));
return ret;
}
- return EOK;
+ ret = EOK;
+
+done:
+ talloc_free(svcs);
+ return ret;
}
static int get_service_config(struct mt_ctx *ctx, const char *name,
@@ -604,7 +677,7 @@ static int get_service_config(struct mt_ctx *ctx, const char *name,
return EOK;
}
-static int add_new_service (struct mt_ctx *ctx, const char *name)
+static int add_new_service(struct mt_ctx *ctx, const char *name)
{
int ret;
struct mt_svc *svc;
@@ -701,7 +774,7 @@ static int get_provider_config(struct mt_ctx *ctx, const char *name,
return EOK;
}
-static int add_new_provider (struct mt_ctx *ctx, const char *name)
+static int add_new_provider(struct mt_ctx *ctx, const char *name)
{
int ret;
struct mt_svc *svc;
@@ -958,9 +1031,233 @@ static void monitor_hup(struct tevent_context *ev,
update_monitor_config(ctx);
}
+#ifdef HAVE_SYS_INOTIFY_H
+static void config_file_changed(struct tevent_context *ev,
+ struct tevent_fd *fde,
+ uint16_t flags, void *data)
+{
+ int ret;
+ TALLOC_CTX *tmp_ctx;
+ struct inotify_event *in_event;
+ char *buf;
+ char *name;
+ ssize_t len, total_len;
+ ssize_t event_size = sizeof(struct inotify_event);
+ struct config_file_ctx *file_ctx =
+ talloc_get_type(data, struct config_file_ctx);
+
+ DEBUG(1, ("Config file changed\n"));
+
+ tmp_ctx = talloc_new(NULL);
+ if (!tmp_ctx) return;
+
+ buf = talloc_size(tmp_ctx, event_size);
+ if (!buf) {
+ talloc_free(tmp_ctx);
+ return;
+ }
+
+ total_len = 0;
+ while (total_len < event_size) {
+ len = read(file_ctx->fd, &buf+total_len, event_size-total_len);
+ if (len == -1 && errno != EINTR) {
+ DEBUG(0, ("Critical error reading inotify file descriptor.\n"));
+ talloc_free(tmp_ctx);
+ return;
+ }
+ total_len += len;
+ }
+
+ in_event = (struct inotify_event *)&buf;
+
+ if (in_event->len > 0) {
+ /* Read in the name, even though we don't use it,
+ * so that read ptr is in the right place
+ */
+ name = talloc_size(tmp_ctx, len);
+ total_len = 0;
+ while (total_len < in_event->len) {
+ len = read(file_ctx->fd, &name, in_event->len);
+ if (len == -1 && errno != EINTR) {
+ DEBUG(0, ("Critical error reading inotify file descriptor.\n"));
+ talloc_free(tmp_ctx);
+ return;
+ }
+ total_len += len;
+ }
+ }
+
+ /* Parse the configuration file */
+ ret = confdb_init_db(file_ctx->filename, file_ctx->cdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Could not reload configuration!"));
+ kill(getpid(), SIGTERM);
+ }
+
+ /* Tell the monitor to signal the children */
+ file_ctx->reconf_fn(file_ctx->cdb, file_ctx->reconf_pvt);
+
+ talloc_free(tmp_ctx);
+}
+#endif
+
+static void poll_config_file(struct tevent_context *ev,
+ struct tevent_timer *te,
+ struct timeval t, void *ptr)
+{
+ int ret, err;
+ struct stat file_stat;
+ struct timeval tv;
+ struct tevent_timer *timer;
+ struct config_file_ctx *file_ctx =
+ talloc_get_type(ptr,struct config_file_ctx);
+
+ ret = stat(file_ctx->filename, &file_stat);
+ if (ret < 0) {
+ err = errno;
+ DEBUG(0, ("Could not stat file [%s]. Error [%d:%s]\n",
+ file_ctx->filename, err, strerror(err)));
+ /* TODO: If the config file is missing, should we shut down? */
+ return;
+ }
+
+ if (file_stat.st_mtime != file_ctx->modified) {
+ /* Parse the configuration file and signal the children */
+ /* Note: this will fire if the modification time changes into the past
+ * as well as the future.
+ */
+ DEBUG(1, ("Config file changed\n"));
+ file_ctx->modified = file_stat.st_mtime;
+
+ ret = confdb_init_db(file_ctx->filename, file_ctx->cdb);
+ if (ret != EOK) {
+ DEBUG(0, ("Could not reload configuration!"));
+ kill(getpid(), SIGTERM);
+ }
+
+ /* Tell the monitor to signal the children */
+ file_ctx->reconf_fn(file_ctx->cdb, file_ctx->reconf_pvt);
+ }
+
+ gettimeofday(&tv, NULL);
+ tv.tv_sec += CONFIG_FILE_POLL_INTERVAL;
+ tv.tv_usec = 0;
+ timer = tevent_add_timer(ev, file_ctx->parent_ctx, tv,
+ poll_config_file, file_ctx);
+ if (!timer) {
+ DEBUG(0, ("Error: Config file no longer monitored for changes!"));
+ }
+}
+
+static int try_inotify(struct config_file_ctx *file_ctx)
+{
+#ifdef HAVE_SYS_INOTIFY_H
+ int fd, wd, err, fd_args, ret;
+ struct tevent_fd *tfd;
+
+ /* Set up inotify to monitor the config file for changes */
+ fd = inotify_init();
+ if (fd < 0) {
+ err = errno;
+ DEBUG(0, ("Could not initialize inotify, error [%d:%s]\n",
+ err, strerror(err)));
+ return err;
+ }
+
+ fd_args = fcntl(fd, F_GETFL, NULL);
+ if (fd_args < 0) {
+ /* Could not set nonblocking */
+ close(fd);
+ return EINVAL;
+ }
+
+ fd_args |= O_NONBLOCK;
+ ret = fcntl(fd, F_SETFL, fd_args);
+ if (ret < 0) {
+ /* Could not set nonblocking */
+ close(fd);
+ return EINVAL;
+ }
+
+ wd = inotify_add_watch(fd, file_ctx->filename, IN_MODIFY);
+ if (wd < 0) {
+ err = errno;
+ DEBUG(0, ("Could not add inotify watch for file [%s]. Error [%d:%s]\n",
+ file_ctx->filename, err, strerror(err)));
+ close(fd);
+ return err;
+ }
+
+ /* Add the inotify file descriptor to the TEvent context */
+ file_ctx->fd = fd;
+
+ tfd = tevent_add_fd(file_ctx->ev, file_ctx, fd, TEVENT_FD_READ,
+ config_file_changed, file_ctx);
+ if (!tfd) {
+ inotify_rm_watch(fd, wd);
+ close(fd);
+ return EIO;
+ }
+ return EOK;
+#else
+ return EINVAL;
+#endif
+}
+
+static int monitor_config_file(TALLOC_CTX *mem_ctx,
+ struct confdb_ctx *cdb,
+ struct tevent_context *ev,
+ const char *file,
+ confdb_reconf_fn fn,
+ void *reconf_pvt)
+{
+ int ret, err;
+ struct timeval tv;
+
+ struct stat file_stat;
+ struct config_file_ctx *file_ctx;
+
+ struct tevent_timer *timer;
+
+ ret = stat(file, &file_stat);
+ if (ret < 0) {
+ err = errno;
+ DEBUG(0, ("Could not stat file [%s]. Error [%d:%s]\n",
+ file, err, strerror(err)));
+ return err;
+ }
+
+ file_ctx = talloc_zero(mem_ctx, struct config_file_ctx);
+ if (!file_ctx) return ENOMEM;
+
+ file_ctx->parent_ctx = mem_ctx;
+ file_ctx->cdb = cdb;
+ file_ctx->filename = talloc_strdup(file_ctx, file);
+ file_ctx->modified = file_stat.st_mtime;
+ file_ctx->reconf_fn = fn;
+ file_ctx->reconf_pvt = reconf_pvt;
+ file_ctx->ev = ev;
+
+ ret = try_inotify(file_ctx);
+ if (ret != EOK) {
+ /* Could not monitor file with inotify, fall back to polling */
+ gettimeofday(&tv, NULL);
+ tv.tv_sec += CONFIG_FILE_POLL_INTERVAL;
+ tv.tv_usec = 0;
+ timer = tevent_add_timer(ev, mem_ctx, tv, poll_config_file, file_ctx);
+ if (!timer) {
+ talloc_free(file_ctx);
+ return EIO;
+ }
+ }
+
+ return EOK;
+}
+
int monitor_process_init(TALLOC_CTX *mem_ctx,
struct tevent_context *event_ctx,
- struct confdb_ctx *cdb)
+ struct confdb_ctx *cdb,
+ const char *config_file)
{
struct mt_ctx *ctx;
struct sysdb_ctx *sysdb;
@@ -976,10 +1273,37 @@ int monitor_process_init(TALLOC_CTX *mem_ctx,
ctx->ev = event_ctx;
ctx->cdb = cdb;
+ /* Initialize the CDB from the configuration file */
+ ret = confdb_test(ctx->cdb);
+ if (ret == ENOENT) {
+ /* First-time setup
+ * Load special entries
+ */
+ ret = confdb_create_base(cdb);
+ if (ret != EOK) {
+ talloc_free(ctx);
+ return ret;
+ }
+ }
+
+ ret = confdb_init_db(config_file, cdb);
+ if (ret != EOK) {
+ talloc_free(cdb);
+ DEBUG(0, ("ConfDB initialization has failed [%s]\n",
+ strerror(ret)));
+ talloc_free(ctx);
+ return ret;
+ }
+
+ /* Read in the monitor's configuration */
ret = get_monitor_config(ctx);
if (ret != EOK)
return ret;
+ /* Watch for changes to the confdb config file */
+ ret = monitor_config_file(ctx, cdb, event_ctx, config_file, monitor_signal_reconf, ctx);
+ if (ret != EOK) return ret;
+
/* Avoid a startup race condition between InfoPipe
* and NSS. If the sysdb doesn't exist yet, both
* will try to create it at the same time. So
@@ -1165,6 +1489,8 @@ static void identity_check(DBusPendingCall *pending, void *data)
goto done;
}
+ DEBUG(4,("Received ID reply: (%s,%d)\n", svc_name, svc_ver));
+
/* search this service in the list */
svc = fake_svc->mt_ctx->svc_list;
while (svc) {
@@ -1546,6 +1872,7 @@ int main(int argc, const char *argv[])
poptContext pc;
int opt_daemon = 0;
int opt_interactive = 0;
+ char *opt_config_file = NULL;
int flags = 0;
struct main_context *main_ctx;
int ret;
@@ -1557,6 +1884,8 @@ int main(int argc, const char *argv[])
"Become a daemon (default)", NULL }, \
{"interactive", 'i', POPT_ARG_NONE, &opt_interactive, 0, \
"Run interactive (not a daemon)", NULL}, \
+ {"config", 'c', POPT_ARG_STRING, &opt_config_file, 0, \
+ "Specify a non-default config file", NULL}, \
{ NULL }
};
@@ -1581,6 +1910,7 @@ int main(int argc, const char *argv[])
if (opt_daemon) flags |= FLAGS_DAEMON;
if (opt_interactive) flags |= FLAGS_INTERACTIVE;
+ if (!opt_config_file) opt_config_file = CONFDB_DEFAULT_CONFIG_FILE;
/* we want a pid file check */
flags |= FLAGS_PID_FILE;
@@ -1591,7 +1921,8 @@ int main(int argc, const char *argv[])
ret = monitor_process_init(main_ctx,
main_ctx->event_ctx,
- main_ctx->confdb_ctx);
+ main_ctx->confdb_ctx,
+ opt_config_file);
if (ret != EOK) return 3;
/* loop on main */
diff --git a/server/monitor/monitor.h b/server/monitor/monitor.h
index 77b6e781d..2a5218b14 100644
--- a/server/monitor/monitor.h
+++ b/server/monitor/monitor.h
@@ -1,4 +1,4 @@
-/*
+/*
SSSD
Service monitor
@@ -22,8 +22,11 @@
#ifndef _MONITOR_H_
#define _MONITOR_H_
+#define CONFIG_FILE_POLL_INTERVAL 5 /* seconds */
+
int monitor_process_init(TALLOC_CTX *mem_ctx,
struct tevent_context *event_ctx,
- struct confdb_ctx *cdb);
+ struct confdb_ctx *cdb,
+ const char *config_file);
#endif /* _MONITOR_H */
diff --git a/server/sbus/sssd_dbus_connection.c b/server/sbus/sssd_dbus_connection.c
index 1a3f107c9..cd9d5a182 100644
--- a/server/sbus/sssd_dbus_connection.c
+++ b/server/sbus/sssd_dbus_connection.c
@@ -573,6 +573,7 @@ DBusHandlerResult sbus_message_handler(DBusConnection *conn,
ctx = talloc_get_type(user_data, struct sbus_message_handler_ctx);
method = dbus_message_get_member(message);
+ DEBUG(9, ("Received SBUS method [%s]\n", method));
path = dbus_message_get_path(message);
msg_interface = dbus_message_get_interface(message);