|
|
ca1eb8 |
From 7f9567ba8d62536c4aeb68897316781e82116c21 Mon Sep 17 00:00:00 2001
|
|
|
ca1eb8 |
From: Jakub Hrozek <jhrozek@redhat.com>
|
|
|
ca1eb8 |
Date: Wed, 4 Jul 2018 13:14:40 +0200
|
|
|
ca1eb8 |
Subject: [PATCH] AD: Add Global Catalog usability check in subdomain code by
|
|
|
ca1eb8 |
looking at the schema
|
|
|
ca1eb8 |
MIME-Version: 1.0
|
|
|
ca1eb8 |
Content-Type: text/plain; charset=UTF-8
|
|
|
ca1eb8 |
Content-Transfer-Encoding: 8bit
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
Addsa a new tevent request which checks for the presence of uidNumber
|
|
|
ca1eb8 |
and gidNumber under the schema naming context, which is typically
|
|
|
ca1eb8 |
cn=schema,cn=configuration,$BASEDN. For both objects representing each of
|
|
|
ca1eb8 |
the attributes, the isMemberOfPartialAttributeSet attribute is requested. If
|
|
|
ca1eb8 |
this attribute is set to TRUE, then the attribute corresponding to this
|
|
|
ca1eb8 |
schema object had been replicated to the Global Catalog.
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
Because the isMemberOfPartialAttributeSet is not replicated to the GC
|
|
|
ca1eb8 |
itself, we use the LDAP connection for the search.
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
Related:
|
|
|
ca1eb8 |
https://pagure.io/SSSD/sssd/issue/3755
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
Reviewed-by: Pavel Březina <pbrezina@redhat.com>
|
|
|
ca1eb8 |
(cherry picked from commit ba96e7b839b875946f03787a3a57f259230a0fef)
|
|
|
ca1eb8 |
---
|
|
|
ca1eb8 |
src/providers/ad/ad_subdomains.c | 308 +++++++++++++++++++++++++++++--
|
|
|
ca1eb8 |
1 file changed, 288 insertions(+), 20 deletions(-)
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
diff --git a/src/providers/ad/ad_subdomains.c b/src/providers/ad/ad_subdomains.c
|
|
|
ca1eb8 |
index 84886e920b37f8803d85ce0903b74e6c809a8904..549c2c1f76d4bbccdf03c6ab619fba5f9186358f 100644
|
|
|
ca1eb8 |
--- a/src/providers/ad/ad_subdomains.c
|
|
|
ca1eb8 |
+++ b/src/providers/ad/ad_subdomains.c
|
|
|
ca1eb8 |
@@ -54,9 +54,39 @@
|
|
|
ca1eb8 |
#define SLAVE_DOMAIN_FILTER "(&"SLAVE_DOMAIN_FILTER_BASE")"
|
|
|
ca1eb8 |
#define FOREST_ROOT_FILTER_FMT "(&"SLAVE_DOMAIN_FILTER_BASE"(cn=%s))"
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
+/* Attributes of schema objects. See e.g.
|
|
|
ca1eb8 |
+ * https://docs.microsoft.com/en-us/windows/desktop/AD/characteristics-of-attributes
|
|
|
ca1eb8 |
+ * for more details
|
|
|
ca1eb8 |
+ */
|
|
|
ca1eb8 |
+#define AD_SCHEMA_AT_OC "attributeSchema"
|
|
|
ca1eb8 |
+#define AD_AT_SCHEMA_NAME "cn"
|
|
|
ca1eb8 |
+#define AD_AT_SCHEMA_IS_REPL "isMemberOfPartialAttributeSet"
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
/* do not refresh more often than every 5 seconds for now */
|
|
|
ca1eb8 |
#define AD_SUBDOMAIN_REFRESH_LIMIT 5
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
+static void
|
|
|
ca1eb8 |
+ad_disable_gc(struct ad_options *ad_options)
|
|
|
ca1eb8 |
+{
|
|
|
ca1eb8 |
+ errno_t ret;
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ if (dp_opt_get_bool(ad_options->basic, AD_ENABLE_GC) == false) {
|
|
|
ca1eb8 |
+ return;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_IMPORTANT_INFO, "POSIX attributes were requested "
|
|
|
ca1eb8 |
+ "but are not present on the server side. Global Catalog "
|
|
|
ca1eb8 |
+ "lookups will be disabled\n");
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ ret = dp_opt_set_bool(ad_options->basic,
|
|
|
ca1eb8 |
+ AD_ENABLE_GC, false);
|
|
|
ca1eb8 |
+ if (ret != EOK) {
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_MINOR_FAILURE,
|
|
|
ca1eb8 |
+ "Could not turn off GC support\n");
|
|
|
ca1eb8 |
+ /* Not fatal */
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+}
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
static struct sss_domain_info *
|
|
|
ca1eb8 |
ads_get_root_domain(struct be_ctx *be_ctx, struct sysdb_attrs *attrs)
|
|
|
ca1eb8 |
{
|
|
|
ca1eb8 |
@@ -1261,6 +1291,212 @@ static errno_t ad_get_root_domain_recv(TALLOC_CTX *mem_ctx,
|
|
|
ca1eb8 |
return EOK;
|
|
|
ca1eb8 |
}
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
+static void ad_check_gc_usability_search_done(struct tevent_req *subreq);
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+struct ad_check_gc_usability_state {
|
|
|
ca1eb8 |
+ struct sdap_options *sdap_opts;
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ const char *attrs[3];
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ bool is_gc_usable;
|
|
|
ca1eb8 |
+};
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+static struct tevent_req *
|
|
|
ca1eb8 |
+ad_check_gc_usability_send(TALLOC_CTX *mem_ctx,
|
|
|
ca1eb8 |
+ struct tevent_context *ev,
|
|
|
ca1eb8 |
+ struct ad_options *ad_options,
|
|
|
ca1eb8 |
+ struct sdap_options *sdap_opts,
|
|
|
ca1eb8 |
+ struct sdap_id_op *op,
|
|
|
ca1eb8 |
+ const char *domain_name,
|
|
|
ca1eb8 |
+ const char *domain_sid)
|
|
|
ca1eb8 |
+{
|
|
|
ca1eb8 |
+ struct ad_check_gc_usability_state *state = NULL;
|
|
|
ca1eb8 |
+ struct tevent_req *req = NULL;
|
|
|
ca1eb8 |
+ struct tevent_req *subreq = NULL;
|
|
|
ca1eb8 |
+ const char *filter = NULL;
|
|
|
ca1eb8 |
+ errno_t ret;
|
|
|
ca1eb8 |
+ bool uses_id_mapping;
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ req = tevent_req_create(mem_ctx, &state,
|
|
|
ca1eb8 |
+ struct ad_check_gc_usability_state);
|
|
|
ca1eb8 |
+ if (req == NULL) {
|
|
|
ca1eb8 |
+ return NULL;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+ state->sdap_opts = sdap_opts;
|
|
|
ca1eb8 |
+ state->is_gc_usable = false;
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ if (dp_opt_get_bool(ad_options->basic, AD_ENABLE_GC) == false) {
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_TRACE_FUNC, "GC explicitly disabled\n");
|
|
|
ca1eb8 |
+ state->is_gc_usable = false;
|
|
|
ca1eb8 |
+ ret = EOK;
|
|
|
ca1eb8 |
+ goto immediately;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ uses_id_mapping = sdap_idmap_domain_has_algorithmic_mapping(
|
|
|
ca1eb8 |
+ sdap_opts->idmap_ctx,
|
|
|
ca1eb8 |
+ domain_name,
|
|
|
ca1eb8 |
+ domain_sid);
|
|
|
ca1eb8 |
+ if (uses_id_mapping == true) {
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_TRACE_FUNC, "GC always usable while ID mapping\n");
|
|
|
ca1eb8 |
+ state->is_gc_usable = true;
|
|
|
ca1eb8 |
+ ret = EOK;
|
|
|
ca1eb8 |
+ goto immediately;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ /* The schema partition is replicated across all DCs in the forest, so
|
|
|
ca1eb8 |
+ * it's safe to use the baseDN even if e.g. joined to a child domain
|
|
|
ca1eb8 |
+ * even though the base DN "looks" like a part of the forest root
|
|
|
ca1eb8 |
+ * tree. On the other hand, it doesn't make sense to guess the value
|
|
|
ca1eb8 |
+ * if we can't detect it from the rootDSE.
|
|
|
ca1eb8 |
+ */
|
|
|
ca1eb8 |
+ if (state->sdap_opts->schema_basedn == NULL) {
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_TRACE_FUNC,
|
|
|
ca1eb8 |
+ "No idea where to look for the schema, disabling GC\n");
|
|
|
ca1eb8 |
+ state->is_gc_usable = false;
|
|
|
ca1eb8 |
+ ret = EOK;
|
|
|
ca1eb8 |
+ goto immediately;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ state->attrs[0] = AD_AT_SCHEMA_NAME;
|
|
|
ca1eb8 |
+ state->attrs[1] = AD_AT_SCHEMA_IS_REPL;
|
|
|
ca1eb8 |
+ state->attrs[2] = NULL;
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_TRACE_FUNC, "Checking for POSIX attributes in GC\n");
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ filter = talloc_asprintf(
|
|
|
ca1eb8 |
+ state,
|
|
|
ca1eb8 |
+ "(&(objectclass=%s)(|(%s=%s)(%s=%s)))",
|
|
|
ca1eb8 |
+ AD_SCHEMA_AT_OC,
|
|
|
ca1eb8 |
+ AD_AT_SCHEMA_NAME,
|
|
|
ca1eb8 |
+ state->sdap_opts->user_map[SDAP_AT_USER_UID].name,
|
|
|
ca1eb8 |
+ AD_AT_SCHEMA_NAME,
|
|
|
ca1eb8 |
+ state->sdap_opts->group_map[SDAP_AT_GROUP_GID].name);
|
|
|
ca1eb8 |
+ if (filter == NULL) {
|
|
|
ca1eb8 |
+ ret = ENOMEM;
|
|
|
ca1eb8 |
+ goto immediately;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ subreq = sdap_get_generic_send(state,
|
|
|
ca1eb8 |
+ ev,
|
|
|
ca1eb8 |
+ state->sdap_opts,
|
|
|
ca1eb8 |
+ sdap_id_op_handle(op),
|
|
|
ca1eb8 |
+ state->sdap_opts->schema_basedn,
|
|
|
ca1eb8 |
+ LDAP_SCOPE_SUBTREE,
|
|
|
ca1eb8 |
+ filter,
|
|
|
ca1eb8 |
+ state->attrs,
|
|
|
ca1eb8 |
+ NULL, 0,
|
|
|
ca1eb8 |
+ dp_opt_get_int(state->sdap_opts->basic,
|
|
|
ca1eb8 |
+ SDAP_SEARCH_TIMEOUT),
|
|
|
ca1eb8 |
+ false);
|
|
|
ca1eb8 |
+ if (subreq == NULL) {
|
|
|
ca1eb8 |
+ ret = ENOMEM;
|
|
|
ca1eb8 |
+ goto immediately;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+ tevent_req_set_callback(subreq, ad_check_gc_usability_search_done, req);
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ return req;
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+immediately:
|
|
|
ca1eb8 |
+ if (ret == EOK) {
|
|
|
ca1eb8 |
+ tevent_req_done(req);
|
|
|
ca1eb8 |
+ } else {
|
|
|
ca1eb8 |
+ tevent_req_error(req, ret);
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+ tevent_req_post(req, ev);
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ return req;
|
|
|
ca1eb8 |
+}
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+static void ad_check_gc_usability_search_done(struct tevent_req *subreq)
|
|
|
ca1eb8 |
+{
|
|
|
ca1eb8 |
+ struct tevent_req *req = tevent_req_callback_data(subreq,
|
|
|
ca1eb8 |
+ struct tevent_req);
|
|
|
ca1eb8 |
+ struct ad_check_gc_usability_state *state = tevent_req_data(req,
|
|
|
ca1eb8 |
+ struct ad_check_gc_usability_state);
|
|
|
ca1eb8 |
+ errno_t ret;
|
|
|
ca1eb8 |
+ size_t reply_count;
|
|
|
ca1eb8 |
+ struct sysdb_attrs **reply = NULL;
|
|
|
ca1eb8 |
+ bool uid = false;
|
|
|
ca1eb8 |
+ bool gid = false;
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ ret = sdap_get_generic_recv(subreq, state, &reply_count, &reply);
|
|
|
ca1eb8 |
+ talloc_zfree(subreq);
|
|
|
ca1eb8 |
+ if (ret != EOK) {
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_OP_FAILURE,
|
|
|
ca1eb8 |
+ "sdap_get_generic_recv failed [%d]: %s\n",
|
|
|
ca1eb8 |
+ ret, strerror(ret));
|
|
|
ca1eb8 |
+ /* We continue to finish sdap_id_op. */
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ if (reply_count == 0) {
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_TRACE_LIBS,
|
|
|
ca1eb8 |
+ "Nothing found, so no POSIX attrs can exist\n");
|
|
|
ca1eb8 |
+ state->is_gc_usable = false;
|
|
|
ca1eb8 |
+ tevent_req_done(req);
|
|
|
ca1eb8 |
+ return;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ for (size_t i = 0; i < reply_count; i++) {
|
|
|
ca1eb8 |
+ const char *name = NULL;
|
|
|
ca1eb8 |
+ const char *is_in_partial_set = NULL;
|
|
|
ca1eb8 |
+ bool *val = NULL;
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ ret = sysdb_attrs_get_string(reply[i], AD_AT_SCHEMA_NAME, &name);
|
|
|
ca1eb8 |
+ if (ret != EOK) {
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot get "AD_AT_SCHEMA_NAME);
|
|
|
ca1eb8 |
+ continue;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ if (strcasecmp(name, state->sdap_opts->user_map[SDAP_AT_USER_UID].name) == 0) {
|
|
|
ca1eb8 |
+ val = &ui;;
|
|
|
ca1eb8 |
+ } else if (strcasecmp(name, state->sdap_opts->user_map[SDAP_AT_USER_GID].name) == 0) {
|
|
|
ca1eb8 |
+ val = &gid;
|
|
|
ca1eb8 |
+ } else {
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unexpected attribute\n");
|
|
|
ca1eb8 |
+ continue;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ ret = sysdb_attrs_get_string(reply[i],
|
|
|
ca1eb8 |
+ AD_AT_SCHEMA_IS_REPL,
|
|
|
ca1eb8 |
+ &is_in_partial_set);
|
|
|
ca1eb8 |
+ if (ret != EOK) {
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_MINOR_FAILURE, "Cannot get "AD_AT_SCHEMA_IS_REPL);
|
|
|
ca1eb8 |
+ continue;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ if (strcasecmp(is_in_partial_set, "true") == 0) {
|
|
|
ca1eb8 |
+ *val = true;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ if (uid == true && gid == true) {
|
|
|
ca1eb8 |
+ state->is_gc_usable = true;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ if (state->is_gc_usable == true) {
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_FUNC_DATA, "Server has POSIX attributes. Global Catalog will "
|
|
|
ca1eb8 |
+ "be used for user and group lookups. Note that if "
|
|
|
ca1eb8 |
+ "only a subset of POSIX attributes is present "
|
|
|
ca1eb8 |
+ "in GC, the non-replicated attributes are "
|
|
|
ca1eb8 |
+ "currently not read from the LDAP port\n");
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ tevent_req_done(req);
|
|
|
ca1eb8 |
+}
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+static errno_t ad_check_gc_usability_recv(struct tevent_req *req,
|
|
|
ca1eb8 |
+ bool *_is_gc_usable)
|
|
|
ca1eb8 |
+{
|
|
|
ca1eb8 |
+ struct ad_check_gc_usability_state *state = NULL;
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ state = tevent_req_data(req, struct ad_check_gc_usability_state);
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ TEVENT_REQ_RETURN_ON_ERROR(req);
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ *_is_gc_usable = state->is_gc_usable;
|
|
|
ca1eb8 |
+ return EOK;
|
|
|
ca1eb8 |
+}
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
struct ad_subdomains_refresh_state {
|
|
|
ca1eb8 |
struct tevent_context *ev;
|
|
|
ca1eb8 |
struct be_ctx *be_ctx;
|
|
|
ca1eb8 |
@@ -1268,11 +1504,14 @@ struct ad_subdomains_refresh_state {
|
|
|
ca1eb8 |
struct sdap_id_op *sdap_op;
|
|
|
ca1eb8 |
struct sdap_id_ctx *id_ctx;
|
|
|
ca1eb8 |
struct ad_options *ad_options;
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ char *forest;
|
|
|
ca1eb8 |
};
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
static errno_t ad_subdomains_refresh_retry(struct tevent_req *req);
|
|
|
ca1eb8 |
static void ad_subdomains_refresh_connect_done(struct tevent_req *subreq);
|
|
|
ca1eb8 |
static void ad_subdomains_refresh_master_done(struct tevent_req *subreq);
|
|
|
ca1eb8 |
+static void ad_subdomains_refresh_gc_check_done(struct tevent_req *subreq);
|
|
|
ca1eb8 |
static void ad_subdomains_refresh_root_done(struct tevent_req *subreq);
|
|
|
ca1eb8 |
static void ad_subdomains_refresh_done(struct tevent_req *subreq);
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
@@ -1385,37 +1624,73 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq)
|
|
|
ca1eb8 |
struct ad_subdomains_refresh_state *state;
|
|
|
ca1eb8 |
struct tevent_req *req;
|
|
|
ca1eb8 |
const char *realm;
|
|
|
ca1eb8 |
- const char *ad_domain;
|
|
|
ca1eb8 |
char *master_sid;
|
|
|
ca1eb8 |
char *flat_name;
|
|
|
ca1eb8 |
- char *forest;
|
|
|
ca1eb8 |
errno_t ret;
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
req = tevent_req_callback_data(subreq, struct tevent_req);
|
|
|
ca1eb8 |
state = tevent_req_data(req, struct ad_subdomains_refresh_state);
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
ret = ad_master_domain_recv(subreq, state, &flat_name, &master_sid,
|
|
|
ca1eb8 |
- NULL, &forest);
|
|
|
ca1eb8 |
+ NULL, &state->forest);
|
|
|
ca1eb8 |
talloc_zfree(subreq);
|
|
|
ca1eb8 |
if (ret != EOK) {
|
|
|
ca1eb8 |
DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get master domain information "
|
|
|
ca1eb8 |
"[%d]: %s\n", ret, sss_strerror(ret));
|
|
|
ca1eb8 |
- goto done;
|
|
|
ca1eb8 |
+ tevent_req_error(req, ret);
|
|
|
ca1eb8 |
+ return;
|
|
|
ca1eb8 |
}
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
realm = dp_opt_get_cstring(state->ad_options->basic, AD_KRB5_REALM);
|
|
|
ca1eb8 |
if (realm == NULL) {
|
|
|
ca1eb8 |
DEBUG(SSSDBG_CONF_SETTINGS, "Missing realm.\n");
|
|
|
ca1eb8 |
- ret = EINVAL;
|
|
|
ca1eb8 |
- goto done;
|
|
|
ca1eb8 |
+ tevent_req_error(req, EINVAL);
|
|
|
ca1eb8 |
+ return;
|
|
|
ca1eb8 |
}
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
ret = sysdb_master_domain_add_info(state->be_ctx->domain, realm,
|
|
|
ca1eb8 |
- flat_name, master_sid, forest, NULL);
|
|
|
ca1eb8 |
+ flat_name, master_sid, state->forest, NULL);
|
|
|
ca1eb8 |
if (ret != EOK) {
|
|
|
ca1eb8 |
DEBUG(SSSDBG_OP_FAILURE, "Cannot save master domain info [%d]: %s\n",
|
|
|
ca1eb8 |
ret, sss_strerror(ret));
|
|
|
ca1eb8 |
- goto done;
|
|
|
ca1eb8 |
+ tevent_req_error(req, ret);
|
|
|
ca1eb8 |
+ return;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ subreq = ad_check_gc_usability_send(state,
|
|
|
ca1eb8 |
+ state->ev,
|
|
|
ca1eb8 |
+ state->ad_options,
|
|
|
ca1eb8 |
+ state->id_ctx->opts,
|
|
|
ca1eb8 |
+ state->sdap_op,
|
|
|
ca1eb8 |
+ state->be_ctx->domain->name,
|
|
|
ca1eb8 |
+ master_sid);
|
|
|
ca1eb8 |
+ if (subreq == NULL) {
|
|
|
ca1eb8 |
+ tevent_req_error(req, ENOMEM);
|
|
|
ca1eb8 |
+ return;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+ tevent_req_set_callback(subreq, ad_subdomains_refresh_gc_check_done, req);
|
|
|
ca1eb8 |
+}
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+static void ad_subdomains_refresh_gc_check_done(struct tevent_req *subreq)
|
|
|
ca1eb8 |
+{
|
|
|
ca1eb8 |
+ struct ad_subdomains_refresh_state *state;
|
|
|
ca1eb8 |
+ struct tevent_req *req;
|
|
|
ca1eb8 |
+ const char *ad_domain;
|
|
|
ca1eb8 |
+ bool is_gc_usable;
|
|
|
ca1eb8 |
+ errno_t ret;
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ req = tevent_req_callback_data(subreq, struct tevent_req);
|
|
|
ca1eb8 |
+ state = tevent_req_data(req, struct ad_subdomains_refresh_state);
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ ret = ad_check_gc_usability_recv(subreq, &is_gc_usable);
|
|
|
ca1eb8 |
+ talloc_zfree(subreq);
|
|
|
ca1eb8 |
+ if (ret != EOK) {
|
|
|
ca1eb8 |
+ DEBUG(SSSDBG_MINOR_FAILURE, "Unable to get GC usability status\n");
|
|
|
ca1eb8 |
+ is_gc_usable = false;
|
|
|
ca1eb8 |
+ }
|
|
|
ca1eb8 |
+
|
|
|
ca1eb8 |
+ if (is_gc_usable == false) {
|
|
|
ca1eb8 |
+ ad_disable_gc(state->ad_options);
|
|
|
ca1eb8 |
}
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
/*
|
|
|
ca1eb8 |
@@ -1428,7 +1703,8 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq)
|
|
|
ca1eb8 |
state->be_ctx->domain->name) == 0) {
|
|
|
ca1eb8 |
DEBUG(SSSDBG_TRACE_FUNC,
|
|
|
ca1eb8 |
"No other enabled domain than master.\n");
|
|
|
ca1eb8 |
- goto done;
|
|
|
ca1eb8 |
+ tevent_req_done(req);
|
|
|
ca1eb8 |
+ return;
|
|
|
ca1eb8 |
}
|
|
|
ca1eb8 |
}
|
|
|
ca1eb8 |
}
|
|
|
ca1eb8 |
@@ -1440,24 +1716,16 @@ static void ad_subdomains_refresh_master_done(struct tevent_req *subreq)
|
|
|
ca1eb8 |
ad_domain = state->sd_ctx->be_ctx->domain->name;
|
|
|
ca1eb8 |
}
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
- subreq = ad_get_root_domain_send(state, state->ev, ad_domain, forest,
|
|
|
ca1eb8 |
+ subreq = ad_get_root_domain_send(state, state->ev, ad_domain, state->forest,
|
|
|
ca1eb8 |
sdap_id_op_handle(state->sdap_op),
|
|
|
ca1eb8 |
state->sd_ctx);
|
|
|
ca1eb8 |
if (subreq == NULL) {
|
|
|
ca1eb8 |
- ret = ENOMEM;
|
|
|
ca1eb8 |
- goto done;
|
|
|
ca1eb8 |
+ tevent_req_error(req, ENOMEM);
|
|
|
ca1eb8 |
+ return;
|
|
|
ca1eb8 |
}
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
tevent_req_set_callback(subreq, ad_subdomains_refresh_root_done, req);
|
|
|
ca1eb8 |
return;
|
|
|
ca1eb8 |
-
|
|
|
ca1eb8 |
-done:
|
|
|
ca1eb8 |
- if (ret != EOK) {
|
|
|
ca1eb8 |
- tevent_req_error(req, ret);
|
|
|
ca1eb8 |
- return;
|
|
|
ca1eb8 |
- }
|
|
|
ca1eb8 |
-
|
|
|
ca1eb8 |
- tevent_req_done(req);
|
|
|
ca1eb8 |
}
|
|
|
ca1eb8 |
|
|
|
ca1eb8 |
static void ad_subdomains_refresh_root_done(struct tevent_req *subreq)
|
|
|
ca1eb8 |
--
|
|
|
ca1eb8 |
2.17.1
|
|
|
ca1eb8 |
|