Line data Source code
1 : /*
2 : Authors:
3 : Pavel Březina <pbrezina@redhat.com>
4 :
5 : Copyright (C) 2014 Red Hat
6 :
7 : This program is free software; you can redistribute it and/or modify
8 : it under the terms of the GNU General Public License as published by
9 : the Free Software Foundation; either version 3 of the License, or
10 : (at your option) any later version.
11 :
12 : This program is distributed in the hope that it will be useful,
13 : but WITHOUT ANY WARRANTY; without even the implied warranty of
14 : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
15 : GNU General Public License for more details.
16 :
17 : You should have received a copy of the GNU General Public License
18 : along with this program. If not, see <http://www.gnu.org/licenses/>.
19 : */
20 :
21 : #include <string.h>
22 : #include <talloc.h>
23 : #include <signal.h>
24 : #include <errno.h>
25 : #include <utime.h>
26 :
27 : #include "config.h"
28 : #include "confdb/confdb.h"
29 : #include "util/util.h"
30 : #include "responder/common/responder.h"
31 : #include "responder/ifp/ifp_components.h"
32 :
33 : #ifdef HAVE_CONFIG_LIB
34 : #include "util/sss_config.h"
35 : #endif
36 :
37 : #define PATH_MONITOR IFP_PATH_COMPONENTS "/monitor"
38 : #define PATH_RESPONDERS IFP_PATH_COMPONENTS "/Responders"
39 : #define PATH_BACKENDS IFP_PATH_COMPONENTS "/Backends"
40 :
41 : enum component_type {
42 : COMPONENT_MONITOR,
43 : COMPONENT_RESPONDER,
44 : COMPONENT_BACKEND
45 : };
46 :
47 0 : static bool responder_exists(const char *name)
48 : {
49 0 : const char * const *svc = get_known_services();
50 : int i;
51 :
52 0 : for (i = 0; svc[i] != NULL; i++) {
53 0 : if (strcmp(svc[i], name) == 0) {
54 0 : return true;
55 : }
56 : }
57 :
58 0 : return false;
59 : }
60 :
61 0 : static bool backend_exists(struct confdb_ctx *confdb, const char *name)
62 : {
63 0 : char **names = NULL;
64 : errno_t ret;
65 : int i;
66 :
67 0 : ret = confdb_list_all_domain_names(NULL, confdb, &names);
68 0 : if (ret != EOK) {
69 0 : return false;
70 : }
71 :
72 0 : for (i = 0; names[i] != NULL; i++) {
73 0 : if (strcmp(names[i], name) == 0) {
74 0 : return true;
75 : }
76 : }
77 :
78 0 : return false;
79 : }
80 :
81 0 : static errno_t check_and_get_component_from_path(TALLOC_CTX *mem_ctx,
82 : struct confdb_ctx *confdb,
83 : const char *path,
84 : enum component_type *_type,
85 : char **_name)
86 : {
87 : enum component_type type;
88 0 : char *name = NULL;
89 : errno_t ret;
90 :
91 0 : if (confdb == NULL || path == NULL) {
92 0 : return EINVAL;
93 : }
94 :
95 0 : if (strcmp(path, PATH_MONITOR) == 0) {
96 0 : type = COMPONENT_MONITOR;
97 0 : name = talloc_strdup(mem_ctx, "monitor");
98 0 : if (name == NULL) {
99 0 : ret = ENOMEM;
100 0 : goto done;
101 : }
102 : } else {
103 0 : name = sbus_opath_get_object_name(mem_ctx, path, PATH_RESPONDERS);
104 0 : if (name != NULL) {
105 0 : type = COMPONENT_RESPONDER;
106 : } else {
107 0 : name = sbus_opath_get_object_name(mem_ctx, path, PATH_BACKENDS);
108 0 : if (name != NULL) {
109 0 : type = COMPONENT_BACKEND;
110 : } else {
111 0 : ret = EINVAL;
112 0 : goto done;
113 : }
114 : }
115 : }
116 :
117 0 : if (strchr(name, '/') != NULL) {
118 0 : ret = EINVAL;
119 0 : goto done;
120 : }
121 :
122 0 : switch (type) {
123 : case COMPONENT_MONITOR:
124 : /* noop */
125 0 : break;
126 : case COMPONENT_RESPONDER:
127 0 : if (!responder_exists(name)) {
128 0 : ret = ENOENT;
129 0 : goto done;
130 : }
131 0 : break;
132 : case COMPONENT_BACKEND:
133 0 : if (!backend_exists(confdb, name)) {
134 0 : ret = ENOENT;
135 0 : goto done;
136 : }
137 0 : break;
138 : }
139 :
140 0 : if (_type != NULL) {
141 0 : *_type = type;
142 : }
143 :
144 0 : if (_name != NULL) {
145 0 : *_name = name;
146 : }
147 :
148 0 : ret = EOK;
149 :
150 : done:
151 0 : if (ret != EOK) {
152 0 : talloc_free(name);
153 : }
154 :
155 0 : return ret;
156 : }
157 :
158 0 : static errno_t change_debug_level_tmp(struct confdb_ctx *confdb,
159 : const char *name,
160 : enum component_type type,
161 : uint32_t level)
162 : {
163 0 : TALLOC_CTX *tmp_ctx = NULL;
164 0 : const char *confdb_path = NULL;
165 0 : const char **values = NULL;
166 : errno_t ret;
167 :
168 0 : tmp_ctx = talloc_new(NULL);
169 0 : if (tmp_ctx == NULL) {
170 0 : return ENOMEM;
171 : }
172 :
173 0 : switch (type) {
174 : case COMPONENT_MONITOR:
175 0 : confdb_path = CONFDB_MONITOR_CONF_ENTRY;
176 0 : break;
177 : case COMPONENT_RESPONDER:
178 0 : confdb_path = talloc_asprintf(tmp_ctx, CONFDB_SERVICE_PATH_TMPL, name);
179 0 : break;
180 : case COMPONENT_BACKEND:
181 0 : confdb_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, name);
182 0 : break;
183 : }
184 :
185 0 : if (confdb_path == NULL) {
186 0 : ret = ENOMEM;
187 0 : goto done;
188 : }
189 :
190 0 : values = talloc_zero_array(tmp_ctx, const char*, 2);
191 0 : if (values == NULL) {
192 0 : ret = ENOMEM;
193 0 : goto done;
194 : }
195 :
196 0 : values[0] = talloc_asprintf(tmp_ctx, "0x%.4x", level);
197 0 : if (values[0] == NULL) {
198 0 : ret = ENOMEM;
199 0 : goto done;
200 : }
201 :
202 0 : ret = confdb_add_param(confdb, true, confdb_path,
203 : CONFDB_SERVICE_DEBUG_LEVEL, values);
204 0 : if (ret != EOK) {
205 0 : goto done;
206 : }
207 :
208 : /* reload the configuration */
209 0 : if (kill(getppid(), SIGHUP) != 0) {
210 0 : ret = errno;
211 0 : goto done;
212 : }
213 :
214 0 : ret = EOK;
215 :
216 : done:
217 0 : talloc_free(tmp_ctx);
218 0 : return ret;
219 : }
220 :
221 0 : static errno_t list_responders(TALLOC_CTX *mem_ctx,
222 : const char ***_list,
223 : int *_num)
224 : {
225 0 : const char **list = NULL;
226 0 : const char * const *svc = get_known_services();
227 : errno_t ret;
228 : int num;
229 : int i;
230 :
231 0 : for (num = 0; svc[num] != NULL; num++);
232 :
233 0 : list = talloc_array(mem_ctx, const char*, num);
234 0 : if (list == NULL) {
235 0 : ret = ENOMEM;
236 0 : goto done;
237 : }
238 :
239 0 : for (i = 0; i < num; i++) {
240 0 : list[i] = sbus_opath_compose(list, PATH_RESPONDERS, svc[i]);
241 0 : if (list[i] == NULL) {
242 0 : ret = ENOMEM;
243 0 : goto done;
244 : }
245 : }
246 :
247 0 : *_num = num;
248 0 : *_list = list;
249 0 : ret = EOK;
250 :
251 : done:
252 0 : if (ret != EOK) {
253 0 : talloc_free(list);
254 : }
255 :
256 0 : return ret;
257 : }
258 :
259 0 : static errno_t list_backends(TALLOC_CTX *mem_ctx,
260 : struct confdb_ctx *confdb,
261 : const char ***_list,
262 : int *_num)
263 : {
264 0 : TALLOC_CTX *tmp_ctx = NULL;
265 0 : const char **list = NULL;
266 0 : char **names = NULL;
267 : errno_t ret;
268 : int num;
269 : int i;
270 :
271 0 : tmp_ctx = talloc_new(NULL);
272 0 : if (tmp_ctx == NULL) {
273 0 : return ENOMEM;
274 : }
275 :
276 0 : ret = confdb_list_all_domain_names(tmp_ctx, confdb, &names);
277 0 : if (ret != EOK) {
278 0 : goto done;
279 : }
280 :
281 0 : for (num = 0; names[num] != NULL; num++);
282 :
283 0 : list = talloc_array(tmp_ctx, const char*, num);
284 0 : if (list == NULL) {
285 0 : ret = ENOMEM;
286 0 : goto done;
287 : }
288 :
289 0 : for (i = 0; i < num; i++) {
290 0 : list[i] = sbus_opath_compose(list, PATH_BACKENDS, names[i]);
291 0 : if (list[i] == NULL) {
292 0 : ret = ENOMEM;
293 0 : goto done;
294 : }
295 : }
296 :
297 0 : *_num = num;
298 0 : *_list = talloc_steal(mem_ctx, list);
299 0 : ret = EOK;
300 :
301 : done:
302 0 : talloc_free(tmp_ctx);
303 0 : return ret;
304 : }
305 :
306 0 : int ifp_list_components(struct sbus_request *dbus_req, void *data)
307 : {
308 0 : struct ifp_ctx *ctx = NULL;
309 0 : DBusError *error = NULL;
310 0 : const char **responders = NULL;
311 0 : const char **backends = NULL;
312 0 : const char **result = NULL;
313 : int num_responders;
314 : int num_backends;
315 : int num;
316 : int i;
317 : errno_t ret;
318 :
319 0 : ctx = talloc_get_type(data, struct ifp_ctx);
320 0 : if (ctx == NULL) {
321 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
322 0 : ret = EINVAL;
323 0 : goto done;
324 : }
325 :
326 0 : ret = list_responders(dbus_req, &responders, &num_responders);
327 0 : if (ret != EOK) {
328 0 : goto done;
329 : }
330 :
331 0 : ret = list_backends(dbus_req, ctx->rctx->cdb, &backends, &num_backends);
332 0 : if (ret != EOK) {
333 0 : goto done;
334 : }
335 :
336 0 : num = num_responders + num_backends + 1;
337 0 : result = talloc_array(dbus_req, const char*, num);
338 0 : if (result == NULL) {
339 0 : ret = ENOMEM;
340 0 : goto done;
341 : }
342 :
343 0 : result[0] = PATH_MONITOR;
344 :
345 0 : for (i = 0; i < num_responders; i++) {
346 0 : result[i + 1] = talloc_steal(result, responders[i]);
347 : }
348 :
349 0 : for (i = 0; i < num_backends; i++) {
350 0 : result[i + num_responders + 1] = talloc_steal(result, backends[i]);
351 : }
352 :
353 0 : ret = EOK;
354 :
355 : done:
356 0 : if (ret != EOK) {
357 0 : error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
358 : "%s", strerror(ret));
359 0 : return sbus_request_fail_and_finish(dbus_req, error);
360 : }
361 :
362 0 : return iface_ifp_ListComponents_finish(dbus_req, result, num);
363 : }
364 :
365 0 : int ifp_list_responders(struct sbus_request *dbus_req, void *data)
366 : {
367 0 : DBusError *error = NULL;
368 0 : const char **result = NULL;
369 : int num;
370 : errno_t ret;
371 :
372 0 : ret = list_responders(dbus_req, &result, &num);
373 0 : if (ret != EOK) {
374 0 : error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
375 : "%s", strerror(ret));
376 0 : return sbus_request_fail_and_finish(dbus_req, error);
377 : }
378 :
379 0 : return iface_ifp_ListResponders_finish(dbus_req, result, num);
380 : }
381 :
382 0 : int ifp_list_backends(struct sbus_request *dbus_req, void *data)
383 : {
384 0 : struct ifp_ctx *ctx = NULL;
385 0 : DBusError *error = NULL;
386 0 : const char **result = NULL;
387 : int num;
388 : errno_t ret;
389 :
390 0 : ctx = talloc_get_type(data, struct ifp_ctx);
391 0 : if (ctx == NULL) {
392 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
393 0 : ret = EINVAL;
394 0 : goto done;
395 : }
396 :
397 0 : ret = list_backends(dbus_req, ctx->rctx->cdb, &result, &num);
398 :
399 : done:
400 0 : if (ret != EOK) {
401 0 : error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
402 : "%s", strerror(ret));
403 0 : return sbus_request_fail_and_finish(dbus_req, error);
404 : }
405 :
406 0 : return iface_ifp_ListBackends_finish(dbus_req, result, num);
407 : }
408 :
409 0 : int ifp_find_monitor(struct sbus_request *dbus_req, void *data)
410 : {
411 0 : return iface_ifp_FindMonitor_finish(dbus_req, PATH_MONITOR);
412 : }
413 :
414 0 : int ifp_find_responder_by_name(struct sbus_request *dbus_req,
415 : void *data,
416 : const char *arg_name)
417 : {
418 0 : DBusError *error = NULL;
419 0 : const char *result = NULL;
420 :
421 0 : if (responder_exists(arg_name)) {
422 0 : result = sbus_opath_compose(dbus_req, PATH_RESPONDERS, arg_name);
423 0 : if (result == NULL) {
424 0 : return sbus_request_fail_and_finish(dbus_req, NULL);
425 : }
426 : } else {
427 0 : error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
428 : "Responder \"%s\" does not exist", arg_name);
429 0 : return sbus_request_fail_and_finish(dbus_req, error);
430 : }
431 :
432 0 : return iface_ifp_FindResponderByName_finish(dbus_req, result);
433 : }
434 :
435 0 : int ifp_find_backend_by_name(struct sbus_request *dbus_req,
436 : void *data,
437 : const char *arg_name)
438 : {
439 0 : struct ifp_ctx *ctx = NULL;
440 0 : DBusError *error = NULL;
441 0 : const char *result = NULL;
442 :
443 0 : ctx = talloc_get_type(data, struct ifp_ctx);
444 0 : if (ctx == NULL) {
445 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
446 0 : error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
447 : "%s\n", strerror(EINVAL));
448 0 : return sbus_request_fail_and_finish(dbus_req, error);
449 : }
450 :
451 0 : if (backend_exists(ctx->rctx->cdb, arg_name)) {
452 0 : result = sbus_opath_compose(dbus_req, PATH_BACKENDS, arg_name);
453 0 : if (result == NULL) {
454 0 : return sbus_request_fail_and_finish(dbus_req, NULL);
455 : }
456 : } else {
457 0 : error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED,
458 : "Backend \"%s\" does not exist", arg_name);
459 0 : return sbus_request_fail_and_finish(dbus_req, error);
460 : }
461 :
462 0 : return iface_ifp_FindBackendByName_finish(dbus_req, result);
463 : }
464 :
465 0 : int ifp_component_enable(struct sbus_request *dbus_req, void *data)
466 : {
467 : #ifndef HAVE_CONFIG_LIB
468 : return sbus_request_fail_and_finish(dbus_req,
469 : sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL));
470 : #else
471 0 : struct ifp_ctx *ctx = NULL;
472 0 : DBusError *error = NULL;
473 0 : const char *path = dbus_message_get_path(dbus_req->message);
474 0 : char *name = NULL;
475 : enum component_type type;
476 0 : struct sss_config_ctx *config_ctx = NULL;
477 : errno_t ret;
478 :
479 0 : ctx = talloc_get_type(data, struct ifp_ctx);
480 0 : if (ctx == NULL) {
481 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
482 0 : ret = EINVAL;
483 0 : goto done;
484 : }
485 :
486 0 : ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
487 : path, &type, &name);
488 0 : if (ret != EOK) {
489 0 : goto done;
490 : }
491 :
492 0 : config_ctx = sss_config_open(dbus_req, NULL, CONFDB_DEFAULT_CONFIG_FILE);
493 0 : if (config_ctx == NULL) {
494 0 : ret = ENOMEM;
495 0 : goto done;
496 : }
497 :
498 0 : switch (type) {
499 : case COMPONENT_MONITOR:
500 0 : error = sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL);
501 0 : goto done;
502 : break;
503 : case COMPONENT_RESPONDER:
504 0 : ret = sss_config_service_enable(config_ctx, name);
505 0 : break;
506 : case COMPONENT_BACKEND:
507 0 : ret = sss_config_domain_enable(config_ctx, name);
508 0 : break;
509 : }
510 :
511 0 : if (ret != EOK) {
512 0 : goto done;
513 : }
514 :
515 0 : ret = sss_config_save(config_ctx);
516 0 : if (ret != EOK) {
517 0 : goto done;
518 : }
519 :
520 : done:
521 0 : sss_config_close(&config_ctx);
522 :
523 0 : if (ret == ENOMEM) {
524 0 : return sbus_request_fail_and_finish(dbus_req, NULL);
525 0 : } else if (error != NULL) {
526 0 : return sbus_request_fail_and_finish(dbus_req, error);
527 0 : } else if (ret != EOK) {
528 0 : error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret));
529 0 : return sbus_request_fail_and_finish(dbus_req, error);
530 : }
531 :
532 0 : return iface_ifp_components_Enable_finish(dbus_req);
533 : #endif
534 : }
535 :
536 0 : int ifp_component_disable(struct sbus_request *dbus_req, void *data)
537 : {
538 : #ifndef HAVE_CONFIG_LIB
539 : return sbus_request_fail_and_finish(dbus_req,
540 : sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL));
541 : #else
542 0 : struct ifp_ctx *ctx = NULL;
543 0 : DBusError *error = NULL;
544 0 : const char *path = dbus_message_get_path(dbus_req->message);
545 0 : char *name = NULL;
546 : enum component_type type;
547 0 : struct sss_config_ctx *config_ctx = NULL;
548 : errno_t ret;
549 :
550 0 : ctx = talloc_get_type(data, struct ifp_ctx);
551 0 : if (ctx == NULL) {
552 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
553 0 : ret = EINVAL;
554 0 : goto done;
555 : }
556 :
557 0 : ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
558 : path, &type, &name);
559 0 : if (ret != EOK) {
560 0 : goto done;
561 : }
562 :
563 0 : config_ctx = sss_config_open(dbus_req, NULL, CONFDB_DEFAULT_CONFIG_FILE);
564 0 : if (config_ctx == NULL) {
565 0 : ret = ENOMEM;
566 0 : goto done;
567 : }
568 :
569 0 : switch (type) {
570 : case COMPONENT_MONITOR:
571 0 : error = sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL);
572 0 : goto done;
573 : break;
574 : case COMPONENT_RESPONDER:
575 0 : ret = sss_config_service_disable(config_ctx, name);
576 0 : break;
577 : case COMPONENT_BACKEND:
578 0 : ret = sss_config_domain_disable(config_ctx, name);
579 0 : break;
580 : }
581 :
582 0 : if (ret != EOK) {
583 0 : goto done;
584 : }
585 :
586 0 : ret = sss_config_save(config_ctx);
587 0 : if (ret != EOK) {
588 0 : goto done;
589 : }
590 :
591 : done:
592 0 : sss_config_close(&config_ctx);
593 :
594 0 : if (ret == ENOMEM) {
595 0 : return sbus_request_fail_and_finish(dbus_req, NULL);
596 0 : } else if (error != NULL) {
597 0 : return sbus_request_fail_and_finish(dbus_req, error);
598 0 : } else if (ret != EOK) {
599 0 : error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret));
600 0 : return sbus_request_fail_and_finish(dbus_req, error);
601 : }
602 :
603 0 : return iface_ifp_components_Disable_finish(dbus_req);
604 : #endif
605 : }
606 :
607 0 : int ifp_component_change_debug_level(struct sbus_request *dbus_req,
608 : void *data,
609 : uint32_t arg_new_level)
610 : {
611 : #ifndef HAVE_CONFIG_LIB
612 : return sbus_request_fail_and_finish(dbus_req,
613 : sbus_error_new(dbus_req, DBUS_ERROR_NOT_SUPPORTED, NULL));
614 : #else
615 0 : struct ifp_ctx *ctx = NULL;
616 0 : DBusError *error = NULL;
617 0 : const char *path = dbus_message_get_path(dbus_req->message);
618 0 : char *name = NULL;
619 : enum component_type type;
620 0 : struct sss_config_ctx *config_ctx = NULL;
621 0 : const char *section = NULL;
622 : errno_t ret;
623 :
624 0 : ctx = talloc_get_type(data, struct ifp_ctx);
625 0 : if (ctx == NULL) {
626 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
627 0 : ret = EINVAL;
628 0 : goto done;
629 : }
630 :
631 0 : ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
632 : path, &type, &name);
633 0 : if (ret != EOK) {
634 0 : goto done;
635 : }
636 :
637 0 : switch (type) {
638 : case COMPONENT_MONITOR:
639 0 : section = "sssd";
640 0 : break;
641 : case COMPONENT_RESPONDER:
642 0 : section = name;
643 0 : break;
644 : case COMPONENT_BACKEND:
645 0 : section = talloc_asprintf(dbus_req, "domain/%s", name);
646 0 : break;
647 : }
648 :
649 0 : if (section == NULL) {
650 0 : ret = ENOMEM;
651 0 : goto done;
652 : }
653 :
654 0 : config_ctx = sss_config_open(dbus_req, NULL, CONFDB_DEFAULT_CONFIG_FILE);
655 0 : if (config_ctx == NULL) {
656 0 : ret = ENOMEM;
657 0 : goto done;
658 : }
659 :
660 0 : ret = sss_config_set_debug_level(config_ctx, section, arg_new_level);
661 0 : if (ret != EOK) {
662 0 : goto done;
663 : }
664 :
665 0 : ret = sss_config_save(config_ctx);
666 0 : if (ret != EOK) {
667 0 : goto done;
668 : }
669 :
670 0 : ret = change_debug_level_tmp(ctx->rctx->cdb, name, type, arg_new_level);
671 0 : if (ret != EOK) {
672 0 : goto done;
673 : }
674 :
675 : done:
676 0 : sss_config_close(&config_ctx);
677 :
678 0 : if (ret == ENOMEM) {
679 0 : return sbus_request_fail_and_finish(dbus_req, NULL);
680 0 : } else if (ret != EOK) {
681 0 : error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret));
682 0 : return sbus_request_fail_and_finish(dbus_req, error);
683 : }
684 :
685 0 : return iface_ifp_components_ChangeDebugLevel_finish(dbus_req);
686 : #endif
687 : }
688 :
689 0 : int ifp_component_change_debug_level_tmp(struct sbus_request *dbus_req,
690 : void *data,
691 : uint32_t arg_new_level)
692 : {
693 0 : struct ifp_ctx *ctx = NULL;
694 0 : DBusError *error = NULL;
695 0 : char *name = NULL;
696 : enum component_type type;
697 : errno_t ret;
698 :
699 0 : ctx = talloc_get_type(data, struct ifp_ctx);
700 0 : if (ctx == NULL) {
701 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
702 0 : ret = EINVAL;
703 0 : goto done;
704 : }
705 :
706 0 : ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
707 : dbus_req->path, &type, &name);
708 0 : if (ret != EOK) {
709 0 : goto done;
710 : }
711 :
712 0 : ret = change_debug_level_tmp(ctx->rctx->cdb, name, type, arg_new_level);
713 0 : if (ret != EOK) {
714 0 : goto done;
715 : }
716 :
717 : /* Touch configuration file to make sure debug level is reloaded. */
718 0 : if (utime(CONFDB_DEFAULT_CONFIG_FILE, NULL) == -1) {
719 0 : ret = errno;
720 0 : goto done;
721 : }
722 :
723 0 : ret = EOK;
724 :
725 : done:
726 0 : if (ret != EOK) {
727 0 : error = sbus_error_new(dbus_req, DBUS_ERROR_FAILED, "%s", strerror(ret));
728 0 : return sbus_request_fail_and_finish(dbus_req, error);
729 : }
730 :
731 0 : return iface_ifp_components_ChangeDebugLevelTemporarily_finish(dbus_req);
732 : }
733 :
734 0 : void ifp_component_get_name(struct sbus_request *dbus_req,
735 : void *data,
736 : const char **_out)
737 : {
738 0 : struct ifp_ctx *ctx = NULL;
739 0 : char *name = NULL;
740 : errno_t ret;
741 :
742 0 : *_out = NULL;
743 :
744 0 : ctx = talloc_get_type(data, struct ifp_ctx);
745 0 : if (ctx == NULL) {
746 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
747 0 : return;
748 : }
749 :
750 0 : ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
751 : dbus_req->path, NULL, &name);
752 0 : if (ret != EOK) {
753 0 : DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n",
754 : ret, strerror(ret));
755 0 : return;
756 : }
757 :
758 0 : *_out = name;
759 : }
760 :
761 0 : void ifp_component_get_debug_level(struct sbus_request *dbus_req,
762 : void *data,
763 : uint32_t *_out)
764 : {
765 0 : struct ifp_ctx *ctx = NULL;
766 0 : const char *confdb_path = NULL;
767 0 : char *name = NULL;
768 : enum component_type type;
769 : int level;
770 : errno_t ret;
771 :
772 0 : *_out = 0;
773 :
774 0 : ctx = talloc_get_type(data, struct ifp_ctx);
775 0 : if (ctx == NULL) {
776 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
777 0 : return;
778 : }
779 :
780 0 : ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
781 : dbus_req->path, &type, &name);
782 0 : if (ret != EOK) {
783 0 : DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n",
784 : ret, strerror(ret));
785 0 : return;
786 : }
787 :
788 0 : switch (type) {
789 : case COMPONENT_MONITOR:
790 0 : confdb_path = CONFDB_MONITOR_CONF_ENTRY;
791 0 : break;
792 : case COMPONENT_RESPONDER:
793 0 : confdb_path = talloc_asprintf(dbus_req, CONFDB_SERVICE_PATH_TMPL, name);
794 0 : break;
795 : case COMPONENT_BACKEND:
796 0 : confdb_path = talloc_asprintf(dbus_req, CONFDB_DOMAIN_PATH_TMPL, name);
797 0 : break;
798 : }
799 :
800 0 : if (confdb_path == NULL) {
801 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Out of memory\n");
802 0 : return;
803 : }
804 :
805 0 : ret = confdb_get_int(ctx->rctx->cdb, confdb_path,
806 : CONFDB_SERVICE_DEBUG_LEVEL, SSSDBG_DEFAULT, &level);
807 0 : if (ret != EOK) {
808 0 : DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve configuration option"
809 : "[%d]: %s\n", ret, strerror(ret));
810 0 : return;
811 : }
812 :
813 0 : *_out = level;
814 : }
815 :
816 0 : void ifp_component_get_enabled(struct sbus_request *dbus_req,
817 : void *data,
818 : bool *_out)
819 : {
820 0 : struct ifp_ctx *ctx = NULL;
821 0 : const char *param = NULL;
822 0 : char **values = NULL;
823 0 : char *name = NULL;
824 : enum component_type type;
825 : errno_t ret;
826 : int i;
827 :
828 0 : *_out = false;
829 :
830 0 : ctx = talloc_get_type(data, struct ifp_ctx);
831 0 : if (ctx == NULL) {
832 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
833 0 : return;
834 : }
835 :
836 0 : ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
837 : dbus_req->path, &type, &name);
838 0 : if (ret != EOK) {
839 0 : DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n",
840 : ret, strerror(ret));
841 0 : return;
842 : }
843 :
844 0 : switch (type) {
845 : case COMPONENT_MONITOR:
846 0 : *_out = true;
847 0 : return;
848 : case COMPONENT_RESPONDER:
849 0 : param = CONFDB_MONITOR_ACTIVE_SERVICES;
850 0 : break;
851 : case COMPONENT_BACKEND:
852 0 : param = CONFDB_MONITOR_ACTIVE_DOMAINS;
853 0 : break;
854 : }
855 :
856 0 : ret = confdb_get_string_as_list(ctx->rctx->cdb, dbus_req,
857 : CONFDB_MONITOR_CONF_ENTRY, param, &values);
858 0 : if (ret != EOK) {
859 0 : DEBUG(SSSDBG_OP_FAILURE, "Unable to retrieve configuration option"
860 : "[%d]: %s\n", ret, strerror(ret));
861 0 : return;
862 : }
863 :
864 0 : for (i = 0; values[i] != NULL; i++) {
865 0 : if (strcmp(values[i], name) == 0) {
866 0 : *_out = true;
867 0 : return;
868 : }
869 : }
870 : }
871 :
872 0 : void ifp_component_get_type(struct sbus_request *dbus_req,
873 : void *data,
874 : const char **_out)
875 : {
876 0 : struct ifp_ctx *ctx = NULL;
877 : enum component_type type;
878 : errno_t ret;
879 :
880 0 : *_out = NULL;
881 :
882 0 : ctx = talloc_get_type(data, struct ifp_ctx);
883 0 : if (ctx == NULL) {
884 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
885 0 : return;
886 : }
887 :
888 0 : ret = check_and_get_component_from_path(dbus_req, ctx->rctx->cdb,
889 : dbus_req->path, &type, NULL);
890 0 : if (ret != EOK) {
891 0 : DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n",
892 : ret, strerror(ret));
893 0 : return;
894 : }
895 :
896 0 : switch (type) {
897 : case COMPONENT_MONITOR:
898 0 : *_out = "monitor";
899 0 : break;
900 : case COMPONENT_RESPONDER:
901 0 : *_out = "responder";
902 0 : break;
903 : case COMPONENT_BACKEND:
904 0 : *_out = "backend";
905 0 : break;
906 : }
907 : }
908 :
909 0 : void ifp_backend_get_providers(struct sbus_request *dbus_req,
910 : void *data,
911 : const char ***_out,
912 : int *_out_len)
913 : {
914 0 : TALLOC_CTX *tmp_ctx = NULL;
915 0 : struct ifp_ctx *ctx = NULL;
916 0 : const char *confdb_path = NULL;
917 0 : char *name = NULL;
918 : enum component_type type;
919 0 : const char **out = NULL;
920 0 : char *value = NULL;
921 : static const char *providers[] = {CONFDB_DOMAIN_ID_PROVIDER,
922 : CONFDB_DOMAIN_AUTH_PROVIDER,
923 : CONFDB_DOMAIN_ACCESS_PROVIDER,
924 : CONFDB_DOMAIN_CHPASS_PROVIDER,
925 : CONFDB_DOMAIN_SUDO_PROVIDER,
926 : CONFDB_DOMAIN_AUTOFS_PROVIDER,
927 : CONFDB_DOMAIN_SELINUX_PROVIDER,
928 : CONFDB_DOMAIN_HOSTID_PROVIDER,
929 : CONFDB_DOMAIN_SUBDOMAINS_PROVIDER};
930 0 : int num_providers = sizeof(providers) / sizeof(providers[0]);
931 : errno_t ret;
932 : int i;
933 : int j;
934 :
935 0 : *_out = NULL;
936 0 : *_out_len = 0;
937 :
938 0 : tmp_ctx = talloc_new(NULL);
939 0 : if (tmp_ctx == NULL) {
940 0 : return;
941 : }
942 :
943 0 : ctx = talloc_get_type(data, struct ifp_ctx);
944 0 : if (ctx == NULL) {
945 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Invalid ifp context!\n");
946 0 : return;
947 : }
948 :
949 0 : ret = check_and_get_component_from_path(tmp_ctx, ctx->rctx->cdb,
950 : dbus_req->path, &type, &name);
951 0 : if (ret != EOK) {
952 0 : DEBUG(SSSDBG_OP_FAILURE, "Unknown object [%d]: %s\n",
953 : ret, strerror(ret));
954 0 : return;
955 : }
956 :
957 0 : if (type != COMPONENT_BACKEND) {
958 0 : return;
959 : }
960 :
961 0 : confdb_path = talloc_asprintf(tmp_ctx, CONFDB_DOMAIN_PATH_TMPL, name);
962 0 : if (confdb_path == NULL) {
963 0 : return;
964 : }
965 :
966 0 : out = talloc_zero_array(tmp_ctx, const char*, num_providers);
967 0 : if (out == NULL) {
968 0 : return;
969 : }
970 :
971 0 : j = 0;
972 0 : for (i = 0; i < num_providers; i++) {
973 0 : ret = confdb_get_string(ctx->rctx->cdb, tmp_ctx, confdb_path,
974 : providers[i], NULL, &value);
975 0 : if (ret != EOK) {
976 0 : return;
977 : }
978 :
979 0 : if (value == NULL) {
980 0 : continue;
981 : }
982 :
983 0 : out[j] = talloc_asprintf(out, "%s=%s", providers[i], value);
984 0 : if (out[j] == NULL) {
985 0 : return;
986 : }
987 :
988 0 : j++;
989 : }
990 :
991 0 : *_out = talloc_steal(dbus_req, out);
992 0 : *_out_len = j;
993 :
994 0 : talloc_free(tmp_ctx);
995 0 : return;
996 : }
|