Line data Source code
1 :
2 : /*
3 : SSSD
4 :
5 : Common Responder utility functions
6 :
7 : Copyright (C) Sumit Bose <sbose@redhat.com> 2014
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 :
25 : #include "util/util.h"
26 :
27 : static inline bool
28 60 : attr_in_list(const char **list, size_t nlist, const char *str)
29 : {
30 : size_t i;
31 :
32 109 : for (i = 0; i < nlist; i++) {
33 63 : if (strcasecmp(list[i], str) == 0) {
34 14 : break;
35 : }
36 : }
37 :
38 60 : return (i < nlist) ? true : false;
39 : }
40 :
41 12 : const char **parse_attr_list_ex(TALLOC_CTX *mem_ctx, const char *conf_str,
42 : const char **defaults)
43 : {
44 : TALLOC_CTX *tmp_ctx;
45 : errno_t ret;
46 12 : const char **list = NULL;
47 12 : const char **res = NULL;
48 : int list_size;
49 12 : char **conf_list = NULL;
50 12 : int conf_list_size = 0;
51 12 : const char **allow = NULL;
52 12 : const char **deny = NULL;
53 12 : int ai = 0, di = 0, li = 0;
54 : int i;
55 :
56 12 : tmp_ctx = talloc_new(NULL);
57 12 : if (tmp_ctx == NULL) {
58 0 : return NULL;
59 : }
60 :
61 12 : if (conf_str) {
62 10 : ret = split_on_separator(tmp_ctx, conf_str, ',', true, true,
63 : &conf_list, &conf_list_size);
64 10 : if (ret != EOK) {
65 0 : DEBUG(SSSDBG_OP_FAILURE,
66 : "Cannot parse attribute ACL list %s: %d\n", conf_str, ret);
67 0 : goto done;
68 : }
69 :
70 10 : allow = talloc_zero_array(tmp_ctx, const char *, conf_list_size);
71 10 : deny = talloc_zero_array(tmp_ctx, const char *, conf_list_size);
72 10 : if (allow == NULL || deny == NULL) {
73 : goto done;
74 : }
75 : }
76 :
77 36 : for (i = 0; i < conf_list_size; i++) {
78 25 : switch (conf_list[i][0]) {
79 : case '+':
80 9 : allow[ai] = conf_list[i] + 1;
81 9 : ai++;
82 9 : continue;
83 : case '-':
84 15 : deny[di] = conf_list[i] + 1;
85 15 : di++;
86 15 : continue;
87 : default:
88 1 : DEBUG(SSSDBG_CRIT_FAILURE, "ACL values must start with "
89 : "either '+' (allow) or '-' (deny), got '%s'\n",
90 : conf_list[i]);
91 1 : goto done;
92 : }
93 : }
94 :
95 : /* Assume the output will have to hold defaults and all the configured,
96 : * values, resize later
97 : */
98 11 : list_size = 0;
99 11 : if (defaults != NULL) {
100 69 : while (defaults[list_size]) {
101 51 : list_size++;
102 : }
103 : }
104 11 : list_size += conf_list_size;
105 :
106 11 : list = talloc_zero_array(tmp_ctx, const char *, list_size + 1);
107 11 : if (list == NULL) {
108 0 : goto done;
109 : }
110 :
111 : /* Start by copying explicitly allowed attributes */
112 20 : for (i = 0; i < ai; i++) {
113 : /* if the attribute is explicitly denied, skip it */
114 9 : if (attr_in_list(deny, di, allow[i])) {
115 2 : continue;
116 : }
117 :
118 7 : list[li] = talloc_strdup(list, allow[i]);
119 7 : if (list[li] == NULL) {
120 0 : goto done;
121 : }
122 7 : li++;
123 :
124 7 : DEBUG(SSSDBG_TRACE_INTERNAL,
125 : "Added allowed attr %s to whitelist\n", allow[i]);
126 : }
127 :
128 : /* Add defaults */
129 11 : if (defaults != NULL) {
130 60 : for (i = 0; defaults[i]; i++) {
131 : /* if the attribute is explicitly denied, skip it */
132 51 : if (attr_in_list(deny, di, defaults[i])) {
133 12 : continue;
134 : }
135 :
136 39 : list[li] = talloc_strdup(list, defaults[i]);
137 39 : if (list[li] == NULL) {
138 0 : goto done;
139 : }
140 39 : li++;
141 :
142 39 : DEBUG(SSSDBG_TRACE_INTERNAL,
143 : "Added default attr %s to whitelist\n", defaults[i]);
144 : }
145 : }
146 :
147 11 : res = talloc_steal(mem_ctx, list);
148 : done:
149 12 : talloc_free(tmp_ctx);
150 12 : return res;
151 : }
|