1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny/*
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny SSSD
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny IPA Backend Module -- SELinux user maps (maps retrieval)
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny Authors:
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny Jan Zeleny <jzeleny@redhat.com>
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny Copyright (C) 2012 Red Hat
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny This program is free software; you can redistribute it and/or modify
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny it under the terms of the GNU General Public License as published by
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny the Free Software Foundation; either version 3 of the License, or
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny (at your option) any later version.
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny This program is distributed in the hope that it will be useful,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny but WITHOUT ANY WARRANTY; without even the implied warranty of
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny GNU General Public License for more details.
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny You should have received a copy of the GNU General Public License
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny along with this program. If not, see <http://www.gnu.org/licenses/>.
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny*/
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny#include "providers/ipa/ipa_common.h"
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny#include "providers/ipa/ipa_selinux_maps.h"
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenystruct ipa_selinux_get_maps_state {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct tevent_context *ev;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct sysdb_ctx *sysdb;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct sdap_handle *sh;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct sdap_options *opts;
fdab7bbf8933351f6254438c30ff361cd748b15aJan Zeleny struct ipa_options *ipa_opts;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny const char **attrs;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct sdap_search_base **search_bases;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny int search_base_iter;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny char *cur_filter;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny char *maps_filter;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny size_t map_count;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct sysdb_attrs **maps;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny};
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenystatic errno_t
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenyipa_selinux_get_maps_next(struct tevent_req *req,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct ipa_selinux_get_maps_state *state);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenystatic void
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenyipa_selinux_get_maps_done(struct tevent_req *subreq);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenystruct tevent_req *ipa_selinux_get_maps_send(TALLOC_CTX *mem_ctx,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct tevent_context *ev,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct sysdb_ctx *sysdb,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct sdap_handle *sh,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct sdap_options *opts,
fdab7bbf8933351f6254438c30ff361cd748b15aJan Zeleny struct ipa_options *ipa_opts,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct sdap_search_base **search_bases)
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny{
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct tevent_req *req;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct ipa_selinux_get_maps_state *state;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny errno_t ret;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny req = tevent_req_create(mem_ctx, &state, struct ipa_selinux_get_maps_state);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (req == NULL) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny return NULL;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->ev = ev;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->sysdb = sysdb;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->sh = sh;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->opts = opts;
fdab7bbf8933351f6254438c30ff361cd748b15aJan Zeleny state->ipa_opts = ipa_opts;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->search_bases = search_bases;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->search_base_iter = 0;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->map_count = 0;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->maps = NULL;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
fdab7bbf8933351f6254438c30ff361cd748b15aJan Zeleny ret = build_attrs_from_map(state, ipa_opts->selinuxuser_map,
64ddff90c7fcc02ccb06824ac93af7d5f361a88fJan Zeleny IPA_OPTS_SELINUX_USERMAP, NULL,
64ddff90c7fcc02ccb06824ac93af7d5f361a88fJan Zeleny &state->attrs, NULL);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (ret != EOK) goto fail;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->cur_filter = NULL;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->maps_filter = talloc_asprintf(state,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny "(&(objectclass=%s)(%s=TRUE))",
fdab7bbf8933351f6254438c30ff361cd748b15aJan Zeleny ipa_opts->selinuxuser_map[IPA_OC_SELINUX_USERMAP].name,
fdab7bbf8933351f6254438c30ff361cd748b15aJan Zeleny ipa_opts->selinuxuser_map[IPA_AT_SELINUX_USERMAP_ENABLED].name);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (state->maps_filter == NULL) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny ret = ENOMEM;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny goto fail;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny ret = ipa_selinux_get_maps_next(req, state);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (ret == EOK) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny ret = EINVAL;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (ret != EAGAIN) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny goto fail;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny return req;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenyfail:
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny tevent_req_error(req, ret);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny tevent_req_post(req, ev);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny return req;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny}
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenystatic errno_t
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenyipa_selinux_get_maps_next(struct tevent_req *req,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct ipa_selinux_get_maps_state *state)
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny{
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct sdap_search_base *base;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct tevent_req *subreq;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny base = state->search_bases[state->search_base_iter];
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (base == NULL) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny return EOK;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny talloc_zfree(state->cur_filter);
92ec40e6aa25f75903ffdb166a8ec56b67bfd77dPavel Březina state->cur_filter = sdap_combine_filters(state, state->maps_filter,
92ec40e6aa25f75903ffdb166a8ec56b67bfd77dPavel Březina base->filter);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (state->cur_filter == NULL) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny return ENOMEM;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "Trying to fetch SELinux maps with following "
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny "parameters: [%d][%s][%s]\n", base->scope,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov state->cur_filter, base->basedn);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny subreq = sdap_get_generic_send(state, state->ev, state->opts,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->sh, base->basedn,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny base->scope, state->cur_filter,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->attrs,
fdab7bbf8933351f6254438c30ff361cd748b15aJan Zeleny state->ipa_opts->selinuxuser_map,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny IPA_OPTS_SELINUX_USERMAP,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny dp_opt_get_int(state->opts->basic,
2f3ee3f49019f5b60adbe073070f31e6e2d7c7abStephen Gallagher SDAP_ENUM_SEARCH_TIMEOUT),
2f3ee3f49019f5b60adbe073070f31e6e2d7c7abStephen Gallagher true);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (subreq == NULL) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny return ENOMEM;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny tevent_req_set_callback(subreq, ipa_selinux_get_maps_done, req);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny return EAGAIN;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny}
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenystatic void ipa_selinux_get_maps_done(struct tevent_req *subreq)
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny{
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny errno_t ret;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct tevent_req *req = tevent_req_callback_data(subreq,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct tevent_req);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct ipa_selinux_get_maps_state *state = tevent_req_data(req,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct ipa_selinux_get_maps_state);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct sysdb_attrs **results;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny size_t total_count;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny size_t count;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny int i;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny ret = sdap_get_generic_recv(subreq, state, &count, &results);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (ret != EOK) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny goto done;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (count > 0) {
0e65abe5cf2abf5d4b431cf6bd161b419f07901dLukas Slebodnik DEBUG(SSSDBG_TRACE_FUNC,
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov "Found %zu user maps in current search base\n", count);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny total_count = count + state->map_count;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->maps = talloc_realloc(state, state->maps, struct sysdb_attrs *, total_count);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (state->maps == NULL) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny ret = ENOMEM;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny goto done;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny i = 0;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny while (state->map_count < total_count) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->maps[state->map_count] = talloc_steal(state->maps, results[i]);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->map_count++;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny i++;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny state->search_base_iter++;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny ret = ipa_selinux_get_maps_next(req, state);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (ret == EAGAIN) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny return;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny } else if (ret != EOK) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny goto done;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (state->map_count == 0) {
a3c8390d19593b1e5277d95bfb4ab206d4785150Nikolai Kondrashov DEBUG(SSSDBG_TRACE_FUNC, "No SELinux user maps found!\n");
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny ret = ENOENT;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenydone:
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny if (ret != EOK) {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny tevent_req_error(req, ret);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny } else {
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny tevent_req_done(req);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny }
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny}
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenyerrno_t
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zelenyipa_selinux_get_maps_recv(struct tevent_req *req,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny TALLOC_CTX *mem_ctx,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny size_t *count,
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct sysdb_attrs ***maps)
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny{
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny struct ipa_selinux_get_maps_state *state =
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny tevent_req_data(req, struct ipa_selinux_get_maps_state);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny TEVENT_REQ_RETURN_ON_ERROR(req);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny *count = state->map_count;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny *maps = talloc_steal(mem_ctx, state->maps);
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny return EOK;
1a853121ca2ba8ede6df429ee76942131ffb0f65Jan Zeleny}