Branch data Line data Source code
1 : : /*
2 : : SSSD
3 : :
4 : : Data Provider Helpers
5 : :
6 : : Copyright (C) Simo Sorce <ssorce@redhat.com> 2009
7 : :
8 : : This program is free software; you can redistribute it and/or modify
9 : : it under the terms of the GNU General Public License as published by
10 : : the Free Software Foundation; either version 3 of the License, or
11 : : (at your option) any later version.
12 : :
13 : : This program is distributed in the hope that it will be useful,
14 : : but WITHOUT ANY WARRANTY; without even the implied warranty of
15 : : MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
16 : : GNU General Public License for more details.
17 : :
18 : : You should have received a copy of the GNU General Public License
19 : : along with this program. If not, see <http://www.gnu.org/licenses/>.
20 : : */
21 : :
22 : : #include "data_provider.h"
23 : :
24 : : /* =Retrieve-Options====================================================== */
25 : :
26 : 0 : int dp_get_options(TALLOC_CTX *memctx,
27 : : struct confdb_ctx *cdb,
28 : : const char *conf_path,
29 : : struct dp_option *def_opts,
30 : : int num_opts,
31 : : struct dp_option **_opts)
32 : : {
33 : : struct dp_option *opts;
34 : : int i, ret;
35 : :
36 : 0 : opts = talloc_zero_array(memctx, struct dp_option, num_opts);
37 [ # # ]: 0 : if (!opts) return ENOMEM;
38 : :
39 [ # # ]: 0 : for (i = 0; i < num_opts; i++) {
40 : : char *tmp;
41 : :
42 : 0 : opts[i].opt_name = def_opts[i].opt_name;
43 : 0 : opts[i].type = def_opts[i].type;
44 : 0 : opts[i].def_val = def_opts[i].def_val;
45 : :
46 [ # # # # : 0 : switch (def_opts[i].type) {
# ]
47 : : case DP_OPT_STRING:
48 : 0 : ret = confdb_get_string(cdb, opts, conf_path,
49 : : opts[i].opt_name,
50 : : opts[i].def_val.cstring,
51 : : &opts[i].val.string);
52 [ # # ][ # # ]: 0 : if (ret != EOK ||
53 [ # # ]: 0 : ((opts[i].def_val.string != NULL) &&
54 : 0 : (opts[i].val.string == NULL))) {
55 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
56 : : ("Failed to retrieve value for option (%s)\n",
57 : : opts[i].opt_name));
58 [ # # ]: 0 : if (ret == EOK) ret = EINVAL;
59 : : goto done;
60 : : }
61 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_TRACE_FUNC, ("Option %s has%s value %s\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
62 : : opts[i].opt_name,
63 : : opts[i].val.cstring ? "" : " no",
64 : : opts[i].val.cstring ? opts[i].val.cstring : ""));
65 : : break;
66 : :
67 : : case DP_OPT_BLOB:
68 : 0 : ret = confdb_get_string(cdb, opts, conf_path,
69 : : opts[i].opt_name,
70 : : NULL, &tmp);
71 [ # # ]: 0 : if (ret != EOK) {
72 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
73 : : ("Failed to retrieve value for option (%s)\n",
74 : : opts[i].opt_name));
75 : : goto done;
76 : : }
77 : :
78 [ # # ]: 0 : if (tmp) {
79 : 0 : opts[i].val.blob.data = (uint8_t *)tmp;
80 : 0 : opts[i].val.blob.length = strlen(tmp);
81 : : } else {
82 : 0 : opts[i].val.blob.data = NULL;
83 : 0 : opts[i].val.blob.length = 0;
84 : : }
85 : :
86 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_TRACE_FUNC, ("Option %s has %s binary value.\n",
[ # # ][ # # ]
[ # # ][ # # ]
87 : : opts[i].opt_name, opts[i].val.blob.length?"a":"no"));
88 : : break;
89 : :
90 : : case DP_OPT_NUMBER:
91 : 0 : ret = confdb_get_int(cdb, conf_path,
92 : : opts[i].opt_name,
93 : : opts[i].def_val.number,
94 : : &opts[i].val.number);
95 [ # # ]: 0 : if (ret != EOK) {
96 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
97 : : ("Failed to retrieve value for option (%s)\n",
98 : : opts[i].opt_name));
99 : : goto done;
100 : : }
101 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_TRACE_FUNC, ("Option %s has value %d\n",
[ # # ][ # # ]
[ # # ]
102 : : opts[i].opt_name, opts[i].val.number));
103 : : break;
104 : :
105 : : case DP_OPT_BOOL:
106 : 0 : ret = confdb_get_bool(cdb, conf_path,
107 : : opts[i].opt_name,
108 : 0 : opts[i].def_val.boolean,
109 : : &opts[i].val.boolean);
110 [ # # ]: 0 : if (ret != EOK) {
111 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
112 : : ("Failed to retrieve value for option (%s)\n",
113 : : opts[i].opt_name));
114 : : goto done;
115 : : }
116 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_TRACE_FUNC, ("Option %s is %s\n",
[ # # ][ # # ]
[ # # ][ # # ]
117 : : opts[i].opt_name, opts[i].val.boolean?"TRUE":"FALSE"));
118 : : break;
119 : : }
120 : : }
121 : :
122 : 0 : ret = EOK;
123 : 0 : *_opts = opts;
124 : :
125 : : done:
126 [ # # ]: 0 : if (ret != EOK) talloc_zfree(opts);
127 : 0 : return ret;
128 : : }
129 : :
130 : : /* =Basic-Option-Helpers================================================== */
131 : :
132 : 0 : int dp_copy_options(TALLOC_CTX *memctx,
133 : : struct dp_option *src_opts,
134 : : int num_opts,
135 : : struct dp_option **_opts)
136 : : {
137 : : struct dp_option *opts;
138 : 0 : int i, ret = EOK;
139 : :
140 : 0 : opts = talloc_zero_array(memctx, struct dp_option, num_opts);
141 [ # # ]: 0 : if (!opts) return ENOMEM;
142 : :
143 [ # # ]: 0 : for (i = 0; i < num_opts; i++) {
144 : 0 : opts[i].opt_name = src_opts[i].opt_name;
145 : 0 : opts[i].type = src_opts[i].type;
146 : 0 : opts[i].def_val = src_opts[i].def_val;
147 : 0 : ret = EOK;
148 : :
149 [ # # # # : 0 : switch (src_opts[i].type) {
# ]
150 : : case DP_OPT_STRING:
151 [ # # ]: 0 : if (src_opts[i].val.string) {
152 : 0 : ret = dp_opt_set_string(opts, i, src_opts[i].val.string);
153 [ # # ]: 0 : } else if (src_opts[i].def_val.string) {
154 : 0 : ret = dp_opt_set_string(opts, i, src_opts[i].def_val.string);
155 : : }
156 [ # # ]: 0 : if (ret != EOK) {
157 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
158 : : ("Failed to copy value for option (%s)\n",
159 : : opts[i].opt_name));
160 : : goto done;
161 : : }
162 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_TRACE_FUNC, ("Option %s has%s value %s\n",
[ # # ][ # # ]
[ # # ][ # # ]
[ # # ]
163 : : opts[i].opt_name,
164 : : opts[i].val.cstring ? "" : " no",
165 : : opts[i].val.cstring ? opts[i].val.cstring : ""));
166 : : break;
167 : :
168 : : case DP_OPT_BLOB:
169 [ # # ]: 0 : if (src_opts[i].val.blob.data) {
170 : 0 : ret = dp_opt_set_blob(opts, i, src_opts[i].val.blob);
171 [ # # ]: 0 : } else if (src_opts[i].def_val.blob.data) {
172 : 0 : ret = dp_opt_set_blob(opts, i, src_opts[i].def_val.blob);
173 : : }
174 [ # # ]: 0 : if (ret != EOK) {
175 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
176 : : ("Failed to retrieve value for option (%s)\n",
177 : : opts[i].opt_name));
178 : : goto done;
179 : : }
180 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_TRACE_FUNC, ("Option %s has %s binary value.\n",
[ # # ][ # # ]
[ # # ][ # # ]
181 : : opts[i].opt_name, opts[i].val.blob.length?"a":"no"));
182 : : break;
183 : :
184 : : case DP_OPT_NUMBER:
185 [ # # ]: 0 : if (src_opts[i].val.number) {
186 : 0 : ret = dp_opt_set_int(opts, i, src_opts[i].val.number);
187 [ # # ]: 0 : } else if (src_opts[i].def_val.number) {
188 : 0 : ret = dp_opt_set_int(opts, i, src_opts[i].def_val.number);
189 : : }
190 [ # # ]: 0 : if (ret != EOK) {
191 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
192 : : ("Failed to retrieve value for option (%s)\n",
193 : : opts[i].opt_name));
194 : : goto done;
195 : : }
196 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_TRACE_FUNC, ("Option %s has value %d\n",
[ # # ][ # # ]
[ # # ]
197 : : opts[i].opt_name, opts[i].val.number));
198 : : break;
199 : :
200 : : case DP_OPT_BOOL:
201 [ # # ]: 0 : if (src_opts[i].val.boolean) {
202 : 0 : ret = dp_opt_set_bool(opts, i, src_opts[i].val.boolean);
203 [ # # ]: 0 : } else if (src_opts[i].def_val.boolean) {
204 : 0 : ret = dp_opt_set_int(opts, i, src_opts[i].def_val.boolean);
205 : : }
206 [ # # ]: 0 : if (ret != EOK) {
207 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_CRIT_FAILURE,
[ # # ][ # # ]
[ # # ]
208 : : ("Failed to retrieve value for option (%s)\n",
209 : : opts[i].opt_name));
210 : : goto done;
211 : : }
212 [ # # ][ # # ]: 0 : DEBUG(SSSDBG_TRACE_FUNC, ("Option %s is %s\n",
[ # # ][ # # ]
[ # # ][ # # ]
213 : : opts[i].opt_name, opts[i].val.boolean?"TRUE":"FALSE"));
214 : : break;
215 : : }
216 : : }
217 : :
218 : 0 : *_opts = opts;
219 : :
220 : : done:
221 [ # # ]: 0 : if (ret != EOK) talloc_zfree(opts);
222 : 0 : return ret;
223 : : }
224 : :
225 : : static const char *dp_opt_type_to_string(enum dp_opt_type type)
226 : : {
227 : : switch (type) {
228 : : case DP_OPT_STRING:
229 : : return "String";
230 : : case DP_OPT_BLOB:
231 : : return "Blob";
232 : : case DP_OPT_NUMBER:
233 : : return "Number";
234 : : case DP_OPT_BOOL:
235 : : return "Boolean";
236 : : }
237 : : return NULL;
238 : : }
239 : :
240 : : /* Getters */
241 : 0 : const char *_dp_opt_get_cstring(struct dp_option *opts,
242 : : int id, const char *location)
243 : : {
244 [ # # ]: 0 : if (opts[id].type != DP_OPT_STRING) {
245 [ # # ][ # # ]: 0 : DEBUG(0, ("[%s] Requested type 'String' for option '%s'"
[ # # ][ # # ]
[ # # ][ # # ]
246 : : " but value is of type '%s'!\n",
247 : : location, opts[id].opt_name,
248 : : dp_opt_type_to_string(opts[id].type)));
249 : : return NULL;
250 : : }
251 : 0 : return opts[id].val.cstring;
252 : : }
253 : :
254 : 13 : char *_dp_opt_get_string(struct dp_option *opts,
255 : : int id, const char *location)
256 : : {
257 [ - + ]: 13 : if (opts[id].type != DP_OPT_STRING) {
258 [ # # ][ # # ]: 0 : DEBUG(0, ("[%s] Requested type 'String' for option '%s'"
[ # # ][ # # ]
[ # # ][ # # ]
259 : : " but value is of type '%s'!\n",
260 : : location, opts[id].opt_name,
261 : : dp_opt_type_to_string(opts[id].type)));
262 : : return NULL;
263 : : }
264 : 13 : return opts[id].val.string;
265 : : }
266 : :
267 : 0 : struct dp_opt_blob _dp_opt_get_blob(struct dp_option *opts,
268 : : int id, const char *location)
269 : : {
270 : 0 : struct dp_opt_blob null_blob = { NULL, 0 };
271 [ # # ]: 0 : if (opts[id].type != DP_OPT_BLOB) {
272 [ # # ][ # # ]: 0 : DEBUG(0, ("[%s] Requested type 'Blob' for option '%s'"
[ # # ][ # # ]
[ # # ][ # # ]
273 : : " but value is of type '%s'!\n",
274 : : location, opts[id].opt_name,
275 : : dp_opt_type_to_string(opts[id].type)));
276 : 0 : return null_blob;
277 : : }
278 : 0 : return opts[id].val.blob;
279 : : }
280 : :
281 : 0 : int _dp_opt_get_int(struct dp_option *opts,
282 : : int id, const char *location)
283 : : {
284 [ # # ]: 0 : if (opts[id].type != DP_OPT_NUMBER) {
285 [ # # ][ # # ]: 0 : DEBUG(0, ("[%s] Requested type 'Number' for option '%s'"
[ # # ][ # # ]
[ # # ][ # # ]
286 : : " but value is of type '%s'!\n",
287 : : location, opts[id].opt_name,
288 : : dp_opt_type_to_string(opts[id].type)));
289 : : return 0;
290 : : }
291 : 0 : return opts[id].val.number;
292 : : }
293 : :
294 : 0 : bool _dp_opt_get_bool(struct dp_option *opts,
295 : : int id, const char *location)
296 : : {
297 [ # # ]: 0 : if (opts[id].type != DP_OPT_BOOL) {
298 [ # # ][ # # ]: 0 : DEBUG(0, ("[%s] Requested type 'Boolean' for option '%s'"
[ # # ][ # # ]
[ # # ][ # # ]
299 : : " but value is of type '%s'!\n",
300 : : location, opts[id].opt_name,
301 : : dp_opt_type_to_string(opts[id].type)));
302 : : return false;
303 : : }
304 : 0 : return opts[id].val.boolean;
305 : : }
306 : :
307 : : /* Setters */
308 : 46 : int _dp_opt_set_string(struct dp_option *opts, int id,
309 : : const char *s, const char *location)
310 : : {
311 [ - + ]: 46 : if (opts[id].type != DP_OPT_STRING) {
312 [ # # ][ # # ]: 0 : DEBUG(0, ("[%s] Requested type 'String' for option '%s'"
[ # # ][ # # ]
[ # # ][ # # ]
313 : : " but type is '%s'!\n",
314 : : location, opts[id].opt_name,
315 : : dp_opt_type_to_string(opts[id].type)));
316 : : return EINVAL;
317 : : }
318 : :
319 [ + + ]: 46 : if (opts[id].val.string) {
320 : 20 : talloc_zfree(opts[id].val.string);
321 : : }
322 [ + - ]: 46 : if (s) {
323 : 46 : opts[id].val.string = talloc_strdup(opts, s);
324 [ - + ]: 46 : if (!opts[id].val.string) {
325 [ # # ][ # # ]: 46 : DEBUG(0, ("talloc_strdup() failed!\n"));
[ # # ][ # # ]
[ # # ]
326 : : return ENOMEM;
327 : : }
328 : : }
329 : :
330 : : return EOK;
331 : : }
332 : :
333 : 0 : int _dp_opt_set_blob(struct dp_option *opts, int id,
334 : : struct dp_opt_blob b, const char *location)
335 : : {
336 [ # # ]: 0 : if (opts[id].type != DP_OPT_BLOB) {
337 [ # # ][ # # ]: 0 : DEBUG(0, ("[%s] Requested type 'Blob' for option '%s'"
[ # # ][ # # ]
[ # # ][ # # ]
338 : : " but type is '%s'!\n",
339 : : location, opts[id].opt_name,
340 : : dp_opt_type_to_string(opts[id].type)));
341 : : return EINVAL;
342 : : }
343 : :
344 [ # # ]: 0 : if (opts[id].val.blob.data) {
345 : 0 : talloc_zfree(opts[id].val.blob.data);
346 : 0 : opts[id].val.blob.length = 0;
347 : : }
348 [ # # ]: 0 : if (b.data) {
349 : 0 : opts[id].val.blob.data = talloc_memdup(opts, b.data, b.length);
350 [ # # ]: 0 : if (!opts[id].val.blob.data) {
351 [ # # ][ # # ]: 0 : DEBUG(0, ("talloc_memdup() failed!\n"));
[ # # ][ # # ]
[ # # ]
352 : : return ENOMEM;
353 : : }
354 : : }
355 : 0 : opts[id].val.blob.length = b.length;
356 : :
357 : 0 : return EOK;
358 : : }
359 : :
360 : 0 : int _dp_opt_set_int(struct dp_option *opts, int id,
361 : : int i, const char *location)
362 : : {
363 [ # # ]: 0 : if (opts[id].type != DP_OPT_NUMBER) {
364 [ # # ][ # # ]: 0 : DEBUG(0, ("[%s] Requested type 'Number' for option '%s'"
[ # # ][ # # ]
[ # # ][ # # ]
365 : : " but type is '%s'!\n",
366 : : location, opts[id].opt_name,
367 : : dp_opt_type_to_string(opts[id].type)));
368 : : return EINVAL;
369 : : }
370 : :
371 : 0 : opts[id].val.number = i;
372 : :
373 : 0 : return EOK;
374 : : }
375 : :
376 : 0 : int _dp_opt_set_bool(struct dp_option *opts, int id,
377 : : bool b, const char *location)
378 : : {
379 [ # # ]: 0 : if (opts[id].type != DP_OPT_BOOL) {
380 [ # # ][ # # ]: 0 : DEBUG(0, ("[%s] Requested type 'Boolean' for option '%s'"
[ # # ][ # # ]
[ # # ][ # # ]
381 : : " but type is '%s'!\n",
382 : : location, opts[id].opt_name,
383 : : dp_opt_type_to_string(opts[id].type)));
384 : : return EINVAL;
385 : : }
386 : :
387 : 0 : opts[id].val.boolean = b;
388 : :
389 : 0 : return EOK;
390 : : }
391 : :
|