From 680e9a9523e57592b48700639ca9868d9eb5e766 Mon Sep 17 00:00:00 2001 From: Alexander Bokovoy Date: Tue, 29 Jul 2014 12:04:34 +0300 Subject: Add support for FreeIPA ID views FreeIPA ID views allow to override POSIX attributes for certain users and groups. A support is added to allow using specific ID view when serving compatibility tree. Each user or group entry which has an override in the view is amended with the overridden values from the view before served out to the LDAP client. A view to use is specified as a part of base DN: cn=,cn=views,cn=compat,$SUFFIX where cn=compat,$SUFFIX is the original compatibility tree base DN. Each entry, when served through the view, gets new DN rewritten to specify the view. Additionally, if override in the view changes uid (for users) or cn (for groups) attribute, the entry's RDN is changed accordingly. For groups memberUid attribute is modified as well in case there is an override in the view that changes uid value of that member. FreeIPA ID views support overrides for users of trusted Active Directory domains. In case of a trusted AD domain's user or group is returned via compatibility tree, view overrides are applied in two stages: 1. SSSD applies default view for AD users 2. slapi-nis applies explicitly specified (host-specific) view on top of the entry returned by SSSD Thus, slapi-nis does not need to apply default view for AD users and if there are no host-specific views in use, there is no need to specify a view in the base DN, making overhead of a default view for AD users lower. --- src/back-sch-nss.c | 63 ++++++++++++++++++++++++++++++++++++++---------------- 1 file changed, 44 insertions(+), 19 deletions(-) (limited to 'src/back-sch-nss.c') diff --git a/src/back-sch-nss.c b/src/back-sch-nss.c index f192bb9..db57cb8 100644 --- a/src/back-sch-nss.c +++ b/src/back-sch-nss.c @@ -52,17 +52,6 @@ #include "back-sch.h" #include "format.h" -struct backend_search_filter_config { - bool_t search_user; - bool_t search_group; - bool_t search_uid; - bool_t search_gid; - bool_t search_members; - bool_t name_set; - bool_t wrong_search; - char *name; -}; - static int bvstrcasecmp(const struct berval *bval, const char *s) { @@ -127,6 +116,10 @@ backend_search_filter_has_cn_uid(Slapi_Filter *filter, void *arg) } } + if (config->callback != NULL) { + config->callback(filter, filter_type, bval, config); + } + if ((config->search_uid || config->search_gid || config->search_user || @@ -210,8 +203,6 @@ backend_make_user_entry_from_nsswitch_passwd(struct passwd *pwd, "objectClass", "top"); slapi_entry_add_string(entry, "objectClass", "posixAccount"); - slapi_entry_add_string(entry, - "objectClass", "extensibleObject"); slapi_entry_add_string(entry, "uid", pwd->pw_name); slapi_entry_attr_set_uint(entry, @@ -240,7 +231,20 @@ backend_make_user_entry_from_nsswitch_passwd(struct passwd *pwd, #ifdef HAVE_SSS_NSS_IDMAP rc = sss_nss_getsidbyid(pwd->pw_uid, &sid_str, &id_type); if ((rc == 0) && (sid_str != NULL)) { +#ifdef USE_IPA_IDVIEWS + char *anchor = NULL; + /* For overrides of AD users to work correctly, we need to generate + * ipaAnchorUUID value so that idviews can be properly searched for the override */ + anchor = slapi_ch_smprintf(":SID:%s", sid_str); + if (anchor != NULL) { + slapi_entry_add_string(entry, "objectClass", "ipaOverrideTarget"); + slapi_entry_add_string(entry, "ipaAnchorUUID", anchor); + slapi_ch_free_string(&anchor); + } +#else + slapi_entry_add_string(entry, "objectClass", "extensibleObject"); slapi_entry_add_string(entry, "ipaNTSecurityIdentifier", sid_str); +#endif free(sid_str); } #endif @@ -334,8 +338,6 @@ backend_make_group_entry_from_nsswitch_group(struct group *grp, "objectClass", "top"); slapi_entry_add_string(entry, "objectClass", "posixGroup"); - slapi_entry_add_string(entry, - "objectClass", "extensibleObject"); slapi_entry_add_string(entry, "cn", grp->gr_name); slapi_entry_attr_set_uint(entry, @@ -352,7 +354,20 @@ backend_make_group_entry_from_nsswitch_group(struct group *grp, #ifdef HAVE_SSS_NSS_IDMAP rc = sss_nss_getsidbyid(grp->gr_gid, &sid_str, &id_type); if ((rc == 0) && (sid_str != NULL)) { +#ifdef USE_IPA_IDVIEWS + char *anchor = NULL; + /* For overrides of AD users to work correctly, we need to generate + * ipaAnchorUUID value so that idviews can be properly searched for the override */ + anchor = slapi_ch_smprintf(":SID:%s", sid_str); + if (anchor != NULL) { + slapi_entry_add_string(entry, "objectClass", "ipaOverrideTarget"); + slapi_entry_add_string(entry, "ipaAnchorUUID", anchor); + slapi_ch_free_string(&anchor); + } +#else + slapi_entry_add_string(entry, "objectClass", "extensibleObject"); slapi_entry_add_string(entry, "ipaNTSecurityIdentifier", sid_str); +#endif free(sid_str); } #endif @@ -558,6 +573,16 @@ nsswitch_type_to_name(enum sch_search_nsswitch_t type) return "(unknown)"; } +int +backend_analyze_search_filter(Slapi_Filter *filter, struct backend_search_filter_config *config) +{ + int result, rc; + result = slapi_filter_apply(filter, + backend_search_filter_has_cn_uid, + config, &rc); + return (result != SLAPI_FILTER_SCAN_STOP) ? 1 : 0; +} + /* Check if the filter is one (like uid=) that should trigger an * nsswitch lookup, and if it is, make a note that we should perform such a * lookup. */ @@ -566,15 +591,15 @@ backend_search_nsswitch(struct backend_set_data *set_data, struct backend_search_cbdata *cbdata) { int result, rc; - struct backend_search_filter_config config = {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL}; + struct backend_search_filter_config config = + {FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, FALSE, NULL, NULL, NULL}; struct backend_staged_search *staged = NULL; char *idptr = NULL; unsigned long id; /* First, we search the filter to see if it includes a cn|uid= test. */ - result = slapi_filter_apply(cbdata->filter, - backend_search_filter_has_cn_uid, &config, &rc); - if ((result != SLAPI_FILTER_SCAN_STOP)) { + result = backend_analyze_search_filter(cbdata->filter, &config); + if (result != 0) { return; } -- cgit