From 0a5e61c042679679646f6f8f673028f8fbcf3ea7 Mon Sep 17 00:00:00 2001
From: Alexander Bokovoy <abokovoy@redhat.com>
Date: Wed, 15 Jun 2016 12:15:46 +0300
Subject: [PATCH 03/17] slapi-nis: resolve IPA groups with fully qualified
suffix
With SSSD 1.14+ there is a logic change to handling of a default domain
suffix.
SSSD has two different formats to handle: the input and output. The
input format is parsed into (name,domain) tuples with the re_expression
option and the output is formatted with the full_name_format option.
Because of the way SSSD used to store the usernames in sysdb, it was
tied to the full_name_format option, just changing the output format
changed the way the names are stored internally. SSSD changed the cache
to always store names in a unified format (foo@bar) and use the
full_name_format only for output, as it should be.
This changed a logic of use_fully_qualified_names=True. It now mandates
that the /input/ contains both the name and the domain part and then
SSSD formats the output using the full_name_format option. The
default_domain_suffix is a hack that just appends its value to an
unqualified input, making all queries for "foo" into "foo@bar".
In new SSSD if configuration contains:
default_domain_suffix = win.domain
full_name_format = $1 # only name
then a request for "foo" will internally turn into "foo@win.domain" but
return "foo" on the output. However, queries for IPA's foo will have to
be qualified by the admin manually like "foo@ipa.domain" otherwise sssd
doesn't know which foo you meant.
Support this logic by querying associatedDomain attribute of the
restricted bases of the data set. IPA stores this information in the
$SUFFIX base dn (dc=example,dc=com) and configures slapi-nis with
restricted base set to $SUFFIX (and the plugin config). While
associatedDomain attribute is multivalued, the $SUFFIX object always has
a single value corresponding to the IPA domain name that is the same as
SSSD domain suffix.
---
src/back-sch.c | 41 +++++++++++++++++++++++++++++++++++++++++
src/back-sch.h | 1 +
2 files changed, 42 insertions(+)
diff --git a/src/back-sch.c b/src/back-sch.c
index bb2aa74..cdd2b3c 100644
--- a/src/back-sch.c
+++ b/src/back-sch.c
@@ -98,6 +98,7 @@ backend_set_config_free_config_contents(void *data)
slapi_sdn_free(&set_data->container_sdn);
free(set_data->rdn_format);
backend_shr_free_strlist(set_data->attribute_format);
+ slapi_ch_free_string(&set_data->associated_domain);
}
}
void
@@ -149,6 +150,7 @@ backend_copy_set_config(const struct backend_set_data *data)
ret->check_access = data->check_access;
ret->check_nsswitch = data->check_nsswitch;
ret->nsswitch_min_id = data->nsswitch_min_id;
+ ret->associated_domain = data->associated_domain ? slapi_ch_strdup(data->associated_domain) : NULL;
if ((ret->common.group == NULL) ||
(ret->common.set == NULL) ||
@@ -266,6 +268,39 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e,
free(nsswitch_min_id);
}
+ ret.associated_domain = NULL;
+ if (ret.common.restrict_subtrees != NULL) {
+ Slapi_PBlock *pb = NULL;
+ int result = 0;
+ Slapi_Entry **entries = NULL;
+ int i,j;
+ for (i=0; ret.common.restrict_subtrees[i] != NULL; i++) {
+ pb = wrap_pblock_new(NULL);
+ if (pb != NULL) {
+ slapi_search_internal_set_pb_ext(pb, (Slapi_DN*) ret.common.restrict_subtrees[i], LDAP_SCOPE_BASE,
+ "(&(objectclass=domainRelatedObject)(associatedDomain=*))",
+ NULL, 0, NULL, NULL, state->plugin_identity, 0);
+ result = slapi_search_internal_pb(pb);
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &result);
+ if (result == 0) {
+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries);
+ slapi_pblock_set(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, NULL);
+ for (j=0; entries[j] != NULL; j++) {
+ ret.associated_domain = slapi_entry_attr_get_charptr(entries[j], "associatedDomain");
+ slapi_entry_free(entries[i]);
+ if (ret.associated_domain != NULL)
+ break;
+ }
+ slapi_ch_free((void**)entries);
+ }
+ }
+ slapi_pblock_destroy(pb);
+ pb = NULL;
+ if (ret.associated_domain != NULL)
+ break;
+ }
+ }
+
*pret = backend_copy_set_config(&ret);
if (*pret == NULL) {
if (strlen(container) > 0) {
@@ -437,6 +472,7 @@ backend_set_process_external_members(Slapi_PBlock *pb,
struct backend_staged_search staged = {0, };
struct backend_search_cbdata cbdata = {0, };
char *plugin_id = state->plugin_desc->spd_id;
+ char *gname = NULL;
is_attr_exists = slapi_entry_attr_find(e, IPA_ATTR_EXTERNAL_MEMBER, &attr) == 0;
@@ -448,6 +484,11 @@ backend_set_process_external_members(Slapi_PBlock *pb,
* and update entry's memberUid attribute */
staged.name = slapi_entry_attr_get_charptr(e, "cn");
+ if (data->associated_domain != NULL) {
+ gname = slapi_ch_smprintf("%s@%s", staged.name, data->associated_domain);
+ slapi_ch_free_string(&staged.name);
+ staged.name = gname;
+ }
staged.type = SCH_NSSWITCH_GROUP;
staged.search_members = FALSE;
staged.is_id = FALSE;
diff --git a/src/back-sch.h b/src/back-sch.h
index 72ba641..c15d1ed 100644
--- a/src/back-sch.h
+++ b/src/back-sch.h
@@ -38,6 +38,7 @@ struct backend_set_data {
bool_t check_access;
enum sch_search_nsswitch_t check_nsswitch;
unsigned long nsswitch_min_id;
+ char *associated_domain;
};
struct backend_entry_data {
--
2.13.6