387014f928
required for building freeipa-4.5.x in rawhide
532 lines
18 KiB
Diff
532 lines
18 KiB
Diff
From 825e8bf2f73a815c2eceb36ae805145fcbacf74d Mon Sep 17 00:00:00 2001
|
|
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
Date: Mon, 27 Mar 2017 09:48:46 +0200
|
|
Subject: [PATCH 65/97] CONFDB: Allow configuring [application] sections as
|
|
non-POSIX domains
|
|
MIME-Version: 1.0
|
|
Content-Type: text/plain; charset=UTF-8
|
|
Content-Transfer-Encoding: 8bit
|
|
|
|
Related to:
|
|
https://pagure.io/SSSD/sssd/issue/3310
|
|
|
|
Allows to add a new section:
|
|
[application/$name]
|
|
|
|
This section internally (on the confdb level) expands to:
|
|
[domain/$name]
|
|
domain_type = application
|
|
|
|
The reasons to add this new section is two-fold. One, to make the
|
|
configuration of application domains more explicit and two, to make it
|
|
possible to share configuration between two domains, one POSIX and one
|
|
non-POSIX by application domain's inherit_from option:
|
|
[application/$name]
|
|
inherit_from = posix_domain_name
|
|
|
|
Reviewed-by: Sumit Bose <sbose@redhat.com>
|
|
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
|
---
|
|
src/confdb/confdb.c | 288 ++++++++++++++++++++++++++++++++++++++++++++---
|
|
src/confdb/confdb.h | 4 +
|
|
src/config/cfg_rules.ini | 9 +-
|
|
src/man/sssd.conf.5.xml | 77 +++++++++++++
|
|
src/monitor/monitor.c | 8 ++
|
|
5 files changed, 368 insertions(+), 18 deletions(-)
|
|
|
|
diff --git a/src/confdb/confdb.c b/src/confdb/confdb.c
|
|
index 70a1eb7b2c7e83dfa9d217a15c7d3d4c8580b891..88e114457deac3ca50c291a131122624fb6f6fe4 100644
|
|
--- a/src/confdb/confdb.c
|
|
+++ b/src/confdb/confdb.c
|
|
@@ -813,6 +813,50 @@ done:
|
|
return ret;
|
|
}
|
|
|
|
+static int confdb_get_domain_section(TALLOC_CTX *mem_ctx,
|
|
+ struct confdb_ctx *cdb,
|
|
+ const char *section,
|
|
+ const char *name,
|
|
+ struct ldb_result **_res)
|
|
+{
|
|
+ TALLOC_CTX *tmp_ctx;
|
|
+ int ret;
|
|
+ struct ldb_result *res;
|
|
+ struct ldb_dn *dn;
|
|
+
|
|
+ tmp_ctx = talloc_new(NULL);
|
|
+ if (tmp_ctx == NULL) {
|
|
+ return ENOMEM;
|
|
+ }
|
|
+
|
|
+ dn = ldb_dn_new_fmt(tmp_ctx, cdb->ldb, "cn=%s,%s", name, section);
|
|
+ if (dn == NULL) {
|
|
+ ret = ENOMEM;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn,
|
|
+ LDB_SCOPE_BASE, NULL, NULL);
|
|
+ if (ret != LDB_SUCCESS) {
|
|
+ ret = sysdb_error_to_errno(ret);
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ if (res->count == 0) {
|
|
+ ret = ENOENT;
|
|
+ goto done;
|
|
+ } else if (res->count > 1) {
|
|
+ ret = E2BIG;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ *_res = talloc_steal(mem_ctx, res);
|
|
+ ret = EOK;
|
|
+done:
|
|
+ talloc_free(tmp_ctx);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
static int confdb_get_domain_internal(struct confdb_ctx *cdb,
|
|
TALLOC_CTX *mem_ctx,
|
|
const char *name,
|
|
@@ -821,7 +865,6 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
|
|
struct sss_domain_info *domain;
|
|
struct ldb_result *res;
|
|
TALLOC_CTX *tmp_ctx;
|
|
- struct ldb_dn *dn;
|
|
const char *tmp;
|
|
int ret, val;
|
|
uint32_t entry_cache_timeout;
|
|
@@ -833,23 +876,15 @@ static int confdb_get_domain_internal(struct confdb_ctx *cdb,
|
|
tmp_ctx = talloc_new(mem_ctx);
|
|
if (!tmp_ctx) return ENOMEM;
|
|
|
|
- dn = ldb_dn_new_fmt(tmp_ctx, cdb->ldb,
|
|
- "cn=%s,%s", name, CONFDB_DOMAIN_BASEDN);
|
|
- if (!dn) {
|
|
- ret = ENOMEM;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- ret = ldb_search(cdb->ldb, tmp_ctx, &res, dn,
|
|
- LDB_SCOPE_BASE, NULL, NULL);
|
|
- if (ret != LDB_SUCCESS) {
|
|
- ret = EIO;
|
|
- goto done;
|
|
- }
|
|
-
|
|
- if (res->count != 1) {
|
|
+ ret = confdb_get_domain_section(tmp_ctx, cdb, CONFDB_DOMAIN_BASEDN,
|
|
+ name, &res);
|
|
+ if (ret == ENOENT) {
|
|
DEBUG(SSSDBG_FATAL_FAILURE, "Unknown domain [%s]\n", name);
|
|
- ret = ENOENT;
|
|
+ goto done;
|
|
+ } else if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_FATAL_FAILURE,
|
|
+ "Error %d: %s while retrieving %s\n",
|
|
+ ret, sss_strerror(ret), name);
|
|
goto done;
|
|
}
|
|
|
|
@@ -1841,3 +1876,222 @@ int confdb_ensure_files_domain(struct confdb_ctx *cdb,
|
|
return activate_files_domain(cdb, implicit_files_dom_name);
|
|
#endif /* ADD_FILES_DOMAIN */
|
|
}
|
|
+
|
|
+static int confdb_get_parent_domain(TALLOC_CTX *mem_ctx,
|
|
+ const char *name,
|
|
+ struct confdb_ctx *cdb,
|
|
+ struct ldb_result *app_dom,
|
|
+ struct ldb_result **_parent_dom)
|
|
+{
|
|
+ const char *inherit_from;
|
|
+
|
|
+ inherit_from = ldb_msg_find_attr_as_string(app_dom->msgs[0],
|
|
+ CONFDB_DOMAIN_INHERIT_FROM, NULL);
|
|
+ if (inherit_from == NULL) {
|
|
+ DEBUG(SSSDBG_CONF_SETTINGS,
|
|
+ "%s does not inherit from any POSIX domain\n", name);
|
|
+ *_parent_dom = NULL;
|
|
+ return EOK;
|
|
+ }
|
|
+
|
|
+ return confdb_get_domain_section(mem_ctx, cdb,
|
|
+ CONFDB_DOMAIN_BASEDN, inherit_from,
|
|
+ _parent_dom);
|
|
+}
|
|
+
|
|
+static int confdb_add_app_domain(TALLOC_CTX *mem_ctx,
|
|
+ struct confdb_ctx *cdb,
|
|
+ const char *name)
|
|
+{
|
|
+ char *cdb_path = NULL;
|
|
+ const char *val[2] = { NULL, NULL };
|
|
+ int ret;
|
|
+
|
|
+ cdb_path = talloc_asprintf(mem_ctx, CONFDB_DOMAIN_PATH_TMPL, name);
|
|
+ if (cdb_path == NULL) {
|
|
+ return ENOMEM;
|
|
+ }
|
|
+
|
|
+ val[0] = CONFDB_DOMAIN_TYPE_APP;
|
|
+ ret = confdb_add_param(cdb, true, cdb_path, CONFDB_DOMAIN_TYPE, val);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add id_provider [%d]: %s\n",
|
|
+ ret, sss_strerror(ret));
|
|
+ return ret;
|
|
+ }
|
|
+
|
|
+ return EOK;
|
|
+}
|
|
+
|
|
+static int confdb_merge_parent_domain(const char *name,
|
|
+ struct confdb_ctx *cdb,
|
|
+ struct ldb_result *app_section)
|
|
+{
|
|
+ int ret;
|
|
+ int ldb_flag;
|
|
+ struct ldb_result *parent_domain = NULL;
|
|
+ struct ldb_message *replace_msg = NULL;
|
|
+ struct ldb_message *app_msg = NULL;
|
|
+ struct ldb_dn *domain_dn;
|
|
+ TALLOC_CTX *tmp_ctx = NULL;
|
|
+
|
|
+ tmp_ctx = talloc_new(NULL);
|
|
+ if (tmp_ctx == NULL) {
|
|
+ DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
|
|
+ return ENOMEM;
|
|
+ }
|
|
+
|
|
+ domain_dn = ldb_dn_new_fmt(tmp_ctx,
|
|
+ cdb->ldb,
|
|
+ "%s=%s,%s",
|
|
+ CONFDB_DOMAIN_ATTR,
|
|
+ name,
|
|
+ CONFDB_DOMAIN_BASEDN);
|
|
+ if (domain_dn == NULL) {
|
|
+ ret = ENOMEM;
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ /* Copy the parent domain parameters */
|
|
+ ret = confdb_get_parent_domain(tmp_ctx, name, cdb,
|
|
+ app_section, &parent_domain);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
+ "Cannot retrieve the parent domain [%d]: %s\n",
|
|
+ ret, sss_strerror(ret));
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ if (parent_domain != NULL) {
|
|
+ replace_msg = ldb_msg_copy(tmp_ctx, parent_domain->msgs[0]);
|
|
+ if (replace_msg == NULL) {
|
|
+ ret = ENOMEM;
|
|
+ goto done;
|
|
+ }
|
|
+ replace_msg->dn = domain_dn;
|
|
+
|
|
+ for (unsigned i = 0; i < replace_msg->num_elements; i++) {
|
|
+ replace_msg->elements[i].flags = LDB_FLAG_MOD_ADD;
|
|
+ }
|
|
+
|
|
+ ret = ldb_modify(cdb->ldb, replace_msg);
|
|
+ if (ret != LDB_SUCCESS) {
|
|
+ ret = sysdb_error_to_errno(ret);
|
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
+ "Inheriting options from parent domain failed [%d]: %s\n",
|
|
+ ret, sss_strerror(ret));
|
|
+ goto done;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ /* Finally, add any app-domain specific overrides */
|
|
+ app_msg = ldb_msg_new(tmp_ctx);
|
|
+ if (app_msg == NULL) {
|
|
+ ret = ENOMEM;
|
|
+ goto done;
|
|
+ }
|
|
+ app_msg->dn = domain_dn;
|
|
+
|
|
+ for (unsigned i = 0; i < app_section->msgs[0]->num_elements; i++) {
|
|
+ struct ldb_message_element *el = NULL;
|
|
+
|
|
+ if (replace_msg != NULL) {
|
|
+ el = ldb_msg_find_element(replace_msg,
|
|
+ app_section->msgs[0]->elements[i].name);
|
|
+ if (el == NULL) {
|
|
+ /* Adding an element */
|
|
+ ldb_flag = LDB_FLAG_MOD_ADD;
|
|
+ } else {
|
|
+ /* Overriding an element */
|
|
+ ldb_flag = LDB_FLAG_MOD_REPLACE;
|
|
+ }
|
|
+ } else {
|
|
+ /* If there was no domain to inherit from, just add all */
|
|
+ ldb_flag = LDB_FLAG_MOD_ADD;
|
|
+ }
|
|
+
|
|
+ ret = ldb_msg_add(app_msg,
|
|
+ &app_section->msgs[0]->elements[i],
|
|
+ ldb_flag);
|
|
+ if (ret != EOK) {
|
|
+ continue;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ret = ldb_modify(cdb->ldb, app_msg);
|
|
+ if (ret != LDB_SUCCESS) {
|
|
+ ret = sysdb_error_to_errno(ret);
|
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
+ "Adding app-specific options failed [%d]: %s\n",
|
|
+ ret, sss_strerror(ret));
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ DEBUG(SSSDBG_TRACE_LIBS, "Added a domain section for %s\n", name);
|
|
+ ret = EOK;
|
|
+done:
|
|
+ talloc_free(tmp_ctx);
|
|
+ return ret;
|
|
+}
|
|
+
|
|
+int confdb_expand_app_domains(struct confdb_ctx *cdb)
|
|
+{
|
|
+ int ret;
|
|
+ char **domlist;
|
|
+ TALLOC_CTX *tmp_ctx;
|
|
+ struct ldb_result *app_domain = NULL;
|
|
+
|
|
+ tmp_ctx = talloc_new(NULL);
|
|
+ if (tmp_ctx == NULL) {
|
|
+ return ENOMEM;
|
|
+ }
|
|
+
|
|
+ ret = confdb_get_string_as_list(cdb, tmp_ctx,
|
|
+ CONFDB_MONITOR_CONF_ENTRY,
|
|
+ CONFDB_MONITOR_ACTIVE_DOMAINS,
|
|
+ &domlist);
|
|
+ if (ret == ENOENT) {
|
|
+ DEBUG(SSSDBG_FATAL_FAILURE, "No domains configured, fatal error!\n");
|
|
+ goto done;
|
|
+ } else if (ret != EOK ) {
|
|
+ DEBUG(SSSDBG_FATAL_FAILURE, "Fatal error retrieving domains list!\n");
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ for (int i = 0; domlist[i]; i++) {
|
|
+ ret = confdb_get_domain_section(tmp_ctx, cdb,
|
|
+ CONFDB_APP_DOMAIN_BASEDN, domlist[i],
|
|
+ &app_domain);
|
|
+ if (ret == ENOENT) {
|
|
+ DEBUG(SSSDBG_TRACE_INTERNAL,
|
|
+ "%s is not an app domain\n", domlist[i]);
|
|
+ continue;
|
|
+ } else if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_FATAL_FAILURE,
|
|
+ "Error %d: %s while retrieving %s\n",
|
|
+ ret, sss_strerror(ret), domlist[i]);
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ ret = confdb_add_app_domain(tmp_ctx, cdb, domlist[i]);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
+ "Cannot add the app domain section [%d]: %s\n",
|
|
+ ret, sss_strerror(ret));
|
|
+ goto done;
|
|
+ }
|
|
+
|
|
+ ret = confdb_merge_parent_domain(domlist[i], cdb, app_domain);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
+ "Cannot add options into the app domain section [%d]: %s\n",
|
|
+ ret, sss_strerror(ret));
|
|
+ goto done;
|
|
+ }
|
|
+ }
|
|
+
|
|
+ ret = EOK;
|
|
+done:
|
|
+ talloc_free(tmp_ctx);
|
|
+ return ret;
|
|
+}
|
|
diff --git a/src/confdb/confdb.h b/src/confdb/confdb.h
|
|
index a4046610f3cdbdb832de8924bf4397fb0018f2db..5a8d377c312f641f544b1c7cf38826192462ea3c 100644
|
|
--- a/src/confdb/confdb.h
|
|
+++ b/src/confdb/confdb.h
|
|
@@ -164,6 +164,7 @@
|
|
/* Domains */
|
|
#define CONFDB_DOMAIN_PATH_TMPL "config/domain/%s"
|
|
#define CONFDB_DOMAIN_BASEDN "cn=domain,cn=config"
|
|
+#define CONFDB_APP_DOMAIN_BASEDN "cn=application,cn=config"
|
|
#define CONFDB_DOMAIN_ID_PROVIDER "id_provider"
|
|
#define CONFDB_DOMAIN_AUTH_PROVIDER "auth_provider"
|
|
#define CONFDB_DOMAIN_ACCESS_PROVIDER "access_provider"
|
|
@@ -212,6 +213,7 @@
|
|
#define CONFDB_DOMAIN_TYPE "domain_type"
|
|
#define CONFDB_DOMAIN_TYPE_POSIX "posix"
|
|
#define CONFDB_DOMAIN_TYPE_APP "application"
|
|
+#define CONFDB_DOMAIN_INHERIT_FROM "inherit_from"
|
|
|
|
/* Local Provider */
|
|
#define CONFDB_LOCAL_DEFAULT_SHELL "default_shell"
|
|
@@ -398,6 +400,8 @@ int confdb_get_domains(struct confdb_ctx *cdb,
|
|
int confdb_ensure_files_domain(struct confdb_ctx *cdb,
|
|
const char *implicit_files_dom_name);
|
|
|
|
+int confdb_expand_app_domains(struct confdb_ctx *cdb);
|
|
+
|
|
/**
|
|
* Get a null-terminated linked-list of all domain names
|
|
* @param[in] mem_ctx The parent memory context for the value list
|
|
diff --git a/src/config/cfg_rules.ini b/src/config/cfg_rules.ini
|
|
index 3c857236eaa55b313d176bc4bb479918163b60d5..8fd2d2c5236246394353a88c50d1510bd6233f77 100644
|
|
--- a/src/config/cfg_rules.ini
|
|
+++ b/src/config/cfg_rules.ini
|
|
@@ -12,6 +12,7 @@ section = secrets
|
|
section = kcm
|
|
section_re = ^secrets/users/[0-9]\+$
|
|
section_re = ^domain/.*$
|
|
+section_re = ^application/.*$
|
|
|
|
[rule/allowed_sssd_options]
|
|
validator = ini_allowed_options
|
|
@@ -286,7 +287,7 @@ option = responder_idle_timeout
|
|
|
|
[rule/allowed_domain_options]
|
|
validator = ini_allowed_options
|
|
-section_re = ^domain/.*$
|
|
+section_re = ^(domain|application)/.*$
|
|
|
|
option = debug
|
|
option = debug_level
|
|
@@ -684,3 +685,9 @@ option = ldap_user_ssh_public_key
|
|
option = ldap_user_uid_number
|
|
option = ldap_user_uuid
|
|
option = ldap_use_tokengroups
|
|
+
|
|
+[rule/allowed_application_options]
|
|
+validator = ini_allowed_options
|
|
+section_re = ^application/.*$
|
|
+
|
|
+option = inherit_from
|
|
diff --git a/src/man/sssd.conf.5.xml b/src/man/sssd.conf.5.xml
|
|
index 9abcff84a95ea1b27e36845e830cc125fdc89f90..8294793c765bfa6bf481693c7d7f206950454681 100644
|
|
--- a/src/man/sssd.conf.5.xml
|
|
+++ b/src/man/sssd.conf.5.xml
|
|
@@ -1539,6 +1539,10 @@ pam_account_locked_message = Account locked, please contact help desk.
|
|
<quote>id_provider=ldap</quote> only.
|
|
</para>
|
|
<para>
|
|
+ For an easy way to configure a non-POSIX domains, please
|
|
+ see the <quote>Application domains</quote> section.
|
|
+ </para>
|
|
+ <para>
|
|
Default: posix
|
|
</para>
|
|
</listitem>
|
|
@@ -2692,6 +2696,79 @@ subdomain_inherit = ldap_purge_cache_timeout
|
|
</variablelist>
|
|
</para>
|
|
|
|
+ <refsect2 id='app_domains'>
|
|
+ <title>Application domains</title>
|
|
+ <para>
|
|
+ SSSD, with its D-Bus interface (see
|
|
+ <citerefentry>
|
|
+ <refentrytitle>sssd-ifp</refentrytitle>
|
|
+ <manvolnum>5</manvolnum>
|
|
+ </citerefentry>) is appealing to applications
|
|
+ as a gateway to an LDAP directory where users and groups
|
|
+ are stored. However, contrary to the traditional SSSD
|
|
+ deployment where all users and groups either have POSIX
|
|
+ attributes or those attributes can be inferred from the
|
|
+ Windows SIDs, in many cases the users and groups in the
|
|
+ application support scenario have no POSIX attributes.
|
|
+ Instead of setting a
|
|
+ <quote>[domain/<replaceable>NAME</replaceable>]</quote>
|
|
+ section, the administrator can set up an
|
|
+ <quote>[application/<replaceable>NAME</replaceable>]</quote>
|
|
+ section that internally represents a domain with type
|
|
+ <quote>application</quote> optionally inherits settings
|
|
+ from a tradition SSSD domain.
|
|
+ </para>
|
|
+ <para>
|
|
+ Please note that the application domain must still be
|
|
+ explicitly enabled in the <quote>domains</quote> parameter
|
|
+ so that the lookup order between the application domain
|
|
+ and its POSIX sibling domain is set correctly.
|
|
+ </para>
|
|
+ <variablelist>
|
|
+ <title>Application domain parameters</title>
|
|
+ <varlistentry>
|
|
+ <term>inherit_from (string)</term>
|
|
+ <listitem>
|
|
+ <para>
|
|
+ The SSSD POSIX-type domain the application
|
|
+ domain inherits all settings from. The
|
|
+ application domain can moreover add its own
|
|
+ settings to the application settings that augment
|
|
+ or override the <quote>sibling</quote>
|
|
+ domain settings.
|
|
+ </para>
|
|
+ <para>
|
|
+ Default: Not set
|
|
+ </para>
|
|
+ </listitem>
|
|
+ </varlistentry>
|
|
+ </variablelist>
|
|
+ <para>
|
|
+ The following example illustrates the use of an application
|
|
+ domain. In this setup, the POSIX domain is connected to an LDAP
|
|
+ server and is used by the OS through the NSS responder. In addition,
|
|
+ the application domains also requests the telephoneNumber attribute,
|
|
+ stores it as the phone attribute in the cache and makes the phone
|
|
+ attribute reachable through the D-Bus interface.
|
|
+ </para>
|
|
+<programlisting>
|
|
+[sssd]
|
|
+domains = appdom, posixdom
|
|
+
|
|
+[ifp]
|
|
+user_attributes = +phone
|
|
+
|
|
+[domain/posixdom]
|
|
+id_provider = ldap
|
|
+ldap_uri = ldap://ldap.example.com
|
|
+ldap_search_base = dc=example,dc=com
|
|
+
|
|
+[application/appdom]
|
|
+inherit_from = posixdom
|
|
+ldap_user_extra_attrs = phone:telephoneNumber
|
|
+</programlisting>
|
|
+ </refsect2>
|
|
+
|
|
<refsect2 id='local_domain'>
|
|
<title>The local domain section</title>
|
|
<para>
|
|
diff --git a/src/monitor/monitor.c b/src/monitor/monitor.c
|
|
index 7e7b5a07d11aecf1c0b11592213b90d385fd5076..2753b46667f7ae0b022776862c67a327d3356d6d 100644
|
|
--- a/src/monitor/monitor.c
|
|
+++ b/src/monitor/monitor.c
|
|
@@ -1064,6 +1064,14 @@ static int get_monitor_config(struct mt_ctx *ctx)
|
|
/* Not fatal */
|
|
}
|
|
|
|
+ ret = confdb_expand_app_domains(ctx->cdb);
|
|
+ if (ret != EOK) {
|
|
+ DEBUG(SSSDBG_FATAL_FAILURE, "Failed to expand application domains\n");
|
|
+ /* This must not be fatal so that SSSD keeps running and lets
|
|
+ * admin correct the error.
|
|
+ */
|
|
+ }
|
|
+
|
|
ret = confdb_get_domains(ctx->cdb, &ctx->domains);
|
|
if (ret != EOK) {
|
|
DEBUG(SSSDBG_FATAL_FAILURE, "No domains configured.\n");
|
|
--
|
|
2.12.2
|
|
|