ipa_netgroups.c revision 5e9bc89b28f1ac3ce573ecdece74fe9623580c28
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek Async IPA Helper routines for netgroups
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek Jan Zeleny <jzeleny@redhat.com>
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek Copyright (C) 2011 Red Hat
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek This program is free software; you can redistribute it and/or modify
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek it under the terms of the GNU General Public License as published by
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek the Free Software Foundation; either version 3 of the License, or
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek (at your option) any later version.
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek This program is distributed in the hope that it will be useful,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek but WITHOUT ANY WARRANTY; without even the implied warranty of
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek GNU General Public License for more details.
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek You should have received a copy of the GNU General Public License
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek along with this program. If not, see <http://www.gnu.org/licenses/>.
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char **attrs;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* Entities which have been already asked for
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * and are scheduled for inspection */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic errno_t ipa_save_netgroup(TALLOC_CTX *mem_ctx,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek opts->netgroup_map[IPA_AT_NETGROUP_NAME].sys_name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("Storing netgroup %s\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(attrs, SYSDB_ORIG_DN, &el);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(7, ("Original DN is not available for [%s].\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(7, ("Adding original DN [%s] to attributes of [%s].\n",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_add_string(netgroup_attrs, SYSDB_ORIG_DN,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(attrs, SYSDB_NETGROUP_TRIPLE, &el);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(SSSDBG_TRACE_INTERNAL, ("No netgroup triples for netgroup [%s].\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(netgroup_attrs, SYSDB_NETGROUP_TRIPLE, &el);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek opts->netgroup_map[IPA_AT_NETGROUP_MEMBER].sys_name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(7, ("No original members for netgroup [%s]\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(7, ("Adding original members to netgroup [%s]\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek opts->netgroup_map[IPA_AT_NETGROUP_MEMBER].sys_name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(attrs, SYSDB_NETGROUP_MEMBER, &el);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(7, ("No members for netgroup [%s]\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(7, ("Adding members to netgroup [%s]\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_add_string(netgroup_attrs, SYSDB_NETGROUP_MEMBER,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(6, ("Storing info for netgroup %s\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_add_netgroup(ctx, name, NULL, netgroup_attrs, NULL,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(2, ("Failed to save netgroup %s\n", name));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic errno_t ipa_netgr_next_base(struct tevent_req *req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic void ipa_get_netgroups_process(struct tevent_req *subreq);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int ipa_netgr_process_all(struct ipa_get_netgroups_state *state);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstruct tevent_req *ipa_get_netgroups_send(TALLOC_CTX *memctx,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char **attrs,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek req = tevent_req_create(memctx, &state, struct ipa_get_netgroups_state);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ("Netgroup lookup request without a search base\n"));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sss_hash_create(state, 32, &state->new_netgroups);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sss_hash_create(state, 32, &state->new_users);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sss_hash_create(state, 32, &state->new_hosts);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic errno_t ipa_netgr_next_base(struct tevent_req *req)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state = tevent_req_data(req, struct ipa_get_netgroups_state);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek netgr_bases = state->ipa_opts->id->netgroup_search_bases;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ("Searching for netgroups with base [%s]\n",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_set_callback(subreq, ipa_get_netgroups_process, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int ipa_netgr_fetch_netgroups(struct ipa_get_netgroups_state *state,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int ipa_netgr_fetch_users(struct ipa_get_netgroups_state *state,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic void ipa_netgr_members_process(struct tevent_req *subreq);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic void ipa_get_netgroups_process(struct tevent_req *subreq)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *req = tevent_req_callback_data(subreq,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ipa_get_netgroups_state *state = tevent_req_data(req,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek netgr_bases = state->ipa_opts->id->netgroup_search_bases;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sdap_get_generic_recv(subreq, state, &netgroups_count, &netgroups);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek DEBUG(6, ("Search for netgroups, returned %d results.\n", netgroups_count));
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* No netgroups found in this search */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* There are more search bases to try */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek for (i = 0; i < netgroups_count; i++) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(netgroups[i], SYSDB_ORIG_NETGROUP_MEMBER,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(netgroups[i], SYSDB_ORIG_MEMBER_USER,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_el(netgroups[i], SYSDB_ORIG_MEMBER_HOST,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_string(netgroups[i], SYSDB_ORIG_DN, &orig_dn);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = hash_enter(state->new_netgroups, &key, &value);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (ng_found->num_values) state->entities_found |= ENTITY_NG;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (user_found->num_values) state->entities_found |= ENTITY_USER;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek if (host_found->num_values) state->entities_found |= ENTITY_HOST;
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek ret = sss_filter_sanitize(state, orig_dn, &dn);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* Add this to the filter */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter = talloc_asprintf_append(filter, "(%s=%s)",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->opts->netgroup_map[IPA_AT_NETGROUP_MEMBER_OF].name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->filter = talloc_asprintf_append(filter, ")");
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek } else if (state->entities_found & ENTITY_USER) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek } else if (state->entities_found & ENTITY_HOST) {
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozekstatic int ipa_netgr_fetch_netgroups(struct ipa_get_netgroups_state *state,
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek bases = state->ipa_opts->id->netgroup_search_bases;
2745b0156f12df7a7eb93d57716233243658e4d9Jakub Hrozek /* No more bases to try */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek base_filter = bases[state->netgr_base_iter]->filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->opts->netgroup_map[SDAP_OC_NETGROUP].name);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter, state->attrs, state->opts->netgroup_map,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_set_callback(subreq, ipa_netgr_members_process, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int ipa_netgr_fetch_users(struct ipa_get_netgroups_state *state,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char *attrs[] = { state->opts->user_map[SDAP_AT_USER_NAME].name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek state->opts->user_map[SDAP_AT_USER_MEMBEROF].name,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek bases = state->ipa_opts->id->user_search_bases;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek base_filter = bases[state->user_base_iter]->filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_set_callback(subreq, ipa_netgr_members_process, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic int ipa_netgr_fetch_hosts(struct ipa_get_netgroups_state *state,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek const char **attrs;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek base_filter = bases[state->host_base_iter]->filter;
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek filter = talloc_asprintf(state, "(&%s%s(objectclass=%s))",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = build_attrs_from_map(state, state->ipa_opts->host_map,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek subreq = sdap_get_generic_send(state, state->ev, state->opts, state->sh,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek tevent_req_set_callback(subreq, ipa_netgr_members_process, req);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozekstatic void ipa_netgr_members_process(struct tevent_req *subreq)
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct tevent_req *req = tevent_req_callback_data(subreq,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek struct ipa_get_netgroups_state *state = tevent_req_data(req,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek int (* next_call)(struct ipa_get_netgroups_state *,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sdap_get_generic_recv(subreq, state, &count, &entities);
466f5a539be1e4c6e7cfb396a2f406e1eb8c428dLukas Slebodnik DEBUG(SSSDBG_TRACE_INTERNAL, ("Found %u members in current search base\n", count));
466f5a539be1e4c6e7cfb396a2f406e1eb8c428dLukas Slebodnik /* While processing a batch of entities from one search base,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * schedule query for another search base if there is one
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * If there is no other search base, another class of entities
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * will be scheduled for lookup after processing of current
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * batch. The order of lookup is: netgroups -> users -> hosts
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* We just received a batch of netgroups */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* If there is a member netgroup, we always have to
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * ask for both member users and hosts
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * -> now schedule users
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else if (state->current_entity == ENTITY_USER) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* We just received a batch of users */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek } else if (state->current_entity == ENTITY_HOST) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* We just received a batch of hosts */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ("Invalid entity type given for processing: %d\n",
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* Next search base has been scheduled for inspection,
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * don't try to look for other type of entities
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* Process all member entites and store them in the designated hash table */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek for (i = 0; i < count; i++) {
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek ret = sysdb_attrs_get_string(entities[i], SYSDB_ORIG_DN, &orig_dn);
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* Transform the DN to lower case.
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * this is important, as the member/memberof attributes
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * have the value also in lower-case
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* The next search base is already scheduled to be searched */
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* There is another class of members that has to be retrieved
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek * - schedule the lookup
45aeb924ec3ac448bb8d174a5cc061ed98b147c7Jakub Hrozek /* All members, that could have been fetched, were fetched */
fail:
struct sysdb_attrs);
struct extract_state {
const char *group;
const char **entries;
int entries_count;
int i, ret;
const char *member_type,
const char ***_ret_array,
int *_ret_count)
int process_count = 0;
int ret_count = 0;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
ret_count++;
goto done;
done:
return ret;
int i, j, k, ret;
const char **members;
const char *member_name;
int uids_count = 0;
int hosts_count = 0;
const char *domain;
char *triple;
return ENOMEM;
goto done;
goto done;
for (j = 0; members[j]; j++) {
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
goto done;
hosts_count++;
&domain);
goto done;
if (uids_count == 0) {
if (hosts_count == 0) {
for (j = 0; j < uids_count; j++) {
for (k = 0; k < hosts_count; k++) {
domain);
goto done;
triple);
goto done;
goto done;
done:
return ret;
struct ipa_get_netgroups_state);
if (reply_count) {
if (reply) {
return EOK;