Line data Source code
1 : /*
2 : Authors:
3 : Jakub Hrozek <jhrozek@redhat.com>
4 :
5 : Copyright (C) 2013 Red Hat
6 :
7 : SSSD tests: Common utilities for tests that exercise domains
8 :
9 : This program is free software; you can redistribute it and/or modify
10 : it under the terms of the GNU General Public License as published by
11 : the Free Software Foundation; either version 3 of the License, or
12 : (at your option) any later version.
13 :
14 : This program is distributed in the hope that it will be useful,
15 : but WITHOUT ANY WARRANTY; without even the implied warranty of
16 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 : GNU General Public License for more details.
18 :
19 : You should have received a copy of the GNU General Public License
20 : along with this program. If not, see <http://www.gnu.org/licenses/>.
21 : */
22 :
23 : #include <talloc.h>
24 : #include <errno.h>
25 :
26 : #include "tests/common.h"
27 :
28 : static errno_t
29 162 : mock_confdb(TALLOC_CTX *mem_ctx,
30 : const char *tests_path,
31 : const char *cdb_file,
32 : struct confdb_ctx **_cdb)
33 : {
34 162 : TALLOC_CTX *tmp_ctx = NULL;
35 162 : struct confdb_ctx *cdb = NULL;
36 162 : char *cdb_path = NULL;
37 : errno_t ret;
38 :
39 162 : tmp_ctx = talloc_new(NULL);
40 162 : if (tmp_ctx == NULL) {
41 0 : DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
42 0 : return ENOMEM;
43 : }
44 :
45 162 : cdb_path = talloc_asprintf(tmp_ctx, "%s/%s", tests_path, cdb_file);
46 162 : if (cdb_path == NULL) {
47 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_asprintf failed\n");
48 0 : ret = ENOMEM;
49 0 : goto done;
50 : }
51 :
52 : /* connect to the confdb */
53 162 : ret = confdb_init(tmp_ctx, &cdb, cdb_path);
54 162 : if (ret != EOK) {
55 0 : DEBUG(SSSDBG_CRIT_FAILURE, "confdb_init failed: %d\n", ret);
56 0 : goto done;
57 : }
58 :
59 162 : *_cdb = talloc_steal(mem_ctx, cdb);
60 162 : ret = EOK;
61 :
62 : done:
63 162 : talloc_free(tmp_ctx);
64 162 : return ret;
65 : }
66 :
67 : static errno_t
68 210 : mock_confdb_domain(TALLOC_CTX *mem_ctx,
69 : struct confdb_ctx *cdb,
70 : const char *db_path,
71 : const char *name,
72 : const char *id_provider,
73 : struct sss_test_conf_param *params,
74 : char **_cdb_path)
75 : {
76 210 : TALLOC_CTX *tmp_ctx = NULL;
77 210 : const char *val[2] = {NULL, NULL};
78 210 : char *cdb_path = NULL;
79 210 : char **array = NULL;
80 210 : char *list = NULL;
81 210 : bool exists = false;
82 : errno_t ret;
83 : int i;
84 :
85 210 : tmp_ctx = talloc_new(NULL);
86 210 : if (tmp_ctx == NULL) {
87 0 : DEBUG(SSSDBG_CRIT_FAILURE, ("talloc_new() failed\n"));
88 0 : return ENOMEM;
89 : }
90 :
91 : /* get current domain list */
92 210 : ret = confdb_get_string(cdb, tmp_ctx, "config/sssd", "domains",
93 : NULL, &list);
94 210 : if (ret != EOK) {
95 0 : goto done;
96 : }
97 :
98 : /* check if the domain is already in */
99 210 : if (list != NULL) {
100 148 : ret = split_on_separator(tmp_ctx, list, ',', true, true, &array, NULL);
101 148 : if (ret != EOK) {
102 0 : goto done;
103 : }
104 :
105 238 : for (i = 0; array[i] != NULL; i++) {
106 190 : if (strcmp(array[i], name) == 0) {
107 100 : exists = true;
108 100 : break;
109 : }
110 : }
111 : }
112 :
113 : /* add domain to the list of enabled domains */
114 210 : if (!exists) {
115 110 : if (list == NULL) {
116 62 : list = talloc_strdup(tmp_ctx, name);
117 : } else {
118 48 : list = talloc_asprintf_append(list, ", %s", name);
119 : }
120 :
121 110 : if (list == NULL) {
122 0 : ret = ENOMEM;
123 0 : goto done;
124 : }
125 :
126 110 : val[0] = list;
127 110 : ret = confdb_add_param(cdb, true, "config/sssd", "domains", val);
128 110 : if (ret != EOK) {
129 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to change domain list [%d]: %s\n",
130 : ret, sss_strerror(ret));
131 0 : goto done;
132 : }
133 : }
134 :
135 : /* create domain section */
136 210 : cdb_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, name);
137 210 : if (cdb_path == NULL) {
138 0 : ret = ENOMEM;
139 0 : goto done;
140 : }
141 :
142 210 : val[0] = id_provider;
143 210 : ret = confdb_add_param(cdb, true, cdb_path, "id_provider", val);
144 210 : if (ret != EOK) {
145 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add id_provider [%d]: %s\n",
146 : ret, sss_strerror(ret));
147 0 : goto done;
148 : }
149 :
150 210 : if (params != NULL) {
151 282 : for (i = 0; params[i].key != NULL; i++) {
152 166 : val[0] = params[i].value;
153 166 : ret = confdb_add_param(cdb, true, cdb_path, params[i].key, val);
154 166 : if (ret != EOK) {
155 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add parameter %s [%d]: "
156 : "%s\n", params[i].key, ret, sss_strerror(ret));
157 0 : goto done;
158 : }
159 : }
160 : }
161 :
162 210 : if (_cdb_path != NULL) {
163 162 : *_cdb_path = talloc_steal(mem_ctx, cdb_path);
164 : }
165 :
166 210 : ret = EOK;
167 :
168 : done:
169 210 : talloc_free(tmp_ctx);
170 210 : return ret;
171 : }
172 :
173 : static errno_t
174 210 : mock_domain(TALLOC_CTX *mem_ctx,
175 : struct confdb_ctx *cdb,
176 : const char *db_path,
177 : const char *name,
178 : struct sss_domain_info **_domain)
179 : {
180 210 : struct sss_domain_info *domain = NULL;
181 : errno_t ret;
182 :
183 : /* initialize sysdb */
184 210 : ret = sssd_domain_init(mem_ctx, cdb, name, db_path, &domain);
185 210 : if (ret != EOK) {
186 0 : DEBUG(SSSDBG_CRIT_FAILURE, "sssd_domain_init() of %s failed "
187 : "[%d]: %s\n", name, ret, sss_strerror(ret));
188 0 : goto done;
189 : }
190 :
191 : /* init with an AD-style regex to be able to test flat name */
192 210 : ret = sss_names_init_from_args(domain,
193 : "(((?P<domain>[^\\\\]+)\\\\(?P<name>.+$))|" \
194 : "((?P<name>[^@]+)@(?P<domain>.+$))|" \
195 : "(^(?P<name>[^@\\\\]+)$))",
196 210 : "%1$s@%2$s", &domain->names);
197 210 : if (ret != EOK) {
198 0 : DEBUG(SSSDBG_CRIT_FAILURE, "cannot create names context\n");
199 0 : goto done;
200 : }
201 :
202 210 : if (_domain != NULL) {
203 162 : *_domain = domain;
204 : }
205 :
206 210 : ret = EOK;
207 :
208 : done:
209 210 : if (ret != EOK) {
210 0 : talloc_free(domain);
211 : }
212 210 : return ret;
213 : }
214 :
215 : struct sss_test_ctx *
216 162 : create_multidom_test_ctx(TALLOC_CTX *mem_ctx,
217 : const char *tests_path,
218 : const char *cdb_file,
219 : const char **domains,
220 : const char *id_provider,
221 : struct sss_test_conf_param *params)
222 : {
223 162 : struct sss_domain_info *domain = NULL;
224 162 : struct sss_test_ctx *test_ctx = NULL;
225 162 : char *cdb_path = NULL;
226 : errno_t ret;
227 : int i;
228 :
229 162 : test_ctx = create_ev_test_ctx(mem_ctx);
230 162 : if (test_ctx == NULL) {
231 0 : DEBUG(SSSDBG_CRIT_FAILURE, "create_ev_test_ctx() failed\n");
232 0 : goto fail;
233 : }
234 :
235 162 : ret = mock_confdb(test_ctx, tests_path, cdb_file, &test_ctx->confdb);
236 162 : if (ret != EOK) {
237 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize confdb [%d]: %s\n",
238 : ret, sss_strerror(ret));
239 0 : goto fail;
240 : }
241 :
242 : /* create confdb objects for the domains */
243 372 : for (i = 0; domains[i] != NULL; i++) {
244 420 : ret = mock_confdb_domain(test_ctx, test_ctx->confdb, tests_path,
245 210 : domains[i], id_provider, params,
246 210 : (cdb_path == NULL ? &cdb_path : NULL));
247 210 : if (ret != EOK) {
248 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to initialize confdb domain "
249 : "[%d]: %s\n", ret, sss_strerror(ret));
250 0 : goto fail;
251 : }
252 : }
253 :
254 : /* initialize domain list and sysdb of the domains */
255 372 : for (i = 0; domains[i] != NULL; i++) {
256 210 : ret = mock_domain(test_ctx, test_ctx->confdb, tests_path, domains[i],
257 210 : (domain == NULL ? &domain : NULL));
258 210 : if (ret != EOK) {
259 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add new domain [%d]: %s\n",
260 : ret, sss_strerror(ret));
261 0 : goto fail;
262 : }
263 : }
264 :
265 : /* the first domain we obtained is already head of the complete list */
266 162 : test_ctx->dom = domain;
267 :
268 : /* set data from the first domain */
269 162 : test_ctx->sysdb = test_ctx->dom->sysdb;
270 162 : test_ctx->nctx = test_ctx->dom->names;
271 162 : test_ctx->conf_dom_path = cdb_path;
272 :
273 162 : return test_ctx;
274 :
275 : fail:
276 0 : talloc_free(test_ctx);
277 0 : return NULL;
278 : }
279 :
280 :
281 : struct sss_test_ctx *
282 142 : create_dom_test_ctx(TALLOC_CTX *mem_ctx,
283 : const char *tests_path,
284 : const char *confdb_path,
285 : const char *domain_name,
286 : const char *id_provider,
287 : struct sss_test_conf_param *params)
288 : {
289 142 : const char *domains[] = {domain_name, NULL};
290 :
291 142 : return create_multidom_test_ctx(mem_ctx, tests_path, confdb_path, domains,
292 : id_provider, params);
293 : }
294 :
295 86 : void test_multidom_suite_cleanup(const char *tests_path,
296 : const char *cdb_file,
297 : const char **domains)
298 : {
299 86 : TALLOC_CTX *tmp_ctx = NULL;
300 86 : char *cdb_path = NULL;
301 86 : char *sysdb_path = NULL;
302 : errno_t ret;
303 : int i;
304 :
305 86 : tmp_ctx = talloc_new(NULL);
306 86 : if (tmp_ctx == NULL) {
307 0 : DEBUG(SSSDBG_CRIT_FAILURE, "talloc_new() failed\n");
308 0 : return;
309 : }
310 :
311 86 : if (cdb_file != NULL) {
312 86 : cdb_path = talloc_asprintf(tmp_ctx, "%s/%s", tests_path, cdb_file);
313 86 : if (cdb_path == NULL) {
314 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Could not contruct cdb path\n");
315 0 : goto done;
316 : }
317 :
318 86 : errno = 0;
319 86 : ret = unlink(cdb_path);
320 86 : if (ret != 0 && errno != ENOENT) {
321 0 : ret = errno;
322 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete the test config "
323 : "ldb file [%d]: (%s)\n", ret, sss_strerror(ret));
324 : }
325 : }
326 :
327 86 : if (domains != NULL) {
328 222 : for (i = 0; domains[i] != NULL; i++) {
329 136 : if (strcmp(domains[i], LOCAL_SYSDB_FILE) == 0) {
330 : /* local domain */
331 10 : sysdb_path = talloc_asprintf(tmp_ctx, "%s/%s",
332 10 : tests_path, domains[i]);
333 : } else {
334 126 : sysdb_path = talloc_asprintf(tmp_ctx, "%s/cache_%s.ldb",
335 126 : tests_path, domains[i]);
336 : }
337 136 : if (sysdb_path == NULL) {
338 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Could not construct sysdb path\n");
339 0 : goto done;
340 : }
341 :
342 136 : errno = 0;
343 136 : ret = unlink(sysdb_path);
344 136 : if (ret != 0 && errno != ENOENT) {
345 0 : ret = errno;
346 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete the test domain "
347 : "ldb file [%d]: (%s)\n", ret, sss_strerror(ret));
348 : }
349 :
350 136 : talloc_zfree(sysdb_path);
351 : }
352 : }
353 :
354 86 : errno = 0;
355 86 : ret = rmdir(tests_path);
356 86 : if (ret != 0 && errno != ENOENT) {
357 0 : ret = errno;
358 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Could not delete the test dir (%d) (%s)\n",
359 : ret, sss_strerror(ret));
360 : }
361 :
362 : done:
363 86 : talloc_free(tmp_ctx);
364 : }
365 :
366 65 : void test_dom_suite_cleanup(const char *tests_path,
367 : const char *cdb_file,
368 : const char *domain)
369 : {
370 65 : const char *domains[] = {domain, NULL};
371 :
372 65 : test_multidom_suite_cleanup(tests_path, cdb_file, domains);
373 65 : }
374 :
375 22 : struct sss_domain_info *named_domain(TALLOC_CTX *mem_ctx,
376 : const char *name,
377 : struct sss_domain_info *parent)
378 : {
379 22 : struct sss_domain_info *dom = NULL;
380 :
381 22 : dom = talloc_zero(mem_ctx, struct sss_domain_info);
382 22 : if (dom == NULL) {
383 0 : return NULL;
384 : }
385 :
386 22 : dom->name = talloc_strdup(dom, name);
387 22 : if (dom->name == NULL) {
388 0 : talloc_free(dom);
389 0 : return NULL;
390 : }
391 :
392 22 : dom->parent = parent;
393 :
394 22 : return dom;
395 : }
|