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 <dbus/dbus.h>
22 : #include <string.h>
23 : #include <dhash.h>
24 :
25 : #include "lib/sifp/sss_sifp.h"
26 : #include "lib/sifp/sss_sifp_private.h"
27 :
28 : #define check_dbus_arg(iter, type, ret, done) do { \
29 : if (dbus_message_iter_get_arg_type((iter)) != (type)) { \
30 : ret = SSS_SIFP_INTERNAL_ERROR; \
31 : goto done; \
32 : } \
33 : } while (0)
34 :
35 : #define parse_basic(ctx, iter, ret, attr_type, dbus_type, \
36 : data_type, field, done) \
37 : do { \
38 : dbus_type val; \
39 : dbus_message_iter_get_basic(iter, &val); \
40 : attr->type = attr_type; \
41 : attr->data.field = _alloc_zero(ctx, data_type, 1); \
42 : \
43 : if (attr->data.field == NULL) { \
44 : ret = SSS_SIFP_OUT_OF_MEMORY; \
45 : goto done; \
46 : } \
47 : \
48 : attr->data.field[0] = val; \
49 : attr->num_values = 1; \
50 : \
51 : ret = SSS_SIFP_OK; \
52 : } while (0)
53 :
54 : #define parse_array(ctx, iter, ret, attr_type, dbus_type, \
55 : data_type, field, done) \
56 : do { \
57 : dbus_type val; \
58 : unsigned int i; \
59 : \
60 : attr->type = attr_type; \
61 : if (attr->num_values == 0) { \
62 : attr->data.field = NULL; \
63 : ret = SSS_SIFP_OK; \
64 : goto done; \
65 : } \
66 : \
67 : attr->data.field = _alloc_zero(ctx, data_type, attr->num_values); \
68 : if (attr->data.field == NULL) { \
69 : ret = SSS_SIFP_OUT_OF_MEMORY; \
70 : goto done; \
71 : } \
72 : \
73 : for (i = 0; i < attr->num_values; i++) { \
74 : dbus_message_iter_get_basic(iter, &val); \
75 : attr->data.field[i] = val; \
76 : \
77 : if (!dbus_message_iter_next(iter) && i + 1 < attr->num_values) { \
78 : ret = SSS_SIFP_INTERNAL_ERROR; \
79 : goto done; \
80 : } \
81 : } \
82 : \
83 : ret = SSS_SIFP_OK; \
84 : } while (0)
85 :
86 : static unsigned int
87 20 : sss_sifp_get_array_length(DBusMessageIter *iter)
88 : {
89 : DBusMessageIter array_iter;
90 : unsigned int size;
91 :
92 20 : dbus_message_iter_recurse(iter, &array_iter);
93 :
94 20 : if (dbus_message_iter_get_arg_type(&array_iter) == DBUS_TYPE_INVALID) {
95 8 : return 0;
96 : }
97 :
98 12 : size = 0;
99 : do {
100 46 : size++;
101 46 : } while (dbus_message_iter_next(&array_iter));
102 :
103 12 : return size;
104 : }
105 :
106 1 : static void hash_delete_cb(hash_entry_t *item,
107 : hash_destroy_enum type,
108 : void *pvt)
109 : {
110 1 : sss_sifp_ctx *ctx = (sss_sifp_ctx*)pvt;
111 1 : char **values = (char**)(item->value.ptr);
112 : int i;
113 :
114 1 : if (values == NULL) {
115 0 : return;
116 : }
117 :
118 2 : for (i = 0; values[i] != NULL; i++) {
119 1 : _free(ctx, values[i]);
120 1 : values[i] = NULL;
121 : }
122 :
123 1 : _free(ctx, values);
124 1 : item->value.ptr = NULL;
125 : }
126 :
127 : static sss_sifp_error
128 1 : sss_sifp_parse_dict(sss_sifp_ctx *ctx,
129 : DBusMessageIter *iter,
130 : hash_table_t *table)
131 : {
132 : DBusMessageIter dict_iter;
133 : DBusMessageIter array_iter;
134 : sss_sifp_error ret;
135 : hash_key_t table_key;
136 : hash_value_t table_value;
137 1 : const char *key = NULL;
138 1 : const char *value = NULL;
139 1 : char **values = NULL;
140 : unsigned int i;
141 : unsigned int num_values;
142 : int hret;
143 :
144 1 : dbus_message_iter_recurse(iter, &dict_iter);
145 :
146 : /* get the key */
147 1 : check_dbus_arg(&dict_iter, DBUS_TYPE_STRING, ret, done);
148 1 : dbus_message_iter_get_basic(&dict_iter, &key);
149 :
150 1 : table_key.type = HASH_KEY_STRING;
151 1 : table_key.str = sss_sifp_strdup(ctx, key);
152 1 : if (table_key.str == NULL) {
153 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
154 0 : goto done;
155 : }
156 :
157 1 : if (!dbus_message_iter_next(&dict_iter)) {
158 0 : ret = SSS_SIFP_INTERNAL_ERROR;
159 0 : goto done;
160 : }
161 :
162 : /* now read the value */
163 1 : switch (dbus_message_iter_get_arg_type(&dict_iter)) {
164 : case DBUS_TYPE_STRING:
165 1 : dbus_message_iter_get_basic(&dict_iter, &value);
166 1 : values = _alloc_zero(ctx, char *, 2);
167 1 : if (values == NULL) {
168 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
169 0 : goto done;
170 : }
171 :
172 1 : values[0] = sss_sifp_strdup(ctx, value);
173 1 : if (values[0] == NULL) {
174 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
175 0 : goto done;
176 : }
177 :
178 1 : values[1] = NULL;
179 :
180 1 : ret = SSS_SIFP_OK;
181 1 : break;
182 : case DBUS_TYPE_ARRAY:
183 0 : num_values = sss_sifp_get_array_length(&dict_iter);
184 0 : if (num_values == 0) {
185 0 : values = NULL;
186 0 : ret = SSS_SIFP_OK;
187 0 : goto done;
188 : }
189 :
190 0 : if (dbus_message_iter_get_element_type(&dict_iter)
191 : != DBUS_TYPE_STRING) {
192 0 : ret = SSS_SIFP_NOT_SUPPORTED;
193 0 : goto done;
194 : }
195 :
196 0 : dbus_message_iter_recurse(&dict_iter, &array_iter);
197 :
198 0 : values = _alloc_zero(ctx, char*, num_values + 1);
199 0 : if (values == NULL) {
200 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
201 0 : goto done;
202 : }
203 :
204 0 : for (i = 0; i < num_values; i++) {
205 0 : dbus_message_iter_get_basic(&array_iter, &value);
206 0 : values[i] = sss_sifp_strdup(ctx, value);
207 0 : if (values[i] == NULL) {
208 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
209 0 : goto done;
210 : }
211 :
212 0 : dbus_message_iter_next(&array_iter);
213 : }
214 :
215 0 : ret = SSS_SIFP_OK;
216 0 : break;
217 : default:
218 0 : ret = SSS_SIFP_NOT_SUPPORTED;
219 0 : break;
220 : }
221 :
222 1 : table_value.type = HASH_VALUE_PTR;
223 1 : table_value.ptr = values;
224 :
225 1 : hret = hash_enter(table, &table_key, &table_value);
226 1 : if (hret == HASH_ERROR_NO_MEMORY) {
227 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
228 1 : } else if (hret != HASH_SUCCESS) {
229 0 : ret = SSS_SIFP_INTERNAL_ERROR;
230 : }
231 :
232 : done:
233 1 : if (table_key.str != NULL) {
234 1 : _free(ctx, table_key.str);
235 : }
236 :
237 1 : if (ret != SSS_SIFP_OK) {
238 0 : if (values != NULL) {
239 0 : for (i = 0; values[i] != NULL; i++) {
240 0 : _free(ctx, values[i]);
241 : }
242 0 : _free(ctx, values);
243 : }
244 : }
245 :
246 1 : return ret;
247 : }
248 :
249 : static sss_sifp_error
250 24 : sss_sifp_parse_basic(sss_sifp_ctx *ctx,
251 : DBusMessageIter *iter,
252 : sss_sifp_attr *attr)
253 : {
254 : sss_sifp_error ret;
255 :
256 24 : switch (dbus_message_iter_get_arg_type(iter)) {
257 : case DBUS_TYPE_BOOLEAN:
258 1 : parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_BOOL,
259 : dbus_bool_t, bool, boolean, done);
260 25 : break;
261 : case DBUS_TYPE_INT16:
262 1 : parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_INT16,
263 : int16_t, int16_t, int16, done);
264 1 : break;
265 : case DBUS_TYPE_UINT16:
266 1 : parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_UINT16,
267 : uint16_t, uint16_t, uint16, done);
268 1 : break;
269 : case DBUS_TYPE_INT32:
270 1 : parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_INT32,
271 : int32_t, int32_t, int32, done);
272 1 : break;
273 : case DBUS_TYPE_UINT32:
274 8 : parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_UINT32,
275 : uint32_t, uint32_t, uint32, done);
276 8 : break;
277 : case DBUS_TYPE_INT64:
278 1 : parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_INT64,
279 : int64_t, int64_t, int64, done);
280 1 : break;
281 : case DBUS_TYPE_UINT64:
282 1 : parse_basic(ctx, iter, ret, SSS_SIFP_ATTR_TYPE_UINT64,
283 : uint64_t, uint64_t, uint64, done);
284 1 : break;
285 : case DBUS_TYPE_STRING:
286 : case DBUS_TYPE_OBJECT_PATH: ;
287 10 : const char *val = NULL;
288 :
289 10 : dbus_message_iter_get_basic(iter, &val);
290 :
291 10 : attr->type = SSS_SIFP_ATTR_TYPE_STRING;
292 10 : attr->data.str = _alloc_zero(ctx, char*, 1);
293 10 : if (attr->data.str == NULL) { \
294 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
295 0 : goto done;
296 : }
297 :
298 10 : attr->data.str[0] = sss_sifp_strdup(ctx, val);
299 10 : if (attr->data.str[0] == NULL) {
300 0 : _free(ctx, attr->data.str);
301 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
302 0 : goto done;
303 : }
304 :
305 10 : attr->num_values = 1;
306 :
307 10 : ret = SSS_SIFP_OK;
308 10 : break;
309 : default:
310 0 : ret = SSS_SIFP_INVALID_ARGUMENT;
311 0 : break;
312 : }
313 :
314 : done:
315 24 : return ret;
316 : }
317 :
318 : static sss_sifp_error
319 15 : sss_sifp_parse_array(sss_sifp_ctx *ctx,
320 : DBusMessageIter *iter,
321 : sss_sifp_attr *attr)
322 : {
323 : DBusMessageIter array_iter;
324 : sss_sifp_error ret;
325 : int hret;
326 :
327 15 : attr->num_values = sss_sifp_get_array_length(iter);
328 15 : dbus_message_iter_recurse(iter, &array_iter);
329 :
330 15 : switch (dbus_message_iter_get_element_type(iter)) {
331 : case DBUS_TYPE_BOOLEAN:
332 3 : parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_BOOL,
333 : dbus_bool_t, bool, boolean, done);
334 9 : break;
335 : case DBUS_TYPE_INT16:
336 0 : parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_INT16,
337 : int16_t, int16_t, int16, done);
338 0 : break;
339 : case DBUS_TYPE_UINT16:
340 0 : parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_UINT16,
341 : uint16_t, uint16_t, uint16, done);
342 0 : break;
343 : case DBUS_TYPE_INT32:
344 3 : parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_INT32,
345 : int32_t, int32_t, int32, done);
346 1 : break;
347 : case DBUS_TYPE_UINT32:
348 3 : parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_UINT32,
349 : uint32_t, uint32_t, uint32, done);
350 1 : break;
351 : case DBUS_TYPE_INT64:
352 3 : parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_INT64,
353 : int64_t, int64_t, int64, done);
354 1 : break;
355 : case DBUS_TYPE_UINT64:
356 3 : parse_array(ctx, &array_iter, ret, SSS_SIFP_ATTR_TYPE_UINT64,
357 : uint64_t, uint64_t, uint64, done);
358 1 : break;
359 : case DBUS_TYPE_STRING:
360 : case DBUS_TYPE_OBJECT_PATH: ;
361 : const char *val;
362 : unsigned int i;
363 :
364 4 : attr->type = SSS_SIFP_ATTR_TYPE_STRING;
365 4 : if (attr->num_values == 0) {
366 2 : attr->data.str = NULL;
367 2 : ret = SSS_SIFP_OK;
368 2 : goto done;
369 : }
370 :
371 2 : attr->data.str = _alloc_zero(ctx, char *, attr->num_values);
372 2 : if (attr->data.str == NULL) {
373 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
374 0 : goto done;
375 : }
376 :
377 10 : for (i = 0; i < attr->num_values; i++) {
378 8 : dbus_message_iter_get_basic(&array_iter, &val);
379 8 : attr->data.str[i] = sss_sifp_strdup(ctx, val);
380 8 : if (attr->data.str[i] == NULL) {
381 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
382 0 : goto done;
383 : }
384 :
385 8 : if (!dbus_message_iter_next(&array_iter)
386 2 : && i + 1 < attr->num_values) {
387 0 : ret = SSS_SIFP_INTERNAL_ERROR;
388 0 : goto done;
389 : }
390 : }
391 :
392 2 : ret = SSS_SIFP_OK;
393 2 : break;
394 : case DBUS_TYPE_DICT_ENTRY:
395 1 : attr->type = SSS_SIFP_ATTR_TYPE_STRING_DICT;
396 1 : if (attr->num_values == 0) {
397 0 : attr->data.str_dict = NULL;
398 0 : ret = SSS_SIFP_OK;
399 0 : goto done;
400 : }
401 :
402 2 : hret = hash_create_ex(10, &(attr->data.str_dict), 0, 0, 0, 0,
403 1 : ctx->alloc_fn, ctx->free_fn, ctx->alloc_pvt,
404 : hash_delete_cb, ctx);
405 1 : if (hret != HASH_SUCCESS) {
406 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
407 0 : goto done;
408 : }
409 :
410 2 : for (i = 0; i < attr->num_values; i++) {
411 1 : ret = sss_sifp_parse_dict(ctx, &array_iter, attr->data.str_dict);
412 1 : if (ret != SSS_SIFP_OK) {
413 0 : _free(ctx, attr->data.str_dict);
414 0 : goto done;
415 : }
416 :
417 1 : if (!dbus_message_iter_next(&array_iter)
418 1 : && i + 1 < attr->num_values) {
419 0 : ret = SSS_SIFP_INTERNAL_ERROR;
420 0 : goto done;
421 : }
422 : }
423 :
424 1 : ret = SSS_SIFP_OK;
425 1 : break;
426 : default:
427 0 : ret = SSS_SIFP_INVALID_ARGUMENT;
428 0 : break;
429 : }
430 :
431 : done:
432 15 : if (ret != SSS_SIFP_OK) {
433 0 : if (attr->type == SSS_SIFP_ATTR_TYPE_STRING && attr->data.str != NULL) {
434 0 : for (unsigned int i = 0;
435 0 : attr->data.str[i] != NULL && i < attr->num_values;
436 0 : i++) {
437 0 : _free(ctx, attr->data.str[i]);
438 : }
439 0 : _free(ctx, attr->data.str);
440 0 : } else if (attr->type == SSS_SIFP_ATTR_TYPE_STRING_DICT
441 0 : && attr->data.str_dict != NULL) {
442 0 : hash_destroy(attr->data.str_dict);
443 0 : attr->data.str_dict = NULL;
444 : }
445 : }
446 :
447 15 : return ret;
448 : }
449 :
450 : static sss_sifp_error
451 39 : sss_sifp_parse_variant(sss_sifp_ctx *ctx,
452 : DBusMessageIter *iter,
453 : sss_sifp_attr *attr)
454 : {
455 : DBusMessageIter variant_iter;
456 : sss_sifp_error ret;
457 : int type;
458 :
459 39 : check_dbus_arg(iter, DBUS_TYPE_VARIANT, ret, done);
460 :
461 39 : dbus_message_iter_recurse(iter, &variant_iter);
462 :
463 39 : type = dbus_message_iter_get_arg_type(&variant_iter);
464 39 : if (dbus_type_is_basic(type)) {
465 24 : ret = sss_sifp_parse_basic(ctx, &variant_iter, attr);
466 : } else {
467 : /* container types */
468 15 : switch (type) {
469 : /* case DBUS_TYPE_DICT_ENTRY may only be contained within an array
470 : * in variant */
471 : case DBUS_TYPE_ARRAY:
472 15 : ret = sss_sifp_parse_array(ctx, &variant_iter, attr);;
473 15 : break;
474 : default:
475 0 : ret = SSS_SIFP_NOT_SUPPORTED;
476 0 : break;
477 : }
478 : }
479 :
480 : done:
481 39 : return ret;
482 : }
483 :
484 : /**
485 : * DBusMessage format:
486 : * variant:value
487 : *
488 : * Iterator has to point to the variant but not inside the variant.
489 : */
490 : static sss_sifp_error
491 39 : sss_sifp_parse_single_attr(sss_sifp_ctx *ctx,
492 : const char *name,
493 : DBusMessageIter *iter,
494 : sss_sifp_attr **_attr)
495 : {
496 39 : sss_sifp_attr *attr = NULL;
497 : sss_sifp_error ret;
498 :
499 39 : attr = _alloc_zero(ctx, sss_sifp_attr, 1);
500 39 : if (attr == NULL) {
501 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
502 0 : goto done;
503 : }
504 :
505 39 : attr->name = sss_sifp_strdup(ctx, name);
506 39 : if (attr->name == NULL) {
507 0 : _free(ctx, attr);
508 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
509 0 : goto done;
510 : }
511 :
512 39 : ret = sss_sifp_parse_variant(ctx, iter, attr);
513 39 : if (ret != SSS_SIFP_OK) {
514 0 : _free(ctx, attr->name);
515 0 : _free(ctx, attr);
516 : }
517 :
518 39 : *_attr = attr;
519 :
520 : done:
521 39 : return ret;
522 : }
523 :
524 : /**
525 : * DBusMessage format:
526 : * variant:value
527 : */
528 : sss_sifp_error
529 27 : sss_sifp_parse_attr(sss_sifp_ctx *ctx,
530 : const char *name,
531 : DBusMessage *msg,
532 : sss_sifp_attr ***_attrs)
533 : {
534 27 : sss_sifp_attr **attrs = NULL;
535 : DBusMessageIter iter;
536 : sss_sifp_error ret;
537 :
538 27 : dbus_message_iter_init(msg, &iter);
539 :
540 27 : attrs = _alloc_zero(ctx, sss_sifp_attr *, 2);
541 27 : if (attrs == NULL) {
542 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
543 0 : goto done;
544 : }
545 :
546 27 : ret = sss_sifp_parse_single_attr(ctx, name, &iter, &attrs[0]);
547 27 : if (ret != SSS_SIFP_OK) {
548 0 : goto done;
549 : }
550 :
551 27 : *_attrs = attrs;
552 :
553 27 : ret = SSS_SIFP_OK;
554 :
555 : done:
556 27 : if (ret != SSS_SIFP_OK) {
557 0 : sss_sifp_free_attrs(ctx, &attrs);
558 : }
559 :
560 27 : return ret;
561 : }
562 :
563 : /**
564 : * DBusMessage format:
565 : * array of dict_entry(string:attr_name, variant:value)
566 : */
567 : sss_sifp_error
568 5 : sss_sifp_parse_attr_list(sss_sifp_ctx *ctx,
569 : DBusMessage *msg,
570 : sss_sifp_attr ***_attrs)
571 : {
572 : DBusMessageIter iter;
573 : DBusMessageIter array_iter;
574 : DBusMessageIter dict_iter;
575 5 : sss_sifp_attr **attrs = NULL;
576 5 : const char *name = NULL;
577 : unsigned int num_values;
578 : sss_sifp_error ret;
579 : unsigned int i;
580 :
581 5 : dbus_message_iter_init(msg, &iter);
582 :
583 5 : check_dbus_arg(&iter, DBUS_TYPE_ARRAY, ret, done);
584 :
585 5 : if (dbus_message_iter_get_element_type(&iter) != DBUS_TYPE_DICT_ENTRY) {
586 0 : ret = SSS_SIFP_INTERNAL_ERROR;
587 0 : goto done;
588 : }
589 :
590 5 : num_values = sss_sifp_get_array_length(&iter);
591 5 : attrs = _alloc_zero(ctx, sss_sifp_attr *, num_values + 1);
592 5 : if (attrs == NULL) {
593 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
594 0 : goto done;
595 : }
596 :
597 5 : dbus_message_iter_recurse(&iter, &array_iter);
598 :
599 17 : for (i = 0; i < num_values; i++) {
600 12 : dbus_message_iter_recurse(&array_iter, &dict_iter);
601 :
602 : /* get the key */
603 12 : check_dbus_arg(&dict_iter, DBUS_TYPE_STRING, ret, done);
604 12 : dbus_message_iter_get_basic(&dict_iter, &name);
605 :
606 12 : if (!dbus_message_iter_next(&dict_iter)) {
607 0 : ret = SSS_SIFP_INTERNAL_ERROR;
608 0 : goto done;
609 : }
610 :
611 : /* now read the value */
612 12 : check_dbus_arg(&dict_iter, DBUS_TYPE_VARIANT, ret, done);
613 :
614 12 : ret = sss_sifp_parse_single_attr(ctx, name, &dict_iter, &attrs[i]);
615 12 : if (ret != SSS_SIFP_OK) {
616 0 : goto done;
617 : }
618 :
619 12 : dbus_message_iter_next(&array_iter);
620 : }
621 :
622 5 : *_attrs = attrs;
623 5 : ret = SSS_SIFP_OK;
624 :
625 : done:
626 5 : if (ret != SSS_SIFP_OK) {
627 0 : sss_sifp_free_attrs(ctx, &attrs);
628 : }
629 :
630 5 : return ret;
631 : }
632 :
633 : sss_sifp_error
634 5 : sss_sifp_parse_object_path(sss_sifp_ctx *ctx,
635 : DBusMessage *msg,
636 : char **_object_path)
637 : {
638 5 : char *object_path = NULL;
639 5 : const char *dbus_path = NULL;
640 : DBusError dbus_error;
641 : dbus_bool_t bret;
642 : sss_sifp_error ret;
643 :
644 5 : dbus_error_init(&dbus_error);
645 :
646 5 : bret = dbus_message_get_args(msg, &dbus_error,
647 : DBUS_TYPE_OBJECT_PATH, &dbus_path,
648 : DBUS_TYPE_INVALID);
649 5 : if (!bret) {
650 1 : sss_sifp_set_io_error(ctx, &dbus_error);
651 1 : ret = SSS_SIFP_IO_ERROR;
652 1 : goto done;
653 : }
654 :
655 4 : object_path = sss_sifp_strdup(ctx, dbus_path);
656 4 : if (object_path == NULL) {
657 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
658 0 : goto done;
659 : }
660 :
661 4 : *_object_path = object_path;
662 4 : ret = SSS_SIFP_OK;
663 :
664 : done:
665 5 : dbus_error_free(&dbus_error);
666 :
667 5 : return ret;
668 : }
669 :
670 : sss_sifp_error
671 5 : sss_sifp_parse_object_path_list(sss_sifp_ctx *ctx,
672 : DBusMessage *msg,
673 : char ***_object_paths)
674 : {
675 5 : char **object_paths = NULL;
676 5 : char **dbus_paths = NULL;
677 : int num_paths;
678 : DBusError dbus_error;
679 : dbus_bool_t bret;
680 : sss_sifp_error ret;
681 : int i;
682 :
683 5 : dbus_error_init(&dbus_error);
684 :
685 5 : bret = dbus_message_get_args(msg, &dbus_error,
686 : DBUS_TYPE_ARRAY, DBUS_TYPE_OBJECT_PATH,
687 : &dbus_paths, &num_paths,
688 : DBUS_TYPE_INVALID);
689 5 : if (!bret) {
690 1 : sss_sifp_set_io_error(ctx, &dbus_error);
691 1 : ret = SSS_SIFP_IO_ERROR;
692 1 : goto done;
693 : }
694 :
695 4 : object_paths = _alloc_zero(ctx, char *, num_paths + 1);
696 4 : if (object_paths == NULL) {
697 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
698 0 : goto done;
699 : }
700 :
701 12 : for (i = 0; i < num_paths; i++) {
702 8 : object_paths[i] = sss_sifp_strdup(ctx, dbus_paths[i]);
703 8 : if (object_paths[i] == NULL) {
704 0 : ret = SSS_SIFP_OUT_OF_MEMORY;
705 0 : goto done;
706 : }
707 : }
708 :
709 4 : *_object_paths = object_paths;
710 4 : ret = SSS_SIFP_OK;
711 :
712 : done:
713 5 : dbus_error_free(&dbus_error);
714 5 : dbus_free_string_array(dbus_paths);
715 :
716 5 : if (ret != SSS_SIFP_OK && object_paths != NULL) {
717 0 : sss_sifp_free_string_array(ctx, &object_paths);
718 : }
719 :
720 5 : return ret;
721 : }
|