diff --git a/.gitignore b/.gitignore index 663f6f5..45aeca8 100644 --- a/.gitignore +++ b/.gitignore @@ -1 +1 @@ -SOURCES/slapi-nis-0.54.tar.gz +SOURCES/slapi-nis-0.56.0.tar.gz diff --git a/.slapi-nis.metadata b/.slapi-nis.metadata index 40cb360..6769a0c 100644 --- a/.slapi-nis.metadata +++ b/.slapi-nis.metadata @@ -1 +1 @@ -038ed249da1dc20d52d6159099835a230e7f9525 SOURCES/slapi-nis-0.54.tar.gz +097cb06b3adfd66664ec785186c47ff3b0c52c16 SOURCES/slapi-nis-0.56.0.tar.gz diff --git a/SOURCES/slapi-0001-Move-advance-definition-of-backend_passwdmod_extop-b.patch b/SOURCES/slapi-0001-Move-advance-definition-of-backend_passwdmod_extop-b.patch new file mode 100644 index 0000000..729ed8f --- /dev/null +++ b/SOURCES/slapi-0001-Move-advance-definition-of-backend_passwdmod_extop-b.patch @@ -0,0 +1,25 @@ +From 55efe7e2be2ed7664e2d5bb5b2b0d9d11d5e3f70 Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Mon, 20 Jun 2016 21:41:12 +0300 +Subject: [PATCH 1/4] Move advance definition of backend_passwdmod_extop before + use + +--- + src/back-sch.c | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/back-sch.c b/src/back-sch.c +index 5ba04f4..ff8e8a2 100644 +--- a/src/back-sch.c ++++ b/src/back-sch.c +@@ -54,6 +54,7 @@ + #include "map.h" + #include "back-sch.h" + ++static int backend_passwdmod_extop(Slapi_PBlock *pb); + backend_extop_handlers_t extop_handlers[] = {{EXTOP_PASSWD_OID, (IFP) backend_passwdmod_extop}, + {NULL, NULL}}; + static void +-- +2.7.4 + diff --git a/SOURCES/slapi-0002-Initialize-ret-before-use.patch b/SOURCES/slapi-0002-Initialize-ret-before-use.patch new file mode 100644 index 0000000..948a14f --- /dev/null +++ b/SOURCES/slapi-0002-Initialize-ret-before-use.patch @@ -0,0 +1,25 @@ +From a65243050c2c765b8c9edfdab9164c82c754c39b Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Mon, 20 Jun 2016 21:41:35 +0300 +Subject: [PATCH 2/4] Initialize ret before use + +--- + src/back-sch.c | 2 +- + 1 file changed, 1 insertion(+), 1 deletion(-) + +diff --git a/src/back-sch.c b/src/back-sch.c +index ff8e8a2..bb2aa74 100644 +--- a/src/back-sch.c ++++ b/src/back-sch.c +@@ -2376,7 +2376,7 @@ static int + backend_extop_cb(Slapi_PBlock *pb) + { + struct plugin_state *state; +- int ret; ++ int ret = 0; + int i; + char *oid = NULL; + IFP fct = NULL; +-- +2.7.4 + diff --git a/SOURCES/slapi-0004-Declare-int-backend_init_extop-for-reuse-in-plug-sch.patch b/SOURCES/slapi-0004-Declare-int-backend_init_extop-for-reuse-in-plug-sch.patch new file mode 100644 index 0000000..83f9592 --- /dev/null +++ b/SOURCES/slapi-0004-Declare-int-backend_init_extop-for-reuse-in-plug-sch.patch @@ -0,0 +1,24 @@ +From 84c0767f794ca339275f9ec2d4936903d0ac3a42 Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Mon, 20 Jun 2016 21:45:37 +0300 +Subject: [PATCH 4/4] Declare int backend_init_extop for reuse in plug-sch.c + +--- + src/back-sch.h | 1 + + 1 file changed, 1 insertion(+) + +diff --git a/src/back-sch.h b/src/back-sch.h +index c15d1ed..1258ae0 100644 +--- a/src/back-sch.h ++++ b/src/back-sch.h +@@ -164,6 +164,7 @@ bool_t backend_retrieve_from_nsswitch(struct backend_staged_search *staged, + struct backend_search_cbdata *cbdata); + + int backend_sch_do_pam_auth(Slapi_PBlock *pb, const char *username); ++int backend_init_extop(Slapi_PBlock *pb, struct plugin_state *state); + + #ifdef USE_IPA_IDVIEWS + void idview_get_overrides(struct backend_search_cbdata *cbdata); +-- +2.7.4 + diff --git a/SOURCES/slapi-0006-back-sch-do-not-clobber-target-of-the-pblock-for-idv.patch b/SOURCES/slapi-0006-back-sch-do-not-clobber-target-of-the-pblock-for-idv.patch new file mode 100644 index 0000000..4007ce1 --- /dev/null +++ b/SOURCES/slapi-0006-back-sch-do-not-clobber-target-of-the-pblock-for-idv.patch @@ -0,0 +1,198 @@ +From b59b9c87042cb8f4d99421e101349c5f48f91235 Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Tue, 26 Jul 2016 18:11:53 +0300 +Subject: [PATCH 6/8] back-sch: do not clobber target of the pblock for idview + +When extracting idview all we care is the DN of new target. +We don't really use the rewritten target as a string anymore, +so there is no need to rewrite the string in the pblock. + +This fixes a bug when running with 389-ds 1.3.5.10+ which is more +strict about modification of the values in pblock. + +Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1360245 +--- + src/back-sch.c | 43 ++++++++++++++++++++++--------------------- + src/back-sch.h | 2 +- + 2 files changed, 23 insertions(+), 22 deletions(-) + +diff --git a/src/back-sch.c b/src/back-sch.c +index 0745329..e15988f 100644 +--- a/src/back-sch.c ++++ b/src/back-sch.c +@@ -1652,6 +1652,8 @@ backend_search_cb(Slapi_PBlock *pb) + struct backend_search_cbdata cbdata; + struct backend_staged_search *staged, *next; + int i, isroot, ret; ++ char *original_target = NULL; ++ char *target = NULL; + + if (wrap_get_call_level() > 0) { + return 0; +@@ -1676,7 +1678,7 @@ backend_search_cb(Slapi_PBlock *pb) + return 0; + } + +- slapi_pblock_get(pb, SLAPI_SEARCH_TARGET, &cbdata.target); ++ slapi_pblock_get(pb, SLAPI_SEARCH_TARGET, &original_target); + slapi_pblock_get(pb, SLAPI_SEARCH_SCOPE, &cbdata.scope); + slapi_pblock_get(pb, SLAPI_SEARCH_SIZELIMIT, &cbdata.sizelimit); + slapi_pblock_get(pb, SLAPI_SEARCH_TIMELIMIT, &cbdata.timelimit); +@@ -1697,15 +1699,15 @@ backend_search_cb(Slapi_PBlock *pb) + /* Okay, we can search. */ + slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, + "searching from \"%s\" for \"%s\" with scope %d%s\n", +- cbdata.target, cbdata.strfilter, cbdata.scope, ++ original_target, cbdata.strfilter, cbdata.scope, + backend_sch_scope_as_string(cbdata.scope)); +- cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target); ++ cbdata.target_dn = slapi_sdn_new_dn_byval(original_target); + /* Check if there's a backend handling this search. */ + if (!slapi_be_exist(cbdata.target_dn)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, + "slapi_be_exists(\"%s\") = 0, " +- "ignoring search\n", cbdata.target); ++ "ignoring search\n", original_target); + slapi_sdn_free(&cbdata.target_dn); + return 0; + } +@@ -1716,22 +1718,23 @@ backend_search_cb(Slapi_PBlock *pb) + * detect the ID view use. Unless the ID view is within the set we control, don't consider the override */ + map_data_foreach_domain(cbdata.state, backend_search_find_set_dn_cb, &cbdata); + if (cbdata.answer == FALSE) { +- idview_replace_target_dn(&cbdata.target, &cbdata.idview); ++ target = slapi_ch_strdup(original_target); ++ idview_replace_target_dn(&target, &cbdata.idview); + if (cbdata.idview != NULL) { + slapi_sdn_free(&cbdata.target_dn); + /* Perform another check, now for rewritten DN */ +- cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target); ++ cbdata.target_dn = slapi_sdn_new_dn_byval(target); + map_data_foreach_domain(cbdata.state, backend_search_find_set_dn_cb, &cbdata); + /* Rewritten DN might still be outside of our trees */ + if (cbdata.answer == TRUE) { + slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, + "Use of ID view '%s' is detected, searching from \"%s\" " + "for \"%s\" with scope %d%s. Filter may get overridden later.\n", +- cbdata.idview, cbdata.target, cbdata.strfilter, cbdata.scope, ++ cbdata.idview, target, cbdata.strfilter, cbdata.scope, + backend_sch_scope_as_string(cbdata.scope)); + } else { + slapi_sdn_free(&cbdata.target_dn); +- slapi_ch_free_string(&cbdata.target); ++ slapi_ch_free_string(&target); + slapi_ch_free_string(&cbdata.idview); + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata.state->plugin_desc->spd_id, +@@ -1739,6 +1742,8 @@ backend_search_cb(Slapi_PBlock *pb) + "ignoring search\n"); + return 0; + } ++ } else { ++ slapi_ch_free_string(&target); + } + } + cbdata.answer = FALSE; +@@ -1890,7 +1895,7 @@ backend_search_cb(Slapi_PBlock *pb) + } + slapi_sdn_free(&cbdata.target_dn); + if (cbdata.idview != NULL) { +- slapi_ch_free_string(&cbdata.target); ++ slapi_ch_free_string(&target); + } + slapi_ch_free_string(&cbdata.idview); + #ifdef USE_IPA_IDVIEWS +@@ -1904,7 +1909,6 @@ backend_search_cb(Slapi_PBlock *pb) + /* Locate the entry for a given DN. */ + struct backend_locate_cbdata { + struct plugin_state *state; +- char *target; + Slapi_DN *target_dn; + + struct backend_entry_data *entry_data; +@@ -1953,6 +1957,7 @@ static void + backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char **group, const char**set) + { + struct backend_locate_cbdata cbdata; ++ char *original_target = NULL; + + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); + if (cbdata.state->plugin_base == NULL) { +@@ -1960,9 +1965,9 @@ backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char ** + *data = NULL; + return; + } +- slapi_pblock_get(pb, SLAPI_TARGET_DN, &cbdata.target); ++ slapi_pblock_get(pb, SLAPI_TARGET_DN, &original_target); + +- cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target); ++ cbdata.target_dn = slapi_sdn_new_dn_byval(original_target); + cbdata.entry_data = NULL; + cbdata.entry_group = NULL; + cbdata.entry_set = NULL; +@@ -1972,12 +1977,9 @@ backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char ** + * rebuild the target's RDN to use original attribute's value */ + if (cbdata.entry_data == NULL) { + char *idview = NULL; +- char *target, *original_target; +- target = original_target = slapi_ch_strdup(cbdata.target); ++ char *target = NULL; ++ target = slapi_ch_strdup(original_target); + idview_replace_target_dn(&target, &idview); +- if (target != original_target) { +- slapi_ch_free_string(&original_target); +- } + if (idview != NULL) { + char *rdnstr; + char *val; +@@ -1992,7 +1994,6 @@ backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char ** + bval.bv_val = slapi_ch_strdup(val); + memset(&scbdata, 0, sizeof(scbdata)); + scbdata.idview = idview; +- scbdata.target = target; + scbdata.pb = pb; + scbdata.state = cbdata.state; + scbdata.target_dn = slapi_sdn_new_dn_byval(target); +@@ -2025,7 +2026,6 @@ backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char ** + * insufficient-access error. */ + struct backend_group_check_scope_cbdata { + struct plugin_state *state; +- const char *target; + Slapi_DN *target_dn; + bool_t ours; + }; +@@ -2050,14 +2050,15 @@ static bool_t + backend_check_scope_pb(Slapi_PBlock *pb) + { + struct backend_group_check_scope_cbdata cbdata; ++ char *original_target = NULL; + + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); + if (cbdata.state->plugin_base == NULL) { + /* The plugin was not actually started. */ + return FALSE; + } +- slapi_pblock_get(pb, SLAPI_TARGET_DN, &cbdata.target); +- cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target); ++ slapi_pblock_get(pb, SLAPI_TARGET_DN, &original_target); ++ cbdata.target_dn = slapi_sdn_new_dn_byval(original_target); + cbdata.ours = FALSE; + map_data_foreach_domain(cbdata.state, backend_group_check_scope_cb, + &cbdata); +diff --git a/src/back-sch.h b/src/back-sch.h +index 1258ae0..9a9abc7 100644 +--- a/src/back-sch.h ++++ b/src/back-sch.h +@@ -88,7 +88,7 @@ struct entries_to_send { + struct backend_search_cbdata { + Slapi_PBlock *pb; + struct plugin_state *state; +- char *target, *strfilter, **attrs; ++ char *strfilter, **attrs; + char *idview; + Slapi_Entry **overrides; + int scope, sizelimit, timelimit, attrsonly; +-- +2.7.4 + diff --git a/SOURCES/slapi-0007-back-sch-nss-for-users-with-aliases-return-alias-as-.patch b/SOURCES/slapi-0007-back-sch-nss-for-users-with-aliases-return-alias-as-.patch new file mode 100644 index 0000000..77d404d --- /dev/null +++ b/SOURCES/slapi-0007-back-sch-nss-for-users-with-aliases-return-alias-as-.patch @@ -0,0 +1,66 @@ +From e6f9e2c9282905fa41046379e0bc5c2ac82ae3a9 Mon Sep 17 00:00:00 2001 +From: Alexander Bokovoy +Date: Wed, 27 Jul 2016 17:37:14 +0300 +Subject: [PATCH 7/8] back-sch-nss: for users with aliases, return alias as uid + +When SSSD resolves AD users on behalf of slapi-nis, it can accept +any user identifier, including user principal name (UPN) which +may be different than the canonical user name which SSSD returns. + +As result, the entry created by slapi-nis will be using canonical user +name but the filter for search will refer to the original (aliased) +name. The search will not match the newly created entry. + +Fix this issue by returning two values for 'uid' attribute: the +canonical one and the aliased one. This way search will match. + +Verified that SSSD with id_provider=ldap happily consumes such entries. +By LDAP schema, 'uid' attribute can have multiple values. + +Fixes https://fedorahosted.org/slapi-nis/ticket/12 +--- + src/back-sch-nss.c | 14 ++++++++++++++ + 1 file changed, 14 insertions(+) + +diff --git a/src/back-sch-nss.c b/src/back-sch-nss.c +index 702590c..db63e59 100644 +--- a/src/back-sch-nss.c ++++ b/src/back-sch-nss.c +@@ -230,6 +230,7 @@ backend_build_dn(const char *attribute, const char *value, + static Slapi_Entry * + backend_make_user_entry_from_nsswitch_passwd(struct passwd *pwd, + char *container_sdn, ++ char *user_name, + struct backend_search_cbdata *cbdata) + { + Slapi_Entry *entry; +@@ -272,6 +273,18 @@ backend_make_user_entry_from_nsswitch_passwd(struct passwd *pwd, + "objectClass", "posixAccount"); + slapi_entry_add_string(entry, + "uid", name); ++ if (user_name != NULL) { ++ /* For non-NULL original user name check if it was ++ * an alias/UPN. If so, add it to the entry. ++ * Yes, LDAP schema allows multiple values of 'uid' ++ * attribute. ++ */ ++ if (slapi_utf8casecmp((unsigned char*) user_name, ++ (unsigned char*) name) != 0) { ++ slapi_entry_add_string(entry, "uid", user_name); ++ } ++ } ++ + slapi_entry_attr_set_uint(entry, + "uidNumber", pwd->pw_uid); + slapi_entry_attr_set_uint(entry, +@@ -510,6 +523,7 @@ repeat: + } + + entry = backend_make_user_entry_from_nsswitch_passwd(&pwd, container_sdn, ++ is_uid ? NULL : user_name, + cbdata); + entries = malloc(sizeof(entries[0]) * 2); + if (entries != NULL) { +-- +2.7.4 + diff --git a/SOURCES/slapi-nis-0.54.tar.gz.sig b/SOURCES/slapi-nis-0.54.tar.gz.sig deleted file mode 100644 index d6a0bce..0000000 Binary files a/SOURCES/slapi-nis-0.54.tar.gz.sig and /dev/null differ diff --git a/SOURCES/slapi-nis-0.56.0.tar.gz.sig b/SOURCES/slapi-nis-0.56.0.tar.gz.sig new file mode 100644 index 0000000..f83fae6 Binary files /dev/null and b/SOURCES/slapi-nis-0.56.0.tar.gz.sig differ diff --git a/SOURCES/slapi-nis-ID-views-ignore-searches-for-views-outside-the-subtrees.patch b/SOURCES/slapi-nis-ID-views-ignore-searches-for-views-outside-the-subtrees.patch deleted file mode 100644 index aebb1ef..0000000 --- a/SOURCES/slapi-nis-ID-views-ignore-searches-for-views-outside-the-subtrees.patch +++ /dev/null @@ -1,180 +0,0 @@ -From 79391fda05fba164af577bd0e08a2807643b7b48 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Tue, 28 Oct 2014 10:09:47 +0200 -Subject: [PATCH 1/2] ID views: ignore searches for views outside the subtrees - of schema-compat sets - -schema-compat plugin may provide multiple disjoint subtrees which -can be used to request overridden entries by prefixing the subtree -suffix with a - - cn=,cn=views, - -As subtrees may be disjoint, we cannot rely on the common suffix. Thus, -any attempt to replace target DN and update filter terms must only be -done once we are sure the search will be done in the subtree. - -This optimization prevents mistakenly changing the search filter when -FreeIPA and SSSD search for the ID overrides themselves, as the same -structure of the target DN is used for cn=views,cn=accounts,$SUFFIX -subtree in FreeIPA. This subtree is never handled by slapi-nis and -should be ignored. - -https://bugzilla.redhat.com/show_bug.cgi?id=1157989 ---- - src/back-sch-idview.c | 11 +++++-- - src/back-sch.c | 81 +++++++++++++++++++++++++++++++++++++++++++++------ - 2 files changed, 81 insertions(+), 11 deletions(-) - -diff --git a/src/back-sch-idview.c b/src/back-sch-idview.c -index 5a2b450..a56a9e9 100644 ---- a/src/back-sch-idview.c -+++ b/src/back-sch-idview.c -@@ -334,6 +334,10 @@ idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct b - slapi_ber_bvdone(bval); - slapi_ber_bvcpy(bval, slapi_value_get_berval(anchor_val)); - config->override_found = TRUE; -+ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id, -+ "Overriding the filter %s with %s=%*s from the override %s\n.", -+ filter_type, filter_type, bval->bv_len, bval->bv_val, -+ slapi_entry_get_dn_const(cbdata->overrides[i])); - break; - } - } -@@ -346,6 +350,11 @@ idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct b - slapi_ber_bvdone(bval); - slapi_ber_bvcpy(bval, slapi_value_get_berval(anchor_val)); - config->override_found = TRUE; -+ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id, -+ "Overriding the filter %s with %s=%*s from the override %s\n.", -+ filter_type, IPA_IDVIEWS_ATTR_ANCHORUUID, -+ bval->bv_len, bval->bv_val, -+ slapi_entry_get_dn_const(cbdata->overrides[i])); - break; - } - -@@ -366,8 +375,6 @@ idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct b - * - * Note that in reality we don't use original value of the uid/cn attribue. Instead, we use ipaAnchorUUID - * to refer to the original entry. */ --extern char * --slapi_filter_to_string( const struct slapi_filter *f, char *buf, size_t bufsize ); - void - idview_replace_filter(struct backend_search_cbdata *cbdata) - { -diff --git a/src/back-sch.c b/src/back-sch.c -index 27d5101..27ac24f 100644 ---- a/src/back-sch.c -+++ b/src/back-sch.c -@@ -1166,6 +1166,44 @@ backend_search_set_cb(const char *group, const char *set, bool_t flag, - return TRUE; - } - -+/* Routines to search if a target DN is within any of the sets we handle */ -+static bool_t -+backend_search_find_set_dn_in_group_cb(const char *group, const char *set, bool_t flag, -+ void *backend_data, void *cb_data) -+{ -+ struct backend_search_cbdata *cbdata; -+ struct backend_set_data *set_data; -+ -+ cbdata = cb_data; -+ set_data = backend_data; -+ -+ if (slapi_sdn_scope_test(cbdata->target_dn, -+ set_data->container_sdn, -+ cbdata->scope) == 1) { -+ cbdata->answer = TRUE; -+ } -+ -+ if (slapi_sdn_compare(set_data->container_sdn, -+ cbdata->target_dn) == 0) { -+ cbdata->answer = TRUE; -+ } -+ -+ return TRUE; -+ -+} -+ -+static bool_t -+backend_search_find_set_dn_cb(const char *group, void *cb_data) -+{ -+ struct backend_search_cbdata *cbdata; -+ -+ cbdata = cb_data; -+ map_data_foreach_map(cbdata->state, group, -+ backend_search_find_set_dn_in_group_cb, cb_data); -+ return TRUE; -+} -+ -+/* Routines to find out the set that has the same group as requested */ - static bool_t - backend_search_find_set_data_in_group_cb(const char *group, const char *set, bool_t flag, - void *backend_data, void *cb_data) -@@ -1340,9 +1378,6 @@ backend_search_cb(Slapi_PBlock *pb) - "searching from \"%s\" for \"%s\" with scope %d%s\n", - cbdata.target, cbdata.strfilter, cbdata.scope, - backend_sch_scope_as_string(cbdata.scope)); --#ifdef USE_IPA_IDVIEWS -- idview_replace_target_dn(&cbdata.target, &cbdata.idview); --#endif - cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target); - /* Check if there's a backend handling this search. */ - if (!slapi_be_exist(cbdata.target_dn)) { -@@ -1351,19 +1386,47 @@ backend_search_cb(Slapi_PBlock *pb) - "slapi_be_exists(\"%s\") = 0, " - "ignoring search\n", cbdata.target); - slapi_sdn_free(&cbdata.target_dn); -+ return 0; -+ } -+ -+#ifdef USE_IPA_IDVIEWS -+ /* We may have multiple disjoint trees in the sets, search if the target matches any of them -+ * as in general there don't have to be a single subtree (cn=compat,$SUFFIX) for all trees to easily -+ * detect the ID view use. Unless the ID view is within the set we control, don't consider the override */ -+ map_data_foreach_domain(cbdata.state, backend_search_find_set_dn_cb, &cbdata); -+ if (cbdata.answer == FALSE) { -+ idview_replace_target_dn(&cbdata.target, &cbdata.idview); - if (cbdata.idview != NULL) { -- slapi_ch_free_string(&cbdata.target); -+ slapi_sdn_free(&cbdata.target_dn); -+ /* Perform another check, now for rewritten DN */ -+ cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target); -+ map_data_foreach_domain(cbdata.state, backend_search_find_set_dn_cb, &cbdata); -+ /* Rewritten DN might still be outside of our trees */ -+ if (cbdata.answer == TRUE) { -+ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata.state->plugin_desc->spd_id, -+ "Use of ID view '%s' is detected, searching from \"%s\" " -+ "for \"%s\" with scope %d%s. Filter may get overridden later.\n", -+ cbdata.idview, cbdata.target, cbdata.strfilter, cbdata.scope, -+ backend_sch_scope_as_string(cbdata.scope)); -+ } else { -+ slapi_sdn_free(&cbdata.target_dn); -+ slapi_ch_free_string(&cbdata.target); -+ slapi_ch_free_string(&cbdata.idview); -+ slapi_log_error(SLAPI_LOG_PLUGIN, -+ cbdata.state->plugin_desc->spd_id, -+ "The search base didn't match any of the containers, " -+ "ignoring search\n"); -+ return 0; -+ } - } -- slapi_ch_free_string(&cbdata.idview); --#ifdef USE_IPA_IDVIEWS -- idview_free_overrides(&cbdata); --#endif -- return 0; - } -+ cbdata.answer = FALSE; -+#endif - - /* Walk the list of groups. */ - wrap_inc_call_level(); - #ifdef USE_IPA_IDVIEWS -+ /* Filter replacement requires increased call level as we may fetch overrides and thus come back here */ - idview_replace_filter(&cbdata); - #endif - if (map_rdlock() == 0) { --- -2.1.0 - diff --git a/SOURCES/slapi-nis-delay-sending-responses-from-compat-tree-a.patch b/SOURCES/slapi-nis-delay-sending-responses-from-compat-tree-a.patch deleted file mode 100644 index 47a8a7d..0000000 --- a/SOURCES/slapi-nis-delay-sending-responses-from-compat-tree-a.patch +++ /dev/null @@ -1,460 +0,0 @@ -From 44e8e5f79616fb80edf8af010332c18a628af861 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Thu, 29 Oct 2015 17:34:48 +0100 -Subject: [PATCH 1/2] slapi-nis: delay sending responses from compat tree after - map search - -When slapi-nis plugin responds on a search query, it holds read lock for -the internal structure called 'map cache'. The map cache lock can also be taken -for write when modification would be required like responding to DELETE, ADD, or -MODIFY operations. - -As result of the lock semantics, write lock owner is blocked until all read lock -owners release their locks. This is generally not a problem but when readers sent -out LDAP query results, they call into SLAPI function that might take long time -to send out the data due to external reasons (network latencies, clients being -blocked, etc) and all this time map cache is locked for write operations. - -When Kerberos KDC issues a TGT, it needs to modify few Kerberos-related attributes -in the principal's LDAP entry. These updates are generating MOD operations visible -by slapi-nis plugin which triggers re-scan of map cache to potentially replace -the affected entries. To perform potential replacement, slapi-nis has to take a write -lock and be blocked by outstanding readers. - -Therefore, it is possible to encounter a situation where an LDAP client uses -SASL GSSAPI authentication and existing Kerberos ticket did expire in a course -of outstanding search request. According to LDAPv3 protocol specification, an -LDAP client must perform re-negotiation before reading any outstanding PDUs. It -would ask Kerberos KDC for a new (or renewed) TGT, that would cause MOD updates -for the primary tree which is tracked for changes by slapi-nis. These changes -would be blocked by a slapi-nis reader as the client cannot finish reading -outstanding PDUs yet. - -To solve this problem, we avoid sending LDAP entries while keeping map cache -lock. Instead, we generate a linked list of copies of entries which will be -sent out. To allow sharing of entries between multiple parallel queries, we -hash the entry and reference the cached entry in the linked list with increased -reference count. Once entry is actually sent, its reference count decreased and -on reaching zero it is removed from the hash. - -o solve this problem, we avoid sending LDAP entries while keeping map cache -lock. Instead, we generate a linked list of copies of entries which will be -sent out. To allow sharing of entries between multiple parallel queries, we -hash the entry and reference the cached entry in the linked list with increased -reference count. Once entry is actually sent, its reference count decreased and -on reaching zero it is removed from the hash. - -The entry in the hash table might become outdated. This is detected by comparing -both modifyTimestamp and entryUSN values of the entry to be sent and entry in the -hash table. If new version of the entry is different, hash table's entry reference -is replaced with a new copy. The old entry is not removed because it is still -referenced by some outstanding query processing. Thus, the hash table always -references the most recent version of an entry but there might be multiple copies -in possesion of the linked lists from the separate parallel queries. - -An entry sharing via hash table can be disabled by setting - slapi-entry-cache: 0 -in the definition, cn=Schema Compatibility,cn=plugins,cn=config - -Resolves: rhbz#1273587 - -https://bugzilla.redhat.com/show_bug.cgi?id=1273587 ---- - doc/sch-configuration.txt | 7 ++ - src/back-sch.c | 159 ++++++++++++++++++++++++++++++++++++++++++---- - src/back-sch.h | 20 ++++++ - src/plug-sch.c | 34 ++++++++++ - src/plugin.h | 3 + - 5 files changed, 212 insertions(+), 11 deletions(-) - -diff --git a/doc/sch-configuration.txt b/doc/sch-configuration.txt -index e07a4af..dd8b3c4 100644 ---- a/doc/sch-configuration.txt -+++ b/doc/sch-configuration.txt -@@ -16,6 +16,13 @@ look like this: - nsslapd-version: 0.0 - nsslapd-pluginvendor: redhat.com - nsslapd-plugindescription: Schema Compatibility Plugin -+ slapi-entry-cache: 1 -+ -+The only optional attribute is 'slapi-entry-cache' (default to 1) -+controls whether the plugin should use an entry cache for outstanding -+query requests. The entry cache is an optimization technique to -+help reduce memory pressure during parallel requests. Specify 0 to disable -+an entry cache. - - Configuration for individual sets should be stored in entries directly - beneath the plugin's entry. These attributes are recognized: -diff --git a/src/back-sch.c b/src/back-sch.c -index dd6f92d..b2362d0 100644 ---- a/src/back-sch.c -+++ b/src/back-sch.c -@@ -32,6 +32,7 @@ - - #ifdef HAVE_DIRSRV_SLAPI_PLUGIN_H - #include -+#include - #include - #include - #else -@@ -53,6 +54,9 @@ - #include "map.h" - #include "back-sch.h" - -+static void -+backend_entries_to_return_push(struct backend_search_cbdata *cbdata, Slapi_Entry *e); -+ - #define SCH_CONTAINER_CONFIGURATION_FILTER "(&(" SCH_CONTAINER_CONFIGURATION_GROUP_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_BASE_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_FILTER_ATTR "=*)(" SCH_CONTAINER_CONFIGURATION_RDN_ATTR "=*))" - - /* Read the name of the NIS master. A dummy function for the schema -@@ -996,7 +1000,7 @@ backend_search_entry_cb(const char *domain, const char *map, bool_t secure, - void *backend_data, void *cb_data) - { - Slapi_DN *sdn; -- Slapi_Entry *entry; -+ Slapi_Entry *entry = NULL; /* prevent to free an uninitialized entry */ - Slapi_Attr *attr = NULL; - struct backend_search_cbdata *cbdata; - struct backend_entry_data *entry_data; -@@ -1052,8 +1056,7 @@ backend_search_entry_cb(const char *domain, const char *map, bool_t secure, - slapi_entry_delete_string(entry, "objectClass", "ipaOverrideTarget"); - } - #endif -- slapi_send_ldap_search_entry(cbdata->pb, entry, NULL, -- cbdata->attrs, cbdata->attrsonly); -+ backend_entries_to_return_push(cbdata, entry); - cbdata->n_entries++; - - if (entry != entry_data->e) { -@@ -1070,7 +1073,7 @@ backend_search_set_cb(const char *group, const char *set, bool_t flag, - { - struct backend_search_cbdata *cbdata; - struct backend_set_data *set_data; -- Slapi_Entry *set_entry; -+ Slapi_Entry *set_entry = NULL ; /* prevent to free an uninitialized entry */ - int result, n_entries; - int n_entries_without_nsswitch; - const char *ndn; -@@ -1124,12 +1127,11 @@ backend_search_set_cb(const char *group, const char *set, bool_t flag, - set_data->common.group, set_entry); - } - #endif -- slapi_send_ldap_search_entry(cbdata->pb, set_entry, -- NULL, cbdata->attrs, -- cbdata->attrsonly); -+ backend_entries_to_return_push(cbdata, set_entry); - cbdata->n_entries++; - break; - } -+ - slapi_entry_free(set_entry); - } - -@@ -1244,7 +1246,7 @@ backend_search_group_cb(const char *group, void *cb_data) - { - struct backend_search_cbdata *cbdata; - Slapi_DN *group_dn; -- Slapi_Entry *group_entry; -+ Slapi_Entry *group_entry = NULL; /* prevent to free an uninitialized entry */ - int result, n_maps; - - cbdata = cb_data; -@@ -1279,12 +1281,11 @@ backend_search_group_cb(const char *group, void *cb_data) - idview_process_overrides(cbdata, NULL, NULL, group, group_entry); - } - #endif -- slapi_send_ldap_search_entry(cbdata->pb, group_entry, -- NULL, cbdata->attrs, -- cbdata->attrsonly); -+ backend_entries_to_return_push(cbdata, group_entry); - cbdata->n_entries++; - break; - } -+ - slapi_entry_free(group_entry); - } - -@@ -1343,6 +1344,138 @@ backend_sch_scope_as_string(int scope) - return ""; - } - -+/* The entries are pushed (added) at the end of the list -+ * so that they will be send in the head->tail order -+ */ -+static void -+backend_entries_to_return_push(struct backend_search_cbdata *cbdata, Slapi_Entry *e) -+{ -+ struct entries_to_send *e_to_send = NULL; -+ struct cached_entry *entry = NULL; -+ bool_t dont_cache = FALSE; -+ PLHashTable* ht = (PLHashTable*) cbdata->state->cached_entries; -+ -+ if ((cbdata == NULL) || (e == NULL)) return; -+ -+ e_to_send = (struct entries_to_send *) slapi_ch_calloc(1, sizeof(struct entries_to_send)); -+ -+ dont_cache = cbdata->state->use_entry_cache ? FALSE : TRUE; -+ -+ if (!wrap_rwlock_wrlock(cbdata->state->cached_entries_lock)) { -+ entry = PL_HashTableLookup(ht, slapi_entry_get_ndn(e)); -+ if (entry != NULL) { -+ /* There is an entry in the hash table but is it the same? */ -+ char *e_modifyTimestamp = slapi_entry_attr_get_charptr(e, "modifyTimestamp"); -+ char *entry_modifyTimestamp = slapi_entry_attr_get_charptr(entry->entry, "modifyTimestamp"); -+ unsigned long e_usn = slapi_entry_attr_get_ulong(e, "entryUSN"); -+ unsigned long entry_usn = slapi_entry_attr_get_ulong(entry->entry, "entryUSN"); -+ int res = -1; -+ -+ /* Our comparison strategy is following: -+ * - compare modifyTimestamp values first, -+ * - if they are the same (modifyTimestamp in slapi-nis is down to a second precision), -+ * compare entryUSN values if they exist -+ * - default to not using the cached entry to be on safe side if both comparisons don't -+ * give us a definite answer */ -+ if ((e_modifyTimestamp != NULL) && (entry_modifyTimestamp != NULL)) { -+ res = strncmp(e_modifyTimestamp, entry_modifyTimestamp, strlen(e_modifyTimestamp)); -+ } -+ -+ if ((res == 0) && ((e_usn != 0) && (entry_usn != 0))) { -+ res = e_usn != entry_usn ? 1 : 0; -+ } -+ -+ if (res != 0) { -+ /* Cached entry is different, evict it from the hash table */ -+ (void) PL_HashTableRemove(ht, slapi_entry_get_ndn(entry->entry)); -+ -+ /* We don't want to clear the entry because it is still in use by other thread. -+ * Instead, we'll insert new entry into hash table, let the linked list in other -+ * search to remove the entry itself, but mark it as non-cached. */ -+ entry->not_cached = TRUE; -+ entry = NULL; -+ } else { -+ slapi_log_error(SLAPI_LOG_PLUGIN, -+ cbdata->state->plugin_desc->spd_id, -+ "referenced entry [%s], USNs: %ld vs %ld, [%s] vs [%s]\n", -+ slapi_entry_get_ndn(e), e_usn, entry_usn, e_modifyTimestamp, entry_modifyTimestamp); -+ /* It is the same entry, reference it for us */ -+ (void) PR_AtomicIncrement(&entry->refcount); -+ } -+ -+ if (e_modifyTimestamp != NULL) -+ slapi_ch_free_string(&e_modifyTimestamp); -+ if (entry_modifyTimestamp != NULL) -+ slapi_ch_free_string(&entry_modifyTimestamp); -+ } -+ -+ if (entry == NULL) { -+ /* no cached entry for this DN */ -+ entry = (struct cached_entry *) slapi_ch_calloc(1, sizeof(struct cached_entry)); -+ entry->entry = slapi_entry_dup(e); -+ entry->not_cached = FALSE; -+ (void) PR_AtomicSet(&entry->refcount, 1); -+ if ((ht != NULL) && (entry->entry != NULL) && (!dont_cache)) { -+ (void) PL_HashTableAdd(ht, slapi_entry_get_ndn(entry->entry), entry); -+ } -+ } -+ -+ wrap_rwlock_unlock(cbdata->state->cached_entries_lock); -+ } -+ -+ e_to_send->entry = entry; -+ if (cbdata->entries_tail == NULL) { -+ /* First entry in that list */ -+ cbdata->entries_tail = e_to_send; -+ cbdata->entries_head = e_to_send; -+ } else { -+ cbdata->entries_tail->next = e_to_send; -+ cbdata->entries_tail = e_to_send; -+ } -+} -+ -+static void -+backend_send_mapped_entries(struct backend_search_cbdata *cbdata) -+{ -+ struct entries_to_send *e_to_send, *next; -+ PLHashTable* ht = NULL; -+ int i = 0; -+ PRInt32 count; -+ -+ if (cbdata == NULL) return; -+ ht = (PLHashTable*) cbdata->state->cached_entries; -+ -+ /* iterate from head->tail sending the stored entries */ -+ for (e_to_send = cbdata->entries_head, i = 0; e_to_send != NULL; i++) { -+ next = e_to_send->next; -+ if (e_to_send->entry->refcount > 0) { -+ slapi_send_ldap_search_entry(cbdata->pb, e_to_send->entry->entry, NULL, -+ cbdata->attrs, cbdata->attrsonly); -+ -+ /* Clean up entry only if there is no reference to it any more in any outstanding request */ -+ wrap_rwlock_wrlock(cbdata->state->cached_entries_lock); -+ count = PR_AtomicDecrement(&e_to_send->entry->refcount); -+ if (count == 0) { -+ if (!e_to_send->entry->not_cached) { -+ (void) PL_HashTableRemove(ht, slapi_entry_get_ndn(e_to_send->entry->entry)); -+ } -+ /* free this returned entry */ -+ slapi_entry_free(e_to_send->entry->entry); -+ e_to_send->entry->entry = NULL; -+ slapi_ch_free((void **) &e_to_send->entry); -+ e_to_send->entry = NULL; -+ } -+ wrap_rwlock_unlock(cbdata->state->cached_entries_lock); -+ } -+ -+ /* Otherwise only free list item */ -+ slapi_ch_free((void **) &e_to_send); -+ e_to_send = next; -+ } -+ cbdata->entries_head = NULL; -+ cbdata->entries_tail = NULL; -+} -+ - static int - backend_search_cb(Slapi_PBlock *pb) - { -@@ -1443,6 +1576,8 @@ backend_search_cb(Slapi_PBlock *pb) - cbdata.state->plugin_desc->spd_id, - "unable to acquire read lock\n"); - } -+ /* Return existing collected entries */ -+ backend_send_mapped_entries(&cbdata); - wrap_dec_call_level(); - #ifdef USE_NSSWITCH - /* If during search of some sets we staged additional lookups, perform them. */ -@@ -1525,6 +1660,8 @@ backend_search_cb(Slapi_PBlock *pb) - if (map_rdlock() == 0) { - map_data_foreach_domain(cbdata.state, backend_search_group_cb, &cbdata); - map_unlock(); -+ /* Return newly acquired entries */ -+ backend_send_mapped_entries(&cbdata); - } else { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata.state->plugin_desc->spd_id, -diff --git a/src/back-sch.h b/src/back-sch.h -index 1aedf36..e8ec400 100644 ---- a/src/back-sch.h -+++ b/src/back-sch.h -@@ -63,6 +63,24 @@ struct backend_staged_search { - Slapi_Entry **entries; - }; - -+/* Entry to be send to clients is cached to allow multiple threads to re-use results. -+ */ -+struct cached_entry { -+ Slapi_Entry *entry; -+ PRInt32 refcount; -+ bool_t not_cached; -+}; -+ -+/* list of entries to actually send, sorted as a linked list -+ * Entries are references to the ones stored in a cache -+ * Before sending them out one needs to refcount the entry -+ */ -+struct entries_to_send { -+ struct entries_to_send *next; -+ struct entries_to_send *prev; -+ struct cached_entry *entry; -+}; -+ - /* Intercept a search request, and if it belongs to one of our compatibility - * trees, answer from our cache before letting the default database have a - * crack at it. */ -@@ -88,6 +106,8 @@ struct backend_search_cbdata { - int n_entries; - struct backend_staged_search *staged; - struct backend_staged_search *cur_staged; -+ struct entries_to_send *entries_head; -+ struct entries_to_send *entries_tail; - }; - - struct backend_search_filter_config { -diff --git a/src/plug-sch.c b/src/plug-sch.c -index 5a6e736..f132e6d 100644 ---- a/src/plug-sch.c -+++ b/src/plug-sch.c -@@ -44,6 +44,7 @@ - - #ifdef HAVE_DIRSRV_SLAPI_PLUGIN_H - #include -+#include - #include - #include - #else -@@ -100,6 +101,7 @@ plugin_startup(Slapi_PBlock *pb) - { - /* Populate the maps and data. */ - struct plugin_state *state; -+ Slapi_Entry *plugin_entry = NULL; - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); - slapi_pblock_get(pb, SLAPI_TARGET_DN, &state->plugin_base); - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, -@@ -111,12 +113,35 @@ plugin_startup(Slapi_PBlock *pb) - backend_startup(pb, state); - state->pam_lock = wrap_new_rwlock(); - backend_nss_init_context((struct nss_ops_ctx**) &state->nss_context); -+ if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) && -+ (plugin_entry != NULL)) { -+ state->use_entry_cache = backend_shr_get_vattr_boolean(state, plugin_entry, -+ "slapi-entry-cache", -+ 1); -+ } -+ state->cached_entries_lock = wrap_new_rwlock(); -+ wrap_rwlock_wrlock(state->cached_entries_lock); -+ state->cached_entries = PL_NewHashTable(0, PL_HashString, PL_CompareStrings, PL_CompareValues, 0, 0); -+ wrap_rwlock_unlock(state->cached_entries_lock); - /* Note that the plugin is ready to go. */ - slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id, - "plugin startup completed\n"); - return 0; - } - -+static PRIntn -+remove_cached_entries_cb(PLHashEntry *he, PRIntn i, void *arg) -+{ -+ struct cached_entry *e = (struct cached_entry*) he->value; -+ if (e != NULL) { -+ if (e->entry != NULL) { -+ slapi_entry_free(e->entry); -+ } -+ slapi_ch_free((void **) &e); -+ } -+ return HT_ENUMERATE_REMOVE; -+} -+ - static int - plugin_shutdown(Slapi_PBlock *pb) - { -@@ -126,6 +151,15 @@ plugin_shutdown(Slapi_PBlock *pb) - wrap_free_rwlock(state->pam_lock); - state->pam_lock = NULL; - backend_nss_free_context((struct nss_ops_ctx**) &state->nss_context); -+ if (state->cached_entries != NULL) { -+ wrap_rwlock_wrlock(state->cached_entries_lock); -+ PL_HashTableEnumerateEntries(state->cached_entries, remove_cached_entries_cb, NULL); -+ PL_HashTableDestroy(state->cached_entries); -+ state->cached_entries = NULL; -+ wrap_rwlock_unlock(state->cached_entries_lock); -+ wrap_free_rwlock(state->cached_entries_lock); -+ state->cached_entries_lock = NULL; -+ } - state->plugin_base = NULL; - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "plugin shutdown completed\n"); -diff --git a/src/plugin.h b/src/plugin.h -index 94ad747..429e291 100644 ---- a/src/plugin.h -+++ b/src/plugin.h -@@ -47,6 +47,9 @@ struct plugin_state { - /* Schema compat-specific data. */ - struct wrapped_rwlock *pam_lock; - void *nss_context; -+ int use_entry_cache; -+ void *cached_entries; -+ struct wrapped_rwlock *cached_entries_lock; - }; - - #endif --- -2.5.0 - diff --git a/SOURCES/slapi-nis-don-t-search-in-SSSD-when-memberUid-has-no.patch b/SOURCES/slapi-nis-don-t-search-in-SSSD-when-memberUid-has-no.patch deleted file mode 100644 index fc13902..0000000 --- a/SOURCES/slapi-nis-don-t-search-in-SSSD-when-memberUid-has-no.patch +++ /dev/null @@ -1,42 +0,0 @@ -From 7ab0e8ec086d3822f267069bf9a947ac65647870 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Thu, 16 Jul 2015 17:07:31 +0300 -Subject: [PATCH] slapi-nis: don't search in SSSD when memberUid has no '@' - separator - -In the case there are no groups in cn=groups map that have certain -memberUid as a member, we look at possibility that this user might -be coming from a trusted AD forest. However, all users from trusted -AD forests do have '@' separator in the name between the user name -and the domain. - -In case there is no '@' separator, consider such search as not valid -for lookups in SSSD. - -Fixes: https://bugzilla.redhat.com/show_bug.cgi?id=1243823 ---- - src/back-sch-nss.c | 7 +++++-- - 1 file changed, 5 insertions(+), 2 deletions(-) - -diff --git a/src/back-sch-nss.c b/src/back-sch-nss.c -index f8177d7..16d4164 100644 ---- a/src/back-sch-nss.c -+++ b/src/back-sch-nss.c -@@ -140,9 +140,12 @@ backend_search_filter_has_cn_uid(Slapi_Filter *filter, void *arg) - } - slapi_ch_free_string(&memberUid); - } -+ config->name_set = TRUE; -+ config->search_members = TRUE; -+ } else { -+ /* there is no '@' in the memberUid name, it is not a trusted AD forest's user */ -+ config->wrong_search = TRUE; - } -- config->name_set = TRUE; -- config->search_members = TRUE; - } else if ((0 == strcasecmp(filter_type, "objectClass")) && - (0 == bvstrcasecmp(bval, "posixGroup"))) { - config->search_group = TRUE; --- -2.4.3 - diff --git a/SOURCES/slapi-nis-extmem-0005-slapi-nis-populate-data-trees-asynchronously-after-L.patch b/SOURCES/slapi-nis-extmem-0005-slapi-nis-populate-data-trees-asynchronously-after-L.patch deleted file mode 100644 index eafbedd..0000000 --- a/SOURCES/slapi-nis-extmem-0005-slapi-nis-populate-data-trees-asynchronously-after-L.patch +++ /dev/null @@ -1,207 +0,0 @@ -From 2df48b57adb666112cab22e62750dd984fc7450a Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Wed, 23 Dec 2015 14:57:03 +0200 -Subject: [PATCH 05/12] slapi-nis: populate data trees asynchronously after - LDAP server startup - -Currently slapi-nis design assumes the map cache is populated by -scanning the original trees on plugin start up. This has few -consequences: - - LDAP server cannot serve LDAP clients until all plugins are - initialized - - - slapi-nis cannot ask SSSD to resolve external identities at - this point as SSSD will need to talk to the LDAP server which - is at this point not listening for connections. SSSD will put - whole IPA domain into offline and always will respond - with negative result - -To solve these issues, schedule tree scan after LDAP server startup. -The problem here is that it is not possible to reliably detect when -389-ds starts to listen to the incoming connections. However, it is -possible to schedule an event into 389-ds event queue that will run -shortly after start of the event loop. Given that the call back function -which is registered to be called is called within the event loop thread, -one can fire off another thread and wait in the thread function some -time until the LDAP server is ready for connections. - -The time interval is something that would depend on a specific -deployment profile but experiments show that having 5 seconds delay -should be enough as event queue is created just before starting the -listeners. ---- - src/back-shr.c | 110 ++++++++++++++++++++++++++++++++++++++++++++++++--------- - src/plug-sch.c | 4 +-- - 2 files changed, 96 insertions(+), 18 deletions(-) - -diff --git a/src/back-shr.c b/src/back-shr.c -index c68640a..36ecc0b 100644 ---- a/src/back-shr.c -+++ b/src/back-shr.c -@@ -664,40 +664,56 @@ backend_shr_get_vattr_sdnlist(struct plugin_state *state, - return ret; - } - --/* Scan for the list of configured groups and sets. */ --void --backend_shr_startup(struct plugin_state *state, -- Slapi_PBlock *parent_pb, -- const char *filter) -+struct backend_shr_data_init_cbdata { -+ Slapi_PBlock *parent_pb; -+ struct plugin_state *state; -+ const char *filter; -+}; -+ -+#define PLUGIN_SCAN_DELAY 5 -+ -+static void -+backend_shr_data_initialize_thread_cb(void *arg) - { -- Slapi_PBlock *pb; -+ struct backend_shr_data_init_cbdata *cbdata = (struct backend_shr_data_init_cbdata *)arg; -+ Slapi_PBlock *pb = NULL; - struct backend_set_config_entry_add_cbdata set_cbdata; -+ int result = 0; -+ if (cbdata == NULL) { -+ return; -+ } -+ -+ /* Scan may require consulting SSSD for external identities -+ * therefore, we need to make sure the scan starts after ns-slapd -+ * started to serve LDAP clients. There is no a signal for this, -+ * so we just wait some time. */ -+ DS_Sleep(PR_SecondsToInterval(PLUGIN_SCAN_DELAY)); - -- backend_update_params(parent_pb, state); -+ backend_update_params(cbdata->parent_pb, cbdata->state); - - slapi_log_error(SLAPI_LOG_PLUGIN, -- state->plugin_desc->spd_id, -+ cbdata->state->plugin_desc->spd_id, - "searching under \"%s\" for configuration\n", -- state->plugin_base); -- pb = wrap_pblock_new(parent_pb); -+ cbdata->state->plugin_base); -+ pb = wrap_pblock_new(cbdata->parent_pb); - slapi_search_internal_set_pb(pb, -- state->plugin_base, -+ cbdata->state->plugin_base, - LDAP_SCOPE_ONELEVEL, -- filter, -+ cbdata->filter, - NULL, FALSE, - NULL, - NULL, -- state->plugin_identity, -+ cbdata->state->plugin_identity, - 0); - if (map_wrlock() != 0) { - slapi_log_error(SLAPI_LOG_PLUGIN, -- state->plugin_desc->spd_id, -+ cbdata->state->plugin_desc->spd_id, - "failed to search under \"%s\" for " - "configuration: failed to acquire a lock\n", -- state->plugin_base); -+ cbdata->state->plugin_base); - goto done_with_lock; - } -- set_cbdata.state = state; -+ set_cbdata.state = cbdata->state; - set_cbdata.pb = pb; - slapi_search_internal_callback_pb(pb, &set_cbdata, - NULL, -@@ -706,6 +722,68 @@ backend_shr_startup(struct plugin_state *state, - map_unlock(); - done_with_lock: - slapi_pblock_destroy(pb); -+ if (cbdata) { -+ slapi_ch_free((void**)&cbdata); -+ } -+} -+ -+static void -+backend_shr_data_initialize_thread(time_t when, void *arg) -+{ -+ struct backend_shr_data_init_cbdata *cbdata = (struct backend_shr_data_init_cbdata *)arg; -+ PRThread *thread = NULL; -+ -+ /* start data import as a separate thread */ -+ thread = PR_CreateThread(PR_USER_THREAD, backend_shr_data_initialize_thread_cb, -+ (void *)arg, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, -+ PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); -+ if (thread == NULL) { -+ slapi_log_error(SLAPI_LOG_FATAL, -+ cbdata->state->plugin_desc->spd_id, -+ "unable to create compatibility tree scan thread!\n"); -+ } else { -+ slapi_log_error(SLAPI_LOG_FATAL, -+ cbdata->state->plugin_desc->spd_id, -+ "%s tree scan will start in about %d seconds!\n", -+ cbdata->state->plugin_desc->spd_id, PLUGIN_SCAN_DELAY); -+ } -+ -+} -+ -+/* Scan for the list of configured groups and sets. */ -+void -+backend_shr_startup(struct plugin_state *state, -+ Slapi_PBlock *parent_pb, -+ const char *filter) -+{ -+ struct backend_shr_data_init_cbdata *cbdata = NULL; -+ -+ cbdata = (struct backend_shr_data_init_cbdata *) -+ slapi_ch_malloc(sizeof(struct backend_shr_data_init_cbdata)); -+ -+ if (cbdata == NULL) { -+ slapi_log_error(SLAPI_LOG_FATAL, -+ state->plugin_desc->spd_id, -+ "failed to create a task for populating " -+ "compatibility tree\n"); -+ return; -+ } -+ -+ cbdata->state = state; -+ cbdata->parent_pb = parent_pb; -+ cbdata->filter = filter; -+ -+ /* Schedule running a callback that will create a thread */ -+ slapi_eq_once(backend_shr_data_initialize_thread, -+ cbdata, PR_SecondsToInterval(PLUGIN_SCAN_DELAY)); -+ -+ slapi_log_error(SLAPI_LOG_FATAL, -+ cbdata->state->plugin_desc->spd_id, -+ "scheduled %s tree scan in about %d seconds after the server startup!\n", -+ state->plugin_desc->spd_id, PLUGIN_SCAN_DELAY); -+ -+ return; -+ - } - - /* Process a set configuration directory entry. Pull out the group and set -diff --git a/src/plug-sch.c b/src/plug-sch.c -index f132e6d..95a4fd8 100644 ---- a/src/plug-sch.c -+++ b/src/plug-sch.c -@@ -109,8 +109,6 @@ plugin_startup(Slapi_PBlock *pb) - state->plugin_base ? "\"" : "", - state->plugin_base ? state->plugin_base : "NULL", - state->plugin_base ? "\"" : ""); -- /* Populate the tree of fake entries. */ -- backend_startup(pb, state); - state->pam_lock = wrap_new_rwlock(); - backend_nss_init_context((struct nss_ops_ctx**) &state->nss_context); - if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) && -@@ -123,6 +121,8 @@ plugin_startup(Slapi_PBlock *pb) - wrap_rwlock_wrlock(state->cached_entries_lock); - state->cached_entries = PL_NewHashTable(0, PL_HashString, PL_CompareStrings, PL_CompareValues, 0, 0); - wrap_rwlock_unlock(state->cached_entries_lock); -+ /* Populate the tree of fake entries. */ -+ backend_startup(pb, state); - /* Note that the plugin is ready to go. */ - slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id, - "plugin startup completed\n"); --- -2.5.0 - diff --git a/SOURCES/slapi-nis-extmem-0006-nss-force-lower-case-for-memberUid-attribute-as-per-.patch b/SOURCES/slapi-nis-extmem-0006-nss-force-lower-case-for-memberUid-attribute-as-per-.patch deleted file mode 100644 index efdacae..0000000 --- a/SOURCES/slapi-nis-extmem-0006-nss-force-lower-case-for-memberUid-attribute-as-per-.patch +++ /dev/null @@ -1,84 +0,0 @@ -From 52beb5e79905712a8aaabf19e52e654fc4648a94 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Fri, 15 Jan 2016 16:16:00 +0200 -Subject: [PATCH 06/12] nss: force lower case for memberUid attribute as per - RFC2307 - -When memberUid attribute is generated, it has to be normalized or -otherwise searches for members against groups in compat tree will fail. -slapi-nis already normalizes elements of a search filter that mention -memberUid attribute values but the original memberUid value should be -normalized as well. ---- - src/back-sch-nss.c | 22 ++++++++++++++++++---- - 1 file changed, 18 insertions(+), 4 deletions(-) - -diff --git a/src/back-sch-nss.c b/src/back-sch-nss.c -index 16d4164..702590c 100644 ---- a/src/back-sch-nss.c -+++ b/src/back-sch-nss.c -@@ -246,8 +246,8 @@ backend_make_user_entry_from_nsswitch_passwd(struct passwd *pwd, - return NULL; - } - -- dn = backend_build_dn("uid", pwd->pw_name, container_sdn); -- if (dn == NULL) { -+ name = (char *) slapi_utf8StrToLower((unsigned char *) pwd->pw_name); -+ if (name == NULL) { - slapi_log_error(SLAPI_LOG_FATAL, - cbdata->state->plugin_desc->spd_id, - "error building DN for uid=%s,%s skipping\n", -@@ -256,12 +256,22 @@ backend_make_user_entry_from_nsswitch_passwd(struct passwd *pwd, - return NULL; - } - -+ dn = backend_build_dn("uid", name, container_sdn); -+ if (dn == NULL) { -+ slapi_log_error(SLAPI_LOG_FATAL, -+ cbdata->state->plugin_desc->spd_id, -+ "error building DN for uid=%s,%s skipping\n", -+ name, container_sdn); -+ slapi_entry_free(entry); -+ return NULL; -+ } -+ - slapi_entry_add_string(entry, - "objectClass", "top"); - slapi_entry_add_string(entry, - "objectClass", "posixAccount"); - slapi_entry_add_string(entry, -- "uid", pwd->pw_name); -+ "uid", name); - slapi_entry_attr_set_uint(entry, - "uidNumber", pwd->pw_uid); - slapi_entry_attr_set_uint(entry, -@@ -286,6 +296,7 @@ backend_make_user_entry_from_nsswitch_passwd(struct passwd *pwd, - } - - slapi_entry_set_dn(entry, dn); -+ slapi_ch_free_string(&name); - - #ifdef HAVE_SSS_NSS_IDMAP - rc = sss_nss_getsidbyid(pwd->pw_uid, &sid_str, &id_type); -@@ -520,6 +531,7 @@ backend_make_group_entry_from_nsswitch_group(struct group *grp, - Slapi_Entry *entry; - int rc, i; - char *dn = NULL; -+ char *name = NULL; - #ifdef HAVE_SSS_NSS_IDMAP - enum sss_id_type id_type; - char *sid_str; -@@ -551,7 +563,9 @@ backend_make_group_entry_from_nsswitch_group(struct group *grp, - - if (grp->gr_mem) { - for (i=0; grp->gr_mem[i]; i++) { -- slapi_entry_add_string(entry, "memberUid", grp->gr_mem[i]); -+ name = (char *) slapi_utf8StrToLower((unsigned char*) grp->gr_mem[i]); -+ slapi_entry_add_string(entry, "memberUid", name); -+ slapi_ch_free_string(&name); - } - } - --- -2.5.0 - diff --git a/SOURCES/slapi-nis-extmem-0007-slapi-nis-add-support-to-resolve-external-members-of.patch b/SOURCES/slapi-nis-extmem-0007-slapi-nis-add-support-to-resolve-external-members-of.patch deleted file mode 100644 index 6ddaa28..0000000 --- a/SOURCES/slapi-nis-extmem-0007-slapi-nis-add-support-to-resolve-external-members-of.patch +++ /dev/null @@ -1,195 +0,0 @@ -From d1b87904462e890a855ac9d3b68ed02e089450d8 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Wed, 23 Dec 2015 15:04:40 +0200 -Subject: [PATCH 07/12] slapi-nis: add support to resolve external members of - IPA groups - -FreeIPA allows to include external (non-LDAP) members into POSIX groups. -To define external members, an attribute ipaExternalMember is set to -the list of references to external members. Currently both FreeIPA and -SSSD support only references done with SIDs (Security Identifiers) from -the forests trusted by FreeIPA. - -Resolving external members of FreeIPA groups requires resolving SIDs to -user and group names. However, since this resolution is already -implemented by SSSD for the group in question, slapi-nis can use the -fact that there is non-empty ipaExternalMember attribute's value to -trigger lookup of the FreeIPA group via SSSD and then copy over -memberUid attribute value set. - -This logic requires that ipaExternalMember attribute value is present in -the entry to be put into the map cache. Thus, an additional -configuration is needed for the groups container: - -schema-compat-entry-attribute: ipaexternalmember=%deref_r("member","ipaexternalmember") - -Note that resolving external members of IPA groups requires to use -version of slapi-nis that populates the map cache after LDAP server -startup, as SSSD needs to talk back to the LDAP server in the process of -resolving external group members and that is not possible at the time -when slapi-nis plugin starts up as the LDAP server is not yet listenting -for incoming connections at that point. ---- - doc/ipa/sch-ipa.txt | 15 +++++++ - src/back-sch.c | 112 ++++++++++++++++++++++++++++++++++++++++++++++++++++ - 2 files changed, 127 insertions(+) - -diff --git a/doc/ipa/sch-ipa.txt b/doc/ipa/sch-ipa.txt -index 106e6cc..eb6238a 100644 ---- a/doc/ipa/sch-ipa.txt -+++ b/doc/ipa/sch-ipa.txt -@@ -81,6 +81,21 @@ and groups from trusted domains. No additional configuration is needed. - ipa-adtrust-install, however, will not set the minimal numeric id for user or - group. - -+Additionally, group area configuration should include following two attributes to -+allow resolving external members of IPA groups: -+ -+schema-compat-entry-attribute: ipaexternalmember=%deref_r("member","ipaexternalmember") -+schema-compat-entry-attribute: objectclass=ipaexternalgroup -+ -+When 'ipaExternalMember' attribute is present in the group entry generated by -+Schema Compatibility plugin, the plugin will attempt to retrieve the group -+members from SSSD daemon. If group has non-empty list of members, these new -+members will replace the original ones as they will include both IPA and external -+group members. -+ -+SSSD greater than 1.13.3 is required to produce correct behavior due to bug -+https://fedorahosted.org/sssd/ticket/2522 -+ - == Authentication of the trusted domains' users == - - When the Schema Compatibility Plugin is configured to expose users from trusted -diff --git a/src/back-sch.c b/src/back-sch.c -index 98542c5..04fe667 100644 ---- a/src/back-sch.c -+++ b/src/back-sch.c -@@ -419,6 +419,115 @@ backend_set_operational_attributes(Slapi_Entry *e, - } - } - -+#ifdef USE_NSSWITCH -+#define IPA_ATTR_EXTERNAL_MEMBER "ipaExternalMember" -+#define IPA_ATTR_MEMBERUID "memberUid" -+static void -+backend_set_process_external_members(Slapi_PBlock *pb, -+ Slapi_Entry *e, -+ struct plugin_state *state, -+ struct backend_set_data *data) -+{ -+ Slapi_Attr *attr = NULL; -+ Slapi_ValueSet *valueset = NULL; -+ bool_t is_attr_exists, is_group_exists; -+ struct backend_staged_search staged = {0, }; -+ struct backend_search_cbdata cbdata = {0, }; -+ char *plugin_id = state->plugin_desc->spd_id; -+ -+ is_attr_exists = slapi_entry_attr_find(e, IPA_ATTR_EXTERNAL_MEMBER, &attr) == 0; -+ -+ if (!is_attr_exists || attr == NULL) { -+ return; -+ } -+ -+ /* There are external members in this entry, do group lookup via SSSD -+ * and update entry's memberUid attribute */ -+ -+ staged.name = slapi_entry_attr_get_charptr(e, "cn"); -+ staged.type = SCH_NSSWITCH_GROUP; -+ staged.search_members = FALSE; -+ staged.is_id = FALSE; -+ staged.is_sid = FALSE; -+ staged.container_sdn = (char*) slapi_sdn_get_dn(data->container_sdn); -+ staged.entries = NULL; -+ staged.count = 0; -+ cbdata.nsswitch_buffer_len = MAX(16384, MAX(sysconf(_SC_GETPW_R_SIZE_MAX), sysconf(_SC_GETGR_R_SIZE_MAX))); -+ cbdata.nsswitch_buffer = malloc(cbdata.nsswitch_buffer_len); -+ cbdata.state = state; -+ cbdata.staged = &staged; -+ -+ slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, -+ "refreshing group membership for group \"%s\"\n", staged.name); -+ -+ do { -+ /* This group must exist because it exists in the original tree -+ * but as dirsrv was restarted, SSSD might still consider its domain offline. */ -+ is_group_exists = backend_retrieve_from_nsswitch(&staged, &cbdata); -+ if (!is_group_exists) { -+ slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, -+ "group \"%s\" does not exist because SSSD is offline.", -+ staged.name); -+ if (state->ready_to_serve == 0) { -+ /* Only wait for SSSD when we populate the original set */ -+ slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, -+ "waiting for SSSD to become online..."); -+ DS_Sleep(PR_SecondsToInterval(35)); -+ } else { -+ break; -+ } -+ } -+ } while (!is_group_exists); -+ -+ if (staged.entries != NULL && staged.entries[0] != NULL) { -+ attr = NULL; -+ if (slapi_entry_attr_find(staged.entries[0], IPA_ATTR_MEMBERUID, &attr) == 0) { -+#if 0 -+ /* Debug output of original and updated memberUid values */ -+ char **ary1, **ary2; -+ ary1 = slapi_entry_attr_get_charray(e, "memberUid"); -+ ary2 = slapi_entry_attr_get_charray(staged.entries[0], "memberUid"); -+ -+ slapi_log_error(SLAPI_LOG_FATAL, plugin_id, -+ "original group \"%s\":\n", staged.name); -+ for (int i = 0; ary1 && ary1[i] != NULL; ++i) { -+ slapi_log_error(SLAPI_LOG_FATAL, plugin_id, -+ "\t> %s\n", ary1[i]); -+ } -+ slapi_log_error(SLAPI_LOG_FATAL, plugin_id, -+ "new group \"%s\":\n", staged.name); -+ for (int i = 0; ary2 && ary2[i] != NULL; ++i) { -+ slapi_log_error(SLAPI_LOG_FATAL, plugin_id, -+ "\t> %s\n", ary2[i]); -+ } -+ slapi_ch_array_free(ary2); -+ slapi_ch_array_free(ary1); -+#endif -+ -+ (void)slapi_attr_get_valueset(attr, &valueset); -+ -+ if (slapi_entry_attr_find(e, IPA_ATTR_MEMBERUID, &attr) == 0) { -+ (void) slapi_entry_attr_delete(e, IPA_ATTR_MEMBERUID); -+ } -+ (void) slapi_entry_add_valueset(e, IPA_ATTR_MEMBERUID, valueset); -+ slapi_valueset_free(valueset); -+ } else { -+ slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, -+ "group \"%s\" doesn't have memberUid attribute\n", staged.name); -+ } -+ slapi_entry_free(staged.entries[0]); -+ } -+ -+ if (staged.entries != NULL) { -+ free(staged.entries); -+ } -+ -+ (void)slapi_entry_attr_delete(e, IPA_ATTR_EXTERNAL_MEMBER); -+ free(cbdata.nsswitch_buffer); -+ slapi_ch_free_string(&staged.name); -+} -+#endif -+ - /* Given a map-entry directory entry, determine a key, a value, and extra data - * to be stored in the map cache, and add them to the map cache. */ - static void -@@ -613,6 +722,9 @@ backend_set_entry_from(Slapi_PBlock *pb, enum backend_entry_source source, - slapi_entry_add_string(entry, - "objectClass", "extensibleObject"); - } -+#ifdef USE_NSSWITCH -+ backend_set_process_external_members(pb, entry, data->common.state, data); -+#endif - /* Clean up the entry by doing a round trip through the LDIF parser. */ - ldif = slapi_entry2str(entry, &len); - slapi_entry_free(entry); --- -2.5.0 - diff --git a/SOURCES/slapi-nis-extmem-0008-slapi-nis-process-requests-only-when-initialization-.patch b/SOURCES/slapi-nis-extmem-0008-slapi-nis-process-requests-only-when-initialization-.patch deleted file mode 100644 index ec47383..0000000 --- a/SOURCES/slapi-nis-extmem-0008-slapi-nis-process-requests-only-when-initialization-.patch +++ /dev/null @@ -1,150 +0,0 @@ -From 594fcb2320033d01cfe2b8121793d431d1017987 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Fri, 15 Jan 2016 16:39:12 +0200 -Subject: [PATCH 08/12] slapi-nis: process requests only when initialization - completed - -Initializing map cache may take time. Skip slapi-nis lookups untli -the map cache is ready. ---- - src/back-sch.c | 23 ++++++++++++++++++++++- - src/back-shr.c | 20 ++++++++++++++++++++ - src/plugin.h | 1 + - 3 files changed, 43 insertions(+), 1 deletion(-) - -diff --git a/src/back-sch.c b/src/back-sch.c -index 04fe667..871734c 100644 ---- a/src/back-sch.c -+++ b/src/back-sch.c -@@ -1609,7 +1609,7 @@ backend_search_cb(Slapi_PBlock *pb) - { - struct backend_search_cbdata cbdata; - struct backend_staged_search *staged, *next; -- int i; -+ int i, isroot; - - if (wrap_get_call_level() > 0) { - return 0; -@@ -1621,6 +1621,19 @@ backend_search_cb(Slapi_PBlock *pb) - /* The plugin was not actually started. */ - return 0; - } -+ if (cbdata.state->ready_to_serve == 0) { -+ /* No data to serve yet */ -+ return 0; -+ } -+ -+ slapi_pblock_get(pb, SLAPI_REQUESTOR_ISROOT, &isroot); -+ -+ if (slapi_op_internal(pb) || (slapi_is_ldapi_conn(pb) && isroot)) { -+ /* The plugin should not engage in internal searches of other -+ * plugins or ldapi+cn=DM */ -+ return 0; -+ } -+ - slapi_pblock_get(pb, SLAPI_SEARCH_TARGET, &cbdata.target); - slapi_pblock_get(pb, SLAPI_SEARCH_SCOPE, &cbdata.scope); - slapi_pblock_get(pb, SLAPI_SEARCH_SIZELIMIT, &cbdata.sizelimit); -@@ -2018,6 +2031,10 @@ backend_write_cb(Slapi_PBlock *pb, struct plugin_state *state) - if (wrap_get_call_level() > 0) { - return 0; - } -+ if (state->ready_to_serve == 0) { -+ /* No data to serve yet */ -+ return 0; -+ } - - wrap_inc_call_level(); - if (map_rdlock() == 0) { -@@ -2125,6 +2142,10 @@ backend_bind_cb(Slapi_PBlock *pb) - } - - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); -+ if (state->ready_to_serve == 0) { -+ /* No data to serve yet */ -+ return 0; -+ } - /* The code below handles three separate facts: - * 1. For NSSWITCH-discovered users PAM is responsible for authentication. - * We want to run PAM auth without any slapi-nis lock taken to avoid -diff --git a/src/back-shr.c b/src/back-shr.c -index 36ecc0b..131365d 100644 ---- a/src/back-shr.c -+++ b/src/back-shr.c -@@ -725,6 +725,8 @@ done_with_lock: - if (cbdata) { - slapi_ch_free((void**)&cbdata); - } -+ -+ PR_AtomicSet(&state->ready_to_serve, 1); - } - - static void -@@ -769,6 +771,7 @@ backend_shr_startup(struct plugin_state *state, - return; - } - -+ PR_AtomicSet(&state->ready_to_serve, 0); - cbdata->state = state; - cbdata->parent_pb = parent_pb; - cbdata->filter = filter; -@@ -1798,6 +1801,11 @@ backend_shr_add_cb(Slapi_PBlock *pb) - /* The plugin was not actually started. */ - return 0; - } -+ if (cbdata.state->ready_to_serve == 0) { -+ /* No data yet, ignore */ -+ return 0; -+ } -+ - slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e); - slapi_pblock_get(pb, SLAPI_ADD_TARGET, &dn); - slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &rc); -@@ -2208,6 +2216,10 @@ backend_shr_modify_cb(Slapi_PBlock *pb) - /* The plugin was not actually started. */ - return 0; - } -+ if (cbdata.state->ready_to_serve == 0) { -+ /* No data yet, ignore */ -+ return 0; -+ } - slapi_pblock_get(pb, SLAPI_MODIFY_TARGET, &dn); - slapi_pblock_get(pb, SLAPI_MODIFY_MODS, &cbdata.mods); - slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e_pre); -@@ -2410,6 +2422,10 @@ backend_shr_modrdn_cb(Slapi_PBlock *pb) - /* The plugin was not actually started. */ - return 0; - } -+ if (cbdata.state->ready_to_serve == 0) { -+ /* No data yet, ignore */ -+ return 0; -+ } - slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e_pre); - slapi_pblock_get(pb, SLAPI_ENTRY_POST_OP, &cbdata.e_post); - -@@ -2549,6 +2565,10 @@ backend_shr_delete_cb(Slapi_PBlock *pb) - /* The plugin was not actually started. */ - return 0; - } -+ if (cbdata.state->ready_to_serve == 0) { -+ /* No data yet, ignore */ -+ return 0; -+ } - slapi_pblock_get(pb, SLAPI_ENTRY_PRE_OP, &cbdata.e); - slapi_pblock_get(pb, SLAPI_DELETE_TARGET, &dn); - slapi_pblock_get(pb, SLAPI_PLUGIN_OPRETURN, &rc); -diff --git a/src/plugin.h b/src/plugin.h -index 429e291..7a89ac7 100644 ---- a/src/plugin.h -+++ b/src/plugin.h -@@ -33,6 +33,7 @@ struct plugin_state { - Slapi_ComponentId *plugin_identity; - Slapi_PluginDesc *plugin_desc; - unsigned int use_be_txns: 1; -+ PRInt32 ready_to_serve; - - /* NIS-specific data. */ - struct wrapped_thread *tid; --- -2.5.0 - diff --git a/SOURCES/slapi-nis-extmem-0009-slapi-nis-serialize-map-cache-initialization.patch b/SOURCES/slapi-nis-extmem-0009-slapi-nis-serialize-map-cache-initialization.patch deleted file mode 100644 index 85544b9..0000000 --- a/SOURCES/slapi-nis-extmem-0009-slapi-nis-serialize-map-cache-initialization.patch +++ /dev/null @@ -1,105 +0,0 @@ -From 3aaf4941fc17df388c43776eda6d41f62017a143 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Fri, 15 Jan 2016 17:17:23 +0200 -Subject: [PATCH 09/12] slapi-nis: serialize map cache initialization - -Serialize process of initiliazing map cache to avoid locking the -directory server backends. ---- - src/back-shr.c | 55 +++++++++++++++++++++++++++++++++++++------------------ - 1 file changed, 37 insertions(+), 18 deletions(-) - -diff --git a/src/back-shr.c b/src/back-shr.c -index 131365d..0157582 100644 ---- a/src/back-shr.c -+++ b/src/back-shr.c -@@ -678,49 +678,68 @@ backend_shr_data_initialize_thread_cb(void *arg) - struct backend_shr_data_init_cbdata *cbdata = (struct backend_shr_data_init_cbdata *)arg; - Slapi_PBlock *pb = NULL; - struct backend_set_config_entry_add_cbdata set_cbdata; -- int result = 0; -+ int result = 0, i = 0; -+ Slapi_Entry **entries = NULL; -+ struct plugin_state *state = NULL; -+ - if (cbdata == NULL) { - return; - } - -+ state = cbdata->state; -+ - /* Scan may require consulting SSSD for external identities - * therefore, we need to make sure the scan starts after ns-slapd - * started to serve LDAP clients. There is no a signal for this, - * so we just wait some time. */ - DS_Sleep(PR_SecondsToInterval(PLUGIN_SCAN_DELAY)); - -- backend_update_params(cbdata->parent_pb, cbdata->state); -+ backend_update_params(cbdata->parent_pb, state); - - slapi_log_error(SLAPI_LOG_PLUGIN, -- cbdata->state->plugin_desc->spd_id, -+ state->plugin_desc->spd_id, - "searching under \"%s\" for configuration\n", -- cbdata->state->plugin_base); -+ state->plugin_base); - pb = wrap_pblock_new(cbdata->parent_pb); - slapi_search_internal_set_pb(pb, -- cbdata->state->plugin_base, -+ state->plugin_base, - LDAP_SCOPE_ONELEVEL, - cbdata->filter, - NULL, FALSE, - NULL, - NULL, -- cbdata->state->plugin_identity, -+ state->plugin_identity, - 0); -- if (map_wrlock() != 0) { -- slapi_log_error(SLAPI_LOG_PLUGIN, -- cbdata->state->plugin_desc->spd_id, -+ wrap_inc_call_level(); -+ set_cbdata.state = state; -+ set_cbdata.pb = pb; -+ -+ /* Do a search and collect found entries to avoid locking the backends */ -+ if (slapi_search_internal_pb(pb) == 0) { -+ if (map_wrlock() != 0) { -+ slapi_log_error(SLAPI_LOG_PLUGIN, -+ state->plugin_desc->spd_id, - "failed to search under \"%s\" for " - "configuration: failed to acquire a lock\n", -- cbdata->state->plugin_base); -- goto done_with_lock; -+ state->plugin_base); -+ goto done_with_lock; -+ } -+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_RESULT, &result); -+ if (result == 0) { -+ slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); -+ for (i = 0; entries[i] != NULL; i++) { -+ backend_set_config_entry_add_cb(entries[i], &set_cbdata); -+ } -+ } -+ map_unlock(); -+ slapi_free_search_results_internal(pb); - } -- set_cbdata.state = cbdata->state; -- set_cbdata.pb = pb; -- slapi_search_internal_callback_pb(pb, &set_cbdata, -- NULL, -- backend_set_config_entry_add_cb, -- NULL); -- map_unlock(); -+ slapi_log_error(SLAPI_LOG_FATAL, -+ state->plugin_desc->spd_id, -+ "Finished plugin initialization.\n"); -+ - done_with_lock: -+ wrap_dec_call_level(); - slapi_pblock_destroy(pb); - if (cbdata) { - slapi_ch_free((void**)&cbdata); --- -2.5.0 - diff --git a/SOURCES/slapi-nis-extmem-0010-nis-lock-out-accounts-if-nsAccountLock-is-TRUE.patch b/SOURCES/slapi-nis-extmem-0010-nis-lock-out-accounts-if-nsAccountLock-is-TRUE.patch deleted file mode 100644 index 0c125c3..0000000 --- a/SOURCES/slapi-nis-extmem-0010-nis-lock-out-accounts-if-nsAccountLock-is-TRUE.patch +++ /dev/null @@ -1,80 +0,0 @@ -From 5eaad9c4c218d9a59f6930a29f5bee54235c4fab Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Tue, 19 Jan 2016 07:37:46 +0200 -Subject: [PATCH 10/12] nis: lock out accounts if nsAccountLock is TRUE - -Add a rule that adds two bang characters in front of the password. - -When the password algorithm is defined as CRYPT and NIS is used to -authenticate users on other systems, there is no way to disable or lock -accounts. Traditional convention has been to put two bang (exclamation) -characters in front of the password, creating an impossible password -hash. This effectively locks the user account, preventing -authentication. - -All UNIX systems agree that for encrypted passwords presence of a -character which cannot be part of CRYPT password scheme renders -impossible to login to system with such password. However, not all -systems have meaning of locked accounts and even how these locked -accounts express themselves. - -There is certain controversy in what could be used to indicate locked -accounts: - - GNU/Linux systems expect '!' as first character of the password field - - FreeBSD expects '*LOCKED*' string at start of the password field - - Various Solaris versions expect '*LOCK*' string at start of the - password field - - NetBSD has no meaning of locked passwords via content of password field - -Given that it is impossible to serve NIS maps with encrypted passwords -in a different way to different clients, standardize on '!!' scheme as -traditional among UNIX administrators. - -Bug: https://bugzilla.redhat.com/show_bug.cgi?id=1298478 ---- - src/defs-nis.c | 10 +++++----- - 1 file changed, 5 insertions(+), 5 deletions(-) - -diff --git a/src/defs-nis.c b/src/defs-nis.c -index 3d2b9e9..ad0e7dc 100644 ---- a/src/defs-nis.c -+++ b/src/defs-nis.c -@@ -52,17 +52,17 @@ static struct configuration { - {"passwd.byname", config_exact, FALSE, NULL, - "(objectClass=posixAccount)", - "%{uid}", NULL, -- "%{uid}:%ifeq(\"objectClass\",\"shadowAccount\",\"x\",\"%regsubi(\\\"%{userPassword}\\\",\\\"^\\\\\\\\{CRYPT\\\\\\\\}(..*)\\\",\\\"%1\\\",\\\"*\\\")\"):%regmatch(\"%{uidNumber}\",\"[0-9]+\"):%regmatch(\"%{gidNumber}\",\"[0-9]+\"):%{gecos:-%{cn:-}}:%{homeDirectory:-/}:%{loginShell:-" _PATH_BSHELL "}", NULL, -+ "%{uid}:%ifeq(\"nsAccountLock\",\"TRUE\",\"!!\",\"\")%ifeq(\"objectClass\",\"shadowAccount\",\"x\",\"%regsubi(\\\"%{userPassword}\\\",\\\"^\\\\\\\\{CRYPT\\\\\\\\}(..*)\\\",\\\"%1\\\",\\\"*\\\")\"):%regmatch(\"%{uidNumber}\",\"[0-9]+\"):%regmatch(\"%{gidNumber}\",\"[0-9]+\"):%{gecos:-%{cn:-}}:%{homeDirectory:-/}:%{loginShell:-" _PATH_BSHELL "}", NULL, - ":\r\n"}, - {"passwd.byuid", config_exact, FALSE, NULL, - "(objectClass=posixAccount)", - "%{uidNumber}", NULL, -- "%{uid}:%ifeq(\"objectClass\",\"shadowAccount\",\"x\",\"%regsubi(\\\"%{userPassword}\\\",\\\"^\\\\\\\\{CRYPT\\\\\\\\}(..*)\\\",\\\"%1\\\",\\\"*\\\")\"):%regmatch(\"%{uidNumber}\",\"[0-9]+\"):%regmatch(\"%{gidNumber}\",\"[0-9]+\"):%{gecos:-%{cn:-}}:%{homeDirectory:-/}:%{loginShell:-" _PATH_BSHELL "}", NULL, -+ "%{uid}:%ifeq(\"nsAccountLock\",\"TRUE\",\"!!\",\"\")%ifeq(\"objectClass\",\"shadowAccount\",\"x\",\"%regsubi(\\\"%{userPassword}\\\",\\\"^\\\\\\\\{CRYPT\\\\\\\\}(..*)\\\",\\\"%1\\\",\\\"*\\\")\"):%regmatch(\"%{uidNumber}\",\"[0-9]+\"):%regmatch(\"%{gidNumber}\",\"[0-9]+\"):%{gecos:-%{cn:-}}:%{homeDirectory:-/}:%{loginShell:-" _PATH_BSHELL "}", NULL, - ":\r\n"}, - {"shadow.byname", config_exact, TRUE, NULL, - "(objectClass=shadowAccount)", - "%{uid}", NULL, -- "%{uid}:%regsubi(\"%{userPassword}\",\"^\\\\{CRYPT\\\\}(..*)\",\"%1\",\"*\"):%{shadowLastChange:-}:%{shadowMin:-}:%{shadowMax:-}:%{shadowWarning:-}:%{shadowInactive:-}:%{shadowExpire:-}:%{shadowFlag:-}", NULL, -+ "%{uid}:%ifeq(\"nsAccountLock\",\"TRUE\",\"!!\",\"\")%regsubi(\"%{userPassword}\",\"^\\\\{CRYPT\\\\}(..*)\",\"%1\",\"*\"):%{shadowLastChange:-}:%{shadowMin:-}:%{shadowMax:-}:%{shadowWarning:-}:%{shadowInactive:-}:%{shadowExpire:-}:%{shadowFlag:-}", NULL, - ":\r\n"}, - {"passwd.adjunct.byname", config_exact, TRUE, NULL, - "(objectClass=shadowAccount)", -@@ -72,12 +72,12 @@ static struct configuration { - {"group.byname", config_exact, FALSE, NULL, - "(objectClass=posixGroup)", - "%{cn}", NULL, -- "%{cn}:%regsubi(\"%{userPassword}\",\"^\\\\{CRYPT\\\\}(..*)\",\"%1\",\"*\"):%regmatch(\"%{gidNumber}\",\"[0-9]+\"):%merge(\",\",\"%{memberUid}\",\"%deref_r(\\\"member\\\",\\\"uid\\\")\",\"%deref_r(\\\"uniqueMember\\\",\\\"uid\\\")\")", NULL, -+ "%{cn}:%ifeq(\"nsAccountLock\",\"TRUE\",\"!!\",\"\")%regsubi(\"%{userPassword}\",\"^\\\\{CRYPT\\\\}(..*)\",\"%1\",\"*\"):%regmatch(\"%{gidNumber}\",\"[0-9]+\"):%merge(\",\",\"%{memberUid}\",\"%deref_r(\\\"member\\\",\\\"uid\\\")\",\"%deref_r(\\\"uniqueMember\\\",\\\"uid\\\")\")", NULL, - ":,\r\n"}, - {"group.bygid", config_exact, FALSE, NULL, - "(objectClass=posixGroup)", - "%{gidNumber}", NULL, -- "%{cn}:%regsubi(\"%{userPassword}\",\"^\\\\{CRYPT\\\\}(..*)\",\"%1\",\"*\"):%{gidNumber}:%merge(\",\",\"%{memberUid}\",\"%deref_r(\\\"member\\\",\\\"uid\\\")\",\"%deref_r(\\\"uniqueMember\\\",\\\"uid\\\")\")", NULL, -+ "%{cn}:%ifeq(\"nsAccountLock\",\"TRUE\",\"!!\",\"\")%regsubi(\"%{userPassword}\",\"^\\\\{CRYPT\\\\}(..*)\",\"%1\",\"*\"):%{gidNumber}:%merge(\",\",\"%{memberUid}\",\"%deref_r(\\\"member\\\",\\\"uid\\\")\",\"%deref_r(\\\"uniqueMember\\\",\\\"uid\\\")\")", NULL, - ":,\r\n"}, - {"netgroup", config_exact, FALSE, NULL, - "(objectClass=nisNetgroup)", --- -2.5.0 - diff --git a/SOURCES/slapi-nis-extmem-0011-idviews-bind-with-original-DN-if-ID-view-does-not-ov.patch b/SOURCES/slapi-nis-extmem-0011-idviews-bind-with-original-DN-if-ID-view-does-not-ov.patch deleted file mode 100644 index 302beba..0000000 --- a/SOURCES/slapi-nis-extmem-0011-idviews-bind-with-original-DN-if-ID-view-does-not-ov.patch +++ /dev/null @@ -1,117 +0,0 @@ -From 00468e8eebd455ab4e41d4d86772fb5f8a745d0a Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Thu, 21 Jan 2016 19:16:30 +0200 -Subject: [PATCH 11/12] idviews: bind with original DN if ID view does not - override uid attribute - -With ID Views in FreeIPA one can override different kinds of attributes, -including the uid. When uid attribute is overriden, LDAP BINDs with -DNs using new (overridden) uid are properly modified to reference the -original (non-overridden) object. - -However, when uid attribute is not overridden, slapi-nis did mistakenly -avoided to build a reference to the original object without ID view. -This resulted in inability to do LDAP BIND as overriden DN with original -uid attribute. - -Fix the issue by always processing a DN after removing ID view reference -from it, whether RDN value (uid) was replaced or not. - -Fixes https://bugzilla.redhat.com/show_bug.cgi?id=1301300 ---- - src/back-sch-idview.c | 4 ++-- - src/back-sch.c | 24 ++++++++++++------------ - 2 files changed, 14 insertions(+), 14 deletions(-) - -diff --git a/src/back-sch-idview.c b/src/back-sch-idview.c -index 8ffab91..8842906 100644 ---- a/src/back-sch-idview.c -+++ b/src/back-sch-idview.c -@@ -311,7 +311,7 @@ idview_replace_bval_by_override(const char *bval_usage, const char *attr_name, - } - - attr_val = slapi_value_new_berval(bval); -- slapi_log_error(SLAPI_LOG_FATAL, cbdata->state->plugin_desc->spd_id, -+ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id, - "Searching for an override of the %s %s with %s=%*s from the overrides\n.", - bval_usage, attr_name, attr_name, (int) bval->bv_len, bval->bv_val); - -@@ -347,7 +347,7 @@ idview_replace_bval_by_override(const char *bval_usage, const char *attr_name, - slapi_ber_bvdone(bval); - slapi_ber_bvcpy(bval, slapi_value_get_berval(anchor_val)); - anchor_override_found = TRUE; -- slapi_log_error(SLAPI_LOG_FATAL, cbdata->state->plugin_desc->spd_id, -+ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id, - "Overriding the %s %s with %s=%*s from the override %s\n.", - bval_usage, attr_name, IPA_IDVIEWS_ATTR_ANCHORUUID, - (int) bval->bv_len, bval->bv_val, -diff --git a/src/back-sch.c b/src/back-sch.c -index 871734c..9a0e96b 100644 ---- a/src/back-sch.c -+++ b/src/back-sch.c -@@ -465,13 +465,13 @@ backend_set_process_external_members(Slapi_PBlock *pb, - * but as dirsrv was restarted, SSSD might still consider its domain offline. */ - is_group_exists = backend_retrieve_from_nsswitch(&staged, &cbdata); - if (!is_group_exists) { -- slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, -- "group \"%s\" does not exist because SSSD is offline.", -+ slapi_log_error(SLAPI_LOG_FATAL, plugin_id, -+ "group \"%s\" does not exist because SSSD is offline.\n", - staged.name); - if (state->ready_to_serve == 0) { - /* Only wait for SSSD when we populate the original set */ -- slapi_log_error(SLAPI_LOG_PLUGIN, plugin_id, -- "waiting for SSSD to become online..."); -+ slapi_log_error(SLAPI_LOG_FATAL, plugin_id, -+ "waiting for SSSD to become online...\n"); - DS_Sleep(PR_SecondsToInterval(35)); - } else { - break; -@@ -1609,15 +1609,15 @@ backend_search_cb(Slapi_PBlock *pb) - { - struct backend_search_cbdata cbdata; - struct backend_staged_search *staged, *next; -- int i, isroot; -+ int i, isroot, ret; - - if (wrap_get_call_level() > 0) { - return 0; - } - memset(&cbdata, 0, sizeof(cbdata)); - cbdata.pb = pb; -- slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); -- if (cbdata.state->plugin_base == NULL) { -+ ret = slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); -+ if ((ret == -1) || (cbdata.state->plugin_base == NULL)) { - /* The plugin was not actually started. */ - return 0; - } -@@ -1626,9 +1626,9 @@ backend_search_cb(Slapi_PBlock *pb) - return 0; - } - -- slapi_pblock_get(pb, SLAPI_REQUESTOR_ISROOT, &isroot); -+ ret = slapi_pblock_get(pb, SLAPI_REQUESTOR_ISROOT, &isroot); - -- if (slapi_op_internal(pb) || (slapi_is_ldapi_conn(pb) && isroot)) { -+ if ((ret == -1) || (slapi_op_internal(pb) || (slapi_is_ldapi_conn(pb) && isroot))) { - /* The plugin should not engage in internal searches of other - * plugins or ldapi+cn=DM */ - return 0; -@@ -1959,10 +1959,10 @@ backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char ** - if (res == 1) { - slapi_rdn_remove_index(rdn, 1); - slapi_rdn_add(rdn, "uid", bval.bv_val); -- slapi_sdn_free(&cbdata.target_dn); -- cbdata.target_dn = slapi_sdn_set_rdn(scbdata.target_dn, rdn); -- map_data_foreach_map(cbdata.state, NULL, backend_locate_cb, &cbdata); - } -+ slapi_sdn_free(&cbdata.target_dn); -+ cbdata.target_dn = slapi_sdn_set_rdn(scbdata.target_dn, rdn); -+ map_data_foreach_map(cbdata.state, NULL, backend_locate_cb, &cbdata); - slapi_ber_bvdone(&bval); - slapi_rdn_free(&rdn); - idview_free_overrides(&scbdata); --- -2.5.0 - diff --git a/SOURCES/slapi-nis-fix-processing-of-ID-views.patch b/SOURCES/slapi-nis-fix-processing-of-ID-views.patch deleted file mode 100644 index bd8a3df..0000000 --- a/SOURCES/slapi-nis-fix-processing-of-ID-views.patch +++ /dev/null @@ -1,92 +0,0 @@ -From ef773387ede9dc90388fdbc423ceada99aa78e67 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Tue, 3 Nov 2015 14:42:05 +0200 -Subject: [PATCH 2/2] slapi-nis: fix processing of ID views - -- ID View processing should only happen if ID view is defined -- When finding attribute with slapi_entry_attr_find() use correct return - code (slapi_entry_attr_exists() returns 1, _find() returns 0) -- cn=,cn=views,cn=compat,$SUFFIX lookup is fixed - -Resolves: rhbz#1277576, rhbz#1265465 - -https://bugzilla.redhat.com/show_bug.cgi?id=1277576 -https://bugzilla.redhat.com/show_bug.cgi?id=1265465 ---- - src/back-sch-idview.c | 2 +- - src/back-sch.c | 32 ++++++++++++++++++++++++-------- - 2 files changed, 25 insertions(+), 9 deletions(-) - -diff --git a/src/back-sch-idview.c b/src/back-sch-idview.c -index 93fbab5..8ffab91 100644 ---- a/src/back-sch-idview.c -+++ b/src/back-sch-idview.c -@@ -175,7 +175,7 @@ idview_process_overrides(struct backend_search_cbdata *cbdata, - /* Replace the attribute's value with the override or - * add an override value if the attribute didn't exist */ - result = slapi_entry_attr_find(entry, override_type, &sattr); -- if (result == 1) { -+ if (result == 0) { - result = slapi_entry_attr_delete(entry, override_type); - } - result = slapi_attr_get_valueset(override_attr, &override_valueset); -diff --git a/src/back-sch.c b/src/back-sch.c -index b2362d0..98542c5 100644 ---- a/src/back-sch.c -+++ b/src/back-sch.c -@@ -1043,17 +1043,21 @@ backend_search_entry_cb(const char *domain, const char *map, bool_t secure, - slapi_sdn_get_ndn(sdn)); - entry = entry_data->e; - #ifdef USE_IPA_IDVIEWS -- entry = slapi_entry_dup(entry_data->e); - if (cbdata->idview != NULL) { -- idview_process_overrides(cbdata, key, map, domain, entry); -- } -+ entry = slapi_entry_dup(entry_data->e); -+ if (entry != NULL) { -+ idview_process_overrides(cbdata, key, map, domain, entry); - -- /* slapi_entry_attr_exists() was introduced only in https://fedorahosted.org/389/ticket/47710 */ -- is_attr_exists = slapi_entry_attr_find(entry, IPA_IDVIEWS_ATTR_ANCHORUUID, &attr) == 0; -+ /* slapi_entry_attr_exists() was introduced only in https://fedorahosted.org/389/ticket/47710 */ -+ is_attr_exists = slapi_entry_attr_find(entry, IPA_IDVIEWS_ATTR_ANCHORUUID, &attr) == 0; - -- if (is_attr_exists == TRUE) { -- slapi_entry_attr_delete(entry, IPA_IDVIEWS_ATTR_ANCHORUUID); -- slapi_entry_delete_string(entry, "objectClass", "ipaOverrideTarget"); -+ if (is_attr_exists == TRUE) { -+ slapi_entry_attr_delete(entry, IPA_IDVIEWS_ATTR_ANCHORUUID); -+ slapi_entry_delete_string(entry, "objectClass", "ipaOverrideTarget"); -+ } -+ } else { -+ entry = entry_data->e; -+ } - } - #endif - backend_entries_to_return_push(cbdata, entry); -@@ -1203,10 +1207,22 @@ static bool_t - backend_search_find_set_dn_cb(const char *group, void *cb_data) - { - struct backend_search_cbdata *cbdata; -+ Slapi_DN *group_dn; - - cbdata = cb_data; -+ -+ /* Check the group itself. */ -+ group_dn = slapi_sdn_new_dn_byval(group); -+ if (slapi_sdn_scope_test(group_dn, cbdata->target_dn, -+ cbdata->scope) == 1) { -+ cbdata->answer = TRUE; -+ slapi_sdn_free(&group_dn); -+ return TRUE; -+ } -+ - map_data_foreach_map(cbdata->state, group, - backend_search_find_set_dn_in_group_cb, cb_data); -+ slapi_sdn_free(&group_dn); - return TRUE; - } - --- -2.5.0 - diff --git a/SOURCES/slapi-nis-nss-Make-sure-default-buffer-for-nsswitch-operations-is-.patch b/SOURCES/slapi-nis-nss-Make-sure-default-buffer-for-nsswitch-operations-is-.patch deleted file mode 100644 index 26f8579..0000000 --- a/SOURCES/slapi-nis-nss-Make-sure-default-buffer-for-nsswitch-operations-is-.patch +++ /dev/null @@ -1,32 +0,0 @@ -From 92c4f4942547730efdca83501d130906eb07aeb0 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Wed, 25 Feb 2015 10:08:39 +0200 -Subject: [PATCH 3/3] Make sure default buffer for nsswitch operations is big - enough - -By default initial buffer sizes for getgrent/getgrnam/... functions -are way small for large groups in Active Directory so make sure -we have something reasonable for groups with hundreds or thousands members. ---- - src/back-sch.c | 5 +---- - 1 file changed, 1 insertion(+), 4 deletions(-) - -diff --git a/src/back-sch.c b/src/back-sch.c -index 2388d2f..a4ae016 100644 ---- a/src/back-sch.c -+++ b/src/back-sch.c -@@ -1443,10 +1443,7 @@ backend_search_cb(Slapi_PBlock *pb) - /* If during search of some sets we staged additional lookups, perform them. */ - if (cbdata.staged != NULL) { - /* Allocate buffer to be used for getpwnam_r/getgrnam_r requests */ -- cbdata.nsswitch_buffer_len = MAX(sysconf(_SC_GETPW_R_SIZE_MAX), sysconf(_SC_GETGR_R_SIZE_MAX)); -- if (cbdata.nsswitch_buffer_len == -1) { -- cbdata.nsswitch_buffer_len = 16384; -- } -+ cbdata.nsswitch_buffer_len = MAX(16384, MAX(sysconf(_SC_GETPW_R_SIZE_MAX), sysconf(_SC_GETGR_R_SIZE_MAX))); - cbdata.nsswitch_buffer = malloc(cbdata.nsswitch_buffer_len); - /* Go over the list of staged requests and retrieve entries. - * It is important to perform the retrieval *without* holding any locks to the map cache */ --- -2.1.0 - diff --git a/SOURCES/slapi-nis-nss-make-sure-to-remember-the-length-of-reallocated.patch b/SOURCES/slapi-nis-nss-make-sure-to-remember-the-length-of-reallocated.patch deleted file mode 100644 index b63ec75..0000000 --- a/SOURCES/slapi-nis-nss-make-sure-to-remember-the-length-of-reallocated.patch +++ /dev/null @@ -1,49 +0,0 @@ -From af63a29f8689f8649e70d963462a03485f9f30f5 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Tue, 24 Feb 2015 13:18:34 +0200 -Subject: [PATCH 2/2] nss: make sure to remember the length of reallocated - buffer - ---- - src/back-sch-nss.c | 4 ++++ - 1 file changed, 4 insertions(+) - -diff --git a/src/back-sch-nss.c b/src/back-sch-nss.c -index 3a21ff6..f8177d7 100644 ---- a/src/back-sch-nss.c -+++ b/src/back-sch-nss.c -@@ -484,6 +484,7 @@ repeat: - buf = realloc(cbdata->nsswitch_buffer, cbdata->nsswitch_buffer_len * 2); - if (buf != NULL) { - cbdata->nsswitch_buffer = buf; -+ cbdata->nsswitch_buffer_len *= 2; - goto repeat; - } - } -@@ -613,6 +614,7 @@ repeat: - buf = realloc(cbdata->nsswitch_buffer, cbdata->nsswitch_buffer_len * 2); - if (buf != NULL) { - cbdata->nsswitch_buffer = buf; -+ cbdata->nsswitch_buffer_len *= 2; - goto repeat; - } - } -@@ -668,6 +670,7 @@ repeat: - buf = realloc(cbdata->nsswitch_buffer, cbdata->nsswitch_buffer_len * 2); - if (buf != NULL) { - cbdata->nsswitch_buffer = buf; -+ cbdata->nsswitch_buffer_len *= 2; - goto repeat; - } - } -@@ -718,6 +721,7 @@ repeat: - buf = realloc(cbdata->nsswitch_buffer, cbdata->nsswitch_buffer_len * 2); - if (buf != NULL) { - cbdata->nsswitch_buffer = buf; -+ cbdata->nsswitch_buffer_len *= 2; - goto repeat; - } - } --- -2.1.0 - diff --git a/SOURCES/slapi-nis-priming-0001-wrap-add-wrapped-mutex-support.patch b/SOURCES/slapi-nis-priming-0001-wrap-add-wrapped-mutex-support.patch deleted file mode 100644 index 2b5f6fc..0000000 --- a/SOURCES/slapi-nis-priming-0001-wrap-add-wrapped-mutex-support.patch +++ /dev/null @@ -1,145 +0,0 @@ -From 43ea9a5c6cf7f2022f1e586bb4514564fd7826cb Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Tue, 26 Apr 2016 12:44:56 +0300 -Subject: [PATCH 1/4] wrap: add wrapped mutex support - ---- - src/wrap.c | 90 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++ - src/wrap.h | 6 +++++ - 2 files changed, 96 insertions(+) - -diff --git a/src/wrap.c b/src/wrap.c -index c89638f..f8056a4 100644 ---- a/src/wrap.c -+++ b/src/wrap.c -@@ -79,6 +79,18 @@ struct wrapped_rwlock { - #endif - }; - -+struct wrapped_mutex { -+#if defined(USE_SLAPI_LOCKS) -+ Slapi_Mutex *mutex; -+#elif defined(USE_PTHREAD_LOCKS) -+ pthread_mutex_t mutex; -+#elif defined(USE_NSPR_LOCKS) -+ PRLock *mutex; -+#else -+#error "Unknown thread-safe locking model!" -+#endif -+}; -+ - #ifdef USE_NSPR_THREADS - static void - wrap_pthread_starter(void *p) -@@ -169,6 +181,84 @@ wrap_thread_stopfd(struct wrapped_thread *t) - return ret; - } - -+struct wrapped_mutex * -+wrap_new_mutex(void) -+{ -+ struct wrapped_mutex *mutex; -+ mutex = malloc(sizeof(*mutex)); -+ if (mutex == NULL) { -+ return NULL; -+ } -+#ifdef USE_SLAPI_LOCKS -+ mutex->mutex = slapi_new_mutex(); -+ if (mutex->mutex == NULL) { -+ free(mutex); -+ return NULL; -+ } -+#endif -+#ifdef USE_PTHREAD_LOCKS -+ if (pthread_mutex_init(&mutex->mutex, NULL) != 0) { -+ free(mutex); -+ return NULL; -+ } -+#endif -+#ifdef USE_NSPR_LOCKS -+ mutex->mutex = PR_NewLock(); -+ if (mutex->mutex == NULL) { -+ free(mutex); -+ return NULL; -+ } -+#endif -+ return mutex; -+} -+ -+void -+wrap_free_mutex(struct wrapped_mutex *mutex) -+{ -+#ifdef USE_SLAPI_LOCKS -+ slapi_destroy_mutex(mutex->mutex); -+#endif -+#ifdef USE_PTHREAD_LOCKS -+ pthread_mutex_destroy(&mutex->mutex); -+#endif -+#ifdef USE_NSPR_LOCKS -+ PR_DestroyLock(mutex->mutex); -+#endif -+ free(mutex); -+} -+ -+int -+wrap_mutex_lock(struct wrapped_mutex *mutex) -+{ -+#ifdef USE_SLAPI_LOCKS -+ slapi_lock_mutex(mutex->mutex); -+ return 0; -+#endif -+#ifdef USE_PTHREAD_LOCKS -+ return pthread_mutex_lock(&mutex->mutex); -+#endif -+#ifdef USE_NSPR_LOCKS -+ PR_Lock(mutex->mutex); -+ return 0; -+#endif -+} -+ -+int -+wrap_mutex_unlock(struct wrapped_mutex *mutex) -+{ -+#ifdef USE_SLAPI_LOCKS -+ return slapi_unlock_mutex(mutex->mutex); -+#endif -+#ifdef USE_PTHREAD_LOCKS -+ return pthread_mutex_unlock(&mutex->mutex); -+#endif -+#ifdef USE_NSPR_LOCKS -+ PR_Unlock(mutex->mutex); -+ return 0; -+#endif -+} -+ -+ - struct wrapped_rwlock * - wrap_new_rwlock(void) - { -diff --git a/src/wrap.h b/src/wrap.h -index 71bd326..2b797f7 100644 ---- a/src/wrap.h -+++ b/src/wrap.h -@@ -23,6 +23,7 @@ - #define wrap_h - - struct wrapped_thread; -+struct wrapped_mutex; - struct wrapped_rwlock; - - struct wrapped_thread * wrap_start_thread(void * (*fn)(struct wrapped_thread *), -@@ -31,6 +32,11 @@ void *wrap_stop_thread(struct wrapped_thread *t); - void *wrap_thread_arg(struct wrapped_thread *t); - int wrap_thread_stopfd(struct wrapped_thread *t); - -+struct wrapped_mutex *wrap_new_mutex(void); -+void wrap_free_mutex(struct wrapped_mutex *mutex); -+int wrap_mutex_lock(struct wrapped_mutex *mutex); -+int wrap_mutex_unlock(struct wrapped_mutex *mutex); -+ - struct wrapped_rwlock *wrap_new_rwlock(void); - void wrap_free_rwlock(struct wrapped_rwlock *rwlock); - int wrap_rwlock_rdlock(struct wrapped_rwlock *rwlock); --- -2.7.4 - diff --git a/SOURCES/slapi-nis-priming-0002-backend-support-backend-shutdown-for-priming-thread-.patch b/SOURCES/slapi-nis-priming-0002-backend-support-backend-shutdown-for-priming-thread-.patch deleted file mode 100644 index 22550e0..0000000 --- a/SOURCES/slapi-nis-priming-0002-backend-support-backend-shutdown-for-priming-thread-.patch +++ /dev/null @@ -1,268 +0,0 @@ -From c5e89132f2ee017aa026f7b8009a2976b627fa3a Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Tue, 26 Apr 2016 13:00:44 +0300 -Subject: [PATCH 2/4] backend: support backend shutdown for priming thread - cancellation - -Launching a separate thread to populate map cache has a side effect that -the thread could be scheduled to execute over a shutdown time. If LDAP server -received the request to shutdown, we need to stop processing the -original source and shut the priming thread. - -Resolves: rhbz#1327197 ---- - src/back-shr.c | 104 +++++++++++++++++++++++++++++++++++++++++++++++---------- - src/back-shr.h | 1 + - src/backend.h | 1 + - src/plugin.h | 3 ++ - 4 files changed, 92 insertions(+), 17 deletions(-) - -diff --git a/src/back-shr.c b/src/back-shr.c -index 0157582..7842e05 100644 ---- a/src/back-shr.c -+++ b/src/back-shr.c -@@ -665,25 +665,34 @@ backend_shr_get_vattr_sdnlist(struct plugin_state *state, - } - - struct backend_shr_data_init_cbdata { -- Slapi_PBlock *parent_pb; - struct plugin_state *state; - const char *filter; - }; - - #define PLUGIN_SCAN_DELAY 5 - --static void --backend_shr_data_initialize_thread_cb(void *arg) -+static void * -+backend_shr_data_initialize_thread_cb(struct wrapped_thread *t) - { -- struct backend_shr_data_init_cbdata *cbdata = (struct backend_shr_data_init_cbdata *)arg; -+ struct backend_shr_data_init_cbdata *cbdata = wrap_thread_arg(t); - Slapi_PBlock *pb = NULL; - struct backend_set_config_entry_add_cbdata set_cbdata; - int result = 0, i = 0; - Slapi_Entry **entries = NULL; - struct plugin_state *state = NULL; - -+ /* We have to be cautious here as the thread can be executed after -+ * the plugin received a shutdown request, thus a number of checks here. */ -+ if (slapi_is_shutting_down()) { -+ return NULL; -+ } -+ - if (cbdata == NULL) { -- return; -+ return NULL; -+ } -+ -+ if ((cbdata->state == NULL) || (cbdata->state->plugin_base == NULL)) { -+ return NULL; - } - - state = cbdata->state; -@@ -694,13 +703,23 @@ backend_shr_data_initialize_thread_cb(void *arg) - * so we just wait some time. */ - DS_Sleep(PR_SecondsToInterval(PLUGIN_SCAN_DELAY)); - -- backend_update_params(cbdata->parent_pb, state); -+ if (slapi_is_shutting_down()) { -+ return NULL; -+ } -+ -+ if (state->plugin_base == NULL) { -+ return NULL; -+ } -+ -+ pb = wrap_pblock_new(NULL); -+ backend_update_params(pb, state); -+ slapi_pblock_destroy(pb); - - slapi_log_error(SLAPI_LOG_PLUGIN, - state->plugin_desc->spd_id, - "searching under \"%s\" for configuration\n", - state->plugin_base); -- pb = wrap_pblock_new(cbdata->parent_pb); -+ pb = wrap_pblock_new(NULL); - slapi_search_internal_set_pb(pb, - state->plugin_base, - LDAP_SCOPE_ONELEVEL, -@@ -717,10 +736,10 @@ backend_shr_data_initialize_thread_cb(void *arg) - /* Do a search and collect found entries to avoid locking the backends */ - if (slapi_search_internal_pb(pb) == 0) { - if (map_wrlock() != 0) { -- slapi_log_error(SLAPI_LOG_PLUGIN, -+ slapi_log_error(SLAPI_LOG_FATAL, - state->plugin_desc->spd_id, - "failed to search under \"%s\" for " -- "configuration: failed to acquire a lock\n", -+ "configuration: failed to acquire a write lock to a map\n", - state->plugin_base); - goto done_with_lock; - } -@@ -728,6 +747,11 @@ backend_shr_data_initialize_thread_cb(void *arg) - if (result == 0) { - slapi_pblock_get(pb, SLAPI_PLUGIN_INTOP_SEARCH_ENTRIES, &entries); - for (i = 0; entries[i] != NULL; i++) { -+ /* We may be scheduled to run over shutdown time, exit early */ -+ if (slapi_is_shutting_down()) { -+ map_unlock(); -+ goto done_with_lock; -+ } - backend_set_config_entry_add_cb(entries[i], &set_cbdata); - } - } -@@ -746,6 +770,7 @@ done_with_lock: - } - - PR_AtomicSet(&state->ready_to_serve, 1); -+ return NULL; - } - - static void -@@ -754,11 +779,28 @@ backend_shr_data_initialize_thread(time_t when, void *arg) - struct backend_shr_data_init_cbdata *cbdata = (struct backend_shr_data_init_cbdata *)arg; - PRThread *thread = NULL; - -- /* start data import as a separate thread */ -- thread = PR_CreateThread(PR_USER_THREAD, backend_shr_data_initialize_thread_cb, -- (void *)arg, PR_PRIORITY_NORMAL, PR_GLOBAL_THREAD, -- PR_UNJOINABLE_THREAD, SLAPD_DEFAULT_THREAD_STACKSIZE); -- if (thread == NULL) { -+ if (slapi_is_shutting_down()) { -+ return; -+ } -+ -+ if (cbdata->state->priming_mutex == NULL) { -+ /* This mutex is allocated at plugin startup -+ * Without this mutex we can not enforce that shutdown wait for priming completion -+ * This is better to skip the priming -+ */ -+ slapi_log_error(SLAPI_LOG_FATAL, cbdata->state->plugin_desc->spd_id, "priming_mutex not initialized. Priming fails\n"); -+ return; -+ } -+ wrap_mutex_lock(cbdata->state->priming_mutex); -+ -+ if (!cbdata->state->start_priming_thread) { -+ slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id, -+ "Likely a shutdown occurred before we started \n"); -+ goto done; -+ } -+ -+ cbdata->state->priming_tid = wrap_start_thread(&backend_shr_data_initialize_thread_cb, arg); -+ if (cbdata->state->priming_tid == NULL) { - slapi_log_error(SLAPI_LOG_FATAL, - cbdata->state->plugin_desc->spd_id, - "unable to create compatibility tree scan thread!\n"); -@@ -769,6 +811,8 @@ backend_shr_data_initialize_thread(time_t when, void *arg) - cbdata->state->plugin_desc->spd_id, PLUGIN_SCAN_DELAY); - } - -+done: -+ wrap_mutex_unlock(cbdata->state->priming_mutex); - } - - /* Scan for the list of configured groups and sets. */ -@@ -779,6 +823,14 @@ backend_shr_startup(struct plugin_state *state, - { - struct backend_shr_data_init_cbdata *cbdata = NULL; - -+ if (slapi_is_shutting_down()) { -+ slapi_log_error(SLAPI_LOG_FATAL, -+ state->plugin_desc->spd_id, -+ "task for populating compatibility tree will " -+ "not be created due to upcoming server shutdown\n"); -+ return; -+ } -+ - cbdata = (struct backend_shr_data_init_cbdata *) - slapi_ch_malloc(sizeof(struct backend_shr_data_init_cbdata)); - -@@ -792,10 +844,10 @@ backend_shr_startup(struct plugin_state *state, - - PR_AtomicSet(&state->ready_to_serve, 0); - cbdata->state = state; -- cbdata->parent_pb = parent_pb; - cbdata->filter = filter; - -- /* Schedule running a callback that will create a thread */ -+ /* Schedule running a callback that will create a thread -+ * but make sure it is called a first thing when event loop is created */ - slapi_eq_once(backend_shr_data_initialize_thread, - cbdata, PR_SecondsToInterval(PLUGIN_SCAN_DELAY)); - -@@ -808,6 +860,24 @@ backend_shr_startup(struct plugin_state *state, - - } - -+void -+backend_shr_shutdown(struct plugin_state *state) -+{ -+ /* Make sure the priming thread is stopped or will not start -+ * Note: priming_mutex will not be freed because the priming thread -+ * may access it independently of the server/plugin shutdown -+ */ -+ wrap_mutex_lock(state->priming_mutex); -+ state->start_priming_thread = 0; /* prevent spawing of priming thread */ -+ if (state->priming_tid == NULL) { -+ /* priming thread has not yet started or failed to start */ -+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, -+ "At shutdown, priming thread not yet started or failed to start\n"); -+ } else { -+ wrap_stop_thread(state->priming_tid); -+ } -+ wrap_mutex_unlock(state->priming_mutex); -+} - /* Process a set configuration directory entry. Pull out the group and set - * names which are specified in the entry and delete each in turn. */ - int -@@ -2336,7 +2406,7 @@ backend_shr_modify_cb(Slapi_PBlock *pb) - backend_set_config_entry_add_cb(cbdata.e_post, &set_cbdata); - } - /* Lastly, if the entry is our own entry, re-read parameters. */ -- sdn = slapi_sdn_new_dn_byref(cbdata.state->plugin_base); -+ sdn = slapi_sdn_new_dn_byval(cbdata.state->plugin_base); - if (sdn != NULL) { - if ((strcmp(slapi_entry_get_ndn(cbdata.e_pre), - slapi_sdn_get_ndn(sdn)) == 0) || -diff --git a/src/back-shr.h b/src/back-shr.h -index 44c25fe..2caea5d 100644 ---- a/src/back-shr.h -+++ b/src/back-shr.h -@@ -39,6 +39,7 @@ void backend_shr_free_sdnlist(const Slapi_DN **sdnlist); - - void backend_shr_startup(struct plugin_state *state, - Slapi_PBlock *pb, const char *set_filter); -+void backend_shr_shutdown(struct plugin_state *state); - int backend_shr_betxn_postop_init(Slapi_PBlock *pb, - struct plugin_state *state); - int backend_shr_postop_init(Slapi_PBlock *pb, struct plugin_state *state); -diff --git a/src/backend.h b/src/backend.h -index 7974aae..4608d2d 100644 ---- a/src/backend.h -+++ b/src/backend.h -@@ -58,6 +58,7 @@ struct backend_shr_set_data { - - /* Startup/initialization functions called through the map. */ - void backend_startup(struct slapi_pblock *pb, struct plugin_state *state); -+void backend_shutdown(struct plugin_state *state); - int backend_init_preop(struct slapi_pblock *pb, struct plugin_state *state); - int backend_init_betxn_preop(struct slapi_pblock *pb, - struct plugin_state *state); -diff --git a/src/plugin.h b/src/plugin.h -index 7a89ac7..56d672f 100644 ---- a/src/plugin.h -+++ b/src/plugin.h -@@ -34,6 +34,9 @@ struct plugin_state { - Slapi_PluginDesc *plugin_desc; - unsigned int use_be_txns: 1; - PRInt32 ready_to_serve; -+ struct wrapped_mutex *priming_mutex; -+ unsigned int start_priming_thread: 1; /* flag to allow spawning of the priming thread */ -+ struct wrapped_thread *priming_tid; /* priming thread pid. use to join */ - - /* NIS-specific data. */ - struct wrapped_thread *tid; --- -2.7.4 - diff --git a/SOURCES/slapi-nis-priming-0003-nis-add-backend-shutdown-support-to-stop-priming-thr.patch b/SOURCES/slapi-nis-priming-0003-nis-add-backend-shutdown-support-to-stop-priming-thr.patch deleted file mode 100644 index f3122b8..0000000 --- a/SOURCES/slapi-nis-priming-0003-nis-add-backend-shutdown-support-to-stop-priming-thr.patch +++ /dev/null @@ -1,92 +0,0 @@ -From 63212ccae673e46334b874688741bf96d996fd36 Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Tue, 26 Apr 2016 13:17:03 +0300 -Subject: [PATCH 3/4] nis: add backend shutdown support to stop priming thread - -Resolves: rhbz#1327197 ---- - src/back-nis.c | 6 ++++++ - src/plug-nis.c | 34 +++++++++++++++++++++++++++------- - 2 files changed, 33 insertions(+), 7 deletions(-) - -diff --git a/src/back-nis.c b/src/back-nis.c -index b9379c0..7fb191d 100644 ---- a/src/back-nis.c -+++ b/src/back-nis.c -@@ -1021,6 +1021,12 @@ backend_startup(Slapi_PBlock *pb, struct plugin_state *state) - backend_shr_startup(state, pb, NIS_MAP_CONFIGURATION_FILTER); - } - -+void -+backend_shutdown(struct plugin_state *state) -+{ -+ backend_shr_shutdown(state); -+} -+ - /* Set up our post-op callbacks. */ - #ifdef SLAPI_NIS_SUPPORT_BE_TXNS - int -diff --git a/src/plug-nis.c b/src/plug-nis.c -index a1bdf89..ee90c37 100644 ---- a/src/plug-nis.c -+++ b/src/plug-nis.c -@@ -81,14 +81,31 @@ plugin_startup(Slapi_PBlock *pb) - struct plugin_state *state; - const char *pname; - int i, protocol; -+ Slapi_DN *pluginsdn = NULL; -+ - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); -- slapi_pblock_get(pb, SLAPI_TARGET_DN, &state->plugin_base); -- slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, -- "configuration entry is %s%s%s\n", -- state->plugin_base ? "\"" : "", -- state->plugin_base ? state->plugin_base : "NULL", -- state->plugin_base ? "\"" : ""); -+ slapi_pblock_get(pb, SLAPI_TARGET_SDN, &pluginsdn); -+ /* plugin base need to be duplicated because it will be destroyed -+ * when pblock is destroyed but we need to use it in a separate thread */ -+ if (NULL == pluginsdn || 0 == slapi_sdn_get_ndn_len(pluginsdn)) { -+ slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id, -+ "nis plugin_startup: unable to retrieve plugin DN\n"); -+ return -1; -+ -+ } else { -+ state->plugin_base = slapi_ch_strdup(slapi_sdn_get_dn(pluginsdn)); -+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, -+ "configuration entry is %s%s%s\n", -+ state->plugin_base ? "\"" : "", -+ state->plugin_base ? state->plugin_base : "NULL", -+ state->plugin_base ? "\"" : ""); -+ } -+ - /* Populate the maps and data. */ -+ if (state->priming_mutex == NULL) { -+ state->priming_mutex = wrap_new_mutex(); -+ state->start_priming_thread = 1; -+ } - backend_startup(pb, state); - /* Start a new listening thread to handle incoming traffic. */ - state->tid = wrap_start_thread(&dispatch_thread, state); -@@ -177,6 +194,7 @@ plugin_shutdown(Slapi_PBlock *pb) - struct plugin_state *state; - int i, protocol; - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); -+ backend_shutdown(state); - for (i = 0; i < state->n_listeners; i++) { - if (state->pmap_client_socket != -1) { - switch (state->listener[i].type) { -@@ -217,7 +235,9 @@ plugin_shutdown(Slapi_PBlock *pb) - #ifdef HAVE_TCPD_H - free(state->request_info); - #endif -- state->plugin_base = NULL; -+ if (state->plugin_base != NULL) { -+ slapi_ch_free((void **)&state->plugin_base); -+ } - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "plugin shutdown completed\n"); - return 0; --- -2.7.4 - diff --git a/SOURCES/slapi-nis-priming-0004-schema-compat-add-backend-shutdown-support-for-primi.patch b/SOURCES/slapi-nis-priming-0004-schema-compat-add-backend-shutdown-support-for-primi.patch deleted file mode 100644 index 7772689..0000000 --- a/SOURCES/slapi-nis-priming-0004-schema-compat-add-backend-shutdown-support-for-primi.patch +++ /dev/null @@ -1,99 +0,0 @@ -From 02e32192779994cab254c548291c24d89429b335 Mon Sep 17 00:00:00 2001 -From: Thierry Bordaz -Date: Tue, 26 Apr 2016 13:17:46 +0300 -Subject: [PATCH 4/4] schema-compat: add backend shutdown support for priming - thread - -Resolves: rhbz#1327197 ---- - src/back-sch.c | 6 ++++++ - src/plug-sch.c | 34 +++++++++++++++++++++++++++------- - 2 files changed, 33 insertions(+), 7 deletions(-) - -diff --git a/src/back-sch.c b/src/back-sch.c -index 9a0e96b..32b1d9e 100644 ---- a/src/back-sch.c -+++ b/src/back-sch.c -@@ -2280,6 +2280,12 @@ backend_startup(Slapi_PBlock *pb, struct plugin_state *state) - backend_shr_startup(state, pb, SCH_CONTAINER_CONFIGURATION_FILTER); - } - -+void -+backend_shutdown(struct plugin_state *state) -+{ -+ backend_shr_shutdown(state); -+} -+ - int - backend_init_preop(Slapi_PBlock *pb, struct plugin_state *state) - { -diff --git a/src/plug-sch.c b/src/plug-sch.c -index 95a4fd8..7af8480 100644 ---- a/src/plug-sch.c -+++ b/src/plug-sch.c -@@ -102,13 +102,26 @@ plugin_startup(Slapi_PBlock *pb) - /* Populate the maps and data. */ - struct plugin_state *state; - Slapi_Entry *plugin_entry = NULL; -+ Slapi_DN *pluginsdn = NULL; -+ - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); -- slapi_pblock_get(pb, SLAPI_TARGET_DN, &state->plugin_base); -- slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, -- "configuration entry is %s%s%s\n", -- state->plugin_base ? "\"" : "", -- state->plugin_base ? state->plugin_base : "NULL", -- state->plugin_base ? "\"" : ""); -+ slapi_pblock_get(pb, SLAPI_TARGET_SDN, &pluginsdn); -+ /* plugin base need to be duplicated because it will be destroyed -+ * when pblock is destroyed but we need to use it in a separate thread */ -+ if (NULL == pluginsdn || 0 == slapi_sdn_get_ndn_len(pluginsdn)) { -+ slapi_log_error(SLAPI_LOG_FATAL, state->plugin_desc->spd_id, -+ "scheman compat plugin_startup: unable to retrieve plugin DN\n"); -+ return -1; -+ -+ } else { -+ state->plugin_base = slapi_ch_strdup(slapi_sdn_get_dn(pluginsdn)); -+ slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, -+ "configuration entry is %s%s%s\n", -+ state->plugin_base ? "\"" : "", -+ state->plugin_base ? state->plugin_base : "NULL", -+ state->plugin_base ? "\"" : ""); -+ } -+ - state->pam_lock = wrap_new_rwlock(); - backend_nss_init_context((struct nss_ops_ctx**) &state->nss_context); - if ((slapi_pblock_get(pb, SLAPI_PLUGIN_CONFIG_ENTRY, &plugin_entry) == 0) && -@@ -122,6 +135,10 @@ plugin_startup(Slapi_PBlock *pb) - state->cached_entries = PL_NewHashTable(0, PL_HashString, PL_CompareStrings, PL_CompareValues, 0, 0); - wrap_rwlock_unlock(state->cached_entries_lock); - /* Populate the tree of fake entries. */ -+ if (state->priming_mutex == NULL) { -+ state->priming_mutex = wrap_new_mutex(); -+ state->start_priming_thread = 1; -+ } - backend_startup(pb, state); - /* Note that the plugin is ready to go. */ - slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id, -@@ -147,6 +164,7 @@ plugin_shutdown(Slapi_PBlock *pb) - { - struct plugin_state *state; - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); -+ backend_shutdown(state); - map_done(state); - wrap_free_rwlock(state->pam_lock); - state->pam_lock = NULL; -@@ -160,7 +178,9 @@ plugin_shutdown(Slapi_PBlock *pb) - wrap_free_rwlock(state->cached_entries_lock); - state->cached_entries_lock = NULL; - } -- state->plugin_base = NULL; -+ if (state->plugin_base != NULL) { -+ slapi_ch_free((void **)&state->plugin_base); -+ } - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "plugin shutdown completed\n"); - return 0; --- -2.7.4 - diff --git a/SOURCES/slapi-nis-schema-compat-support-ID-overrides-in-bind-callback.patch b/SOURCES/slapi-nis-schema-compat-support-ID-overrides-in-bind-callback.patch deleted file mode 100644 index afc5c4d..0000000 --- a/SOURCES/slapi-nis-schema-compat-support-ID-overrides-in-bind-callback.patch +++ /dev/null @@ -1,257 +0,0 @@ -From 5f5f302e97560b05b154473f562410733e0b775b Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Tue, 28 Oct 2014 11:16:50 +0200 -Subject: [PATCH 2/2] schema-compat: support ID overrides in bind callback - -If RDN of the bind DN is overridden within the ID view, rewrite the -target to use original value of the uid attribute. - -If original uid attribute is not available, fail the search and thus -the whole bind request by claiming that bind DN does not exist. ---- - src/back-sch-idview.c | 86 ++++++++++++++++++++++++++++++++++----------------- - src/back-sch.c | 57 +++++++++++++++++++++++++++++----- - src/back-sch.h | 4 +++ - 3 files changed, 111 insertions(+), 36 deletions(-) - -diff --git a/src/back-sch-idview.c b/src/back-sch-idview.c -index a56a9e9..f1150cd 100644 ---- a/src/back-sch-idview.c -+++ b/src/back-sch-idview.c -@@ -290,21 +290,15 @@ idview_replace_target_dn(char **target, char **idview) - } - } - --static int --idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct berval *bval, struct backend_search_filter_config *config) -+int -+idview_replace_bval_by_override(const char *bval_usage, const char *attr_name, -+ struct berval *bval, struct backend_search_cbdata *cbdata) - { - int res, i; -- Slapi_Value *filter_val, *value, *anchor_val; -+ Slapi_Value *attr_val, *value, *anchor_val; - Slapi_Attr *anchor, *attr = NULL; -- struct backend_search_cbdata *cbdata = (struct backend_search_cbdata *) config->callback_data; -- -- if (cbdata == NULL || cbdata->idview == NULL) { -- return SLAPI_FILTER_SCAN_CONTINUE; -- } -- -- if (filter_type == NULL || config->name == NULL) { -- return SLAPI_FILTER_SCAN_CONTINUE; -- } -+ bool_t uid_override_found = FALSE; -+ bool_t anchor_override_found = FALSE; - - if (cbdata->overrides == NULL) { - /* Only retrieve overrides for the view first time when neccessary */ -@@ -312,31 +306,34 @@ idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct b - } - - if (cbdata->overrides == NULL) { -- return SLAPI_FILTER_SCAN_CONTINUE; -+ return 0; - } - -- filter_val = slapi_value_new_berval(bval); -+ attr_val = slapi_value_new_berval(bval); -+ slapi_log_error(SLAPI_LOG_FATAL, cbdata->state->plugin_desc->spd_id, -+ "Searching for an override of the %s %s with %s=%*s from the overrides\n.", -+ bval_usage, attr_name, attr_name, (int) bval->bv_len, bval->bv_val); - - /* If filter contains an attribute name which is overridden in the view and filter value - * corresponds to the override, replace the filter by (ipaAnchorUUID=...) from the override - * to point to the original because otherwise an entry will not be found in the slapi-nis map */ - for(i=0; cbdata->overrides[i] != NULL; i++) { -- res = slapi_entry_attr_find(cbdata->overrides[i], filter_type, &attr); -+ res = slapi_entry_attr_find(cbdata->overrides[i], attr_name, &attr); - if ((res == 0) && (attr != NULL)) { - res = slapi_attr_first_value(attr, &value); -- res = slapi_value_compare(attr, value, filter_val); -+ res = slapi_value_compare(attr, value, attr_val); - if (res == 0) { - /* For uid overrides we should have ipaOriginalUID in the override */ -- if (strcasecmp(filter_type, "uid") == 0) { -+ if (strcasecmp(attr_name, "uid") == 0) { - res = slapi_entry_attr_find(cbdata->overrides[i], IPA_IDVIEWS_ATTR_ORIGINALUID, &anchor); - if (res == 0) { - res = slapi_attr_first_value(anchor, &anchor_val); - slapi_ber_bvdone(bval); - slapi_ber_bvcpy(bval, slapi_value_get_berval(anchor_val)); -- config->override_found = TRUE; -- slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id, -- "Overriding the filter %s with %s=%*s from the override %s\n.", -- filter_type, filter_type, bval->bv_len, bval->bv_val, -+ uid_override_found = TRUE; -+ slapi_log_error(SLAPI_LOG_FATAL, cbdata->state->plugin_desc->spd_id, -+ "Overriding the %s %s with %s=%*s from the override %s\n.", -+ bval_usage, attr_name, attr_name, (int) bval->bv_len, bval->bv_val, - slapi_entry_get_dn_const(cbdata->overrides[i])); - break; - } -@@ -346,14 +343,13 @@ idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct b - res = slapi_entry_attr_find(cbdata->overrides[i], IPA_IDVIEWS_ATTR_ANCHORUUID, &anchor); - if (res == 0) { - res = slapi_attr_first_value(anchor, &anchor_val); -- slapi_filter_changetype(filter, IPA_IDVIEWS_ATTR_ANCHORUUID); - slapi_ber_bvdone(bval); - slapi_ber_bvcpy(bval, slapi_value_get_berval(anchor_val)); -- config->override_found = TRUE; -- slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id, -- "Overriding the filter %s with %s=%*s from the override %s\n.", -- filter_type, IPA_IDVIEWS_ATTR_ANCHORUUID, -- bval->bv_len, bval->bv_val, -+ anchor_override_found = TRUE; -+ slapi_log_error(SLAPI_LOG_FATAL, cbdata->state->plugin_desc->spd_id, -+ "Overriding the %s %s with %s=%*s from the override %s\n.", -+ bval_usage, attr_name, IPA_IDVIEWS_ATTR_ANCHORUUID, -+ (int) bval->bv_len, bval->bv_val, - slapi_entry_get_dn_const(cbdata->overrides[i])); - break; - } -@@ -362,7 +358,41 @@ idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, struct b - } - } - -- slapi_value_free(&filter_val); -+ slapi_value_free(&attr_val); -+ -+ if (uid_override_found) { -+ return 1; -+ } -+ -+ if (anchor_override_found) { -+ return 2; -+ } -+ -+ return 0; -+} -+ -+static int -+idview_process_filter_cb(Slapi_Filter *filter, const char *filter_type, -+ struct berval *bval, struct backend_search_filter_config *config) -+{ -+ int res; -+ struct backend_search_cbdata *cbdata = (struct backend_search_cbdata *) config->callback_data; -+ -+ if (cbdata == NULL || cbdata->idview == NULL) { -+ return SLAPI_FILTER_SCAN_CONTINUE; -+ } -+ -+ if (filter_type == NULL || config->name == NULL) { -+ return SLAPI_FILTER_SCAN_CONTINUE; -+ } -+ -+ res = idview_replace_bval_by_override("filter", filter_type, bval, cbdata); -+ -+ if (res == 2) { -+ slapi_filter_changetype(filter, IPA_IDVIEWS_ATTR_ANCHORUUID); -+ } -+ -+ config->override_found = (res != 0); - - return SLAPI_FILTER_SCAN_CONTINUE; - -diff --git a/src/back-sch.c b/src/back-sch.c -index 27ac24f..2388d2f 100644 ---- a/src/back-sch.c -+++ b/src/back-sch.c -@@ -1631,7 +1631,6 @@ static void - backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char **group, const char**set) - { - struct backend_locate_cbdata cbdata; -- char *idview = NULL; - - slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); - if (cbdata.state->plugin_base == NULL) { -@@ -1640,22 +1639,64 @@ backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char ** - return; - } - slapi_pblock_get(pb, SLAPI_TARGET_DN, &cbdata.target); --#ifdef USE_IPA_IDVIEWS -- idview_replace_target_dn(&cbdata.target, &idview); --#endif -+ - cbdata.target_dn = slapi_sdn_new_dn_byval(cbdata.target); - cbdata.entry_data = NULL; - cbdata.entry_group = NULL; - cbdata.entry_set = NULL; - map_data_foreach_map(cbdata.state, NULL, backend_locate_cb, &cbdata); -+#ifdef USE_IPA_IDVIEWS -+ /* In case nothing was found but we are operating on the ID override, -+ * rebuild the target's RDN to use original attribute's value */ -+ if (cbdata.entry_data == NULL) { -+ char *idview = NULL; -+ char *target, *original_target; -+ target = original_target = slapi_ch_strdup(cbdata.target); -+ idview_replace_target_dn(&target, &idview); -+ if (target != original_target) { -+ slapi_ch_free_string(&original_target); -+ } -+ if (idview != NULL) { -+ char *rdnstr; -+ char *val; -+ struct berval bval; -+ int res; -+ struct backend_search_cbdata scbdata; -+ Slapi_RDN *rdn = slapi_rdn_new_all_dn(target); -+ if (rdn != NULL) { -+ res = slapi_rdn_get_first(rdn, &rdnstr, &val); -+ if (res == 1) { -+ bval.bv_len = strlen(val) + 1; -+ bval.bv_val = slapi_ch_strdup(val); -+ memset(&scbdata, 0, sizeof(scbdata)); -+ scbdata.idview = idview; -+ scbdata.target = target; -+ scbdata.pb = pb; -+ scbdata.state = cbdata.state; -+ scbdata.target_dn = slapi_sdn_new_dn_byval(target); -+ res = idview_replace_bval_by_override("rdn", rdnstr, &bval, &scbdata); -+ /* only accept uid overrides */ -+ if (res == 1) { -+ slapi_rdn_remove_index(rdn, 1); -+ slapi_rdn_add(rdn, "uid", bval.bv_val); -+ slapi_sdn_free(&cbdata.target_dn); -+ cbdata.target_dn = slapi_sdn_set_rdn(scbdata.target_dn, rdn); -+ map_data_foreach_map(cbdata.state, NULL, backend_locate_cb, &cbdata); -+ } -+ slapi_ber_bvdone(&bval); -+ slapi_rdn_free(&rdn); -+ idview_free_overrides(&scbdata); -+ } -+ } -+ } -+ slapi_ch_free_string(&target); -+ slapi_ch_free_string(&idview); -+ } -+#endif - *data = cbdata.entry_data; - *group = cbdata.entry_group; - *set = cbdata.entry_set; - slapi_sdn_free(&cbdata.target_dn); -- if (idview != NULL) { -- slapi_ch_free_string(&cbdata.target); -- } -- slapi_ch_free_string(&idview); - } - - /* Check if the target DN is part of this group's tree. If it is, return an -diff --git a/src/back-sch.h b/src/back-sch.h -index 9f0b201..26e12d1 100644 ---- a/src/back-sch.h -+++ b/src/back-sch.h -@@ -131,6 +131,10 @@ void idview_process_overrides(struct backend_search_cbdata *cbdata, - Slapi_Entry *entry); - void idview_replace_target_dn(char **target, char **idview); - void idview_replace_filter(struct backend_search_cbdata *cbdata); -+/* Takes struct berval value of an attribute attr_name and replaces it with an override -+ * Returns 0 if no override was found, 1 for 'uid' replacement, 2 for ipaAnchorUUID replacement */ -+int idview_replace_bval_by_override(const char *bval_usage, const char *attr_name, -+ struct berval *bval, struct backend_search_cbdata *cbdata); - #endif - - #endif --- -2.1.0 - diff --git a/SOURCES/slapi-nis-use-libnss_sss.so.2-explicitly.patch b/SOURCES/slapi-nis-use-libnss_sss.so.2-explicitly.patch deleted file mode 100644 index fe53f22..0000000 --- a/SOURCES/slapi-nis-use-libnss_sss.so.2-explicitly.patch +++ /dev/null @@ -1,473 +0,0 @@ -From 89b7a6f79cbcdbaea3b073983864a2a59ab6daaa Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Wed, 12 Nov 2014 13:23:17 +0200 -Subject: [PATCH] schema-compat: use libnss_sss.so.2 explicitly to resolve - trusted domain users via NSS - -When Schema Compatibility plugin is configured to enumerate users and groups -from Active Directory domains trusted by FreeIPA, use nss_sss module directly -instead of following nsswitch.conf configuration. - -The issue with nsswitch.conf configuration is in the fact that for each request -all modules in NSS chain are processed while only one of them is responsible -for users from trusted Active Directory domains, namely, nss_sss. ---- - configure.ac | 1 + - doc/ipa/sch-ipa.txt | 14 ++- - src/back-sch-nss.c | 246 ++++++++++++++++++++++++++++++++++++++++++++-------- - src/back-sch.h | 5 ++ - src/plug-sch.c | 3 + - src/plugin.h | 1 + - 6 files changed, 231 insertions(+), 39 deletions(-) - -diff --git a/configure.ac b/configure.ac -index 9174980..92647ea 100644 ---- a/configure.ac -+++ b/configure.ac -@@ -343,6 +343,7 @@ fi - AM_CONDITIONAL([USE_PAM], [test "x$use_pam" != xno]) - - if test "x$use_nsswitch" != xno ; then -+ AC_CHECK_HEADERS([stdint.h nss.h dlfcn.h]) - if pkg-config sss_nss_idmap 2> /dev/null ; then - if test x$use_sss_nss_idmap != xno ; then - AC_DEFINE(HAVE_SSS_NSS_IDMAP,1,[Define if you have libsss_nss_idmap.]) -diff --git a/doc/ipa/sch-ipa.txt b/doc/ipa/sch-ipa.txt -index f560580..106e6cc 100644 ---- a/doc/ipa/sch-ipa.txt -+++ b/doc/ipa/sch-ipa.txt -@@ -47,6 +47,11 @@ Plugin allows to expose users and groups from trusted domains. These users - and groups are available on the compatibility trees and can be used for - querying their attributes and authenticating against them. - -+Schema Compatibility Plugin relies on SSSD to discover users from trusted -+domains. NSS module provided by SSSD (libnss_sss.so.2) is loaded explicitly by -+Schema Compatibility Plugin and all calls are directed to SSSD instead of using -+generic NSSWITCH API. -+ - Additionally, authentication against IPA users is also supported, provided - that the Schema Compatibility Plugin is given an ordering preference in - the Directory Server configuration. By default, all Directory server plugins -@@ -70,10 +75,11 @@ schema-compat-nsswitch-min-id: - specifies that the minimal numeric id of the user or group should be not less - than the value. Defaults to 1000. - --When FreeIPA 3.3 is in use, ipa-adtrust-install utility will automatically configure --the Schema Compatibility Plugin to allow serving users and groups from trusted domains. --No additional configuration is needed. ipa-adtrust-install, however, will not set the --minimal numeric id for user or group. -+When FreeIPA 3.3 or later is in use, ipa-adtrust-install utility will -+automatically configure the Schema Compatibility Plugin to allow serving users -+and groups from trusted domains. No additional configuration is needed. -+ipa-adtrust-install, however, will not set the minimal numeric id for user or -+group. - - == Authentication of the trusted domains' users == - -diff --git a/src/back-sch-nss.c b/src/back-sch-nss.c -index 12ae589..3a21ff6 100644 ---- a/src/back-sch-nss.c -+++ b/src/back-sch-nss.c -@@ -28,9 +28,10 @@ - #include - #include - #include -+#include -+#include - #include - #include --#include - - #ifdef HAVE_DIRSRV_SLAPI_PLUGIN_H - #include -@@ -307,6 +308,144 @@ backend_make_user_entry_from_nsswitch_passwd(struct passwd *pwd, - return entry; - } - -+/* Possible results of lookup using a nss_* function. -+ * Note: don't include nss.h as its path gets overriden by NSS library */ -+enum nss_status -+{ -+ NSS_STATUS_TRYAGAIN = -2, -+ NSS_STATUS_UNAVAIL, -+ NSS_STATUS_NOTFOUND, -+ NSS_STATUS_SUCCESS, -+ NSS_STATUS_RETURN -+}; -+ -+struct nss_ops_ctx { -+ void *dl_handle; -+ -+ enum nss_status (*getpwnam_r)(const char *name, struct passwd *result, -+ char *buffer, size_t buflen, int *errnop); -+ enum nss_status (*getpwuid_r)(uid_t uid, struct passwd *result, -+ char *buffer, size_t buflen, int *errnop); -+ enum nss_status (*setpwent)(void); -+ enum nss_status (*getpwent_r)(struct passwd *result, -+ char *buffer, size_t buflen, int *errnop); -+ enum nss_status (*endpwent)(void); -+ -+ enum nss_status (*getgrnam_r)(const char *name, struct group *result, -+ char *buffer, size_t buflen, int *errnop); -+ enum nss_status (*getgrgid_r)(gid_t gid, struct group *result, -+ char *buffer, size_t buflen, int *errnop); -+ enum nss_status (*setgrent)(void); -+ enum nss_status (*getgrent_r)(struct group *result, -+ char *buffer, size_t buflen, int *errnop); -+ enum nss_status (*endgrent)(void); -+ -+ enum nss_status (*initgroups_dyn)(const char *user, gid_t group, -+ long int *start, long int *size, -+ gid_t **groups, long int limit, -+ int *errnop); -+}; -+ -+void backend_nss_init_context(struct nss_ops_ctx **nss_context) -+{ -+ struct nss_ops_ctx *ctx = NULL; -+ -+ if (nss_context == NULL) { -+ return; -+ } -+ -+ ctx = calloc(1, sizeof(struct nss_ops_ctx)); -+ -+ *nss_context = ctx; -+ if (ctx == NULL) { -+ return; -+ } -+ -+ ctx->dl_handle = dlopen("libnss_sss.so.2", RTLD_NOW); -+ if (ctx->dl_handle == NULL) { -+ goto fail; -+ } -+ -+ ctx->getpwnam_r = dlsym(ctx->dl_handle, "_nss_sss_getpwnam_r"); -+ if (ctx->getpwnam_r == NULL) { -+ goto fail; -+ } -+ -+ ctx->getpwuid_r = dlsym(ctx->dl_handle, "_nss_sss_getpwuid_r"); -+ if (ctx->getpwuid_r == NULL) { -+ goto fail; -+ } -+ -+ ctx->setpwent = dlsym(ctx->dl_handle, "_nss_sss_setpwent"); -+ if (ctx->setpwent == NULL) { -+ goto fail; -+ } -+ -+ ctx->getpwent_r = dlsym(ctx->dl_handle, "_nss_sss_getpwent_r"); -+ if (ctx->getpwent_r == NULL) { -+ goto fail; -+ } -+ -+ ctx->endpwent = dlsym(ctx->dl_handle, "_nss_sss_endpwent"); -+ if (ctx->endpwent == NULL) { -+ goto fail; -+ } -+ -+ ctx->getgrnam_r = dlsym(ctx->dl_handle, "_nss_sss_getgrnam_r"); -+ if (ctx->getgrnam_r == NULL) { -+ goto fail; -+ } -+ -+ ctx->getgrgid_r = dlsym(ctx->dl_handle, "_nss_sss_getgrgid_r"); -+ if (ctx->getgrgid_r == NULL) { -+ goto fail; -+ } -+ -+ ctx->setgrent = dlsym(ctx->dl_handle, "_nss_sss_setgrent"); -+ if (ctx->setgrent == NULL) { -+ goto fail; -+ } -+ -+ ctx->getgrent_r = dlsym(ctx->dl_handle, "_nss_sss_getgrent_r"); -+ if (ctx->getgrent_r == NULL) { -+ goto fail; -+ } -+ -+ ctx->endgrent = dlsym(ctx->dl_handle, "_nss_sss_endgrent"); -+ if (ctx->endgrent == NULL) { -+ goto fail; -+ } -+ -+ ctx->initgroups_dyn = dlsym(ctx->dl_handle, "_nss_sss_initgroups_dyn"); -+ if (ctx->initgroups_dyn == NULL) { -+ goto fail; -+ } -+ -+ return; -+ -+fail: -+ backend_nss_free_context(nss_context); -+ -+ return; -+} -+ -+void -+backend_nss_free_context(struct nss_ops_ctx **nss_context) -+{ -+ if (nss_context == NULL) { -+ return; -+ } -+ -+ if ((*nss_context)->dl_handle != NULL) { -+ dlclose((*nss_context)->dl_handle); -+ } -+ -+ free((*nss_context)); -+ *nss_context = NULL; -+} -+ -+ -+ - static Slapi_Entry ** - backend_retrieve_user_entry_from_nsswitch(char *user_name, bool_t is_uid, - char *container_sdn, -@@ -315,25 +454,33 @@ backend_retrieve_user_entry_from_nsswitch(char *user_name, bool_t is_uid, - { - struct passwd pwd, *result; - Slapi_Entry *entry, **entries; -- int rc; -+ enum nss_status rc; - char *buf = NULL; -+ struct nss_ops_ctx *ctx = NULL; -+ int lerrno; -+ -+ ctx = cbdata->state->nss_context; - -+ if (ctx == NULL) { -+ return NULL; -+ } - repeat: - if (cbdata->nsswitch_buffer == NULL) { - return NULL; - } - - if (is_uid) { -- rc = getpwuid_r((uid_t) atoll(user_name), &pwd, -- cbdata->nsswitch_buffer, -- cbdata->nsswitch_buffer_len, &result); -+ rc = ctx->getpwuid_r((uid_t) atoll(user_name), &pwd, -+ cbdata->nsswitch_buffer, -+ cbdata->nsswitch_buffer_len, &lerrno); - } else { -- rc = getpwnam_r(user_name, &pwd, -- cbdata->nsswitch_buffer, -- cbdata->nsswitch_buffer_len, &result); -+ rc = ctx->getpwnam_r(user_name, &pwd, -+ cbdata->nsswitch_buffer, -+ cbdata->nsswitch_buffer_len, &lerrno); - } -- if ((result == NULL) || (rc != 0)) { -- if (rc == ERANGE) { -+ -+ if ((rc != NSS_STATUS_SUCCESS)) { -+ if (lerrno == ERANGE) { - buf = realloc(cbdata->nsswitch_buffer, cbdata->nsswitch_buffer_len * 2); - if (buf != NULL) { - cbdata->nsswitch_buffer = buf; -@@ -437,25 +584,32 @@ backend_retrieve_group_entry_from_nsswitch(char *group_name, bool_t is_gid, - { - struct group grp, *result; - Slapi_Entry *entry, **entries; -- int rc; -+ enum nss_status rc; - char *buf = NULL; -+ struct nss_ops_ctx *ctx = NULL; -+ int lerrno = 0; -+ -+ ctx = cbdata->state->nss_context; - -+ if (ctx == NULL) { -+ return NULL; -+ } - repeat: - if (cbdata->nsswitch_buffer == NULL) { - return NULL; - } - - if (is_gid) { -- rc = getgrgid_r((gid_t) atoll(group_name), &grp, -- cbdata->nsswitch_buffer, -- cbdata->nsswitch_buffer_len, &result); -+ rc = ctx->getgrgid_r((gid_t) atoll(group_name), &grp, -+ cbdata->nsswitch_buffer, -+ cbdata->nsswitch_buffer_len, &lerrno); - } else { -- rc = getgrnam_r(group_name, &grp, -- cbdata->nsswitch_buffer, -- cbdata->nsswitch_buffer_len, &result); -+ rc = ctx->getgrnam_r(group_name, &grp, -+ cbdata->nsswitch_buffer, -+ cbdata->nsswitch_buffer_len, &lerrno); - } -- if ((result == NULL) || (rc != 0)) { -- if (rc == ERANGE) { -+ if ((rc != NSS_STATUS_SUCCESS)) { -+ if (lerrno == ERANGE) { - buf = realloc(cbdata->nsswitch_buffer, cbdata->nsswitch_buffer_len * 2); - if (buf != NULL) { - cbdata->nsswitch_buffer = buf; -@@ -490,20 +644,27 @@ backend_retrieve_group_entry_from_nsswitch_by_gid(gid_t gid, - { - struct group grp, *result; - Slapi_Entry *entry; -- int rc; -+ enum nss_status rc; - char *buf = NULL; -+ struct nss_ops_ctx *ctx = NULL; -+ int lerrno = 0; - -+ ctx = cbdata->state->nss_context; -+ -+ if (ctx == NULL) { -+ return NULL; -+ } - repeat: - if (cbdata->nsswitch_buffer == NULL) { - return NULL; - } - -- rc = getgrgid_r(gid, &grp, -- cbdata->nsswitch_buffer, -- cbdata->nsswitch_buffer_len, &result); -+ rc = ctx->getgrgid_r(gid, &grp, -+ cbdata->nsswitch_buffer, -+ cbdata->nsswitch_buffer_len, &lerrno); - -- if ((result == NULL) || (rc != 0)) { -- if (rc == ERANGE) { -+ if ((rc != NSS_STATUS_SUCCESS)) { -+ if (lerrno == ERANGE) { - buf = realloc(cbdata->nsswitch_buffer, cbdata->nsswitch_buffer_len * 2); - if (buf != NULL) { - cbdata->nsswitch_buffer = buf; -@@ -532,19 +693,28 @@ backend_retrieve_group_list_from_nsswitch(char *user_name, char *container_sdn, - gid_t *grouplist, *tmp_list; - Slapi_Entry **entries, *entry, **tmp; - char *buf = NULL; -- int rc, ngroups, i, idx; -- -+ int i, idx; -+ struct nss_ops_ctx *ctx = NULL; -+ int lerrno = 0; -+ long int ngroups = 0; -+ long int start = 0; -+ enum nss_status rc; -+ -+ ctx = cbdata->state->nss_context; -+ if (ctx == NULL) { -+ return NULL; -+ } - repeat: - if (cbdata->nsswitch_buffer == NULL) { - return NULL; - } - -- rc = getpwnam_r(user_name, &pwd, -- cbdata->nsswitch_buffer, -- cbdata->nsswitch_buffer_len, &pwd_result); -+ rc = ctx->getpwnam_r(user_name, &pwd, -+ cbdata->nsswitch_buffer, -+ cbdata->nsswitch_buffer_len, &lerrno); - -- if ((pwd_result == NULL) || (rc != 0)) { -- if (rc == ERANGE) { -+ if ((rc != NSS_STATUS_SUCCESS)) { -+ if (lerrno == ERANGE) { - buf = realloc(cbdata->nsswitch_buffer, cbdata->nsswitch_buffer_len * 2); - if (buf != NULL) { - cbdata->nsswitch_buffer = buf; -@@ -559,14 +729,20 @@ repeat: - } - - ngroups = 32; -+ start = 0; - grouplist = malloc(sizeof(gid_t) * ngroups); - if (grouplist == NULL) { - return NULL; - } - -+ grouplist[0] = pwd.pw_gid; -+ start++; -+ - do { -- rc = getgrouplist(user_name, pwd.pw_gid, grouplist, &ngroups); -- if (rc < ngroups) { -+ rc = ctx->initgroups_dyn(user_name, pwd.pw_gid, -+ &start, &ngroups, &grouplist, -+ -1, &lerrno); -+ if ((rc != NSS_STATUS_SUCCESS)) { - tmp_list = realloc(grouplist, ngroups * sizeof(gid_t)); - if (tmp_list == NULL) { - free(grouplist); -@@ -574,7 +750,7 @@ repeat: - } - grouplist = tmp_list; - } -- } while (rc != ngroups); -+ } while (rc != NSS_STATUS_SUCCESS); - - entries = calloc(ngroups + 1, sizeof(entries[0])); - if (entries == NULL) { -diff --git a/src/back-sch.h b/src/back-sch.h -index 26e12d1..1aedf36 100644 ---- a/src/back-sch.h -+++ b/src/back-sch.h -@@ -115,6 +115,11 @@ struct backend_search_filter_config { - - int backend_analyze_search_filter(Slapi_Filter *filter, struct backend_search_filter_config *config); - -+/* Operations against nsswitch API */ -+struct nss_ops_ctx; -+void backend_nss_init_context(struct nss_ops_ctx **nss_context); -+void backend_nss_free_context(struct nss_ops_ctx **nss_context); -+ - void backend_search_nsswitch(struct backend_set_data *set_data, - struct backend_search_cbdata *cbdata); - -diff --git a/src/plug-sch.c b/src/plug-sch.c -index 5d74beb..5a6e736 100644 ---- a/src/plug-sch.c -+++ b/src/plug-sch.c -@@ -52,6 +52,7 @@ - - #include "backend.h" - #include "back-shr.h" -+#include "back-sch.h" - #include "map.h" - #include "plugin.h" - #include "portmap.h" -@@ -109,6 +110,7 @@ plugin_startup(Slapi_PBlock *pb) - /* Populate the tree of fake entries. */ - backend_startup(pb, state); - state->pam_lock = wrap_new_rwlock(); -+ backend_nss_init_context((struct nss_ops_ctx**) &state->nss_context); - /* Note that the plugin is ready to go. */ - slapi_log_error(SLAPI_LOG_PLUGIN, plugin_description.spd_id, - "plugin startup completed\n"); -@@ -123,6 +125,7 @@ plugin_shutdown(Slapi_PBlock *pb) - map_done(state); - wrap_free_rwlock(state->pam_lock); - state->pam_lock = NULL; -+ backend_nss_free_context((struct nss_ops_ctx**) &state->nss_context); - state->plugin_base = NULL; - slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, - "plugin shutdown completed\n"); -diff --git a/src/plugin.h b/src/plugin.h -index 3967fb0..94ad747 100644 ---- a/src/plugin.h -+++ b/src/plugin.h -@@ -46,6 +46,7 @@ struct plugin_state { - } listener[4]; - /* Schema compat-specific data. */ - struct wrapped_rwlock *pam_lock; -+ void *nss_context; - }; - - #endif --- -2.1.0 - diff --git a/SOURCES/slapi-nis-use-slapi_entry_find_attr.patch b/SOURCES/slapi-nis-use-slapi_entry_find_attr.patch deleted file mode 100644 index 2cb9ad3..0000000 --- a/SOURCES/slapi-nis-use-slapi_entry_find_attr.patch +++ /dev/null @@ -1,65 +0,0 @@ -From 59198a21f15d310ad693f8b8cbd0df9595234ef5 Mon Sep 17 00:00:00 2001 -From: Alexander Bokovoy -Date: Tue, 14 Oct 2014 17:25:46 +0300 -Subject: [PATCH] Use slapi_entry_find_attr instead of slapi_entry_attr_exists - -To keep slapi-nis code portable to older versions of 389-ds-base, -avoid using slapi_entry_attr_exists() as it was only introduced in -389-ds-base 1.3.3.0. ---- - src/back-sch-idview.c | 3 ++- - src/back-sch.c | 7 ++++++- - 2 files changed, 8 insertions(+), 2 deletions(-) - -diff --git a/src/back-sch-idview.c b/src/back-sch-idview.c -index f1150cd..93fbab5 100644 ---- a/src/back-sch-idview.c -+++ b/src/back-sch-idview.c -@@ -157,6 +157,7 @@ idview_process_overrides(struct backend_search_cbdata *cbdata, - /* 2. If there is indeed an override, replace attribute values except for the ones that should be ignored */ - if (override_entry != NULL) { - Slapi_Attr *override_attr = NULL; -+ Slapi_Attr *sattr = NULL; - - result = slapi_entry_first_attr(override_entry, &override_attr); - while (result == 0) { -@@ -173,7 +174,7 @@ idview_process_overrides(struct backend_search_cbdata *cbdata, - if (filterout_attrs[i] == NULL) { - /* Replace the attribute's value with the override or - * add an override value if the attribute didn't exist */ -- result = slapi_entry_attr_exists(entry, override_type); -+ result = slapi_entry_attr_find(entry, override_type, &sattr); - if (result == 1) { - result = slapi_entry_attr_delete(entry, override_type); - } -diff --git a/src/back-sch.c b/src/back-sch.c -index 2388d2f..d0ed323 100644 ---- a/src/back-sch.c -+++ b/src/back-sch.c -@@ -997,9 +997,11 @@ backend_search_entry_cb(const char *domain, const char *map, bool_t secure, - { - Slapi_DN *sdn; - Slapi_Entry *entry; -+ Slapi_Attr *attr = NULL; - struct backend_search_cbdata *cbdata; - struct backend_entry_data *entry_data; - int result; -+ bool_t is_attr_exists = FALSE; - - cbdata = cb_data; - entry_data = backend_data; -@@ -1042,7 +1044,10 @@ backend_search_entry_cb(const char *domain, const char *map, bool_t secure, - idview_process_overrides(cbdata, key, map, domain, entry); - } - -- if (slapi_entry_attr_exists(entry, IPA_IDVIEWS_ATTR_ANCHORUUID) == 1) { -+ /* slapi_entry_attr_exists() was introduced only in https://fedorahosted.org/389/ticket/47710 */ -+ is_attr_exists = slapi_entry_attr_find(entry, IPA_IDVIEWS_ATTR_ANCHORUUID, &attr) == 0; -+ -+ if (is_attr_exists == TRUE) { - slapi_entry_attr_delete(entry, IPA_IDVIEWS_ATTR_ANCHORUUID); - slapi_entry_delete_string(entry, "objectClass", "ipaOverrideTarget"); - } --- -2.1.0 - diff --git a/SPECS/slapi-nis.spec b/SPECS/slapi-nis.spec index 72b396f..6b79862 100644 --- a/SPECS/slapi-nis.spec +++ b/SPECS/slapi-nis.spec @@ -10,38 +10,23 @@ %endif Name: slapi-nis -Version: 0.54 -Release: 11%{?dist} +Version: 0.56.0 +Release: 4%{?dist} Summary: NIS Server and Schema Compatibility plugins for Directory Server Group: System Environment/Daemons License: GPLv2 URL: http://slapi-nis.fedorahosted.org/ Source0: https://fedorahosted.org/releases/s/l/slapi-nis/slapi-nis-%{version}.tar.gz Source1: https://fedorahosted.org/releases/s/l/slapi-nis/slapi-nis-%{version}.tar.gz.sig -Patch0: slapi-nis-use-slapi_entry_find_attr.patch -Patch1: slapi-nis-ID-views-ignore-searches-for-views-outside-the-subtrees.patch -Patch2: slapi-nis-schema-compat-support-ID-overrides-in-bind-callback.patch -Patch3: slapi-nis-use-libnss_sss.so.2-explicitly.patch -Patch4: slapi-nis-nss-make-sure-to-remember-the-length-of-reallocated.patch -Patch5: slapi-nis-nss-Make-sure-default-buffer-for-nsswitch-operations-is-.patch -Patch6: slapi-nis-don-t-search-in-SSSD-when-memberUid-has-no.patch -Patch7: slapi-nis-delay-sending-responses-from-compat-tree-a.patch -Patch8: slapi-nis-fix-processing-of-ID-views.patch -Patch15: slapi-nis-extmem-0005-slapi-nis-populate-data-trees-asynchronously-after-L.patch -Patch16: slapi-nis-extmem-0006-nss-force-lower-case-for-memberUid-attribute-as-per-.patch -Patch17: slapi-nis-extmem-0007-slapi-nis-add-support-to-resolve-external-members-of.patch -Patch18: slapi-nis-extmem-0008-slapi-nis-process-requests-only-when-initialization-.patch -Patch19: slapi-nis-extmem-0009-slapi-nis-serialize-map-cache-initialization.patch -Patch20: slapi-nis-extmem-0010-nis-lock-out-accounts-if-nsAccountLock-is-TRUE.patch -Patch21: slapi-nis-extmem-0011-idviews-bind-with-original-DN-if-ID-view-does-not-ov.patch -Patch22: slapi-nis-priming-0001-wrap-add-wrapped-mutex-support.patch -Patch23: slapi-nis-priming-0002-backend-support-backend-shutdown-for-priming-thread-.patch -Patch24: slapi-nis-priming-0003-nis-add-backend-shutdown-support-to-stop-priming-thr.patch -Patch25: slapi-nis-priming-0004-schema-compat-add-backend-shutdown-support-for-primi.patch -Patch26: slapi-0003-slapi-nis-resolve-IPA-groups-with-fully-qualified-su.patch - +Patch1: slapi-0001-Move-advance-definition-of-backend_passwdmod_extop-b.patch +Patch2: slapi-0002-Initialize-ret-before-use.patch +Patch3: slapi-0003-slapi-nis-resolve-IPA-groups-with-fully-qualified-su.patch +Patch4: slapi-0004-Declare-int-backend_init_extop-for-reuse-in-plug-sch.patch +Patch6: slapi-0006-back-sch-do-not-clobber-target-of-the-pblock-for-idv.patch +Patch7: slapi-0007-back-sch-nss-for-users-with-aliases-return-alias-as-.patch BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -BuildRequires: 389-ds-base-devel, %{ldap_impl}-devel + +BuildRequires: 389-ds-base-devel >= 1.3.5.6, %{ldap_impl}-devel BuildRequires: nspr-devel, nss-devel, /usr/bin/rpcgen %if 0%{?fedora} > 18 || 0%{?rhel} > 6 BuildRequires: libsss_nss_idmap-devel @@ -61,6 +46,7 @@ BuildRequires: libtirpc-devel %if 0%{?rhel} > 0 && 0%{?rhel} < 7 ExclusiveArch: x86_64 %{ix86} %endif +Requires: 389-ds-base >= 1.3.5.6 %description This package provides two plugins for Red Hat and 389 Directory Server. @@ -77,32 +63,13 @@ for attributes from multiple entries in the tree. %prep %setup -q -%patch0 -p1 %patch1 -p1 %patch2 -p1 %patch3 -p1 %patch4 -p1 -%patch5 -p1 +# patch 5 is part of patch 3 %patch6 -p1 %patch7 -p1 -%patch8 -p1 -# patchset for "External membership of IPA groups" -%patch15 -p1 -%patch16 -p1 -%patch17 -p1 -%patch18 -p1 -%patch19 -p1 -# "Lock out NIS entries with nsAccountLock set to TRUE" -%patch20 -p1 -# "Support bind with non-overridden uid rdn" -%patch21 -p1 -# "Wait for priming thread join on shutdown" -%patch22 -p1 -%patch23 -p1 -%patch24 -p1 -%patch25 -p1 -# "Support SSSD 1.14+" -%patch26 -p1 %build %configure --disable-static --with-tcp-wrappers --with-ldap=%{ldap_impl} \ @@ -133,31 +100,45 @@ rm -rf $RPM_BUILD_ROOT %{_sbindir}/nisserver-plugin-defs %changelog -* Tue Jul 12 2016 Alexander Bokovoy - 0.54-11 -- Update SSSD 1.14+ support patch to avoid double free -- Resolves: #1350309 - -* Tue Jun 28 2016 Alexander Bokovoy - 0.54-10 -- Support SSSD 1.14+ when default_domain_suffix is set on IPA master -- Resolves: #1350309 +* Tue Aug 09 2016 Alexander Bokovoy - 0.56.0-4 +- Fixed: UPN-based search for AD users does not match an entry in slapi-nis map cache +- Resolves: #1361123 +- Fixed: slapi-nis plugin modifies DS data +- Resolves: #1360245 + +* Tue Jul 12 2016 Alexander Bokovoy - 0.56.0-3 +- Fix double free in SSSD 1.14+ support +- Resolves: #1353549 + +* Mon Jun 20 2016 Alexander Bokovoy - 0.56.0-2 +- Fix reported coverity issues +- Make sure slapi-nis continue to work with SSSD 1.14 when default domain is defined +- Resolves: #1292148 + +* Mon Jun 20 2016 Alexander Bokovoy - 0.56.0-1 +- New upstream release: + - support updating passwords for the users from the primary tree + - populate map cache in a separate thread to avoid blocking the DS +- Resolves: #1292148 * Tue Apr 26 2016 Alexander Bokovoy - 0.54-9 - Reworked priming thread shutdown support - Resolves: #1327197 - + * Fri Apr 15 2016 Alexander Bokovoy - 0.54-8 - Wait for priming thread to finish before shutdown - Resolves: #1327197 + * Tue Feb 23 2016 Alexander Bokovoy - 0.54-7 -- Resolves: #1311257 -- Resolves: #1311012 +- Resolves: #1138797 +- Resolves: #1301300 * Fri Nov 13 2015 Alexander Bokovoy - 0.54-6 - delay sending responses from compat tree after map cache search -- Resolves: #1281748 +- Resolves: #1273587 - fix processing of ID views -- Resolves: #1281750, #1281752 +- Resolves: #1277576, #1265465 * Tue Jul 28 2015 Alexander Bokovoy - 0.54-5 - Don't lookup groups in SSSD for memberUid without @domain