1:
2:
3:
4:
5:
6:
7:
8:
9:
10:
11:
12:
13:
14:
15:
16:
17:
18:
19:
20:
21:
22:
23:
24:
25: #include "activation.h"
26: #include "connection.h"
27: #include "driver.h"
28: #include "dispatch.h"
29: #include "services.h"
30: #include "selinux.h"
31: #include "signals.h"
32: #include "utils.h"
33: #include <dbus/dbus-string.h>
34: #include <dbus/dbus-internals.h>
35: #include <dbus/dbus-marshal-recursive.h>
36: #include <string.h>
37:
38: static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection,
39: DBusMessage *hello_message,
40: BusTransaction *transaction,
41: DBusError *error);
42:
43: dbus_bool_t
44: bus_driver_send_service_owner_changed (const char *service_name,
45: const char *old_owner,
46: const char *new_owner,
47: BusTransaction *transaction,
48: DBusError *error)
49: {
50: DBusMessage *message;
51: dbus_bool_t retval;
52: const char *null_service;
53:
54: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
55:
56: null_service = "";
57: _dbus_verbose ("sending name owner changed: %s [%s -> %s]\n",
58: service_name,
59: old_owner ? old_owner : null_service,
60: new_owner ? new_owner : null_service);
61:
62: message = dbus_message_new_signal (DBUS_PATH_DBUS,
63: DBUS_INTERFACE_DBUS,
64: "NameOwnerChanged");
65:
66: if (message == NULL)
67: {
68: BUS_SET_OOM (error);
69: return FALSE;
70: }
71:
72: if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
73: goto oom;
74:
75: if (!dbus_message_append_args (message,
76: DBUS_TYPE_STRING, &service_name,
77: DBUS_TYPE_STRING, old_owner ? &old_owner : &null_service,
78: DBUS_TYPE_STRING, new_owner ? &new_owner : &null_service,
79: DBUS_TYPE_INVALID))
80: goto oom;
81:
82: _dbus_assert (dbus_message_has_signature (message, "sss"));
83:
84: retval = bus_dispatch_matches (transaction, NULL, NULL, message, error);
85: dbus_message_unref (message);
86:
87: return retval;
88:
89: oom:
90: dbus_message_unref (message);
91: BUS_SET_OOM (error);
92: return FALSE;
93: }
94:
95: dbus_bool_t
96: bus_driver_send_service_lost (DBusConnection *connection,
97: const char *service_name,
98: BusTransaction *transaction,
99: DBusError *error)
100: {
101: DBusMessage *message;
102:
103: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
104:
105: message = dbus_message_new_signal (DBUS_PATH_DBUS,
106: DBUS_INTERFACE_DBUS,
107: "NameLost");
108:
109: if (message == NULL)
110: {
111: BUS_SET_OOM (error);
112: return FALSE;
113: }
114:
115: if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
116: !dbus_message_append_args (message,
117: DBUS_TYPE_STRING, &service_name,
118: DBUS_TYPE_INVALID))
119: {
120: dbus_message_unref (message);
121: BUS_SET_OOM (error);
122: return FALSE;
123: }
124:
125: if (!bus_transaction_send_from_driver (transaction, connection, message))
126: {
127: dbus_message_unref (message);
128: BUS_SET_OOM (error);
129: return FALSE;
130: }
131: else
132: {
133: dbus_message_unref (message);
134: return TRUE;
135: }
136: }
137:
138: dbus_bool_t
139: bus_driver_send_service_acquired (DBusConnection *connection,
140: const char *service_name,
141: BusTransaction *transaction,
142: DBusError *error)
143: {
144: DBusMessage *message;
145:
146: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
147:
148: message = dbus_message_new_signal (DBUS_PATH_DBUS,
149: DBUS_INTERFACE_DBUS,
150: "NameAcquired");
151:
152: if (message == NULL)
153: {
154: BUS_SET_OOM (error);
155: return FALSE;
156: }
157:
158: if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) ||
159: !dbus_message_append_args (message,
160: DBUS_TYPE_STRING, &service_name,
161: DBUS_TYPE_INVALID))
162: {
163: dbus_message_unref (message);
164: BUS_SET_OOM (error);
165: return FALSE;
166: }
167:
168: if (!bus_transaction_send_from_driver (transaction, connection, message))
169: {
170: dbus_message_unref (message);
171: BUS_SET_OOM (error);
172: return FALSE;
173: }
174: else
175: {
176: dbus_message_unref (message);
177: return TRUE;
178: }
179: }
180:
181: static dbus_bool_t
182: create_unique_client_name (BusRegistry *registry,
183: DBusString *str)
184: {
185:
186:
187:
188:
189:
190:
191:
192: static int next_major_number = 0;
193: static int next_minor_number = 0;
194: int len;
195:
196: len = _dbus_string_get_length (str);
197:
198: while (TRUE)
199: {
200:
201:
202:
203: if (next_minor_number <= 0)
204: {
205: next_major_number += 1;
206: next_minor_number = 0;
207: if (next_major_number <= 0)
208: _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added");
209: }
210:
211: _dbus_assert (next_major_number > 0);
212: _dbus_assert (next_minor_number >= 0);
213:
214:
215:
216: if (!_dbus_string_append (str, ":"))
217: return FALSE;
218:
219: if (!_dbus_string_append_int (str, next_major_number))
220: return FALSE;
221:
222: if (!_dbus_string_append (str, "."))
223: return FALSE;
224:
225: if (!_dbus_string_append_int (str, next_minor_number))
226: return FALSE;
227:
228: next_minor_number += 1;
229:
230:
231: if (bus_registry_lookup (registry, str) == NULL)
232: break;
233:
234:
235: _dbus_string_set_length (str, len);
236: }
237:
238: return TRUE;
239: }
240:
241: static dbus_bool_t
242: bus_driver_handle_hello (DBusConnection *connection,
243: BusTransaction *transaction,
244: DBusMessage *message,
245: DBusError *error)
246: {
247: DBusString unique_name;
248: BusService *service;
249: dbus_bool_t retval;
250: BusRegistry *registry;
251: BusConnections *connections;
252:
253: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
254:
255: if (bus_connection_is_active (connection))
256: {
257:
258: dbus_set_error (error, DBUS_ERROR_FAILED,
259: "Already handled an Hello message");
260: return FALSE;
261: }
262:
263:
264:
265:
266:
267:
268:
269: connections = bus_connection_get_connections (connection);
270: if (!bus_connections_check_limits (connections, connection,
271: error))
272: {
273: _DBUS_ASSERT_ERROR_IS_SET (error);
274: return FALSE;
275: }
276:
277: if (!_dbus_string_init (&unique_name))
278: {
279: BUS_SET_OOM (error);
280: return FALSE;
281: }
282:
283: retval = FALSE;
284:
285: registry = bus_connection_get_registry (connection);
286:
287: if (!create_unique_client_name (registry, &unique_name))
288: {
289: BUS_SET_OOM (error);
290: goto out_0;
291: }
292:
293: if (!bus_connection_complete (connection, &unique_name, error))
294: {
295: _DBUS_ASSERT_ERROR_IS_SET (error);
296: goto out_0;
297: }
298:
299: if (!dbus_message_set_sender (message,
300: bus_connection_get_name (connection)))
301: {
302: BUS_SET_OOM (error);
303: goto out_0;
304: }
305:
306: if (!bus_driver_send_welcome_message (connection, message, transaction, error))
307: goto out_0;
308:
309:
310: service = bus_registry_ensure (registry,
311: &unique_name, connection, 0, transaction, error);
312: if (service == NULL)
313: goto out_0;
314:
315: _dbus_assert (bus_connection_is_active (connection));
316: retval = TRUE;
317:
318: out_0:
319: _dbus_string_free (&unique_name);
320: return retval;
321: }
322:
323: static dbus_bool_t
324: bus_driver_send_welcome_message (DBusConnection *connection,
325: DBusMessage *hello_message,
326: BusTransaction *transaction,
327: DBusError *error)
328: {
329: DBusMessage *welcome;
330: const char *name;
331:
332: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
333:
334: name = bus_connection_get_name (connection);
335: _dbus_assert (name != NULL);
336:
337: welcome = dbus_message_new_method_return (hello_message);
338: if (welcome == NULL)
339: {
340: BUS_SET_OOM (error);
341: return FALSE;
342: }
343:
344: if (!dbus_message_append_args (welcome,
345: DBUS_TYPE_STRING, &name,
346: DBUS_TYPE_INVALID))
347: {
348: dbus_message_unref (welcome);
349: BUS_SET_OOM (error);
350: return FALSE;
351: }
352:
353: _dbus_assert (dbus_message_has_signature (welcome, DBUS_TYPE_STRING_AS_STRING));
354:
355: if (!bus_transaction_send_from_driver (transaction, connection, welcome))
356: {
357: dbus_message_unref (welcome);
358: BUS_SET_OOM (error);
359: return FALSE;
360: }
361: else
362: {
363: dbus_message_unref (welcome);
364: return TRUE;
365: }
366: }
367:
368: static dbus_bool_t
369: bus_driver_handle_list_services (DBusConnection *connection,
370: BusTransaction *transaction,
371: DBusMessage *message,
372: DBusError *error)
373: {
374: DBusMessage *reply;
375: int len;
376: char **services;
377: BusRegistry *registry;
378: int i;
379: DBusMessageIter iter;
380: DBusMessageIter sub;
381:
382: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
383:
384: registry = bus_connection_get_registry (connection);
385:
386: reply = dbus_message_new_method_return (message);
387: if (reply == NULL)
388: {
389: BUS_SET_OOM (error);
390: return FALSE;
391: }
392:
393: if (!bus_registry_list_services (registry, &services, &len))
394: {
395: dbus_message_unref (reply);
396: BUS_SET_OOM (error);
397: return FALSE;
398: }
399:
400: dbus_message_iter_init_append (reply, &iter);
401:
402: if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
403: DBUS_TYPE_STRING_AS_STRING,
404: &sub))
405: {
406: dbus_free_string_array (services);
407: dbus_message_unref (reply);
408: BUS_SET_OOM (error);
409: return FALSE;
410: }
411:
412: {
413:
414: const char *v_STRING = DBUS_SERVICE_DBUS;
415: if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
416: &v_STRING))
417: {
418: dbus_free_string_array (services);
419: dbus_message_unref (reply);
420: BUS_SET_OOM (error);
421: return FALSE;
422: }
423: }
424:
425: i = 0;
426: while (i < len)
427: {
428: if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
429: &services[i]))
430: {
431: dbus_free_string_array (services);
432: dbus_message_unref (reply);
433: BUS_SET_OOM (error);
434: return FALSE;
435: }
436: ++i;
437: }
438:
439: dbus_free_string_array (services);
440:
441: if (!dbus_message_iter_close_container (&iter, &sub))
442: {
443: dbus_message_unref (reply);
444: BUS_SET_OOM (error);
445: return FALSE;
446: }
447:
448: if (!bus_transaction_send_from_driver (transaction, connection, reply))
449: {
450: dbus_message_unref (reply);
451: BUS_SET_OOM (error);
452: return FALSE;
453: }
454: else
455: {
456: dbus_message_unref (reply);
457: return TRUE;
458: }
459: }
460:
461: static dbus_bool_t
462: bus_driver_handle_list_activatable_services (DBusConnection *connection,
463: BusTransaction *transaction,
464: DBusMessage *message,
465: DBusError *error)
466: {
467: DBusMessage *reply;
468: int len;
469: char **services;
470: BusActivation *activation;
471: int i;
472: DBusMessageIter iter;
473: DBusMessageIter sub;
474:
475: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
476:
477: activation = bus_connection_get_activation (connection);
478:
479: reply = dbus_message_new_method_return (message);
480: if (reply == NULL)
481: {
482: BUS_SET_OOM (error);
483: return FALSE;
484: }
485:
486: if (!bus_activation_list_services (activation, &services, &len))
487: {
488: dbus_message_unref (reply);
489: BUS_SET_OOM (error);
490: return FALSE;
491: }
492:
493: dbus_message_iter_init_append (reply, &iter);
494:
495: if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY,
496: DBUS_TYPE_STRING_AS_STRING,
497: &sub))
498: {
499: dbus_free_string_array (services);
500: dbus_message_unref (reply);
501: BUS_SET_OOM (error);
502: return FALSE;
503: }
504:
505: {
506:
507: const char *v_STRING = DBUS_SERVICE_DBUS;
508: if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
509: &v_STRING))
510: {
511: dbus_free_string_array (services);
512: dbus_message_unref (reply);
513: BUS_SET_OOM (error);
514: return FALSE;
515: }
516: }
517:
518: i = 0;
519: while (i < len)
520: {
521: if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING,
522: &services[i]))
523: {
524: dbus_free_string_array (services);
525: dbus_message_unref (reply);
526: BUS_SET_OOM (error);
527: return FALSE;
528: }
529: ++i;
530: }
531:
532: dbus_free_string_array (services);
533:
534: if (!dbus_message_iter_close_container (&iter, &sub))
535: {
536: dbus_message_unref (reply);
537: BUS_SET_OOM (error);
538: return FALSE;
539: }
540:
541: if (!bus_transaction_send_from_driver (transaction, connection, reply))
542: {
543: dbus_message_unref (reply);
544: BUS_SET_OOM (error);
545: return FALSE;
546: }
547: else
548: {
549: dbus_message_unref (reply);
550: return TRUE;
551: }
552: }
553:
554: static dbus_bool_t
555: bus_driver_handle_acquire_service (DBusConnection *connection,
556: BusTransaction *transaction,
557: DBusMessage *message,
558: DBusError *error)
559: {
560: DBusMessage *reply;
561: DBusString service_name;
562: const char *name;
563: dbus_uint32_t service_reply;
564: dbus_uint32_t flags;
565: dbus_bool_t retval;
566: BusRegistry *registry;
567:
568: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
569:
570: registry = bus_connection_get_registry (connection);
571:
572: if (!dbus_message_get_args (message, error,
573: DBUS_TYPE_STRING, &name,
574: DBUS_TYPE_UINT32, &flags,
575: DBUS_TYPE_INVALID))
576: return FALSE;
577:
578: _dbus_verbose ("Trying to own name %s with flags 0x%x\n", name, flags);
579:
580: retval = FALSE;
581: reply = NULL;
582:
583: _dbus_string_init_const (&service_name, name);
584:
585: if (!bus_registry_acquire_service (registry, connection,
586: &service_name, flags,
587: &service_reply, transaction,
588: error))
589: goto out;
590:
591: reply = dbus_message_new_method_return (message);
592: if (reply == NULL)
593: {
594: BUS_SET_OOM (error);
595: goto out;
596: }
597:
598: if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID))
599: {
600: BUS_SET_OOM (error);
601: goto out;
602: }
603:
604: if (!bus_transaction_send_from_driver (transaction, connection, reply))
605: {
606: BUS_SET_OOM (error);
607: goto out;
608: }
609:
610: retval = TRUE;
611:
612: out:
613: if (reply)
614: dbus_message_unref (reply);
615: return retval;
616: }
617:
618: static dbus_bool_t
619: bus_driver_handle_release_service (DBusConnection *connection,
620: BusTransaction *transaction,
621: DBusMessage *message,
622: DBusError *error)
623: {
624: DBusMessage *reply;
625: DBusString service_name;
626: const char *name;
627: dbus_uint32_t service_reply;
628: dbus_bool_t retval;
629: BusRegistry *registry;
630:
631: _DBUS_ASSERT_ERROR_IS_CLEAR (error);
632:
633: registry = bus_connection_get_registry (connection);
634:
635: if (!dbus_message_get_args (message, error,
636: DBUS_TYPE_STRING, &name,
637: DBUS_TYPE_INVALID))
638: return FALSE;
639:
640: _dbus_verbose ("Trying to release name %s\n", name);
641:
642: retval = FALSE;
643: reply = NULL;
644:
645: _dbus_string_init_const (&service_name, name);
646:
647: if (!bus_registry_release_service (registry, connection,
648: &service_name, &service_reply,
649: transaction, error))
650: goto out;
651: