Line data Source code
1 : /*
2 : Authors:
3 : Pavel Březina <pbrezina@redhat.com>
4 :
5 : Copyright (C) 2015 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 <ldb.h>
22 : #include <talloc.h>
23 : #include <dhash.h>
24 :
25 : #include "providers/ldap/sdap.h"
26 : #include "providers/ipa/ipa_common.h"
27 : #include "providers/ipa/ipa_dn.h"
28 : #include "db/sysdb_sudo.h"
29 : #include "db/sysdb.h"
30 : #include "util/util.h"
31 :
32 : #define SUDO_DN_CMDGROUPS "sudocmdgroups"
33 : #define SUDO_DN_CMDS "sudocmds"
34 : #define SUDO_DN_CONTAINER "sudo"
35 : #define SUDO_DN_CN "cn"
36 :
37 : #define MATCHDN(cat) SUDO_DN_CN, (cat), SUDO_DN_CN, SUDO_DN_CONTAINER
38 : #define MATCHDN_CMDGROUPS MATCHDN(SUDO_DN_CMDGROUPS)
39 : #define MATCHDN_CMDS MATCHDN(SUDO_DN_CMDS)
40 :
41 : #define MATCHRDN_CMDGROUPS(map) (map)[IPA_AT_SUDOCMDGROUP_NAME].name, MATCHDN_CMDGROUPS
42 : #define MATCHRDN_CMDS(attr, map) (map)[attr].name, MATCHDN_CMDS
43 :
44 : #define MATCHRDN_USER(map) (map)[SDAP_AT_USER_NAME].name, "cn", "users", "cn", "accounts"
45 : #define MATCHRDN_GROUP(map) (map)[SDAP_AT_GROUP_NAME].name, "cn", "groups", "cn", "accounts"
46 : #define MATCHRDN_HOST(map) (map)[IPA_AT_HOST_FQDN].name, "cn", "computers", "cn", "accounts"
47 : #define MATCHRDN_HOSTGROUP(map) (map)[IPA_AT_HOSTGROUP_NAME].name, "cn", "hostgroups", "cn", "accounts"
48 :
49 : struct ipa_sudo_conv {
50 : struct sysdb_ctx *sysdb;
51 :
52 : struct sdap_attr_map *map_rule;
53 : struct sdap_attr_map *map_cmdgroup;
54 : struct sdap_attr_map *map_cmd;
55 : struct sdap_attr_map *map_user;
56 : struct sdap_attr_map *map_group;
57 : struct sdap_attr_map *map_host;
58 : struct sdap_attr_map *map_hostgroup;
59 :
60 : hash_table_t *rules;
61 : hash_table_t *cmdgroups;
62 : hash_table_t *cmds;
63 : };
64 :
65 : struct ipa_sudo_dn_list {
66 : struct ipa_sudo_dn_list *prev, *next;
67 : const char *dn;
68 : };
69 :
70 : struct ipa_sudo_rulemember {
71 : struct ipa_sudo_dn_list *cmdgroups;
72 : struct ipa_sudo_dn_list *cmds;
73 : };
74 :
75 : struct ipa_sudo_rule {
76 : struct sysdb_attrs *attrs;
77 : struct ipa_sudo_rulemember allow;
78 : struct ipa_sudo_rulemember deny;
79 : };
80 :
81 : struct ipa_sudo_cmdgroup {
82 : struct ipa_sudo_dn_list *cmds;
83 : const char **expanded;
84 : };
85 :
86 : static size_t
87 0 : ipa_sudo_dn_list_count(struct ipa_sudo_dn_list *list)
88 : {
89 : struct ipa_sudo_dn_list *item;
90 : size_t i;
91 :
92 0 : for (i = 0, item = list; item != NULL; item = item->next, i++) {
93 : /* no op */
94 : }
95 :
96 0 : return i;
97 : }
98 :
99 : static errno_t
100 0 : ipa_sudo_conv_store(hash_table_t *table,
101 : const char *key,
102 : void *value)
103 : {
104 : hash_key_t hkey;
105 : hash_value_t hvalue;
106 : int hret;
107 :
108 0 : if (table == NULL || key == NULL) {
109 0 : return EINVAL;
110 : }
111 :
112 0 : hkey.type = HASH_KEY_STRING;
113 0 : hkey.str = discard_const(key);
114 :
115 : /* If value is NULL we don't want to override existing entry. */
116 0 : if (value == NULL && hash_has_key(table, &hkey)) {
117 0 : return EEXIST;
118 : }
119 :
120 0 : hvalue.type = HASH_VALUE_PTR;
121 0 : hvalue.ptr = value;
122 :
123 0 : hret = hash_enter(table, &hkey, &hvalue);
124 0 : if (hret != HASH_SUCCESS) {
125 0 : return EIO;
126 : }
127 :
128 0 : if (value != NULL) {
129 0 : talloc_steal(table, value);
130 : }
131 :
132 0 : return EOK;
133 : }
134 :
135 : static void *
136 0 : ipa_sudo_conv_lookup(hash_table_t *table,
137 : const char *key)
138 : {
139 : hash_key_t hkey;
140 : hash_value_t hvalue;
141 : int hret;
142 :
143 0 : hkey.type = HASH_KEY_STRING;
144 0 : hkey.str = discard_const(key);
145 :
146 0 : hret = hash_lookup(table, &hkey, &hvalue);
147 0 : if (hret == HASH_ERROR_KEY_NOT_FOUND) {
148 0 : DEBUG(SSSDBG_OP_FAILURE, "Key not found %s\n", key);
149 0 : return NULL;
150 0 : } else if (hret != HASH_SUCCESS) {
151 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to lookup value [%d]\n", hret);
152 0 : return NULL;
153 : }
154 :
155 0 : return hvalue.ptr;
156 : }
157 :
158 : static errno_t
159 0 : store_rulemember(TALLOC_CTX *mem_ctx,
160 : struct ipa_sudo_dn_list **list,
161 : hash_table_t *table,
162 : const char *dn)
163 : {
164 : struct ipa_sudo_dn_list *item;
165 : errno_t ret;
166 :
167 0 : item = talloc_zero(mem_ctx, struct ipa_sudo_dn_list);
168 0 : if (item == NULL) {
169 0 : return ENOMEM;
170 : }
171 :
172 0 : ret = ipa_sudo_conv_store(table, dn, NULL);
173 0 : if (ret != EOK && ret != EEXIST) {
174 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to store DN %s [%d]: %s\n",
175 : dn, ret, sss_strerror(ret));
176 0 : goto done;
177 : }
178 :
179 0 : item->dn = talloc_steal(item, dn);
180 0 : DLIST_ADD(*list, item);
181 :
182 : done:
183 0 : if (ret != EOK && ret != EEXIST) {
184 0 : talloc_free(item);
185 : }
186 :
187 0 : return ret;
188 : }
189 :
190 0 : static bool is_ipacmdgroup(struct ipa_sudo_conv *conv, const char *dn)
191 : {
192 0 : if (ipa_check_rdn_bool(conv->sysdb, dn,
193 : MATCHRDN_CMDGROUPS(conv->map_cmdgroup))) {
194 0 : return true;
195 : }
196 :
197 0 : return false;
198 : }
199 :
200 0 : static bool is_ipacmd(struct ipa_sudo_conv *conv, const char *dn)
201 : {
202 0 : if (ipa_check_rdn_bool(conv->sysdb, dn,
203 : MATCHRDN_CMDS(IPA_AT_SUDOCMD_UUID, conv->map_cmd))) {
204 0 : return true;
205 : }
206 :
207 : /* For older versions of FreeIPA than 3.1. */
208 0 : if (ipa_check_rdn_bool(conv->sysdb, dn,
209 : MATCHRDN_CMDS(IPA_AT_SUDOCMD_CMD, conv->map_cmd))) {
210 0 : return true;
211 : }
212 :
213 0 : return false;
214 : }
215 :
216 : static errno_t
217 0 : process_rulemember(TALLOC_CTX *mem_ctx,
218 : struct ipa_sudo_conv *conv,
219 : struct ipa_sudo_rulemember *rulemember,
220 : struct sysdb_attrs *rule,
221 : const char *attr)
222 : {
223 : TALLOC_CTX *tmp_ctx;
224 : const char **members;
225 : errno_t ret;
226 : int i;
227 :
228 0 : tmp_ctx = talloc_new(NULL);
229 0 : if (tmp_ctx == NULL) {
230 0 : return ENOMEM;
231 : }
232 :
233 0 : ret = sysdb_attrs_get_string_array(rule, attr, tmp_ctx, &members);
234 0 : if (ret == ENOENT) {
235 0 : ret = EOK;
236 0 : goto done;
237 0 : } else if (ret != EOK) {
238 0 : goto done;
239 : }
240 :
241 0 : for (i = 0; members[i] != NULL; i++) {
242 0 : if (is_ipacmdgroup(conv, members[i])) {
243 0 : ret = store_rulemember(mem_ctx, &rulemember->cmdgroups,
244 0 : conv->cmdgroups, members[i]);
245 0 : if (ret == EOK) {
246 0 : DEBUG(SSSDBG_TRACE_INTERNAL, "Found sudo command group %s\n",
247 : members[i]);
248 0 : } else if (ret != EEXIST) {
249 0 : goto done;
250 : }
251 0 : } else if (is_ipacmd(conv, members[i])) {
252 0 : ret = store_rulemember(mem_ctx, &rulemember->cmds,
253 0 : conv->cmds, members[i]);
254 0 : if (ret == EOK) {
255 0 : DEBUG(SSSDBG_TRACE_INTERNAL, "Found sudo command %s\n",
256 : members[i]);
257 0 : } else if (ret != EEXIST) {
258 0 : goto done;
259 : }
260 : } else {
261 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Invalid member DN %s, skipping...\n",
262 : members[i]);
263 0 : continue;
264 : }
265 : }
266 :
267 0 : ret = EOK;
268 :
269 : done:
270 0 : talloc_free(tmp_ctx);
271 0 : return ret;
272 : }
273 :
274 : static errno_t
275 0 : process_allowcmd(struct ipa_sudo_conv *conv,
276 : struct ipa_sudo_rule *rule)
277 : {
278 0 : return process_rulemember(rule, conv, &rule->allow, rule->attrs,
279 : SYSDB_IPA_SUDORULE_ALLOWCMD);
280 : }
281 :
282 : static errno_t
283 0 : process_denycmd(struct ipa_sudo_conv *conv,
284 : struct ipa_sudo_rule *rule)
285 : {
286 0 : return process_rulemember(rule, conv, &rule->deny, rule->attrs,
287 : SYSDB_IPA_SUDORULE_DENYCMD);
288 : }
289 :
290 : static errno_t
291 0 : process_cmdgroupmember(struct ipa_sudo_conv *conv,
292 : struct ipa_sudo_cmdgroup *cmdgroup,
293 : struct sysdb_attrs *attrs)
294 : {
295 : TALLOC_CTX *tmp_ctx;
296 : struct ipa_sudo_dn_list *item;
297 : const char **members;
298 : errno_t ret;
299 : int i;
300 :
301 0 : tmp_ctx = talloc_new(NULL);
302 0 : if (tmp_ctx == NULL) {
303 0 : return ENOMEM;
304 : }
305 :
306 0 : ret = sysdb_attrs_get_string_array(attrs, SYSDB_MEMBER, tmp_ctx, &members);
307 0 : if (ret == ENOENT) {
308 0 : ret = EOK;
309 0 : goto done;
310 0 : } else if (ret != EOK) {
311 0 : goto done;
312 : }
313 :
314 0 : for (i = 0; members[i] != NULL; i++) {
315 0 : ret = ipa_sudo_conv_store(conv->cmds, members[i], NULL);
316 0 : if (ret == EOK) {
317 0 : DEBUG(SSSDBG_TRACE_INTERNAL, "Found sudo command %s\n",
318 : members[i]);
319 0 : } else if (ret != EEXIST) {
320 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to store DN [%d]: %s\n",
321 : ret, sss_strerror(ret));
322 0 : goto done;
323 : }
324 :
325 0 : item = talloc_zero(tmp_ctx, struct ipa_sudo_dn_list);
326 0 : if (item == NULL) {
327 0 : ret = ENOMEM;
328 0 : goto done;
329 : }
330 :
331 0 : item->dn = talloc_steal(item, members[i]);
332 0 : DLIST_ADD(cmdgroup->cmds, item);
333 0 : talloc_steal(cmdgroup, item);
334 : }
335 :
336 0 : ret = EOK;
337 :
338 : done:
339 0 : talloc_free(tmp_ctx);
340 0 : return ret;
341 : }
342 :
343 : struct ipa_sudo_conv *
344 0 : ipa_sudo_conv_init(TALLOC_CTX *mem_ctx,
345 : struct sysdb_ctx *sysdb,
346 : struct sdap_attr_map *map_rule,
347 : struct sdap_attr_map *map_cmdgroup,
348 : struct sdap_attr_map *map_cmd,
349 : struct sdap_attr_map *map_user,
350 : struct sdap_attr_map *map_group,
351 : struct sdap_attr_map *map_host,
352 : struct sdap_attr_map *map_hostgroup)
353 : {
354 : struct ipa_sudo_conv *conv;
355 : errno_t ret;
356 :
357 0 : conv = talloc_zero(mem_ctx, struct ipa_sudo_conv);
358 0 : if (conv == NULL) {
359 0 : return NULL;
360 : }
361 :
362 0 : conv->sysdb = sysdb;
363 0 : conv->map_rule = map_rule;
364 0 : conv->map_cmdgroup = map_cmdgroup;
365 0 : conv->map_cmd = map_cmd;
366 0 : conv->map_user = map_user;
367 0 : conv->map_group = map_group;
368 0 : conv->map_host = map_host;
369 0 : conv->map_hostgroup = map_hostgroup;
370 :
371 0 : ret = sss_hash_create(conv, 20, &conv->rules);
372 0 : if (ret != EOK) {
373 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n",
374 : ret, sss_strerror(ret));
375 0 : goto done;
376 : }
377 :
378 0 : ret = sss_hash_create(conv, 20, &conv->cmdgroups);
379 0 : if (ret != EOK) {
380 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n",
381 : ret, sss_strerror(ret));
382 0 : goto done;
383 : }
384 :
385 0 : ret = sss_hash_create(conv, 20, &conv->cmds);
386 0 : if (ret != EOK) {
387 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to create hash table [%d]: %s\n",
388 : ret, sss_strerror(ret));
389 0 : goto done;
390 : }
391 :
392 : done:
393 0 : if (ret != EOK) {
394 0 : talloc_free(conv);
395 0 : return NULL;
396 : }
397 :
398 0 : return conv;
399 : }
400 :
401 : errno_t
402 0 : ipa_sudo_conv_rules(struct ipa_sudo_conv *conv,
403 : struct sysdb_attrs **rules,
404 : size_t num_rules)
405 : {
406 0 : struct ipa_sudo_rule *rule = NULL;
407 : const char *key;
408 : errno_t ret;
409 : size_t i;
410 :
411 0 : if (num_rules == 0) {
412 : /* We're done here. */
413 0 : return EOK;
414 : }
415 :
416 0 : for (i = 0; i < num_rules; i++) {
417 0 : ret = sysdb_attrs_get_string(rules[i], SYSDB_NAME, &key);
418 0 : if (ret != EOK) {
419 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get rule name, skipping "
420 : "[%d]: %s\n", ret, sss_strerror(ret));
421 0 : continue;
422 : }
423 :
424 0 : rule = talloc_zero(conv->rules, struct ipa_sudo_rule);
425 0 : if (rule == NULL) {
426 0 : ret = ENOMEM;
427 0 : goto done;
428 : }
429 :
430 0 : rule->attrs = rules[i];
431 :
432 0 : ret = process_allowcmd(conv, rule);
433 0 : if (ret != EOK && ret != EEXIST) {
434 0 : DEBUG(SSSDBG_OP_FAILURE, "Failed to process memberAllowCmd "
435 : "[%d]: %s\n", ret, sss_strerror(ret));
436 0 : return ret;
437 : }
438 :
439 0 : ret = process_denycmd(conv, rule);
440 0 : if (ret != EOK && ret != EEXIST) {
441 0 : DEBUG(SSSDBG_OP_FAILURE, "Failed to process memberDenyCmd "
442 : "[%d]: %s\n", ret, sss_strerror(ret));
443 0 : return ret;
444 : }
445 :
446 0 : ret = ipa_sudo_conv_store(conv->rules, key, rule);
447 0 : if (ret != EOK) {
448 0 : DEBUG(SSSDBG_OP_FAILURE, "Failed to store rule into table "
449 : "[%d]: %s\n", ret, sss_strerror(ret));
450 0 : goto done;
451 : }
452 :
453 0 : talloc_steal(rule, rule->attrs);
454 0 : rule = NULL;
455 : }
456 :
457 0 : ret = EOK;
458 :
459 : done:
460 0 : if (ret != EOK) {
461 0 : talloc_free(rule);
462 : }
463 :
464 0 : return ret;
465 : }
466 :
467 : errno_t
468 0 : ipa_sudo_conv_cmdgroups(struct ipa_sudo_conv *conv,
469 : struct sysdb_attrs **cmdgroups,
470 : size_t num_cmdgroups)
471 : {
472 0 : struct ipa_sudo_cmdgroup *cmdgroup = NULL;
473 : const char *key;
474 : errno_t ret;
475 : size_t i;
476 :
477 0 : if (num_cmdgroups == 0) {
478 : /* We're done here. */
479 0 : return EOK;
480 : }
481 :
482 0 : for (i = 0; i < num_cmdgroups; i++) {
483 0 : ret = sysdb_attrs_get_string(cmdgroups[i], SYSDB_ORIG_DN, &key);
484 0 : if (ret != EOK) {
485 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get command group DN, "
486 : "skipping [%d]: %s\n", ret, sss_strerror(ret));
487 0 : continue;
488 : }
489 :
490 0 : cmdgroup = talloc_zero(conv->cmdgroups, struct ipa_sudo_cmdgroup);
491 0 : if (cmdgroup == NULL) {
492 0 : ret = ENOMEM;
493 0 : goto done;
494 : }
495 :
496 0 : ret = process_cmdgroupmember(conv, cmdgroup, cmdgroups[i]);
497 0 : if (ret != EOK) {
498 0 : DEBUG(SSSDBG_OP_FAILURE, "Failed to process member "
499 : "[%d]: %s\n", ret, sss_strerror(ret));
500 0 : return ret;
501 : }
502 :
503 0 : ret = ipa_sudo_conv_store(conv->cmdgroups, key, cmdgroup);
504 0 : if (ret != EOK) {
505 0 : DEBUG(SSSDBG_OP_FAILURE, "Failed to store command group into "
506 : "table [%d]: %s\n", ret, sss_strerror(ret));
507 0 : goto done;
508 : }
509 :
510 0 : cmdgroup = NULL;
511 : }
512 :
513 0 : ret = EOK;
514 :
515 : done:
516 0 : if (ret != EOK) {
517 0 : talloc_free(cmdgroup);
518 : }
519 :
520 0 : return ret;
521 : }
522 :
523 : errno_t
524 0 : ipa_sudo_conv_cmds(struct ipa_sudo_conv *conv,
525 : struct sysdb_attrs **cmds,
526 : size_t num_cmds)
527 : {
528 : const char *key;
529 : const char *cmd;
530 : errno_t ret;
531 : size_t i;
532 :
533 0 : if (num_cmds == 0) {
534 : /* We're done here. */
535 0 : return EOK;
536 : }
537 :
538 0 : for (i = 0; i < num_cmds; i++) {
539 0 : ret = sysdb_attrs_get_string(cmds[i], SYSDB_ORIG_DN, &key);
540 0 : if (ret != EOK) {
541 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get command DN, skipping "
542 : "[%d]: %s\n", ret, sss_strerror(ret));
543 0 : continue;
544 : }
545 :
546 0 : ret = sysdb_attrs_get_string(cmds[i], SYSDB_IPA_SUDOCMD_SUDOCMD, &cmd);
547 0 : if (ret != EOK) {
548 0 : DEBUG(SSSDBG_MINOR_FAILURE, "Failed to get command, skipping "
549 : "[%d]: %s\n", ret, sss_strerror(ret));
550 0 : continue;
551 : }
552 :
553 0 : ret = ipa_sudo_conv_store(conv->cmds, key, discard_const(cmd));
554 0 : if (ret != EOK) {
555 0 : DEBUG(SSSDBG_OP_FAILURE, "Failed to store command into table "
556 : "[%d]: %s\n", ret, sss_strerror(ret));
557 0 : goto done;
558 : }
559 : }
560 :
561 0 : ret = EOK;
562 :
563 : done:
564 0 : return ret;
565 : }
566 :
567 : bool
568 0 : ipa_sudo_conv_has_cmdgroups(struct ipa_sudo_conv *conv)
569 : {
570 0 : return hash_count(conv->cmdgroups) == 0;
571 : }
572 :
573 : bool
574 0 : ipa_sudo_conv_has_cmds(struct ipa_sudo_conv *conv)
575 : {
576 0 : return hash_count(conv->cmds) == 0;
577 : }
578 :
579 : typedef errno_t (*ipa_sudo_conv_rdn_fn)(TALLOC_CTX *mem_ctx,
580 : struct sdap_attr_map *map,
581 : struct sysdb_ctx *sysdb,
582 : const char *dn,
583 : char **_rdn_val,
584 : const char **_rdn_attr);
585 :
586 0 : static errno_t get_sudo_cmdgroup_rdn(TALLOC_CTX *mem_ctx,
587 : struct sdap_attr_map *map,
588 : struct sysdb_ctx *sysdb,
589 : const char *dn,
590 : char **_rdn_val,
591 : const char **_rdn_attr)
592 : {
593 : char *rdn_val;
594 : errno_t ret;
595 :
596 0 : ret = ipa_get_rdn(mem_ctx, sysdb, dn, &rdn_val,
597 : MATCHRDN_CMDGROUPS(map));
598 0 : if (ret != EOK) {
599 0 : return ret;
600 : }
601 :
602 0 : *_rdn_val = rdn_val;
603 0 : *_rdn_attr = map[IPA_AT_SUDOCMDGROUP_NAME].name;
604 :
605 0 : return EOK;
606 : }
607 :
608 0 : static errno_t get_sudo_cmd_rdn(TALLOC_CTX *mem_ctx,
609 : struct sdap_attr_map *map,
610 : struct sysdb_ctx *sysdb,
611 : const char *dn,
612 : char **_rdn_val,
613 : const char **_rdn_attr)
614 : {
615 : char *rdn_val;
616 : errno_t ret;
617 :
618 0 : ret = ipa_get_rdn(mem_ctx, sysdb, dn, &rdn_val,
619 : MATCHRDN_CMDS(IPA_AT_SUDOCMD_UUID, map));
620 0 : if (ret == EOK) {
621 0 : *_rdn_val = rdn_val;
622 0 : *_rdn_attr = map[IPA_AT_SUDOCMD_UUID].name;
623 :
624 0 : return EOK;
625 0 : } else if (ret != ENOENT) {
626 0 : return ret;
627 : }
628 :
629 : /* For older versions of FreeIPA than 3.1. */
630 0 : ret = ipa_get_rdn(mem_ctx, sysdb, dn, &rdn_val,
631 : MATCHRDN_CMDS(IPA_AT_SUDOCMD_CMD, map));
632 0 : if (ret != EOK) {
633 0 : return ret;
634 : }
635 :
636 0 : *_rdn_val = rdn_val;
637 0 : *_rdn_attr = map[IPA_AT_SUDOCMD_CMD].name;;
638 :
639 0 : return EOK;
640 : }
641 :
642 : static char *
643 0 : build_filter(TALLOC_CTX *mem_ctx,
644 : struct sysdb_ctx *sysdb,
645 : hash_table_t *table,
646 : struct sdap_attr_map *map,
647 : ipa_sudo_conv_rdn_fn rdn_fn)
648 : {
649 : TALLOC_CTX *tmp_ctx;
650 : hash_key_t *keys;
651 : unsigned long int count;
652 : unsigned long int i;
653 : char *filter;
654 : char *rdn_val;
655 : const char *rdn_attr;
656 : char *safe_rdn;
657 : errno_t ret;
658 : int hret;
659 :
660 0 : tmp_ctx = talloc_new(NULL);
661 0 : if (tmp_ctx == NULL) {
662 0 : return NULL;
663 : }
664 :
665 0 : hret = hash_keys(table, &count, &keys);
666 0 : if (hret != HASH_SUCCESS) {
667 0 : ret = ENOMEM;
668 0 : goto done;
669 : }
670 :
671 0 : talloc_steal(tmp_ctx, keys);
672 :
673 0 : filter = talloc_strdup(tmp_ctx, "");
674 0 : if (filter == NULL) {
675 0 : ret = ENOMEM;
676 0 : goto done;
677 : }
678 :
679 0 : for (i = 0; i < count; i++) {
680 0 : ret = rdn_fn(tmp_ctx, map, sysdb, keys[i].str, &rdn_val, &rdn_attr);
681 0 : if (ret != EOK) {
682 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to get member %s [%d]: %s\n",
683 : keys[i].str, ret, sss_strerror(ret));
684 0 : goto done;
685 : }
686 :
687 0 : ret = sss_filter_sanitize(tmp_ctx, rdn_val, &safe_rdn);
688 0 : if (ret != EOK) {
689 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to sanitize DN "
690 : "[%d]: %s\n", ret, sss_strerror(ret));
691 0 : goto done;
692 : }
693 :
694 0 : filter = talloc_asprintf_append(filter, "(%s=%s)", rdn_attr, safe_rdn);
695 0 : if (filter == NULL) {
696 0 : ret = ENOMEM;
697 0 : goto done;
698 : }
699 : }
700 :
701 : /* objectClass is always first */
702 0 : filter = talloc_asprintf(filter, "(&(objectClass=%s)(|%s))",
703 : map[0].name, filter);
704 0 : if (filter == NULL) {
705 0 : ret = ENOMEM;
706 0 : goto done;
707 : }
708 :
709 0 : talloc_steal(mem_ctx, filter);
710 :
711 0 : ret = EOK;
712 :
713 : done:
714 0 : talloc_free(tmp_ctx);
715 :
716 0 : if (ret != EOK) {
717 0 : return NULL;
718 : }
719 :
720 0 : return filter;
721 : }
722 :
723 : char *
724 0 : ipa_sudo_conv_cmdgroup_filter(TALLOC_CTX *mem_ctx,
725 : struct ipa_sudo_conv *conv)
726 : {
727 0 : return build_filter(mem_ctx, conv->sysdb, conv->cmdgroups,
728 : conv->map_cmdgroup, get_sudo_cmdgroup_rdn);
729 : }
730 :
731 : char *
732 0 : ipa_sudo_conv_cmd_filter(TALLOC_CTX *mem_ctx,
733 : struct ipa_sudo_conv *conv)
734 : {
735 0 : return build_filter(mem_ctx, conv->sysdb, conv->cmds,
736 : conv->map_cmd, get_sudo_cmd_rdn);
737 : }
738 :
739 : struct ipa_sudo_conv_result_ctx {
740 : struct ipa_sudo_conv *conv;
741 : struct sysdb_attrs **rules;
742 : size_t num_rules;
743 : errno_t ret;
744 : };
745 :
746 : static const char *
747 0 : convert_host(TALLOC_CTX *mem_ctx,
748 : struct ipa_sudo_conv *conv,
749 : const char *value)
750 : {
751 : char *rdn;
752 : const char *group;
753 : errno_t ret;
754 :
755 0 : ret = ipa_get_rdn(mem_ctx, conv->sysdb, value, &rdn,
756 : MATCHRDN_HOST(conv->map_host));
757 0 : if (ret == EOK) {
758 0 : return rdn;
759 0 : } else if (ret != ENOENT) {
760 0 : DEBUG(SSSDBG_OP_FAILURE, "ipa_get_rdn() failed on value %s [%d]: %s\n",
761 : value, ret, sss_strerror(ret));
762 0 : return NULL;
763 : }
764 :
765 0 : ret = ipa_get_rdn(mem_ctx, conv->sysdb, value, &rdn,
766 : MATCHRDN_HOSTGROUP(conv->map_hostgroup));
767 0 : if (ret == ENOENT) {
768 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected DN %s\n", value);
769 0 : return NULL;
770 0 : } else if (ret != EOK) {
771 0 : DEBUG(SSSDBG_OP_FAILURE, "ipa_get_rdn() failed on value %s [%d]: %s\n",
772 : value, ret, sss_strerror(ret));
773 0 : return NULL;
774 : }
775 :
776 0 : group = talloc_asprintf(mem_ctx, "+%s", rdn);
777 0 : talloc_free(rdn);
778 :
779 0 : return group;
780 : }
781 :
782 : static const char *
783 0 : convert_user(TALLOC_CTX *mem_ctx,
784 : struct ipa_sudo_conv *conv,
785 : const char *value)
786 : {
787 : char *rdn;
788 : const char *group;
789 : errno_t ret;
790 :
791 0 : ret = ipa_get_rdn(mem_ctx, conv->sysdb, value, &rdn,
792 : MATCHRDN_USER(conv->map_user));
793 0 : if (ret == EOK) {
794 0 : return rdn;
795 0 : } else if (ret != ENOENT) {
796 0 : DEBUG(SSSDBG_OP_FAILURE, "ipa_get_rdn() failed on value %s [%d]: %s\n",
797 : value, ret, sss_strerror(ret));
798 0 : return NULL;
799 : }
800 :
801 0 : ret = ipa_get_rdn(mem_ctx, conv->sysdb, value, &rdn,
802 : MATCHRDN_GROUP(conv->map_group));
803 0 : if (ret == ENOENT) {
804 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected DN %s\n", value);
805 0 : return NULL;
806 0 : } else if (ret != EOK) {
807 0 : DEBUG(SSSDBG_OP_FAILURE, "ipa_get_rdn() failed on value %s [%d]: %s\n",
808 : value, ret, sss_strerror(ret));
809 0 : return NULL;
810 : }
811 :
812 0 : group = talloc_asprintf(mem_ctx, "%%%s", rdn);
813 0 : talloc_free(rdn);
814 :
815 0 : return group;
816 : }
817 :
818 : static const char *
819 0 : convert_group(TALLOC_CTX *mem_ctx,
820 : struct ipa_sudo_conv *conv,
821 : const char *value)
822 : {
823 : char *rdn;
824 : errno_t ret;
825 :
826 0 : ret = ipa_get_rdn(mem_ctx, conv->sysdb, value, &rdn,
827 : MATCHRDN_GROUP(conv->map_group));
828 0 : if (ret == ENOENT) {
829 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unexpected DN %s\n", value);
830 0 : return NULL;
831 0 : } else if (ret != EOK) {
832 0 : DEBUG(SSSDBG_OP_FAILURE, "ipa_get_rdn() failed on value %s [%d]: %s\n",
833 : value, ret, sss_strerror(ret));
834 0 : return NULL;
835 : }
836 :
837 0 : return rdn;
838 : }
839 :
840 : static const char *
841 0 : convert_runasextusergroup(TALLOC_CTX *mem_ctx,
842 : struct ipa_sudo_conv *conv,
843 : const char *value)
844 : {
845 0 : return talloc_asprintf(mem_ctx, "%%%s", value);
846 : }
847 :
848 : static const char *
849 0 : convert_cat(TALLOC_CTX *mem_ctx,
850 : struct ipa_sudo_conv *conv,
851 : const char *value)
852 : {
853 0 : if (strcmp(value, "all") == 0) {
854 0 : return talloc_strdup(mem_ctx, "ALL");
855 : }
856 :
857 0 : return value;
858 : }
859 :
860 : static errno_t
861 0 : convert_attributes(struct ipa_sudo_conv *conv,
862 : struct ipa_sudo_rule *rule,
863 : struct sysdb_attrs *attrs)
864 : {
865 : TALLOC_CTX *tmp_ctx;
866 : const char **values;
867 : const char *value;
868 : errno_t ret;
869 : int i, j;
870 : static struct {
871 : const char *ipa;
872 : const char *sudo;
873 : const char *(*conv_fn)(TALLOC_CTX *mem_ctx,
874 : struct ipa_sudo_conv *conv,
875 : const char *value);
876 : } table[] = {{SYSDB_NAME, SYSDB_SUDO_CACHE_AT_CN , NULL},
877 : {SYSDB_IPA_SUDORULE_HOST, SYSDB_SUDO_CACHE_AT_HOST , convert_host},
878 : {SYSDB_IPA_SUDORULE_USER, SYSDB_SUDO_CACHE_AT_USER , convert_user},
879 : {SYSDB_IPA_SUDORULE_RUNASUSER, SYSDB_SUDO_CACHE_AT_RUNASUSER , convert_user},
880 : {SYSDB_IPA_SUDORULE_RUNASGROUP, SYSDB_SUDO_CACHE_AT_RUNASGROUP , convert_group},
881 : {SYSDB_IPA_SUDORULE_OPTION, SYSDB_SUDO_CACHE_AT_OPTION , NULL},
882 : {SYSDB_IPA_SUDORULE_NOTAFTER, SYSDB_SUDO_CACHE_AT_NOTAFTER , NULL},
883 : {SYSDB_IPA_SUDORULE_NOTBEFORE, SYSDB_SUDO_CACHE_AT_NOTBEFORE , NULL},
884 : {SYSDB_IPA_SUDORULE_SUDOORDER, SYSDB_SUDO_CACHE_AT_ORDER , NULL},
885 : {SYSDB_IPA_SUDORULE_CMDCATEGORY, SYSDB_SUDO_CACHE_AT_COMMAND , convert_cat},
886 : {SYSDB_IPA_SUDORULE_HOSTCATEGORY, SYSDB_SUDO_CACHE_AT_HOST , convert_cat},
887 : {SYSDB_IPA_SUDORULE_USERCATEGORY, SYSDB_SUDO_CACHE_AT_USER , convert_cat},
888 : {SYSDB_IPA_SUDORULE_RUNASUSERCATEGORY, SYSDB_SUDO_CACHE_AT_RUNASUSER , convert_cat},
889 : {SYSDB_IPA_SUDORULE_RUNASGROUPCATEGORY, SYSDB_SUDO_CACHE_AT_RUNASGROUP , convert_cat},
890 : {SYSDB_IPA_SUDORULE_RUNASEXTUSER, SYSDB_SUDO_CACHE_AT_RUNASUSER , NULL},
891 : {SYSDB_IPA_SUDORULE_RUNASEXTGROUP, SYSDB_SUDO_CACHE_AT_RUNASGROUP , NULL},
892 : {SYSDB_IPA_SUDORULE_RUNASEXTUSERGROUP, SYSDB_SUDO_CACHE_AT_RUNASUSER , convert_runasextusergroup},
893 : {SYSDB_IPA_SUDORULE_EXTUSER, SYSDB_SUDO_CACHE_AT_USER , NULL},
894 : {SYSDB_IPA_SUDORULE_ALLOWCMD, SYSDB_IPA_SUDORULE_ORIGCMD , NULL},
895 : {SYSDB_IPA_SUDORULE_DENYCMD, SYSDB_IPA_SUDORULE_ORIGCMD , NULL},
896 : {NULL, NULL, NULL}};
897 :
898 0 : tmp_ctx = talloc_new(NULL);
899 0 : if (tmp_ctx == NULL) {
900 0 : return ENOMEM;
901 : }
902 :
903 0 : for (i = 0; table[i].ipa != NULL; i++) {
904 0 : ret = sysdb_attrs_get_string_array(rule->attrs, table[i].ipa,
905 : tmp_ctx, &values);
906 0 : if (ret == ENOENT) {
907 0 : continue;
908 0 : } else if (ret != EOK) {
909 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to read attribute "
910 : "%s [%d]: %s\n", table[i].ipa, ret, sss_strerror(ret));
911 0 : goto done;
912 : }
913 :
914 0 : for (j = 0; values[j] != NULL; j++) {
915 0 : if (table[i].conv_fn != NULL) {
916 0 : value = table[i].conv_fn(tmp_ctx, conv, values[j]);
917 0 : if (value == NULL) {
918 0 : ret = ENOMEM;
919 0 : goto done;
920 : }
921 : } else {
922 0 : value = values[j];
923 : }
924 :
925 0 : ret = sysdb_attrs_add_string_safe(attrs, table[i].sudo, value);
926 0 : if (ret != EOK) {
927 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add attribute "
928 : "%s [%d]: %s\n", table[i].sudo, ret, sss_strerror(ret));
929 0 : goto done;
930 : }
931 : }
932 : }
933 :
934 0 : ret = EOK;
935 :
936 : done:
937 0 : talloc_free(tmp_ctx);
938 0 : return ret;
939 : }
940 :
941 : static const char **
942 0 : combine_cmdgroups(TALLOC_CTX *mem_ctx,
943 : struct ipa_sudo_conv *conv,
944 : struct ipa_sudo_dn_list *list)
945 : {
946 : TALLOC_CTX *tmp_ctx;
947 : struct ipa_sudo_cmdgroup *cmdgroup;
948 : struct ipa_sudo_dn_list *listitem;
949 0 : const char **values = NULL;
950 : errno_t ret;
951 :
952 0 : tmp_ctx = talloc_new(NULL);
953 0 : if (tmp_ctx == NULL) {
954 0 : return NULL;
955 : }
956 :
957 0 : values = talloc_zero_array(tmp_ctx, const char *, 1);
958 0 : if (values == NULL) {
959 0 : talloc_free(tmp_ctx);
960 0 : return NULL;
961 : }
962 :
963 0 : DLIST_FOR_EACH(listitem, list) {
964 0 : cmdgroup = ipa_sudo_conv_lookup(conv->cmdgroups, listitem->dn);
965 0 : if (cmdgroup == NULL) {
966 0 : DEBUG(SSSDBG_MINOR_FAILURE,
967 : "ipa_sudo_conv_lookup failed for DN:%s\n", listitem->dn);
968 0 : continue;
969 : }
970 :
971 0 : ret = add_strings_lists(mem_ctx, values, cmdgroup->expanded,
972 : false, discard_const(&values));
973 0 : if (ret != EOK) {
974 0 : talloc_free(tmp_ctx);
975 0 : return NULL;
976 : }
977 : }
978 :
979 0 : talloc_steal(mem_ctx, values);
980 0 : talloc_free(tmp_ctx);
981 :
982 0 : return values;
983 : }
984 :
985 : static const char **
986 0 : combine_cmds(TALLOC_CTX *mem_ctx,
987 : struct ipa_sudo_conv *conv,
988 : struct ipa_sudo_dn_list *list)
989 : {
990 : struct ipa_sudo_dn_list *listitem;
991 : const char **values;
992 : const char *command;
993 : size_t count;
994 : size_t i;
995 :
996 0 : count = ipa_sudo_dn_list_count(list);
997 :
998 0 : values = talloc_zero_array(mem_ctx, const char *, count + 1);
999 0 : if (values == NULL) {
1000 0 : return NULL;
1001 : }
1002 :
1003 0 : i = 0;
1004 0 : DLIST_FOR_EACH(listitem, list) {
1005 0 : command = ipa_sudo_conv_lookup(conv->cmds, listitem->dn);
1006 0 : if (command == NULL) {
1007 0 : continue;
1008 : }
1009 :
1010 0 : values[i] = command;
1011 0 : i++;
1012 : }
1013 :
1014 0 : return values;
1015 : }
1016 :
1017 : static errno_t
1018 0 : build_sudocommand(struct ipa_sudo_conv *conv,
1019 : struct ipa_sudo_rulemember *mlist,
1020 : struct sysdb_attrs *attrs,
1021 : char prefix)
1022 : {
1023 : TALLOC_CTX *tmp_ctx;
1024 : const char **cmds[2];
1025 : const char *command;
1026 : errno_t ret;
1027 : int i, j;
1028 :
1029 0 : tmp_ctx = talloc_new(NULL);
1030 0 : if (tmp_ctx == NULL) {
1031 0 : return ENOMEM;
1032 : }
1033 :
1034 0 : cmds[0] = combine_cmdgroups(tmp_ctx, conv, mlist->cmdgroups);
1035 0 : if (cmds[0] == NULL) {
1036 0 : ret = ENOMEM;
1037 0 : goto done;
1038 : }
1039 :
1040 0 : cmds[1] = combine_cmds(tmp_ctx, conv, mlist->cmds);
1041 0 : if (cmds[1] == NULL) {
1042 0 : ret = ENOMEM;
1043 0 : goto done;
1044 : }
1045 :
1046 0 : for (i = 0; i < 2; i++) {
1047 0 : for (j = 0; cmds[i][j] != NULL; j++) {
1048 0 : if (prefix == '\0') {
1049 0 : command = cmds[i][j];
1050 : } else {
1051 0 : command = talloc_asprintf(tmp_ctx, "%c%s", prefix, cmds[i][j]);
1052 0 : if (command == NULL) {
1053 0 : ret = ENOMEM;
1054 0 : goto done;
1055 : }
1056 : }
1057 :
1058 0 : ret = sysdb_attrs_add_string_safe(attrs,
1059 : SYSDB_SUDO_CACHE_AT_COMMAND, command);
1060 0 : if (ret != EOK) {
1061 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to add attribute "
1062 : "%s [%d]: %s\n", SYSDB_SUDO_CACHE_AT_COMMAND,
1063 : ret, sss_strerror(ret));
1064 0 : goto done;
1065 : }
1066 : }
1067 : }
1068 :
1069 0 : ret = EOK;
1070 :
1071 : done:
1072 0 : talloc_free(tmp_ctx);
1073 0 : return ret;
1074 : }
1075 :
1076 : static errno_t
1077 0 : convert_sudocommand(struct ipa_sudo_conv *conv,
1078 : struct ipa_sudo_rule *rule,
1079 : struct sysdb_attrs *attrs)
1080 : {
1081 : TALLOC_CTX *tmp_ctx;
1082 : errno_t ret;
1083 :
1084 0 : tmp_ctx = talloc_new(NULL);
1085 0 : if (tmp_ctx == NULL) {
1086 0 : return ENOMEM;
1087 : }
1088 :
1089 0 : ret = build_sudocommand(conv, &rule->allow, attrs, '\0');
1090 0 : if (ret != EOK) {
1091 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build allow commands "
1092 : "[%d]: %s\n", ret, sss_strerror(ret));
1093 0 : goto done;
1094 : }
1095 :
1096 0 : ret = build_sudocommand(conv, &rule->deny, attrs, '!');
1097 0 : if (ret != EOK) {
1098 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to build deny commands "
1099 : "[%d]: %s\n", ret, sss_strerror(ret));
1100 0 : goto done;
1101 : }
1102 :
1103 0 : ret = EOK;
1104 :
1105 : done:
1106 0 : talloc_free(tmp_ctx);
1107 0 : return ret;
1108 : }
1109 :
1110 : static bool
1111 0 : rules_iterator(hash_entry_t *item,
1112 : void *user_data)
1113 : {
1114 0 : struct ipa_sudo_conv_result_ctx *ctx = user_data;
1115 0 : struct ipa_sudo_rule *rule = item->value.ptr;
1116 : struct sysdb_attrs *attrs;
1117 :
1118 0 : if (ctx == NULL) {
1119 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Bug: ctx is NULL\n");
1120 0 : return false;
1121 : }
1122 :
1123 0 : if (rule == NULL) {
1124 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Bug: rule is NULL\n");
1125 0 : ctx->ret = ERR_INTERNAL;
1126 0 : return false;
1127 : }
1128 :
1129 0 : attrs = sysdb_new_attrs(ctx->rules);
1130 0 : if (attrs == NULL) {
1131 0 : ctx->ret = ENOMEM;
1132 0 : return false;
1133 : }
1134 :
1135 0 : ctx->ret = convert_attributes(ctx->conv, rule, attrs);
1136 0 : if (ctx->ret != EOK) {
1137 0 : DEBUG(SSSDBG_OP_FAILURE, "Unable to convert attributes [%d]: %s\n",
1138 : ctx->ret, sss_strerror(ctx->ret));
1139 0 : talloc_free(attrs);
1140 0 : return false;
1141 : }
1142 :
1143 0 : ctx->ret = convert_sudocommand(ctx->conv, rule, attrs);
1144 0 : if (ctx->ret != EOK) {
1145 0 : DEBUG(SSSDBG_OP_FAILURE, "Unable to build sudoCommand [%d]: %s\n",
1146 : ctx->ret, sss_strerror(ctx->ret));
1147 0 : talloc_free(attrs);
1148 0 : return false;
1149 : }
1150 :
1151 0 : ctx->rules[ctx->num_rules] = attrs;
1152 0 : ctx->num_rules++;
1153 :
1154 0 : return true;
1155 : }
1156 :
1157 : static bool
1158 0 : cmdgroups_iterator(hash_entry_t *item,
1159 : void *user_data)
1160 : {
1161 0 : struct ipa_sudo_conv_result_ctx *ctx = user_data;
1162 0 : struct ipa_sudo_cmdgroup *cmdgroup = item->value.ptr;
1163 : const char **values;
1164 :
1165 0 : if (ctx == NULL) {
1166 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Bug: ctx is NULL\n");
1167 0 : return false;
1168 : }
1169 :
1170 0 : if (cmdgroup == NULL) {
1171 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Bug: rule is NULL\n");
1172 0 : ctx->ret = ERR_INTERNAL;
1173 0 : return false;
1174 : }
1175 :
1176 0 : values = combine_cmds(cmdgroup, ctx->conv, cmdgroup->cmds);
1177 0 : if (values == NULL) {
1178 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to expand commands\n");
1179 0 : ctx->ret = ENOMEM;
1180 0 : return false;
1181 : }
1182 :
1183 0 : cmdgroup->expanded = values;
1184 0 : ctx->ret = EOK;
1185 :
1186 0 : return true;
1187 : }
1188 :
1189 : errno_t
1190 0 : ipa_sudo_conv_result(TALLOC_CTX *mem_ctx,
1191 : struct ipa_sudo_conv *conv,
1192 : struct sysdb_attrs ***_rules,
1193 : size_t *_num_rules)
1194 : {
1195 : struct ipa_sudo_conv_result_ctx ctx;
1196 : struct sysdb_attrs **rules;
1197 : unsigned long num_rules;
1198 : int hret;
1199 :
1200 0 : num_rules = hash_count(conv->rules);
1201 0 : if (num_rules == 0) {
1202 0 : *_rules = NULL;
1203 0 : *_num_rules = 0;
1204 0 : return EOK;
1205 : }
1206 :
1207 0 : ctx.conv = conv;
1208 0 : ctx.rules = NULL;
1209 0 : ctx.num_rules = 0;
1210 :
1211 : /* If there are no cmdgroups the iterator is not called and ctx.ret is
1212 : * uninitialized. Since it is ok that there are no cmdgroups initializing
1213 : * ctx.ret to EOK. */
1214 0 : ctx.ret = EOK;
1215 :
1216 : /* Expand commands in command groups. */
1217 0 : hret = hash_iterate(conv->cmdgroups, cmdgroups_iterator, &ctx);
1218 0 : if (hret != HASH_SUCCESS) {
1219 0 : DEBUG(SSSDBG_OP_FAILURE, "Unable to iterate over command groups "
1220 : "[%d]\n", hret);
1221 0 : return EIO;
1222 : }
1223 :
1224 0 : if (ctx.ret != EOK) {
1225 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to expand command groups "
1226 : "[%d]: %s\n", ctx.ret, sss_strerror(ctx.ret));
1227 0 : return ctx.ret;
1228 : }
1229 :
1230 : /* Convert rules. */
1231 0 : rules = talloc_zero_array(mem_ctx, struct sysdb_attrs *, num_rules);
1232 0 : if (rules == NULL) {
1233 0 : return ENOMEM;
1234 : }
1235 :
1236 0 : ctx.rules = rules;
1237 0 : ctx.num_rules = 0;
1238 :
1239 0 : hret = hash_iterate(conv->rules, rules_iterator, &ctx);
1240 0 : if (hret != HASH_SUCCESS) {
1241 0 : DEBUG(SSSDBG_OP_FAILURE, "Unable to iterate over rules [%d]\n", hret);
1242 0 : return EIO;
1243 : }
1244 :
1245 0 : if (ctx.ret != EOK) {
1246 0 : DEBUG(SSSDBG_CRIT_FAILURE, "Unable to convert rules [%d]: %s\n",
1247 : ctx.ret, sss_strerror(ctx.ret));
1248 0 : talloc_free(rules);
1249 0 : return ctx.ret;
1250 : }
1251 :
1252 0 : *_rules = ctx.rules;
1253 0 : *_num_rules = ctx.num_rules;
1254 :
1255 0 : return EOK;
1256 : }
|