1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23: #include "config-parser.h"
24: #include "test.h"
25: #include "utils.h"
26: #include "policy.h"
27: #include "selinux.h"
28: #include <dbus/dbus-list.h>
29: #include <dbus/dbus-internals.h>
30: #include <string.h>
31:
32: typedef enum
33: {
34: ELEMENT_NONE,
35: ELEMENT_BUSCONFIG,
36: ELEMENT_INCLUDE,
37: ELEMENT_USER,
38: ELEMENT_LISTEN,
39: ELEMENT_AUTH,
40: ELEMENT_POLICY,
41: ELEMENT_LIMIT,
42: ELEMENT_ALLOW,
43: ELEMENT_DENY,
44: ELEMENT_FORK,
45: ELEMENT_PIDFILE,
46: ELEMENT_SERVICEDIR,
47: ELEMENT_INCLUDEDIR,
48: ELEMENT_TYPE,
49: ELEMENT_SELINUX,
50: ELEMENT_ASSOCIATE,
51: ELEMENT_STANDARD_SESSION_SERVICEDIRS
52: } ElementType;
53:
54: typedef enum
55: {
56:
57: POLICY_IGNORED,
58:
59:
60: POLICY_DEFAULT,
61: POLICY_MANDATORY,
62: POLICY_USER,
63: POLICY_GROUP,
64: POLICY_CONSOLE
65: } PolicyType;
66:
67: typedef struct
68: {
69: ElementType type;
70:
71: unsigned int had_content : 1;
72:
73: union
74: {
75: struct
76: {
77: unsigned int ignore_missing : 1;
78: unsigned int if_selinux_enabled : 1;
79: unsigned int selinux_root_relative : 1;
80: } include;
81:
82: struct
83: {
84: PolicyType type;
85: unsigned long gid_uid_or_at_console;
86: } policy;
87:
88: struct
89: {
90: char *name;
91: long value;
92: } limit;
93:
94: } d;
95:
96: } Element;
97:
98:
99:
100:
101: struct BusConfigParser
102: {
103: int refcount;
104:
105: DBusString basedir;
106:
107: DBusList *stack;
108:
109: char *user;
110:
111: char *bus_type;
112:
113: DBusList *listen_on;
114:
115: DBusList *mechanisms;
116:
117: DBusList *service_dirs;
118:
119: DBusList *conf_dirs;
120:
121: BusPolicy *policy;
122:
123: BusLimits limits;
124:
125: char *pidfile;
126:
127: DBusList *included_files;
128:
129: DBusHashTable *service_context_table;
130:
131: unsigned int fork : 1;
132:
133: unsigned int is_toplevel : 1;
134: };
135:
136: static const char*
137: element_type_to_name (ElementType type)
138: {
139: switch (type)
140: {
141: case ELEMENT_NONE:
142: return NULL;
143: case ELEMENT_BUSCONFIG:
144: return "busconfig";
145: case ELEMENT_INCLUDE:
146: return "include";
147: case ELEMENT_USER:
148: return "user";
149: case ELEMENT_LISTEN:
150: return "listen";
151: case ELEMENT_AUTH:
152: return "auth";
153: case ELEMENT_POLICY:
154: return "policy";
155: case ELEMENT_LIMIT:
156: return "limit";
157: case ELEMENT_ALLOW:
158: return "allow";
159: case ELEMENT_DENY:
160: return "deny";
161: case ELEMENT_FORK:
162: return "fork";
163: case ELEMENT_PIDFILE:
164: return "pidfile";
165: case ELEMENT_STANDARD_SESSION_SERVICEDIRS:
166: return "standard_session_servicedirs";
167: case ELEMENT_SERVICEDIR:
168: return "servicedir";
169: case ELEMENT_INCLUDEDIR:
170: return "includedir";
171: case ELEMENT_TYPE:
172: return "type";
173: case ELEMENT_SELINUX:
174: return "selinux";
175: case ELEMENT_ASSOCIATE:
176: return "associate";
177: }
178:
179: _dbus_assert_not_reached ("bad element type");
180:
181: return NULL;
182: }
183:
184: static Element*
185: push_element (BusConfigParser *parser,
186: ElementType type)
187: {
188: Element *e;
189:
190: _dbus_assert (type != ELEMENT_NONE);
191:
192: e = dbus_new0 (Element, 1);
193: if (e == NULL)
194: return NULL;
195:
196: if (!_dbus_list_append (&parser->stack, e))
197: {
198: dbus_free (e);
199: return NULL;
200: }
201:
202: e->type = type;
203:
204: return e;
205: }
206:
207: static void
208: element_free (Element *e)
209: {
210: if (e->type == ELEMENT_LIMIT)
211: dbus_free (e->d.limit.name);
212:
213: dbus_free (e);
214: }
215:
216: static void
217: pop_element (BusConfigParser *parser)
218: {
219: Element *e;
220:
221: e = _dbus_list_pop_last (&parser->stack);
222:
223: element_free (e);
224: }
225:
226: static Element*
227: peek_element (BusConfigParser *parser)
228: {
229: Element *e;
230:
231: e = _dbus_list_get_last (&parser->stack);
232:
233: return e;
234: }
235:
236: static ElementType
237: top_element_type (BusConfigParser *parser)
238: {
239: Element *e;
240:
241: e = _dbus_list_get_last (&parser->stack);
242:
243: if (e)
244: return e->type;
245: else
246: return ELEMENT_NONE;
247: }
248:
249: static dbus_bool_t
250: merge_service_context_hash (DBusHashTable *dest,
251: DBusHashTable *from)
252: {
253: DBusHashIter iter;
254: char *service_copy;
255: char *context_copy;
256:
257: service_copy = NULL;
258: context_copy = NULL;
259:
260: _dbus_hash_iter_init (from, &iter);
261: while (_dbus_hash_iter_next (&iter))
262: {
263: const char *service = _dbus_hash_iter_get_string_key (&iter);
264: const char *context = _dbus_hash_iter_get_value (&iter);
265:
266: service_copy = _dbus_strdup (service);
267: if (service_copy == NULL)
268: goto fail;
269: context_copy = _dbus_strdup (context);
270: if (context_copy == NULL)
271: goto fail;
272:
273: if (!_dbus_hash_table_insert_string (dest, service_copy, context_copy))
274: goto fail;
275:
276: service_copy = NULL;
277: context_copy = NULL;
278: }
279:
280: return TRUE;
281:
282: fail:
283: if (service_copy)
284: dbus_free (service_copy);
285:
286: if (context_copy)
287: dbus_free (context_copy);
288:
289: return FALSE;
290: }
291:
292: static dbus_bool_t
293: service_dirs_find_dir (DBusList **service_dirs,
294: const char *dir)
295: {
296: DBusList *link;
297:
298: _dbus_assert (dir != NULL);
299:
300: for (link = *service_dirs; link; link = _dbus_list_get_next_link(service_dirs, link))
301: {
302: const char *link_dir;
303:
304: link_dir = (const char *)link->data;
305: if (strcmp (dir, link_dir) == 0)
306: return TRUE;
307: }
308:
309: return FALSE;
310: }
311:
312: static dbus_bool_t
313: service_dirs_append_unique_or_free (DBusList **service_dirs,
314: char *dir)
315: {
316: if (!service_dirs_find_dir (service_dirs, dir))
317: return _dbus_list_append (service_dirs, dir);
318:
319: dbus_free (dir);
320: return TRUE;
321: }
322:
323: static void
324: service_dirs_append_link_unique_or_free (DBusList **service_dirs,
325: DBusList *dir_link)
326: {
327: if (!service_dirs_find_dir (service_dirs, dir_link->data))
328: {
329: _dbus_list_append_link (service_dirs, dir_link);
330: }
331: else
332: {
333: dbus_free (dir_link->data);
334: _dbus_list_free_link (dir_link);
335: }
336: }
337:
338: static dbus_bool_t
339: merge_included (BusConfigParser *parser,
340: BusConfigParser *included,
341: DBusError *error)
342: {
343: DBusList *link;
344:
345: if (!bus_policy_merge (parser->policy,
346: included->policy))
347: {
348: BUS_SET_OOM (error);
349: return FALSE;
350: }
351:
352: if (!merge_service_context_hash (parser->service_context_table,
353: included->service_context_table))
354: {
355: BUS_SET_OOM (error);
356: return FALSE;
357: }
358:
359: if (included->user != NULL)
360: {
361: dbus_free (parser->user);
362: parser->user = included->user;
363: included->user = NULL;
364: }
365:
366: if (included->bus_type != NULL)
367: {
368: dbus_free (parser->bus_type);
369: parser->bus_type = included->bus_type;
370: included->bus_type = NULL;
371: }
372:
373: if (included->fork)
374: parser->fork = TRUE;
375:
376: if (included->pidfile != NULL)
377: {
378: dbus_free (parser->pidfile);
379: parser->pidfile = included->pidfile;
380: included->pidfile = NULL;
381: }
382:
383: while ((link = _dbus_list_pop_first_link (&included->listen_on)))
384: _dbus_list_append_link (&parser->listen_on, link);
385:
386: while ((link = _dbus_list_pop_first_link (&included->mechanisms)))
387: _dbus_list_append_link (&parser->mechanisms, link);
388:
389: while ((link = _dbus_list_pop_first_link (&included->service_dirs)))
390: service_dirs_append_link_unique_or_free (&parser->service_dirs, link);
391:
392: while ((link = _dbus_list_pop_first_link (&included->conf_dirs)))
393: _dbus_list_append_link (&parser->conf_dirs, link);
394:
395: return TRUE;
396: }
397:
398: static dbus_bool_t
399: seen_include (BusConfigParser *parser,
400: const DBusString *file)
401: {
402: DBusList *iter;
403:
404: iter = parser->included_files;
405: while (iter != NULL)
406: {
407: if (! strcmp (_dbus_string_get_const_data (file), iter->data))
408: return TRUE;
409:
410: iter = _dbus_list_get_next_link (&parser->included_files, iter);
411: }
412:
413: return FALSE;
414: }
415:
416: BusConfigParser*
417: bus_config_parser_new (const DBusString *basedir,
418: dbus_bool_t is_toplevel,
419: const BusConfigParser *parent)
420: {
421: BusConfigParser *parser;
422:
423: parser = dbus_new0 (BusConfigParser, 1);
424: if (parser == NULL)
425: return NULL;
426:
427: parser->is_toplevel = !!is_toplevel;
428:
429: if (!_dbus_string_init (&parser->basedir))
430: {
431: dbus_free (parser);
432: return NULL;
433: }
434:
435: if (((parser->policy = bus_policy_new ()) == NULL) ||
436: !_dbus_string_copy (basedir, 0, &parser->basedir, 0) ||
437: ((parser->service_context_table = _dbus_hash_table_new (DBUS_HASH_STRING,
438: dbus_free,
439: dbus_free)) == NULL))
440: {
441: if (parser->policy)
442: bus_policy_unref (parser->policy);
443:
444: _dbus_string_free (&parser->basedir);
445:
446: dbus_free (parser);
447: return NULL;
448: }
449:
450: if (parent != NULL)
451: {
452:
453: parser->limits = parent->limits;
454:
455:
456:
457: parser->included_files = parent->included_files;
458: }
459: else
460: {
461:
462:
463: parser->limits.max_incoming_bytes = _DBUS_ONE_MEGABYTE * 63;
464: parser->limits.max_outgoing_bytes = _DBUS_ONE_MEGABYTE * 63;
465: parser->limits.max_message_size = _DBUS_ONE_MEGABYTE * 32;
466:
467:
468:
469:
470:
471: parser->limits.activation_timeout = 25000;
472:
473:
474:
475:
476:
477: parser->limits.auth_timeout = 30000;
478:
479: parser->limits.max_incomplete_connections = 32;
480: parser->limits.max_connections_per_user = 128;
481:
482:
483:
484:
485:
486: parser->limits.max_completed_connections = 1024;
487:
488: parser->limits.max_pending_activations = 256;
489: parser->limits.max_services_per_connection = 256;
490:
491: parser->limits.max_match_rules_per_connection = 512;
492:
493: parser->limits.reply_timeout = 5 * 60 * 1000;
494: parser->limits.max_replies_per_connection = 32;
495: }
496:
497: parser->refcount = 1;
498:
499: return parser;
500: }
501:
502: BusConfigParser *
503: bus_config_parser_ref (BusConfigParser *parser)
504: {
505: _dbus_assert (parser->refcount > 0);
506:
507: parser->refcount += 1;
508:
509: return parser;
510: }
511:
512: void
513: bus_config_parser_unref (BusConfigParser *parser)
514: {
515: _dbus_assert (parser->refcount > 0);
516:
517: parser->refcount -= 1;
518:
519: if (parser->refcount == 0)
520: {
521: while (parser->stack != NULL)
522: pop_element (parser);
523:
524: dbus_free (parser->user);
525: dbus_free (parser->bus_type);
526: dbus_free (parser->pidfile);
527:
528: _dbus_list_foreach (&parser->listen_on,
529: (DBusForeachFunction) dbus_free,
530: NULL);
531:
532: _dbus_list_clear (&parser->listen_on);
533:
534: _dbus_list_foreach (&parser->service_dirs,
535: (DBusForeachFunction) dbus_free,
536: NULL);
537:
538: _dbus_list_clear (&parser->service_dirs);
539:
540: _dbus_list_foreach (&parser->conf_dirs,
541: (DBusForeachFunction) dbus_free,
542: NULL);
543:
544: _dbus_list_clear (&parser->conf_dirs);
545:
546: _dbus_list_foreach (&parser->mechanisms,
547: (DBusForeachFunction) dbus_free,
548: NULL);
549:
550: _dbus_list_clear (&parser->mechanisms);
551:
552: _dbus_string_free (&parser->basedir);
553:
554: if (parser->policy)
555: bus_policy_unref (parser->policy);
556:
557: if (parser->service_context_table)
558: _dbus_hash_table_unref (parser->service_context_table);
559:
560: dbus_free (parser);
561: }
562: }
563:
564: dbus_bool_t
565: bus_config_parser_check_doctype (BusConfigParser *parser,
566: const char *doctype,
567: DBusError *error)
568: {
569: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
570:
571: if (strcmp (doctype, "busconfig") != 0)
572: {
573: dbus_set_error (error,
574: DBUS_ERROR_FAILED,
575: "Configuration file has the wrong document type %s",
576: doctype);
577: return FALSE;
578: }
579: else
580: return TRUE;
581: }
582:
583: typedef struct
584: {
585: const char *name;
586: const char **retloc;
587: } LocateAttr;
588:
589: static dbus_bool_t
590: locate_attributes (BusConfigParser *parser,
591: const char *element_name,
592: const char **attribute_names,
593: const char **attribute_values,
594: DBusError *error,
595: const char *first_attribute_name,
596: const char **first_attribute_retloc,
597: ...)
598: {
599: va_list args;
600: const char *name;
601: const char **retloc;
602: int n_attrs;
603: #define MAX_ATTRS 24
604: LocateAttr attrs[MAX_ATTRS];
605: dbus_bool_t retval;
606: int i;
607:
608: _dbus_assert (first_attribute_name != NULL);
609: _dbus_assert (first_attribute_retloc != NULL);
610:
611: retval = TRUE;
612:
613: n_attrs = 1;
614: attrs[0].name = first_attribute_name;
615: attrs[0].retloc = first_attribute_retloc;
616: *first_attribute_retloc = NULL;
617:
618: va_start (args, first_attribute_retloc);
619:
620: name = va_arg (args, const char*);
621: retloc = va_arg (args, const char**);
622:
623: while (name != NULL)
624: {
625: _dbus_assert (retloc != NULL);
626: _dbus_assert (n_attrs < MAX_ATTRS);
627:
628: attrs[n_attrs].name = name;
629: