sdap_async_netgroups.c revision b9941359b3181c42f415530d5ccad0f4664d85fa
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina Async LDAP Helper routines for netgroups
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina Sumit Bose <sbose@redhat.com>
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina Copyright (C) 2010 Red Hat
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina This program is free software; you can redistribute it and/or modify
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina it under the terms of the GNU General Public License as published by
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina the Free Software Foundation; either version 3 of the License, or
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina (at your option) any later version.
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina This program is distributed in the hope that it will be useful,
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina but WITHOUT ANY WARRANTY; without even the implied warranty of
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina GNU General Public License for more details.
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina You should have received a copy of the GNU General Public License
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina along with this program. If not, see <http://www.gnu.org/licenses/>.
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březina ret = ldap_str2dn(str, &dn, LDAP_DN_FORMAT_LDAPV3);
a1e4113a5388e34c08459c5b69679c82ac2bddc9Pavel Březinastatic errno_t sdap_save_netgroup(TALLOC_CTX *memctx,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina ret = sdap_get_netgroup_primary_name(memctx, opts, attrs, dom, &name);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_OP_FAILURE, "Failed to get netgroup name\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Processing netgroup %s\n", name);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina ret = sdap_attrs_add_string(attrs, SYSDB_ORIG_DN,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "original DN",
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina opts->netgroup_map[SDAP_AT_NETGROUP_MODSTAMP].sys_name,
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina "Original mod-Timestamp is not available for [%s].\n",
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina opts->netgroup_map[SDAP_AT_NETGROUP_MODSTAMP].sys_name,
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina timestamp = talloc_strdup(memctx, (const char*)el->values[0].data);
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina opts->netgroup_map[SDAP_AT_NETGROUP_TRIPLE].sys_name,
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina "netgroup triple",
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina opts->netgroup_map[SDAP_AT_NETGROUP_MEMBER].sys_name,
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina "original members",
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina ret = sdap_attrs_add_list(attrs, SYSDB_NETGROUP_MEMBER,
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina DEBUG(SSSDBG_TRACE_FUNC, "Storing info for netgroup %s\n", name);
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina ret = sdap_save_all_names(name, attrs, dom, SYSDB_MEMBER_NETGROUP,
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Failed to save netgroup names\n");
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina /* Make sure that any attributes we requested from LDAP that we
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina * did not receive are also removed from the sysdb
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina ret = list_missing_attrs(attrs, opts->netgroup_map, SDAP_OPTS_NETGROUP,
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Failed to list missing attributes\n");
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina /* We store memberNisNetgroup from LDAP as originalMemberNisNetgroup in
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina * sysdb. It may contain simple name or DN. That's the reason why we always
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina * translate/generate simple name and store it in SYSDB_NETGROUP_MEMBER
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina * (memberNisNetgroup) in sysdb which is internally used for searching
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina * We need to ensure if originalMemberNisNetgroup is missing,
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina * memberNisNetgroup is missing too.
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina if (string_in_list(SYSDB_ORIG_NETGROUP_MEMBER, missing, false)) {
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina ret = add_string_to_list(attrs, SYSDB_NETGROUP_MEMBER, &missing);
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Failed to add string into list\n");
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina ret = sysdb_add_netgroup(dom, name, NULL, netgroup_attrs, missing,
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina DEBUG(SSSDBG_OP_FAILURE, "Failed to save netgroup %s\n", name);
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březinaerrno_t update_dn_list(struct dn_item *dn_list, const size_t count,
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina const char *dn;
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina const char *cn;
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina for(c = 0; c < count; c++) {
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina dn = ldb_msg_find_attr_as_string(res[c], SYSDB_ORIG_DN, NULL);
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Missing original DN.\n");
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina "Found matching entry for [%s].\n", dn_item->dn);
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina cn = ldb_msg_find_attr_as_string(res[c], SYSDB_NAME, NULL);
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "Missing name.\n");
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březinastatic errno_t netgr_translate_members_ldap_step(struct tevent_req *req);
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březinastatic void netgr_translate_members_ldap_done(struct tevent_req *subreq);
132e477d69e07e02fe6e4d668c0bb6226206474aPavel Březinastruct tevent_req *netgr_translate_members_send(TALLOC_CTX *memctx,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina const char *cn_attr[] = { SYSDB_NAME, SYSDB_ORIG_DN, NULL };
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina for (c = 0; c < count; c++) {
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina ret = sysdb_attrs_get_string_array(netgroups[c],
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_TRACE_LIBS, "Missing netgroup members.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "talloc failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "Adding [%s] to DN list.\n", member_list[mc]);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina ret = sysdb_attrs_add_string(netgroups[c], SYSDB_NETGROUP_MEMBER,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "sysdb_attrs_add_string failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_TRACE_ALL, "No DNs found among netgroup members.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina dn_filter = talloc_asprintf_append(dn_filter, "(%s=%s)",
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina dn_filter = talloc_asprintf_append(dn_filter, ")");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf_append failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina sysdb_filter = talloc_asprintf(state, "(&(%s)%s)", SYSDB_NC, dn_filter);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina netgr_basedn = sysdb_netgroup_base_dn(state, dom);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina ret = sysdb_search_entry(state, sysdb, netgr_basedn, LDB_SCOPE_BASE,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina sysdb_filter, cn_attr, &sysdb_count, &sysdb_res);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_search_entry failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina ret = update_dn_list(state->dn_list, sysdb_count, sysdb_res,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "update_dn_list failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina ret = sysdb_attrs_add_string(dn_item->netgroup,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "sysdb_attrs_add_string failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "netgr_translate_members_ldap_step failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina/* netgr_translate_members_ldap_step() returns
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina * EOK: if everthing is translated, the caller can call tevent_req_done
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina * EAGAIN: if there are still members waiting to be translated, the caller
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina * should return to the mainloop
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina * Exyz: every other return code indicates an error and tevent_req_error
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina * should be called
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březinastatic errno_t netgr_translate_members_ldap_step(struct tevent_req *req)
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina struct netgr_translate_members_state *state = tevent_req_data(req,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina const char **cn_attr;
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DLIST_FOR_EACH(state->dn_item, state->dn_idx) {
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DLIST_FOR_EACH(state->dn_item, state->dn_list) {
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina ret = sysdb_attrs_add_string(state->dn_item->netgroup,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "sysdb_attrs_add_string failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina if (!sss_ldap_dn_in_search_bases(state, state->dn_item->dn,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina /* not in search base, skip it */
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina return netgr_translate_members_ldap_step(req);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina cn_attr = talloc_array(state, const char *, 3);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "talloc_array failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina cn_attr[0] = state->opts->netgroup_map[SDAP_AT_NETGROUP_NAME].name;
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_TRACE_ALL, "LDAP base search for [%s].\n", state->dn_item->dn);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "sdap_get_generic_send failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina tevent_req_set_callback(subreq, netgr_translate_members_ldap_done, req);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březinastatic void netgr_translate_members_ldap_done(struct tevent_req *subreq)
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina struct tevent_req *req = tevent_req_callback_data(subreq,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina struct netgr_translate_members_state *state = tevent_req_data(req,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina const char *str;
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina ret = sdap_get_generic_recv(subreq, state, &count, &netgroups);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "sdap_get_generic request failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "sdap_get_generic_recv found no entry for [%s].\n",
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina ret = sysdb_attrs_get_string(netgroups[0], SYSDB_NAME, &str);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "sysdb_attrs_add_string failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina state->dn_item->cn = talloc_strdup(state->dn_item, str);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina DEBUG(SSSDBG_CRIT_FAILURE, "talloc_strdup failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "Unexpected number of results [%zu] for base search.\n",
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "Failed to resolve netgroup name for DN [%s], using DN.\n",
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina state->dn_item->cn = talloc_strdup(state->dn_item, state->dn_item->dn);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "netgr_translate_members_ldap_step failed.\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březinastatic errno_t netgroup_translate_ldap_members_recv(struct tevent_req *req,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina struct netgr_translate_members_state *state = tevent_req_data(req,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina *netgroups = talloc_steal(mem_ctx, state->netgroups);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina/* ==Search-Netgroups-with-filter============================================ */
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina const char **attrs;
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březinastatic errno_t sdap_get_netgroups_next_base(struct tevent_req *req);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březinastatic void sdap_get_netgroups_process(struct tevent_req *subreq);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březinastatic void netgr_translate_members_done(struct tevent_req *subreq);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březinastruct tevent_req *sdap_get_netgroups_send(TALLOC_CTX *memctx,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina const char **attrs,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina req = tevent_req_create(memctx, &state, struct sdap_get_netgroups_state);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "Netgroup lookup request without a netgroup search base\n");
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březinastatic errno_t sdap_get_netgroups_next_base(struct tevent_req *req)
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina state = tevent_req_data(req, struct sdap_get_netgroups_state);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina state->filter = sdap_combine_filters(state, state->base_filter,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina state->search_bases[state->base_iter]->filter);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "Searching for netgroups with base [%s]\n",
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina state->search_bases[state->base_iter]->basedn);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina state->search_bases[state->base_iter]->basedn,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina state->opts->netgroup_map, SDAP_OPTS_NETGROUP,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina tevent_req_set_callback(subreq, sdap_get_netgroups_process, req);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březinastatic void sdap_get_netgroups_process(struct tevent_req *subreq)
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina struct tevent_req *req = tevent_req_callback_data(subreq,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina struct sdap_get_netgroups_state *state = tevent_req_data(req,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina "Search for netgroups, returned %zu results.\n", state->count);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina /* No netgroups found in this search */
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina /* There are more search bases to try */
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina subreq = netgr_translate_members_send(state, state->ev, state->opts,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina tevent_req_set_callback(subreq, netgr_translate_members_done, req);
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březinastatic void netgr_translate_members_done(struct tevent_req *subreq)
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina struct tevent_req *req = tevent_req_callback_data(subreq,
8fe171bf5a7a570591418e6548105f1d5a0097b3Pavel Březina struct sdap_get_netgroups_state *state = tevent_req_data(req,
int ret;
size_t c;
if (ret) {
now);
if (ret) {
struct sdap_get_netgroups_state);
if (timestamp) {
if (reply_count) {
if (reply) {
return EOK;