diff options
author | Alexander Bokovoy <abokovoy@redhat.com> | 2014-07-29 12:04:34 +0300 |
---|---|---|
committer | Alexander Bokovoy <abokovoy@redhat.com> | 2014-10-01 18:54:53 +0300 |
commit | 680e9a9523e57592b48700639ca9868d9eb5e766 (patch) | |
tree | e490cf7a5fbaa0adb139f528337109e45ddb9b88 /src/back-sch.c | |
parent | 7e319653c352da1e8c6354bc8f95a2306d70c54b (diff) | |
download | slapi-nis-idviews.tar.gz slapi-nis-idviews.tar.xz slapi-nis-idviews.zip |
Add support for FreeIPA ID viewsidviews
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=<view>,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.
Diffstat (limited to 'src/back-sch.c')
-rw-r--r-- | src/back-sch.c | 62 |
1 files changed, 52 insertions, 10 deletions
diff --git a/src/back-sch.c b/src/back-sch.c index 78f2627..1c388da 100644 --- a/src/back-sch.c +++ b/src/back-sch.c @@ -259,15 +259,6 @@ backend_set_config_read_config(struct plugin_state *state, Slapi_Entry *e, free(nsswitch_min_id); } - if (ret.check_nsswitch != SCH_NSSWITCH_NONE) { - /* If we're adding nsswitch-based entries to this map, make - * sure that we copy the schema-compat-origin and SID - * attributes, so that we can read the former during the BIND - * callback. */ - backend_shr_add_strlist(&ret.attribute_format, "objectClass=%ifeq(\"%{ipaNTSecurityIdentifier}\",\"\",\"\",\"extensibleObject\")"); - backend_shr_add_strlist(&ret.attribute_format, "ipaNTSecurityIdentifier=%{ipaNTSecurityIdentifier}"); - } - *pret = backend_copy_set_config(&ret); if (*pret == NULL) { if (strlen(container) > 0) { @@ -1005,6 +996,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; struct backend_search_cbdata *cbdata; struct backend_entry_data *entry_data; int result; @@ -1043,9 +1035,25 @@ backend_search_entry_cb(const char *domain, const char *map, bool_t secure, cbdata->state->plugin_desc->spd_id, "search matched %s\n", slapi_sdn_get_ndn(sdn)); - slapi_send_ldap_search_entry(cbdata->pb, entry_data->e, NULL, + entry = entry_data->e; +#ifdef USE_IPA_IDVIEWS + if (cbdata->idview != NULL) { + entry = slapi_entry_dup(entry_data->e); + idview_process_overrides(cbdata, key, map, domain, entry); + } + + if (slapi_entry_attr_exists(entry, IPA_IDVIEWS_ATTR_ANCHORUUID) == 1) { + slapi_entry_attr_delete(entry, IPA_IDVIEWS_ATTR_ANCHORUUID); + slapi_entry_delete_string(entry, "objectClass", "ipaOverrideTarget"); + } +#endif + slapi_send_ldap_search_entry(cbdata->pb, entry, NULL, cbdata->attrs, cbdata->attrsonly); cbdata->n_entries++; + + if (entry != entry_data->e) { + slapi_entry_free(entry); + } break; } @@ -1104,6 +1112,13 @@ backend_search_set_cb(const char *group, const char *set, bool_t flag, slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id, "search matched %s\n", ndn); +#ifdef USE_IPA_IDVIEWS + if (cbdata->idview != NULL) { + idview_process_overrides(cbdata, NULL, + set_data->common.set, + set_data->common.group, set_entry); + } +#endif slapi_send_ldap_search_entry(cbdata->pb, set_entry, NULL, cbdata->attrs, cbdata->attrsonly); @@ -1216,6 +1231,11 @@ backend_search_group_cb(const char *group, void *cb_data) slapi_log_error(SLAPI_LOG_PLUGIN, cbdata->state->plugin_desc->spd_id, "search matched %s\n", group); +#ifdef USE_IPA_IDVIEWS + if (cbdata->idview != NULL) { + idview_process_overrides(cbdata, NULL, NULL, group, group_entry); + } +#endif slapi_send_ldap_search_entry(cbdata->pb, group_entry, NULL, cbdata->attrs, cbdata->attrsonly); @@ -1313,11 +1333,16 @@ backend_search_cb(Slapi_PBlock *pb) cbdata.n_entries = 0; cbdata.staged = NULL; cbdata.cur_staged = NULL; + cbdata.idview = NULL; + cbdata.overrides = NULL; /* 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, 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)) { @@ -1326,10 +1351,18 @@ backend_search_cb(Slapi_PBlock *pb) "slapi_be_exists(\"%s\") = 0, " "ignoring search\n", cbdata.target); slapi_sdn_free(&cbdata.target_dn); + slapi_ch_free_string(&cbdata.idview); +#ifdef USE_IPA_IDVIEWS + idview_free_overrides(&cbdata); +#endif return 0; } + /* Walk the list of groups. */ wrap_inc_call_level(); +#ifdef USE_IPA_IDVIEWS + idview_replace_filter(&cbdata); +#endif if (map_rdlock() == 0) { map_data_foreach_domain(cbdata.state, backend_search_group_cb, &cbdata); @@ -1468,6 +1501,10 @@ backend_search_cb(Slapi_PBlock *pb) cbdata.n_entries, NULL); } slapi_sdn_free(&cbdata.target_dn); + slapi_ch_free_string(&cbdata.idview); +#ifdef USE_IPA_IDVIEWS + idview_free_overrides(&cbdata); +#endif free(cbdata.closest_match); free(cbdata.text); return cbdata.answer ? -1 : 0; @@ -1525,6 +1562,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 *idview = NULL; slapi_pblock_get(pb, SLAPI_PLUGIN_PRIVATE, &cbdata.state); if (cbdata.state->plugin_base == NULL) { @@ -1533,6 +1571,9 @@ 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; @@ -1542,6 +1583,7 @@ backend_locate(Slapi_PBlock *pb, struct backend_entry_data **data, const char ** *group = cbdata.entry_group; *set = cbdata.entry_set; slapi_sdn_free(&cbdata.target_dn); + slapi_ch_free_string(&idview); } /* Check if the target DN is part of this group's tree. If it is, return an |