Line data Source code
1 : /*
2 : SSSD
3 :
4 : IPA Backend Module -- SELinux user maps (maps retrieval)
5 :
6 : Authors:
7 : Jan Zeleny <jzeleny@redhat.com>
8 :
9 : Copyright (C) 2012 Red Hat
10 :
11 : This program is free software; you can redistribute it and/or modify
12 : it under the terms of the GNU General Public License as published by
13 : the Free Software Foundation; either version 3 of the License, or
14 : (at your option) any later version.
15 :
16 : This program is distributed in the hope that it will be useful,
17 : but WITHOUT ANY WARRANTY; without even the implied warranty of
18 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
19 : GNU General Public License for more details.
20 :
21 : You should have received a copy of the GNU General Public License
22 : along with this program. If not, see <http://www.gnu.org/licenses/>.
23 : */
24 :
25 : #include "providers/ipa/ipa_common.h"
26 : #include "providers/ipa/ipa_selinux_maps.h"
27 :
28 : struct ipa_selinux_get_maps_state {
29 : struct tevent_context *ev;
30 : struct sysdb_ctx *sysdb;
31 : struct sdap_handle *sh;
32 : struct sdap_options *opts;
33 : struct ipa_options *ipa_opts;
34 : const char **attrs;
35 :
36 : struct sdap_search_base **search_bases;
37 : int search_base_iter;
38 :
39 : char *cur_filter;
40 : char *maps_filter;
41 :
42 : size_t map_count;
43 : struct sysdb_attrs **maps;
44 : };
45 :
46 : static errno_t
47 : ipa_selinux_get_maps_next(struct tevent_req *req,
48 : struct ipa_selinux_get_maps_state *state);
49 : static void
50 : ipa_selinux_get_maps_done(struct tevent_req *subreq);
51 :
52 0 : struct tevent_req *ipa_selinux_get_maps_send(TALLOC_CTX *mem_ctx,
53 : struct tevent_context *ev,
54 : struct sysdb_ctx *sysdb,
55 : struct sdap_handle *sh,
56 : struct sdap_options *opts,
57 : struct ipa_options *ipa_opts,
58 : struct sdap_search_base **search_bases)
59 : {
60 : struct tevent_req *req;
61 : struct ipa_selinux_get_maps_state *state;
62 : errno_t ret;
63 :
64 0 : req = tevent_req_create(mem_ctx, &state, struct ipa_selinux_get_maps_state);
65 0 : if (req == NULL) {
66 0 : return NULL;
67 : }
68 :
69 0 : state->ev = ev;
70 0 : state->sysdb = sysdb;
71 0 : state->sh = sh;
72 0 : state->opts = opts;
73 0 : state->ipa_opts = ipa_opts;
74 0 : state->search_bases = search_bases;
75 0 : state->search_base_iter = 0;
76 0 : state->map_count = 0;
77 0 : state->maps = NULL;
78 :
79 0 : ret = build_attrs_from_map(state, ipa_opts->selinuxuser_map,
80 : IPA_OPTS_SELINUX_USERMAP, NULL,
81 0 : &state->attrs, NULL);
82 0 : if (ret != EOK) goto fail;
83 :
84 0 : state->cur_filter = NULL;
85 0 : state->maps_filter = talloc_asprintf(state,
86 : "(&(objectclass=%s)(%s=TRUE))",
87 0 : ipa_opts->selinuxuser_map[IPA_OC_SELINUX_USERMAP].name,
88 0 : ipa_opts->selinuxuser_map[IPA_AT_SELINUX_USERMAP_ENABLED].name);
89 0 : if (state->maps_filter == NULL) {
90 0 : ret = ENOMEM;
91 0 : goto fail;
92 : }
93 :
94 0 : ret = ipa_selinux_get_maps_next(req, state);
95 0 : if (ret == EOK) {
96 0 : ret = EINVAL;
97 : }
98 :
99 0 : if (ret != EAGAIN) {
100 0 : goto fail;
101 : }
102 :
103 0 : return req;
104 :
105 : fail:
106 0 : tevent_req_error(req, ret);
107 0 : tevent_req_post(req, ev);
108 0 : return req;
109 : }
110 :
111 : static errno_t
112 0 : ipa_selinux_get_maps_next(struct tevent_req *req,
113 : struct ipa_selinux_get_maps_state *state)
114 : {
115 : struct sdap_search_base *base;
116 : struct tevent_req *subreq;
117 :
118 0 : base = state->search_bases[state->search_base_iter];
119 0 : if (base == NULL) {
120 0 : return EOK;
121 : }
122 :
123 0 : talloc_zfree(state->cur_filter);
124 0 : state->cur_filter = sdap_combine_filters(state, state->maps_filter,
125 : base->filter);
126 0 : if (state->cur_filter == NULL) {
127 0 : return ENOMEM;
128 : }
129 :
130 0 : DEBUG(SSSDBG_TRACE_FUNC, "Trying to fetch SELinux maps with following "
131 : "parameters: [%d][%s][%s]\n", base->scope,
132 : state->cur_filter, base->basedn);
133 0 : subreq = sdap_get_generic_send(state, state->ev, state->opts,
134 : state->sh, base->basedn,
135 0 : base->scope, state->cur_filter,
136 : state->attrs,
137 0 : state->ipa_opts->selinuxuser_map,
138 : IPA_OPTS_SELINUX_USERMAP,
139 0 : dp_opt_get_int(state->opts->basic,
140 : SDAP_ENUM_SEARCH_TIMEOUT),
141 : true);
142 0 : if (subreq == NULL) {
143 0 : return ENOMEM;
144 : }
145 :
146 0 : tevent_req_set_callback(subreq, ipa_selinux_get_maps_done, req);
147 0 : return EAGAIN;
148 : }
149 :
150 0 : static void ipa_selinux_get_maps_done(struct tevent_req *subreq)
151 : {
152 : errno_t ret;
153 0 : struct tevent_req *req = tevent_req_callback_data(subreq,
154 : struct tevent_req);
155 0 : struct ipa_selinux_get_maps_state *state = tevent_req_data(req,
156 : struct ipa_selinux_get_maps_state);
157 : struct sysdb_attrs **results;
158 : size_t total_count;
159 : size_t count;
160 : int i;
161 :
162 0 : ret = sdap_get_generic_recv(subreq, state, &count, &results);
163 0 : if (ret != EOK) {
164 0 : goto done;
165 : }
166 :
167 0 : if (count > 0) {
168 0 : DEBUG(SSSDBG_TRACE_FUNC,
169 : "Found %zu user maps in current search base\n", count);
170 :
171 0 : total_count = count + state->map_count;
172 0 : state->maps = talloc_realloc(state, state->maps, struct sysdb_attrs *, total_count);
173 0 : if (state->maps == NULL) {
174 0 : ret = ENOMEM;
175 0 : goto done;
176 : }
177 :
178 0 : i = 0;
179 0 : while (state->map_count < total_count) {
180 0 : state->maps[state->map_count] = talloc_steal(state->maps, results[i]);
181 0 : state->map_count++;
182 0 : i++;
183 : }
184 : }
185 :
186 0 : state->search_base_iter++;
187 0 : ret = ipa_selinux_get_maps_next(req, state);
188 0 : if (ret == EAGAIN) {
189 0 : return;
190 0 : } else if (ret != EOK) {
191 0 : goto done;
192 : }
193 :
194 0 : if (state->map_count == 0) {
195 0 : DEBUG(SSSDBG_TRACE_FUNC, "No SELinux user maps found!\n");
196 0 : ret = ENOENT;
197 : }
198 :
199 : done:
200 0 : if (ret != EOK) {
201 0 : tevent_req_error(req, ret);
202 : } else {
203 0 : tevent_req_done(req);
204 : }
205 : }
206 :
207 : errno_t
208 0 : ipa_selinux_get_maps_recv(struct tevent_req *req,
209 : TALLOC_CTX *mem_ctx,
210 : size_t *count,
211 : struct sysdb_attrs ***maps)
212 : {
213 0 : struct ipa_selinux_get_maps_state *state =
214 0 : tevent_req_data(req, struct ipa_selinux_get_maps_state);
215 :
216 0 : TEVENT_REQ_RETURN_ON_ERROR(req);
217 :
218 0 : *count = state->map_count;
219 0 : *maps = talloc_steal(mem_ctx, state->maps);
220 :
221 0 : return EOK;
222 : }
|