From 28b0a00b8c1aec25116367c5e8e3718b4514fc3e Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 12 Sep 2017 18:02:57 +0300 Subject: [PATCH 1/6] Update spec file to Fedora version --- slapi-nis.spec | 31 ++++++++++++++++++++++++++----- 1 file changed, 26 insertions(+), 5 deletions(-) diff --git a/slapi-nis.spec b/slapi-nis.spec index c50cd59..de5bd6d 100644 --- a/slapi-nis.spec +++ b/slapi-nis.spec @@ -11,7 +11,7 @@ Name: slapi-nis Version: 0.56.1 -Release: 1%{?dist} +Release: 2%{?dist} Summary: NIS Server and Schema Compatibility plugins for Directory Server Group: System Environment/Daemons License: GPLv2 @@ -19,7 +19,7 @@ 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 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n) -BuildRequires: 389-ds-base-devel > 1.3.5.6, %{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 @@ -39,6 +39,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. @@ -85,22 +86,36 @@ rm -rf $RPM_BUILD_ROOT %{_sbindir}/nisserver-plugin-defs %changelog -* Sun Aug 07 2016 Alexander Bokovoy - 0.56.1-1 +* Sat Feb 11 2017 Fedora Release Engineering - 0.56.1-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild + +* Mon Aug 08 2016 Alexander Bokovoy - 0.56.1-1 - Support querying external users by UPN alias - Don't clobber target of the pblock for ID views +* Mon Jun 20 2016 Alexander Bokovoy - 0.56.0-2 +- Updated upstream tarball + * Mon Jun 20 2016 Alexander Bokovoy - 0.56-1 -- Add priming thread to populate the map cache without blocking the DS - Add support for changing passwords for users from a primary tree - requires DS 1.3.5.6 or later +* Mon May 30 2016 Alexander Bokovoy - 0.55-3 +- Add support to properly shutdown priming cache from RHEL 7.2.4 + +* Fri Feb 05 2016 Fedora Release Engineering - 0.55-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_24_Mass_Rebuild + * Tue Jan 26 2016 Alexander Bokovoy - 0.55-1 - Support external members of IPA groups in schema compat - Support bind over ID overrides when uid is not overridden - Populate schema compat trees in parallel to LDAP server startup +* Fri Jun 19 2015 Fedora Release Engineering - 0.54.2-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_23_Mass_Rebuild + * Thu Mar 26 2015 Alexander Bokovoy - 0.54.2-1 -- CVE-2015-0283 slapi-nis: infinite loop in getgrnam_r() and getgrgid_r() +- CVE-2015-0283 slapi-nis: infinite loop in getgrnam_r() and getgrgid_r() (#1206049) - Make sure nss_sss.so.2 module is used directly - Allow building slapi-nis with ID views against 389-ds-base from RHEL7.0/CentOS7.0 releases @@ -113,6 +128,12 @@ rm -rf $RPM_BUILD_ROOT - Allow searching SSSD-provided users as memberUid case-insensitevly Fixes bug #1130131 +* Mon Aug 18 2014 Fedora Release Engineering - 0.53-3 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_22_Mass_Rebuild + +* Sun Jun 08 2014 Fedora Release Engineering - 0.53-2 +- Rebuilt for https://fedoraproject.org/wiki/Fedora_21_Mass_Rebuild + * Tue Apr 22 2014 Nalin Dahyabhai - 0.53-1 - correct the default NIS map settings for hosts.byname and hosts.byaddr, from report by Rik Megens -- 2.13.5 From 96ff6873b024718fcbb7b011eee58aab84c3086f Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mon, 11 Sep 2017 15:32:38 +0300 Subject: [PATCH 2/6] Move a helper to build DN to a format.c --- src/back-sch-nss.c | 45 ++------------------------------------------- src/format.c | 41 +++++++++++++++++++++++++++++++++++++++++ src/format.h | 2 ++ 3 files changed, 45 insertions(+), 43 deletions(-) diff --git a/src/back-sch-nss.c b/src/back-sch-nss.c index db63e59..e4d027e 100644 --- a/src/back-sch-nss.c +++ b/src/back-sch-nss.c @@ -186,47 +186,6 @@ backend_search_filter_has_cn_uid(Slapi_Filter *filter, void *arg) return SLAPI_FILTER_SCAN_CONTINUE; } -static char * -backend_build_dn(const char *attribute, const char *value, - const char *container_sdn) -{ - Slapi_RDN *rdn; - Slapi_DN *sdn; - char *val, *dn = NULL; - const char *ndn, *hexchars = "0123456789ABCDEF"; - int i; - - val = malloc(strlen(value) * 3 + 1); - if (val == NULL) { - return NULL; - } - rdn = slapi_rdn_new(); - if (rdn == NULL) { - free(val); - return NULL; - } - for (i = 0; value[i] != '\0'; i++) { - val[i * 3] = '\\'; - val[i * 3 + 1] = hexchars[(value[i] & 0xf0) >> 4]; - val[i * 3 + 2] = hexchars[value[i] & 0xf]; - } - val[i * 3] = '\0'; - if (slapi_rdn_add(rdn, attribute, val) == 1) { - sdn = slapi_sdn_new_dn_byval(container_sdn); - if (sdn != NULL) { - sdn = slapi_sdn_add_rdn(sdn, rdn); - ndn = slapi_sdn_get_ndn(sdn); - if (ndn != NULL) { - dn = slapi_ch_strdup(ndn); - } - slapi_sdn_free(&sdn); - } - } - free(val); - slapi_rdn_free(&rdn); - return dn; -} - static Slapi_Entry * backend_make_user_entry_from_nsswitch_passwd(struct passwd *pwd, char *container_sdn, @@ -257,7 +216,7 @@ backend_make_user_entry_from_nsswitch_passwd(struct passwd *pwd, return NULL; } - dn = backend_build_dn("uid", name, container_sdn); + dn = format_build_dn("uid", name, container_sdn); if (dn == NULL) { slapi_log_error(SLAPI_LOG_FATAL, cbdata->state->plugin_desc->spd_id, @@ -556,7 +515,7 @@ backend_make_group_entry_from_nsswitch_group(struct group *grp, return NULL; } - dn = backend_build_dn("cn", grp->gr_name, container_sdn); + dn = format_build_dn("cn", grp->gr_name, container_sdn); if (dn == NULL) { slapi_log_error(SLAPI_LOG_FATAL, cbdata->state->plugin_desc->spd_id, diff --git a/src/format.c b/src/format.c index ee6b8f3..ae4824c 100644 --- a/src/format.c +++ b/src/format.c @@ -4825,3 +4825,44 @@ format_escape_for_filter(const char *unescaped) } return ret; } + +char * +format_build_dn(const char *attribute, const char *value, + const char *container_sdn) +{ + Slapi_RDN *rdn; + Slapi_DN *sdn; + char *val, *dn = NULL; + const char *ndn, *hexchars = "0123456789ABCDEF"; + int i; + + val = malloc(strlen(value) * 3 + 1); + if (val == NULL) { + return NULL; + } + rdn = slapi_rdn_new(); + if (rdn == NULL) { + free(val); + return NULL; + } + for (i = 0; value[i] != '\0'; i++) { + val[i * 3] = '\\'; + val[i * 3 + 1] = hexchars[(value[i] & 0xf0) >> 4]; + val[i * 3 + 2] = hexchars[value[i] & 0xf]; + } + val[i * 3] = '\0'; + if (slapi_rdn_add(rdn, attribute, val) == 1) { + sdn = slapi_sdn_new_dn_byval(container_sdn); + if (sdn != NULL) { + sdn = slapi_sdn_add_rdn(sdn, rdn); + ndn = slapi_sdn_get_ndn(sdn); + if (ndn != NULL) { + dn = slapi_ch_strdup(ndn); + } + slapi_sdn_free(&sdn); + } + } + free(val); + slapi_rdn_free(&rdn); + return dn; +} diff --git a/src/format.h b/src/format.h index 4cde2dc..626d4a9 100644 --- a/src/format.h +++ b/src/format.h @@ -83,4 +83,6 @@ char **format_get_data_set(struct plugin_state *state, unsigned int **data_lengths); char *format_escape_for_filter(const char *unescaped); +char *format_build_dn(const char *attribute, const char *value, + const char *container_sdn); #endif -- 2.13.5 From 79ddc12c93920840e9fbdf5c8ea25db1c4166af5 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 12 Sep 2017 14:52:21 +0300 Subject: [PATCH 3/6] Add dummy handler for a related add/delete/modify to NIS plugin NIS doesn't need to handle ID overrides, it has to always skip related entries --- src/back-nis.c | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) diff --git a/src/back-nis.c b/src/back-nis.c index 7fb191d..244beba 100644 --- a/src/back-nis.c +++ b/src/back-nis.c @@ -1014,6 +1014,34 @@ backend_check_empty(struct plugin_state *state, } } +bool_t +backend_entry_is_add_related(const char *group, const char *set, bool_t flag, + void *shared_set_data, + Slapi_PBlock *pb, + Slapi_Entry *e) +{ + return FALSE; +} + +bool_t +backend_entry_is_modify_related(const char *group, const char *set, bool_t flag, + void *shared_set_data, + Slapi_PBlock *pb, + Slapi_Entry *e_pre, + Slapi_Entry *e_post) +{ + return FALSE; +} + +bool_t +backend_entry_is_delete_related(const char *group, const char *set, bool_t flag, + void *shared_set_data, + Slapi_PBlock *pb, + Slapi_Entry *e) +{ + return FALSE; +} + /* Scan for the list of configured domains and maps. */ void backend_startup(Slapi_PBlock *pb, struct plugin_state *state) -- 2.13.5 From 6fb0a03de3897d4ec289c22eaa00203d6ea97935 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Mon, 11 Sep 2017 15:33:24 +0300 Subject: [PATCH 4/6] WIP: track changes to ID overrides and evict map cache entries Plug into a processing of LDAP add/delete/modify to see if an ID override entry was added/deleted/updated. ID overrides aren't directly used to produce map cache entries but when AD user or group is resolved, SSSD on IPA master amends that information with ID Override from a Default Trust View. Since nothing else would remove AD user or group entry from the map cache on ID override change, handle their removal here. Check if we have any nssswitch-generated entry in a map cache that corresponds to this entry. Such entries would be evicted from the map cache to allow their refresh. --- src/back-sch.c | 166 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 166 insertions(+) diff --git a/src/back-sch.c b/src/back-sch.c index e15988f..39da302 100644 --- a/src/back-sch.c +++ b/src/back-sch.c @@ -33,6 +33,7 @@ #ifdef HAVE_DIRSRV_SLAPI_PLUGIN_H #include #include +#include #include #include #else @@ -2099,6 +2100,171 @@ backend_write_cb(Slapi_PBlock *pb, struct plugin_state *state) return ret; } +#ifdef USE_IPA_IDVIEWS +/* Check if ID override applies to an entry in our map cache + * and remove the entry in case it does. */ + +static bool_t +backend__get_original_uid_and_ndn(Slapi_Entry *e, + char **original_uid, + const char **original_anchor) +{ + char **elem = NULL; + char *v = NULL; + char *ndn = NULL; + char *view = NULL; + int n_elem = 0; + int i = 0; + + if (e == NULL) { + return FALSE; + } + + elem = slapi_entry_attr_get_charray_ext(e, "objectClass", &n_elem); + if (elem == NULL) { + /* weird, objectClass should be existing */ + return FALSE; + } + + for (i=0; i < n_elem; i++) { + if (strncasecmp(elem[i], "ipaOverrideAnchor", 17) == 0) { + break; + } + } + + slapi_ch_array_free(elem); + if (i == n_elem) { + /* This is not an override, bail out */ + return FALSE; + } + + ndn = slapi_entry_get_ndn(e); + if (ndn == NULL) { + return FALSE; + } + + view = PL_strcasestr(ndn, "cn=Default Trust View,"); + if (view == NULL || view == ndn) { + return FALSE; + } + + /* This is an ID override, we need to search for a referenced ipaOriginalUid or cn in our maps */ + v = slapi_entry_attr_get_charptr(e, "ipaOriginalUid"); + if (v == NULL) { + v = slapi_entry_attr_get_charptr(e, "cn"); + if (v == NULL) { + return FALSE; + } + } + + *original_uid = v; + *original_anchor = ndn; + return TRUE; +} + +bool_t +backend_entry_is_add_related(const char *group, const char *set, bool_t flag, + void *shared_set_data, + Slapi_PBlock *pb, + Slapi_Entry *e) +{ + struct backend_set_data *set_data; + struct plugin_state *state = NULL; + char *id = NULL; + char *original_uid = NULL; + const char *original_anchor = NULL; + const char *rdn_attribute[] = {NULL, "uid=%s,%s,%s", "cn=%s,%s,%s"}; + bool_t result = FALSE; + + set_data = shared_set_data; + + /* We only interested in NSSWITCH-capable maps */ + if (set_data->check_nsswitch == SCH_NSSWITCH_NONE) { + return FALSE; + } + + /* See if the entry pre modification had original UID */ + if (!backend__get_original_uid_and_ndn(e, + &original_uid, + &original_anchor)) { + return FALSE; + } + + id = slapi_ch_smprintf(rdn_attribute[set_data->check_nsswitch], + original_uid, set, group); + + if (id == NULL) { + slapi_ch_free_string(&original_uid); + return FALSE; + } + + slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &state); + result = map_data_check_entry(state, group, set, id); + if (result) { + slapi_log_error(SLAPI_LOG_PLUGIN, state->plugin_desc->spd_id, + "evicted entry %s due to changed content of ID override %s\n", + id, original_anchor); + + /* An entry corresponding to our target is found, evict it */ + map_data_unset_entry(state, group, set, id); + } + + slapi_ch_free_string(&id); + slapi_ch_free_string(&original_uid); + return result; +} + +bool_t +backend_entry_is_modify_related(const char *group, const char *set, bool_t flag, + void *shared_set_data, + Slapi_PBlock *pb, + Slapi_Entry *e_pre, + Slapi_Entry *e_post) +{ + return backend_entry_is_add_related(group, set, flag, shared_set_data, pb, e_pre); +} + +bool_t +backend_entry_is_delete_related(const char *group, const char *set, bool_t flag, + void *shared_set_data, + Slapi_PBlock *pb, + Slapi_Entry *e) +{ + return backend_entry_is_add_related(group, set, flag, shared_set_data, pb, e); +} + +#else + +bool_t +backend_entry_is_add_related(const char *group, const char *set, bool_t flag, + void *shared_set_data, + Slapi_PBlock *pb, + Slapi_Entry *e) +{ + return FALSE; +} + +bool_t +backend_entry_is_modify_related(const char *group, const char *set, bool_t flag, + void *shared_set_data, + Slapi_PBlock *pb, + Slapi_Entry *e_pre, + Slapi_Entry *e_post) +{ + return FALSE; +} + +bool_t +backend_entry_is_delete_related(const char *group, const char *set, bool_t flag, + void *shared_set_data, + Slapi_PBlock *pb, + Slapi_Entry *e) +{ + return FALSE; +} + +#endif + static int backend_pre_write_cb(Slapi_PBlock *pb) { -- 2.13.5 From aa2ccb0029a197c010b3877f77f0358c72370a29 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 12 Sep 2017 14:36:45 +0300 Subject: [PATCH 5/6] Allow backends to inspect entries related to a map set Entries may be related to a map set content but not used directly to generate it. An example would be ID overrides in FreeIPA. An addition, removal or change of an ID override in the Default Trust View should be reflected by evicting an entry from the corresponding seti. Let backends to handle exact logic. NIS backend does not support exposing AD users so it provides set of dummy callbacks that always return FALSE (entry is not related). Schema Compat backend, on other hand, does track ID overrides in a Default Trust View in FreeIPA. --- src/back-shr.c | 55 +++++++++++++++++++++++++++++++++++++++++++------------ src/backend.h | 20 ++++++++++++++++++++ 2 files changed, 63 insertions(+), 12 deletions(-) diff --git a/src/back-shr.c b/src/back-shr.c index 7842e05..a7ea92f 100644 --- a/src/back-shr.c +++ b/src/back-shr.c @@ -1856,11 +1856,21 @@ backend_shr_add_entry_cb(const char *group, const char *set, bool_t secure, /* If the entry doesn't match the set, skip it. */ if (!backend_shr_entry_matches_set(set_data, cbdata->pb, cbdata->e)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata->state->plugin_desc->spd_id, - "entry \"%s\" does not belong in " - "\"%s\"/\"%s\"\n", - cbdata->ndn, group, set); + /* Give backend a chance to perform other operations on the add op. + * For example, ID override addition in FreeIPA need to be noted to + * evict AD user/group entries from a map cache while ID overrides + * themselves aren't present in any map. + * Note that we could do this as a part of backend_shr_entry_matches_set() + * but it is better to isolate this operation in a separate call. */ + if (!backend_entry_is_add_related(group, set, secure, + set_data, cbdata->pb, + cbdata->e)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "entry \"%s\" does not belong in " + "\"%s\"/\"%s\"\n", + cbdata->ndn, group, set); + } return TRUE; } @@ -2010,13 +2020,24 @@ backend_shr_modify_entry_cb(const char *group, const char *set, bool_t flag, cbdata->e_post) && !backend_shr_entry_matches_set(set_data, cbdata->pb, cbdata->e_pre)) { - slapi_log_error(SLAPI_LOG_PLUGIN, - cbdata->state->plugin_desc->spd_id, - "\"%s\" not in \"%s\"/\"%s\", " - "before or after modify\n", - cbdata->ndn, - set_data->group, - set_data->set); + /* Give backend a chance to perform other operations on the modify op. + * For example, ID override updates in FreeIPA need to be noted to + * evict AD user/group entries from a map cache while ID overrides + * themselves aren't present in any map. + * Note that we could do this as a part of backend_shr_entry_matches_set() + * but it is better to isolate this operation in a separate call. */ + if (!backend_entry_is_modify_related(group, set, flag, + set_data, cbdata->pb, + cbdata->e_pre, + cbdata->e_post)) { + slapi_log_error(SLAPI_LOG_PLUGIN, + cbdata->state->plugin_desc->spd_id, + "\"%s\" not in \"%s\"/\"%s\", " + "before or after modify\n", + cbdata->ndn, + set_data->group, + set_data->set); + } return TRUE; } if (set_data->skip_uninteresting_updates && @@ -2631,6 +2652,16 @@ backend_shr_delete_entry_cb(const char *group, const char *set, bool_t flag, group, set, set_data->group, set_data->set, cbdata->ndn); map_data_unset_entry(cbdata->state, group, set, cbdata->ndn); + } else { + /* Give backend a chance to perform other operations on the delete op. + * For example, ID override removal in FreeIPA need to be noted to + * evict AD user/group entries from a map cache while ID overrides + * themselves aren't present in any map. + * Note that we could do this as a part of backend_shr_entry_matches_set() + * but it is better to isolate this operation in a separate call. */ + (void) backend_entry_is_delete_related(group, set, flag, + set_data, cbdata->pb, + cbdata->e); } return TRUE; } diff --git a/src/backend.h b/src/backend.h index 4608d2d..f0a5bbb 100644 --- a/src/backend.h +++ b/src/backend.h @@ -115,4 +115,24 @@ void backend_update_params(Slapi_PBlock *pb, struct plugin_state *state); bool_t backend_shr_is_caller(struct plugin_state *state, struct slapi_pblock *pb); +/* Check if an operation is performed on an entry that is related to + * any entry in the set. This allows to catch changes of the entries that + * aren't directly included in the map set but should affect the set. */ +bool_t +backend_entry_is_modify_related(const char *group, const char *set, bool_t flag, + void *shared_set_data, + Slapi_PBlock *pb, + Slapi_Entry *e_pre, + Slapi_Entry *e_post); +bool_t +backend_entry_is_add_related(const char *group, const char *set, bool_t flag, + void *shared_set_data, + Slapi_PBlock *pb, + Slapi_Entry *e); +bool_t +backend_entry_is_delete_related(const char *group, const char *set, bool_t flag, + void *shared_set_data, + Slapi_PBlock *pb, + Slapi_Entry *e); + #endif -- 2.13.5 From b184ea309a94660c13212e156be3890f6e680be5 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 12 Sep 2017 18:03:32 +0300 Subject: [PATCH 6/6] WIP: spec update --- slapi-nis.spec | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/slapi-nis.spec b/slapi-nis.spec index de5bd6d..2d71949 100644 --- a/slapi-nis.spec +++ b/slapi-nis.spec @@ -11,7 +11,7 @@ Name: slapi-nis Version: 0.56.1 -Release: 2%{?dist} +Release: 2.1%{?dist} Summary: NIS Server and Schema Compatibility plugins for Directory Server Group: System Environment/Daemons License: GPLv2 @@ -86,6 +86,9 @@ rm -rf $RPM_BUILD_ROOT %{_sbindir}/nisserver-plugin-defs %changelog +* Tue Sep 12 2017 Alexander Bokovoy - 0.56.1-2.1 +- ID Overrides + * Sat Feb 11 2017 Fedora Release Engineering - 0.56.1-2 - Rebuilt for https://fedoraproject.org/wiki/Fedora_26_Mass_Rebuild -- 2.13.5