1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24: #include "bus.h"
25: #include "activation.h"
26: #include "connection.h"
27: #include "services.h"
28: #include "utils.h"
29: #include "policy.h"
30: #include "config-parser.h"
31: #include "signals.h"
32: #include "selinux.h"
33: #include "dir-watch.h"
34: #include <dbus/dbus-list.h>
35: #include <dbus/dbus-hash.h>
36: #include <dbus/dbus-internals.h>
37:
38: struct BusContext
39: {
40: int refcount;
41: char *config_file;
42: char *type;
43: char *address;
44: char *pidfile;
45: char *user;
46: DBusLoop *loop;
47: DBusList *servers;
48: BusConnections *connections;
49: BusActivation *activation;
50: BusRegistry *registry;
51: BusPolicy *policy;
52: BusMatchmaker *matchmaker;
53: DBusUserDatabase *user_database;
54: BusLimits limits;
55: unsigned int fork : 1;
56: };
57:
58: static dbus_int32_t server_data_slot = -1;
59:
60: typedef struct
61: {
62: BusContext *context;
63: } BusServerData;
64:
65: #define BUS_SERVER_DATA(server) (dbus_server_get_data ((server), server_data_slot))
66:
67: static BusContext*
68: server_get_context (DBusServer *server)
69: {
70: BusContext *context;
71: BusServerData *bd;
72:
73: if (!dbus_server_allocate_data_slot (&server_data_slot))
74: return NULL;
75:
76: bd = BUS_SERVER_DATA (server);
77: if (bd == NULL)
78: {
79: dbus_server_free_data_slot (&server_data_slot);
80: return NULL;
81: }
82:
83: context = bd->context;
84:
85: dbus_server_free_data_slot (&server_data_slot);
86:
87: return context;
88: }
89:
90: static dbus_bool_t
91: server_watch_callback (DBusWatch *watch,
92: unsigned int condition,
93: void *data)
94: {
95:
96:
97:
98:
99:
100: return dbus_watch_handle (watch, condition);
101: }
102:
103: static dbus_bool_t
104: add_server_watch (DBusWatch *watch,
105: void *data)
106: {
107: DBusServer *server = data;
108: BusContext *context;
109:
110: context = server_get_context (server);
111:
112: return _dbus_loop_add_watch (context->loop,
113: watch, server_watch_callback, server,
114: NULL);
115: }
116:
117: static void
118: remove_server_watch (DBusWatch *watch,
119: void *data)
120: {
121: DBusServer *server = data;
122: BusContext *context;
123:
124: context = server_get_context (server);
125:
126: _dbus_loop_remove_watch (context->loop,
127: watch, server_watch_callback, server);
128: }
129:
130:
131: static void
132: server_timeout_callback (DBusTimeout *timeout,
133: void *data)
134: {
135:
136: dbus_timeout_handle (timeout);
137: }
138:
139: static dbus_bool_t
140: add_server_timeout (DBusTimeout *timeout,
141: void *data)
142: {
143: DBusServer *server = data;
144: BusContext *context;
145:
146: context = server_get_context (server);
147:
148: return _dbus_loop_add_timeout (context->loop,
149: timeout, server_timeout_callback, server, NULL);
150: }
151:
152: static void
153: remove_server_timeout (DBusTimeout *timeout,
154: void *data)
155: {
156: DBusServer *server = data;
157: BusContext *context;
158:
159: context = server_get_context (server);
160:
161: _dbus_loop_remove_timeout (context->loop,
162: timeout, server_timeout_callback, server);
163: }
164:
165: static void
166: new_connection_callback (DBusServer *server,
167: DBusConnection *new_connection,
168: void *data)
169: {
170: BusContext *context = data;
171:
172: if (!bus_connections_setup_connection (context->connections, new_connection))
173: {
174: _dbus_verbose ("No memory to setup new connection\n");
175:
176:
177:
178:
179:
180:
181: dbus_connection_close (new_connection);
182: }
183:
184: dbus_connection_set_max_received_size (new_connection,
185: context->limits.max_incoming_bytes);
186:
187: dbus_connection_set_max_message_size (new_connection,
188: context->limits.max_message_size);
189:
190:
191: }
192:
193: static void
194: free_server_data (void *data)
195: {
196: BusServerData *bd = data;
197:
198: dbus_free (bd);
199: }
200:
201: static dbus_bool_t
202: setup_server (BusContext *context,
203: DBusServer *server,
204: char **auth_mechanisms,
205: DBusError *error)
206: {
207: BusServerData *bd;
208:
209: bd = dbus_new0 (BusServerData, 1);
210: if (!dbus_server_set_data (server,
211: server_data_slot,
212: bd, free_server_data))
213: {
214: dbus_free (bd);
215: BUS_SET_OOM (error);
216: return FALSE;
217: }
218:
219: bd->context = context;
220:
221: if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms))
222: {
223: BUS_SET_OOM (error);
224: return FALSE;
225: }
226:
227: dbus_server_set_new_connection_function (server,
228: new_connection_callback,
229: context, NULL);
230:
231: if (!dbus_server_set_watch_functions (server,
232: add_server_watch,
233: remove_server_watch,
234: NULL,
235: server,
236: NULL))
237: {
238: BUS_SET_OOM (error);
239: return FALSE;
240: }
241:
242: if (!dbus_server_set_timeout_functions (server,
243: add_server_timeout,
244: remove_server_timeout,
245: NULL,
246: server, NULL))
247: {
248: BUS_SET_OOM (error);
249: return FALSE;
250: }
251:
252: return TRUE;
253: }
254:
255:
256:
257:
258: static dbus_bool_t
259: process_config_first_time_only (BusContext *context,
260: BusConfigParser *parser,
261: DBusError *error)
262: {
263: DBusList *link;
264: DBusList **addresses;
265: const char *user, *pidfile;
266: char **auth_mechanisms;
267: DBusList **auth_mechanisms_list;
268: int len;
269: dbus_bool_t retval;
270:
271: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
272:
273: retval = FALSE;
274: auth_mechanisms = NULL;
275:
276:
277:
278:
279:
280:
281: pidfile = bus_config_parser_get_pidfile (parser);
282: if (pidfile != NULL)
283: {
284: DBusString u;
285: DBusStat stbuf;
286:
287: _dbus_string_init_const (&u, pidfile);
288:
289: if (_dbus_stat (&u, &stbuf, NULL))
290: {
291: dbus_set_error (error, DBUS_ERROR_FAILED,
292: "The pid file \"%s\" exists, if the message bus is not running, remove this file",
293: pidfile);
294: goto failed;
295: }
296: }
297:
298:
299: context->pidfile = _dbus_strdup (pidfile);
300:
301:
302:
303: auth_mechanisms_list = bus_config_parser_get_mechanisms (parser);
304: len = _dbus_list_get_length (auth_mechanisms_list);
305:
306: if (len > 0)
307: {
308: int i;
309:
310: auth_mechanisms = dbus_new0 (char*, len + 1);
311: if (auth_mechanisms == NULL)
312: {
313: BUS_SET_OOM (error);
314: goto failed;
315: }
316:
317: i = 0;
318: link = _dbus_list_get_first_link (auth_mechanisms_list);
319: while (link != NULL)
320: {
321: auth_mechanisms[i] = _dbus_strdup (link->data);
322: if (auth_mechanisms[i] == NULL)
323: {
324: BUS_SET_OOM (error);
325: goto failed;
326: }
327: link = _dbus_list_get_next_link (auth_mechanisms_list, link);
328: }
329: }
330: else
331: {
332: auth_mechanisms = NULL;
333: }
334:
335:
336:
337: addresses = bus_config_parser_get_addresses (parser);
338:
339: link = _dbus_list_get_first_link (addresses);
340: while (link != NULL)
341: {
342: DBusServer *server;
343:
344: server = dbus_server_listen (link->data, error);
345: if (server == NULL)
346: {
347: _DBUS_ASSERT_ERROR_IS_SET (error);
348: goto failed;
349: }
350: else if (!setup_server (context, server, auth_mechanisms, error))
351: {
352: _DBUS_ASSERT_ERROR_IS_SET (error);
353: goto failed;
354: }
355:
356: if (!_dbus_list_append (&context->servers, server))
357: {
358: BUS_SET_OOM (error);
359: goto failed;
360: }
361:
362: link = _dbus_list_get_next_link (addresses, link);
363: }
364:
365:
366: context->type = _dbus_strdup (bus_config_parser_get_type (parser));
367: if (bus_config_parser_get_type (parser) != NULL && context->type == NULL)
368: {
369: BUS_SET_OOM (error);
370: goto failed;
371: }
372:
373: user = bus_config_parser_get_user (parser);
374: if (user != NULL)
375: {
376: context->user = _dbus_strdup (user);
377: if (context->user == NULL)
378: {
379: BUS_SET_OOM (error);
380: goto failed;
381: }
382: }
383:
384: context->fork = bus_config_parser_get_fork (parser);
385:
386: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
387: retval = TRUE;
388:
389: failed:
390: dbus_free_string_array (auth_mechanisms);
391: return retval;
392: }
393:
394:
395:
396:
397: static dbus_bool_t
398: process_config_every_time (BusContext *context,
399: BusConfigParser *parser,
400: dbus_bool_t is_reload,
401: DBusError *error)
402: {
403: DBusString full_address;
404: DBusList *link;
405: char *addr;
406:
407: dbus_bool_t retval;
408:
409: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
410:
411: addr = NULL;
412: retval = FALSE;
413:
414: if (!_dbus_string_init (&full_address))
415: {
416: BUS_SET_OOM (error);
417: return FALSE;
418: }
419:
420:
421: bus_config_parser_get_limits (parser, &context->limits);
422:
423: context->policy = bus_config_parser_steal_policy (parser);
424: _dbus_assert (context->policy != NULL);
425:
426:
427:
428:
429: link = _dbus_list_get_last_link (&context->servers);
430: while (link != NULL)
431: {
432: addr = dbus_server_get_address (link->data);
433: if (addr == NULL)
434: {
435: BUS_SET_OOM (error);
436: goto failed;
437: }
438:
439: if (_dbus_string_get_length (&full_address) > 0)
440: {
441: if (!_dbus_string_append (&full_address, ";"))
442: {
443: BUS_SET_OOM (error);
444: goto failed;
445: }
446: }
447:
448: if (!_dbus_string_append (&full_address, addr))
449: {
450: BUS_SET_OOM (error);
451: goto failed;
452: }
453:
454: dbus_free (addr);
455: addr = NULL;
456:
457: link = _dbus_list_get_prev_link (&context->servers, link);
458: }
459:
460: if (is_reload)
461: dbus_free (context->address);
462:
463: if (!_dbus_string_copy_data (&full_address, &context->address))
464: {
465: BUS_SET_OOM (error);
466: goto failed;
467: }
468:
469:
470:
471: if (is_reload)
472: bus_activation_unref (context->activation);
473:
474: context->activation = bus_activation_new (context, &full_address,
475: bus_config_parser_get_service_dirs (parser),
476: error);
477: if (context->activation == NULL)
478: {
479: _DBUS_ASSERT_ERROR_IS_SET (error);
480: goto failed;
481: }
482:
483:
484:
485: if (is_reload)
486: bus_drop_all_directory_watches ();
487:
488: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
489: retval = TRUE;
490:
491: failed:
492: _dbus_string_free (&full_address);
493:
494: if (addr)
495: dbus_free (addr);
496:
497: return retval;
498: }
499:
500: static dbus_bool_t
501: process_config_postinit (BusContext *context,
502: BusConfigParser *parser,
503: DBusError *error)
504: {
505: DBusHashTable *service_context_table;
506:
507: service_context_table = bus_config_parser_steal_service_context_table (parser);
508: if (!bus_registry_set_service_context_table (context->registry,
509: service_context_table))
510: {
511: BUS_SET_OOM (error);
512: return FALSE;
513: }
514:
515: _dbus_hash_table_unref (service_context_table);
516:
517:
518: _dbus_list_foreach (bus_config_parser_get_conf_dirs (parser),
519: (DBusForeachFunction) bus_watch_directory,
520: context);
521:
522: return TRUE;
523: }
524:
525: BusContext*
526: bus_context_new (const DBusString *config_file,
527: ForceForkSetting force_fork,
528: int print_addr_fd,
529: int print_pid_fd,
530: DBusError *error)
531: {
532: BusContext *context;
533: BusConfigParser *parser;
534: DBusCredentials creds;
535:
536: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
537:
538: context = NULL;
539: parser = NULL;
540:
541: if (!dbus_server_allocate_data_slot (&server_data_slot))
542: {
543: BUS_SET_OOM (error);
544: return NULL;
545: }
546:
547: context = dbus_new0 (BusContext, 1);
548: if (context == NULL)
549: {
550: BUS_SET_OOM (error);
551: goto failed;
552: }
553: context->refcount = 1;
554:
555: if (!_dbus_string_copy_data (config_file, &context->config_file))
556: {
557: BUS_SET_OOM (error);
558: goto failed;
559: }
560:
561: context->loop = _dbus_loop_new ();
562: if (context->loop == NULL)
563: {
564: BUS_SET_OOM (error);
565: goto failed;
566: }
567:
568: context->registry = bus_registry_new (context);
569: if (context->registry == NULL)
570: {
571: BUS_SET_OOM (error);
572: goto failed;
573: }
574:
575: parser = bus_config_load (config_file, TRUE, NULL, error);
576: if (parser == NULL)
577: {
578: _DBUS_ASSERT_ERROR_IS_SET (error);
579: goto failed;
580: }
581:
582: if (!process_config_first_time_only (context, parser, error))
583: {
584: _DBUS_ASSERT_ERROR_IS_SET (error);
585: goto failed;
586: }
587: if (!process_config_every_time (context, parser, FALSE, error))
588: {
589: _DBUS_ASSERT_ERROR_IS_SET (error);
590: goto failed;
591: }
592:
593:
594:
595:
596: if (!dbus_server_allocate_data_slot (&server_data_slot))
597: _dbus_assert_not_reached ("second ref of server data slot failed");
598:
599: context->user_database = _dbus_user_database_new ();
600: if (context->user_database == NULL)
601: {
602: BUS_SET_OOM (error);
603: goto failed;
604: }
605:
606:
607:
608:
609:
610:
611: if (print_addr_fd >= 0)
612: {
613: DBusString addr;
614: const char *a = bus_context_get_address (context);
615: int bytes;
616:
617: _dbus_assert (a != NULL);
618: if (!_dbus_string_init (&addr))
619: {
620: BUS_SET_OOM (error);
621: goto failed;
622: }
623:
624: if (!_dbus_string_append (&addr, a) ||
625: !_dbus_string_append (&addr, "\n"))
626: {
627: _dbus_string_free (&addr);
628: BUS_SET_OOM (error);
629: goto failed;
630: }
631:
632: bytes = _dbus_string_get_length (&addr);
633: if (_dbus_write_socket (print_addr_fd, &addr, 0, bytes) != bytes)
634: {
635: dbus_set_error (error, DBUS_ERROR_FAILED,
636: "Printing message bus address: %s\n",
637: _dbus_strerror (errno));
638: _dbus_string_free (&addr);
639: goto failed;
640: }
641:
642: if (print_addr_fd > 2)
643: _dbus_close_socket (print_addr_fd, NULL);
644:
645: _dbus_string_free (&addr);
646: }
647:
648: context->connections = bus_connections_new (context);
649: if (context->connections == NULL)
650: {
651: BUS_SET_OOM (error);
652: goto failed;
653: }
654:
655: context->matchmaker = bus_matchmaker_new ();
656: if (context->matchmaker == NULL)
657: {
658: BUS_SET_OOM (error);
659: goto failed;
660: }
661:
662:
663: if (context->user != NULL)
664: {
665: DBusString u;
666:
667: _dbus_string_init_const (&u, context->user);
668: