1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */
2 /* connection.c Client connections
3 *
4 * Copyright (C) 2003 Red Hat, Inc.
5 *
6 * Licensed under the Academic Free License version 2.1
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 2 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, write to the Free Software
20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
21 *
22 */
23
24 #include <config.h>
25 #include "connection.h"
26 #include "dispatch.h"
27 #include "policy.h"
28 #include "services.h"
29 #include "utils.h"
30 #include "signals.h"
31 #include "expirelist.h"
32 #include "selinux.h"
33 #include "apparmor.h"
34 #include <dbus/dbus-list.h>
35 #include <dbus/dbus-hash.h>
36 #include <dbus/dbus-timeout.h>
37 #include <dbus/dbus-connection-internal.h>
38 #include <dbus/dbus-internals.h>
39
40 /* Trim executed commands to this length; we want to keep logs readable */
41 #define MAX_LOG_COMMAND_LEN 50
42
43 static void bus_connection_remove_transactions (DBusConnection *connection);
44
45 typedef struct
46 {
47 BusExpireItem expire_item;
48
49 DBusConnection *will_get_reply;
50 DBusConnection *will_send_reply;
51
52 dbus_uint32_t reply_serial;
53
54 } BusPendingReply;
55
56 struct BusConnections
57 {
58 int refcount;
59 DBusList *completed; /**< List of all completed connections */
60 int n_completed; /**< Length of completed list */
61 DBusList *incomplete; /**< List of all not-yet-active connections */
62 int n_incomplete; /**< Length of incomplete list */
63 BusContext *context;
64 DBusHashTable *completed_by_user; /**< Number of completed connections for each UID */
65 DBusTimeout *expire_timeout; /**< Timeout for expiring incomplete connections. */
66 int stamp; /**< Incrementing number */
67 BusExpireList *pending_replies; /**< List of pending replies */
68
69 /** List of all monitoring connections, a subset of completed.
70 * Each member is a #DBusConnection. */
71 DBusList *monitors;
72 BusMatchmaker *monitor_matchmaker;
73
74 #ifdef DBUS_ENABLE_STATS
75 int total_match_rules;
76 int peak_match_rules;
77 int peak_match_rules_per_conn;
78
79 int total_bus_names;
80 int peak_bus_names;
81 int peak_bus_names_per_conn;
82 #endif
83 };
84
85 static dbus_int32_t connection_data_slot = -1;
86
87 typedef struct
88 {
89 BusConnections *connections;
90 DBusList *link_in_connection_list;
91 DBusConnection *connection;
92 DBusList *services_owned;
93 int n_services_owned;
94 DBusList *match_rules;
95 int n_match_rules;
96 char *name;
97 DBusList *transaction_messages; /**< Stuff we need to send as part of a transaction */
98 DBusMessage *oom_message;
99 DBusPreallocatedSend *oom_preallocated;
100 BusClientPolicy *policy;
101
102 char *cached_loginfo_string;
103 BusSELinuxID *selinux_id;
104 BusAppArmorConfinement *apparmor_confinement;
105
106 long connection_tv_sec; /**< Time when we connected (seconds component) */
107 long connection_tv_usec; /**< Time when we connected (microsec component) */
108 int stamp; /**< connections->stamp last time we were traversed */
109
110 #ifdef DBUS_ENABLE_STATS
111 int peak_match_rules;
112 int peak_bus_names;
113 #endif
114 int n_pending_unix_fds;
115 DBusTimeout *pending_unix_fds_timeout;
116
117 /** non-NULL if and only if this is a monitor */
118 DBusList *link_in_monitors;
119 } BusConnectionData;
120
121 static dbus_bool_t bus_pending_reply_expired (BusExpireList *list,
122 DBusList *link,
123 void *data);
124
125 static void bus_connection_drop_pending_replies (BusConnections *connections,
126 DBusConnection *connection);
127
128 static dbus_bool_t expire_incomplete_timeout (void *data);
129
130 #define BUS_CONNECTION_DATA(connection) (dbus_connection_get_data ((connection), connection_data_slot))
131
132 static DBusLoop*
connection_get_loop(DBusConnection * connection)133 connection_get_loop (DBusConnection *connection)
134 {
135 BusConnectionData *d;
136
137 d = BUS_CONNECTION_DATA (connection);
138 _dbus_assert(d != NULL);
139
140 return bus_context_get_loop (d->connections->context);
141 }
142
143
144 static int
get_connections_for_uid(BusConnections * connections,dbus_uid_t uid)145 get_connections_for_uid (BusConnections *connections,
146 dbus_uid_t uid)
147 {
148 void *val;
149 int current_count;
150
151 /* val is NULL is 0 when it isn't in the hash yet */
152
153 val = _dbus_hash_table_lookup_uintptr (connections->completed_by_user,
154 uid);
155
156 current_count = _DBUS_POINTER_TO_INT (val);
157
158 return current_count;
159 }
160
161 static dbus_bool_t
adjust_connections_for_uid(BusConnections * connections,dbus_uid_t uid,int adjustment)162 adjust_connections_for_uid (BusConnections *connections,
163 dbus_uid_t uid,
164 int adjustment)
165 {
166 int current_count;
167
168 current_count = get_connections_for_uid (connections, uid);
169
170 _dbus_verbose ("Adjusting connection count for UID " DBUS_UID_FORMAT
171 ": was %d adjustment %d making %d\n",
172 uid, current_count, adjustment, current_count + adjustment);
173
174 _dbus_assert (current_count >= 0);
175
176 current_count += adjustment;
177
178 _dbus_assert (current_count >= 0);
179
180 if (current_count == 0)
181 {
182 _dbus_hash_table_remove_uintptr (connections->completed_by_user, uid);
183 return TRUE;
184 }
185 else
186 {
187 dbus_bool_t retval;
188
189 retval = _dbus_hash_table_insert_uintptr (connections->completed_by_user,
190 uid, _DBUS_INT_TO_POINTER (current_count));
191
192 /* only positive adjustment can fail as otherwise
193 * a hash entry should already exist
194 */
195 _dbus_assert (adjustment > 0 ||
196 (adjustment <= 0 && retval));
197
198 return retval;
199 }
200 }
201
202 void
bus_connection_disconnected(DBusConnection * connection)203 bus_connection_disconnected (DBusConnection *connection)
204 {
205 BusConnectionData *d;
206 BusService *service;
207 BusMatchmaker *matchmaker;
208
209 d = BUS_CONNECTION_DATA (connection);
210 _dbus_assert (d != NULL);
211
212 _dbus_verbose ("%s disconnected, dropping all service ownership and releasing\n",
213 d->name ? d->name : "(inactive)");
214
215 /* Delete our match rules */
216 if (d->n_match_rules > 0)
217 {
218 matchmaker = bus_context_get_matchmaker (d->connections->context);
219 bus_matchmaker_disconnected (matchmaker, connection);
220 }
221
222 /* Drop any service ownership. Unfortunately, this requires
223 * memory allocation and there doesn't seem to be a good way to
224 * handle it other than sleeping; we can't "fail" the operation of
225 * disconnecting a client, and preallocating a broadcast "service is
226 * now gone" message for every client-service pair seems kind of
227 * involved.
228 */
229 while ((service = _dbus_list_get_last (&d->services_owned)))
230 {
231 BusTransaction *transaction;
232 DBusError error;
233
234 retry:
235
236 dbus_error_init (&error);
237
238 while ((transaction = bus_transaction_new (d->connections->context)) == NULL)
239 _dbus_wait_for_memory ();
240
241 if (!bus_service_remove_owner (service, connection,
242 transaction, &error))
243 {
244 _DBUS_ASSERT_ERROR_IS_SET (&error);
245
246 if (dbus_error_has_name (&error, DBUS_ERROR_NO_MEMORY))
247 {
248 dbus_error_free (&error);
249 bus_transaction_cancel_and_free (transaction);
250 _dbus_wait_for_memory ();
251 goto retry;
252 }
253 else
254 {
255 _dbus_verbose ("Failed to remove service owner: %s %s\n",
256 error.name, error.message);
257 _dbus_assert_not_reached ("Removing service owner failed for non-memory-related reason");
258 }
259 }
260
261 bus_transaction_execute_and_free (transaction);
262 }
263
264 bus_dispatch_remove_connection (connection);
265
266 /* no more watching */
267 if (!dbus_connection_set_watch_functions (connection,
268 NULL, NULL, NULL,
269 connection,
270 NULL))
271 _dbus_assert_not_reached ("setting watch functions to NULL failed");
272
273 if (!dbus_connection_set_timeout_functions (connection,
274 NULL, NULL, NULL,
275 connection,
276 NULL))
277 _dbus_assert_not_reached ("setting timeout functions to NULL failed");
278
279 dbus_connection_set_unix_user_function (connection,
280 NULL, NULL, NULL);
281 dbus_connection_set_windows_user_function (connection,
282 NULL, NULL, NULL);
283
284 dbus_connection_set_dispatch_status_function (connection,
285 NULL, NULL, NULL);
286
287 if (d->pending_unix_fds_timeout)
288 {
289 _dbus_loop_remove_timeout (bus_context_get_loop (d->connections->context),
290 d->pending_unix_fds_timeout);
291 _dbus_timeout_unref (d->pending_unix_fds_timeout);
292 }
293 d->pending_unix_fds_timeout = NULL;
294 _dbus_connection_set_pending_fds_function (connection, NULL, NULL);
295
296 bus_connection_remove_transactions (connection);
297
298 if (d->link_in_monitors != NULL)
299 {
300 BusMatchmaker *mm = d->connections->monitor_matchmaker;
301
302 if (mm != NULL)
303 bus_matchmaker_disconnected (mm, connection);
304
305 _dbus_list_remove_link (&d->connections->monitors, d->link_in_monitors);
306 d->link_in_monitors = NULL;
307 }
308
309 if (d->link_in_connection_list != NULL)
310 {
311 if (d->name != NULL)
312 {
313 unsigned long uid;
314
315 _dbus_list_remove_link (&d->connections->completed, d->link_in_connection_list);
316 d->link_in_connection_list = NULL;
317 d->connections->n_completed -= 1;
318
319 if (dbus_connection_get_unix_user (connection, &uid))
320 {
321 if (!adjust_connections_for_uid (d->connections,
322 uid, -1))
323 _dbus_assert_not_reached ("adjusting downward should never fail");
324 }
325 }
326 else
327 {
328 _dbus_list_remove_link (&d->connections->incomplete, d->link_in_connection_list);
329 d->link_in_connection_list = NULL;
330 d->connections->n_incomplete -= 1;
331
332 /* If we have dropped below the max. number of incomplete
333 * connections, start accept()ing again */
334 bus_context_check_all_watches (d->connections->context);
335 }
336
337 _dbus_assert (d->connections->n_incomplete >= 0);
338 _dbus_assert (d->connections->n_completed >= 0);
339 }
340
341 bus_connection_drop_pending_replies (d->connections, connection);
342
343 /* frees "d" as side effect */
344 dbus_connection_set_data (connection,
345 connection_data_slot,
346 NULL, NULL);
347
348 dbus_connection_unref (connection);
349 }
350
351 static dbus_bool_t
add_connection_watch(DBusWatch * watch,void * data)352 add_connection_watch (DBusWatch *watch,
353 void *data)
354 {
355 DBusConnection *connection = data;
356
357 return _dbus_loop_add_watch (connection_get_loop (connection), watch);
358 }
359
360 static void
remove_connection_watch(DBusWatch * watch,void * data)361 remove_connection_watch (DBusWatch *watch,
362 void *data)
363 {
364 DBusConnection *connection = data;
365
366 _dbus_loop_remove_watch (connection_get_loop (connection), watch);
367 }
368
369 static void
toggle_connection_watch(DBusWatch * watch,void * data)370 toggle_connection_watch (DBusWatch *watch,
371 void *data)
372 {
373 DBusConnection *connection = data;
374
375 _dbus_loop_toggle_watch (connection_get_loop (connection), watch);
376 }
377
378 static dbus_bool_t
add_connection_timeout(DBusTimeout * timeout,void * data)379 add_connection_timeout (DBusTimeout *timeout,
380 void *data)
381 {
382 DBusConnection *connection = data;
383
384 return _dbus_loop_add_timeout (connection_get_loop (connection), timeout);
385 }
386
387 static void
remove_connection_timeout(DBusTimeout * timeout,void * data)388 remove_connection_timeout (DBusTimeout *timeout,
389 void *data)
390 {
391 DBusConnection *connection = data;
392
393 _dbus_loop_remove_timeout (connection_get_loop (connection), timeout);
394 }
395
396 static void
dispatch_status_function(DBusConnection * connection,DBusDispatchStatus new_status,void * data)397 dispatch_status_function (DBusConnection *connection,
398 DBusDispatchStatus new_status,
399 void *data)
400 {
401 DBusLoop *loop = data;
402
403 if (new_status != DBUS_DISPATCH_COMPLETE)
404 {
405 while (!_dbus_loop_queue_dispatch (loop, connection))
406 _dbus_wait_for_memory ();
407 }
408 }
409
410 static dbus_bool_t
allow_unix_user_function(DBusConnection * connection,unsigned long uid,void * data)411 allow_unix_user_function (DBusConnection *connection,
412 unsigned long uid,
413 void *data)
414 {
415 BusConnectionData *d;
416
417 d = BUS_CONNECTION_DATA (connection);
418
419 _dbus_assert (d != NULL);
420
421 return bus_context_allow_unix_user (d->connections->context, uid);
422 }
423
424 static void
free_connection_data(void * data)425 free_connection_data (void *data)
426 {
427 BusConnectionData *d = data;
428
429 /* services_owned should be NULL since we should be disconnected */
430 _dbus_assert (d->services_owned == NULL);
431 _dbus_assert (d->n_services_owned == 0);
432 /* similarly */
433 _dbus_assert (d->transaction_messages == NULL);
434
435 if (d->oom_preallocated)
436 dbus_connection_free_preallocated_send (d->connection, d->oom_preallocated);
437
438 if (d->oom_message)
439 dbus_message_unref (d->oom_message);
440
441 if (d->policy)
442 bus_client_policy_unref (d->policy);
443
444 if (d->apparmor_confinement)
445 bus_apparmor_confinement_unref (d->apparmor_confinement);
446
447 dbus_free (d->cached_loginfo_string);
448
449 dbus_free (d->name);
450
451 dbus_free (d);
452 }
453
454 BusConnections*
bus_connections_new(BusContext * context)455 bus_connections_new (BusContext *context)
456 {
457 BusConnections *connections;
458
459 if (!dbus_connection_allocate_data_slot (&connection_data_slot))
460 goto failed_0;
461
462 connections = dbus_new0 (BusConnections, 1);
463 if (connections == NULL)
464 goto failed_1;
465
466 connections->completed_by_user = _dbus_hash_table_new (DBUS_HASH_UINTPTR,
467 NULL, NULL);
468 if (connections->completed_by_user == NULL)
469 goto failed_2;
470
471 connections->expire_timeout = _dbus_timeout_new (100, /* irrelevant */
472 expire_incomplete_timeout,
473 connections, NULL);
474 if (connections->expire_timeout == NULL)
475 goto failed_3;
476
477 _dbus_timeout_disable (connections->expire_timeout);
478
479 connections->pending_replies = bus_expire_list_new (bus_context_get_loop (context),
480 bus_context_get_reply_timeout (context),
481 bus_pending_reply_expired,
482 connections);
483 if (connections->pending_replies == NULL)
484 goto failed_4;
485
486 if (!_dbus_loop_add_timeout (bus_context_get_loop (context),
487 connections->expire_timeout))
488 goto failed_5;
489
490 connections->refcount = 1;
491 connections->context = context;
492
493 return connections;
494
495 failed_5:
496 bus_expire_list_free (connections->pending_replies);
497 failed_4:
498 _dbus_timeout_unref (connections->expire_timeout);
499 failed_3:
500 _dbus_hash_table_unref (connections->completed_by_user);
501 failed_2:
502 dbus_free (connections);
503 failed_1:
504 dbus_connection_free_data_slot (&connection_data_slot);
505 failed_0:
506 return NULL;
507 }
508
509 BusConnections *
bus_connections_ref(BusConnections * connections)510 bus_connections_ref (BusConnections *connections)
511 {
512 _dbus_assert (connections->refcount > 0);
513 connections->refcount += 1;
514
515 return connections;
516 }
517
518 void
bus_connections_unref(BusConnections * connections)519 bus_connections_unref (BusConnections *connections)
520 {
521 _dbus_assert (connections->refcount > 0);
522 connections->refcount -= 1;
523 if (connections->refcount == 0)
524 {
525 /* drop all incomplete */
526 while (connections->incomplete != NULL)
527 {
528 DBusConnection *connection;
529
530 connection = connections->incomplete->data;
531
532 dbus_connection_ref (connection);
533 dbus_connection_close (connection);
534 bus_connection_disconnected (connection);
535 dbus_connection_unref (connection);
536 }
537
538 _dbus_assert (connections->n_incomplete == 0);
539
540 /* drop all real connections */
541 while (connections->completed != NULL)
542 {
543 DBusConnection *connection;
544
545 connection = connections->completed->data;
546
547 dbus_connection_ref (connection);
548 dbus_connection_close (connection);
549 bus_connection_disconnected (connection);
550 dbus_connection_unref (connection);
551 }
552
553 _dbus_assert (connections->n_completed == 0);
554
555 /* disconnecting all the connections should have emptied the list of
556 * monitors (each link is removed in bus_connection_disconnected) */
557 _dbus_assert (connections->monitors == NULL);
558
559 bus_expire_list_free (connections->pending_replies);
560
561 _dbus_loop_remove_timeout (bus_context_get_loop (connections->context),
562 connections->expire_timeout);
563
564 _dbus_timeout_unref (connections->expire_timeout);
565
566 _dbus_hash_table_unref (connections->completed_by_user);
567
568 if (connections->monitor_matchmaker != NULL)
569 bus_matchmaker_unref (connections->monitor_matchmaker);
570
571 dbus_free (connections);
572
573 dbus_connection_free_data_slot (&connection_data_slot);
574 }
575 }
576
577 /* Used for logging */
578 static dbus_bool_t
cache_peer_loginfo_string(BusConnectionData * d,DBusConnection * connection)579 cache_peer_loginfo_string (BusConnectionData *d,
580 DBusConnection *connection)
581 {
582 DBusString loginfo_buf;
583 unsigned long uid;
584 unsigned long pid;
585 char *windows_sid = NULL, *security_label = NULL;
586 dbus_bool_t prev_added;
587
588 if (!_dbus_string_init (&loginfo_buf))
589 return FALSE;
590
591 prev_added = FALSE;
592 if (dbus_connection_get_unix_user (connection, &uid))
593 {
594 if (!_dbus_string_append_printf (&loginfo_buf, "uid=%ld", uid))
595 goto oom;
596 else
597 prev_added = TRUE;
598 }
599
600 if (dbus_connection_get_unix_process_id (connection, &pid))
601 {
602 if (prev_added)
603 {
604 if (!_dbus_string_append_byte (&loginfo_buf, ' '))
605 goto oom;
606 }
607 if (!_dbus_string_append_printf (&loginfo_buf, "pid=%ld comm=\"", pid))
608 goto oom;
609 /* Ignore errors here; we may not have permissions to read the
610 * proc file. */
611 _dbus_command_for_pid (pid, &loginfo_buf, MAX_LOG_COMMAND_LEN, NULL);
612 if (!_dbus_string_append_byte (&loginfo_buf, '"'))
613 goto oom;
614 else
615 prev_added = TRUE;
616 }
617
618 if (dbus_connection_get_windows_user (connection, &windows_sid))
619 {
620 dbus_bool_t did_append;
621
622 if (prev_added)
623 {
624 if (!_dbus_string_append_byte (&loginfo_buf, ' '))
625 goto oom;
626 }
627
628 did_append = _dbus_string_append_printf (&loginfo_buf,
629 "sid=\"%s\"", windows_sid);
630 dbus_free (windows_sid);
631 windows_sid = NULL;
632 if (!did_append)
633 goto oom;
634 else
635 prev_added = TRUE;
636 }
637
638 if (_dbus_connection_get_linux_security_label (connection, &security_label))
639 {
640 dbus_bool_t did_append;
641
642 if (prev_added)
643 {
644 if (!_dbus_string_append_byte (&loginfo_buf, ' '))
645 goto oom;
646 }
647
648 did_append = _dbus_string_append_printf (&loginfo_buf,
649 "label=\"%s\"", security_label);
650 dbus_free (security_label);
651 security_label = NULL;
652 if (!did_append)
653 goto oom;
654 else
655 prev_added = TRUE;
656 }
657
658 if (!_dbus_string_steal_data (&loginfo_buf, &(d->cached_loginfo_string)))
659 goto oom;
660
661 _dbus_string_free (&loginfo_buf);
662
663 return TRUE;
664 oom:
665 _dbus_string_free (&loginfo_buf);
666 if (security_label != NULL)
667 dbus_free (security_label);
668 if (windows_sid != NULL)
669 dbus_free (windows_sid);
670
671 return FALSE;
672 }
673
674 static void
check_pending_fds_cb(DBusConnection * connection)675 check_pending_fds_cb (DBusConnection *connection)
676 {
677 BusConnectionData *d = BUS_CONNECTION_DATA (connection);
678 int n_pending_unix_fds_old;
679 int n_pending_unix_fds_new;
680
681 _dbus_assert(d != NULL);
682
683 n_pending_unix_fds_old = d->n_pending_unix_fds;
684 n_pending_unix_fds_new = _dbus_connection_get_pending_fds_count (connection);
685
686 _dbus_verbose ("Pending fds count changed on connection %p: %d -> %d\n",
687 connection, n_pending_unix_fds_old, n_pending_unix_fds_new);
688
689 if (n_pending_unix_fds_old == 0 && n_pending_unix_fds_new > 0)
690 {
691 _dbus_timeout_restart (d->pending_unix_fds_timeout,
692 bus_context_get_pending_fd_timeout (d->connections->context));
693 }
694
695 if (n_pending_unix_fds_old > 0 && n_pending_unix_fds_new == 0)
696 {
697 _dbus_timeout_disable (d->pending_unix_fds_timeout);
698 }
699
700
701 d->n_pending_unix_fds = n_pending_unix_fds_new;
702 }
703
704 static dbus_bool_t
pending_unix_fds_timeout_cb(void * data)705 pending_unix_fds_timeout_cb (void *data)
706 {
707 DBusConnection *connection = data;
708 BusConnectionData *d = BUS_CONNECTION_DATA (connection);
709 int limit;
710
711 _dbus_assert (d != NULL);
712 limit = bus_context_get_pending_fd_timeout (d->connections->context);
713 bus_context_log (d->connections->context, DBUS_SYSTEM_LOG_WARNING,
714 "Connection \"%s\" (%s) has had Unix fds pending for too long, "
715 "closing it (pending_fd_timeout=%d ms)",
716 d->name != NULL ? d->name : "(null)",
717 bus_connection_get_loginfo (connection),
718 limit);
719
720 dbus_connection_close (connection);
721 return TRUE;
722 }
723
724 dbus_bool_t
bus_connections_setup_connection(BusConnections * connections,DBusConnection * connection)725 bus_connections_setup_connection (BusConnections *connections,
726 DBusConnection *connection)
727 {
728
729 BusConnectionData *d = NULL;
730 DBusError error;
731
732 d = dbus_new0 (BusConnectionData, 1);
733
734 if (d == NULL)
735 goto oom;
736
737 d->connections = connections;
738 d->connection = connection;
739
740 _dbus_get_monotonic_time (&d->connection_tv_sec,
741 &d->connection_tv_usec);
742
743 _dbus_assert (connection_data_slot >= 0);
744
745 if (!dbus_connection_set_data (connection,
746 connection_data_slot,
747 d, free_connection_data))
748 {
749 /* We have to free d explicitly, because this is the only code
750 * path where it's non-NULL but dbus_connection_set_data() hasn't
751 * taken responsibility for freeing it. */
752 dbus_free (d);
753 d = NULL;
754 goto oom;
755 }
756
757 dbus_connection_set_route_peer_messages (connection, TRUE);
758
759 dbus_error_init (&error);
760 d->selinux_id = bus_selinux_init_connection_id (connection,
761 &error);
762 if (dbus_error_is_set (&error))
763 {
764 bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
765 "Unable to set up new connection: %s", error.message);
766 dbus_error_free (&error);
767 goto error;
768 }
769
770 d->apparmor_confinement = bus_apparmor_init_connection_confinement (connection,
771 &error);
772 if (dbus_error_is_set (&error))
773 {
774 bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
775 "Unable to set up new connection: %s", error.message);
776 dbus_error_free (&error);
777 goto error;
778 }
779
780 if (!dbus_connection_set_watch_functions (connection,
781 add_connection_watch,
782 remove_connection_watch,
783 toggle_connection_watch,
784 connection,
785 NULL))
786 goto oom;
787
788 if (!dbus_connection_set_timeout_functions (connection,
789 add_connection_timeout,
790 remove_connection_timeout,
791 NULL,
792 connection, NULL))
793 goto oom;
794
795 /* For now we don't need to set a Windows user function because
796 * there are no policies in the config file controlling what
797 * Windows users can connect. The default 'same user that owns the
798 * bus can connect' behavior of DBusConnection is fine on Windows.
799 */
800 dbus_connection_set_unix_user_function (connection,
801 allow_unix_user_function,
802 NULL, NULL);
803
804 dbus_connection_set_dispatch_status_function (connection,
805 dispatch_status_function,
806 bus_context_get_loop (connections->context),
807 NULL);
808
809 d->link_in_connection_list = _dbus_list_alloc_link (connection);
810 if (d->link_in_connection_list == NULL)
811 goto oom;
812
813 /* Setup the connection with the dispatcher */
814 if (!bus_dispatch_add_connection (connection))
815 goto oom;
816
817 if (dbus_connection_get_dispatch_status (connection) != DBUS_DISPATCH_COMPLETE)
818 {
819 if (!_dbus_loop_queue_dispatch (bus_context_get_loop (connections->context), connection))
820 {
821 bus_dispatch_remove_connection (connection);
822 goto oom;
823 }
824 }
825
826 /* Setup pending fds timeout (see #80559) */
827 d->pending_unix_fds_timeout = _dbus_timeout_new (100, /* irrelevant */
828 pending_unix_fds_timeout_cb,
829 connection, NULL);
830 if (d->pending_unix_fds_timeout == NULL)
831 goto oom;
832
833 _dbus_timeout_disable (d->pending_unix_fds_timeout);
834 if (!_dbus_loop_add_timeout (bus_context_get_loop (connections->context),
835 d->pending_unix_fds_timeout))
836 goto oom;
837
838 _dbus_connection_set_pending_fds_function (connection,
839 (DBusPendingFdsChangeFunction) check_pending_fds_cb,
840 connection);
841
842 _dbus_list_append_link (&connections->incomplete, d->link_in_connection_list);
843 connections->n_incomplete += 1;
844
845 dbus_connection_ref (connection);
846
847 bus_connections_expire_incomplete (connections);
848
849 /* The listening socket is removed from the main loop,
850 * i.e. does not accept(), while n_incomplete is at its
851 * maximum value; so we shouldn't get here in that case */
852 _dbus_assert (connections->n_incomplete <=
853 bus_context_get_max_incomplete_connections (connections->context));
854
855 /* If we have the maximum number of incomplete connections,
856 * stop accept()ing any more, to avert a DoS. See fd.o #80919 */
857 bus_context_check_all_watches (d->connections->context);
858
859 return TRUE;
860
861 oom:
862 bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
863 "No memory to set up new connection");
864 /* fall through */
865 error:
866 if (d != NULL)
867 {
868 d->selinux_id = NULL;
869
870 if (d->apparmor_confinement)
871 bus_apparmor_confinement_unref (d->apparmor_confinement);
872 d->apparmor_confinement = NULL;
873
874 if (!dbus_connection_set_watch_functions (connection,
875 NULL, NULL, NULL,
876 connection,
877 NULL))
878 _dbus_assert_not_reached ("setting watch functions to NULL failed");
879
880 if (!dbus_connection_set_timeout_functions (connection,
881 NULL, NULL, NULL,
882 connection,
883 NULL))
884 _dbus_assert_not_reached ("setting timeout functions to NULL failed");
885
886 dbus_connection_set_unix_user_function (connection,
887 NULL, NULL, NULL);
888
889 dbus_connection_set_windows_user_function (connection,
890 NULL, NULL, NULL);
891
892 dbus_connection_set_dispatch_status_function (connection,
893 NULL, NULL, NULL);
894
895 if (d->pending_unix_fds_timeout)
896 _dbus_timeout_unref (d->pending_unix_fds_timeout);
897
898 d->pending_unix_fds_timeout = NULL;
899
900 _dbus_connection_set_pending_fds_function (connection, NULL, NULL);
901
902 if (d->link_in_connection_list != NULL)
903 {
904 _dbus_assert (d->link_in_connection_list->next == NULL);
905 _dbus_assert (d->link_in_connection_list->prev == NULL);
906 _dbus_list_free_link (d->link_in_connection_list);
907 d->link_in_connection_list = NULL;
908 }
909
910 if (!dbus_connection_set_data (connection,
911 connection_data_slot,
912 NULL, NULL))
913 _dbus_assert_not_reached ("failed to set connection data to null");
914
915 /* "d" has now been freed */
916 }
917
918 return FALSE;
919 }
920
921 void
bus_connections_expire_incomplete(BusConnections * connections)922 bus_connections_expire_incomplete (BusConnections *connections)
923 {
924 int next_interval;
925
926 next_interval = -1;
927
928 if (connections->incomplete != NULL)
929 {
930 long tv_sec, tv_usec;
931 DBusList *link;
932 int auth_timeout;
933
934 _dbus_get_monotonic_time (&tv_sec, &tv_usec);
935 auth_timeout = bus_context_get_auth_timeout (connections->context);
936
937 link = _dbus_list_get_first_link (&connections->incomplete);
938 while (link != NULL)
939 {
940 DBusList *next = _dbus_list_get_next_link (&connections->incomplete, link);
941 DBusConnection *connection;
942 BusConnectionData *d;
943 double elapsed;
944
945 connection = link->data;
946
947 d = BUS_CONNECTION_DATA (connection);
948
949 _dbus_assert (d != NULL);
950
951 elapsed = ELAPSED_MILLISECONDS_SINCE (d->connection_tv_sec,
952 d->connection_tv_usec,
953 tv_sec, tv_usec);
954
955 if (elapsed >= (double) auth_timeout)
956 {
957 /* Unfortunately, we can't identify the connection: it doesn't
958 * have a unique name yet, we don't know its uid/pid yet,
959 * and so on. */
960 bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
961 "Connection has not authenticated soon enough, closing it "
962 "(auth_timeout=%dms, elapsed: %.0fms)",
963 auth_timeout, elapsed);
964
965 _dbus_verbose ("Timing out authentication for connection %p\n", connection);
966 dbus_connection_close (connection);
967 }
968 else
969 {
970 /* We can end the loop, since the connections are in oldest-first order */
971 next_interval = ((double)auth_timeout) - elapsed;
972 _dbus_verbose ("Connection %p authentication expires in %d milliseconds\n",
973 connection, next_interval);
974
975 break;
976 }
977
978 link = next;
979 }
980 }
981
982 bus_expire_timeout_set_interval (connections->expire_timeout,
983 next_interval);
984 }
985
986 static dbus_bool_t
expire_incomplete_timeout(void * data)987 expire_incomplete_timeout (void *data)
988 {
989 BusConnections *connections = data;
990
991 _dbus_verbose ("Running\n");
992
993 /* note that this may remove the timeout */
994 bus_connections_expire_incomplete (connections);
995
996 return TRUE;
997 }
998
999 dbus_bool_t
bus_connection_get_unix_groups(DBusConnection * connection,unsigned long ** groups,int * n_groups,DBusError * error)1000 bus_connection_get_unix_groups (DBusConnection *connection,
1001 unsigned long **groups,
1002 int *n_groups,
1003 DBusError *error)
1004 {
1005 unsigned long uid;
1006
1007 *groups = NULL;
1008 *n_groups = 0;
1009
1010 if (dbus_connection_get_unix_user (connection, &uid))
1011 {
1012 if (!_dbus_unix_groups_from_uid (uid, groups, n_groups))
1013 {
1014 _dbus_verbose ("Did not get any groups for UID %lu\n",
1015 uid);
1016 return FALSE;
1017 }
1018 else
1019 {
1020 _dbus_verbose ("Got %d groups for UID %lu\n",
1021 *n_groups, uid);
1022 return TRUE;
1023 }
1024 }
1025 else
1026 return TRUE; /* successfully got 0 groups */
1027 }
1028
1029 dbus_bool_t
bus_connection_is_in_unix_group(DBusConnection * connection,unsigned long gid)1030 bus_connection_is_in_unix_group (DBusConnection *connection,
1031 unsigned long gid)
1032 {
1033 int i;
1034 unsigned long *group_ids;
1035 int n_group_ids;
1036
1037 if (!bus_connection_get_unix_groups (connection, &group_ids, &n_group_ids,
1038 NULL))
1039 return FALSE;
1040
1041 i = 0;
1042 while (i < n_group_ids)
1043 {
1044 if (group_ids[i] == gid)
1045 {
1046 dbus_free (group_ids);
1047 return TRUE;
1048 }
1049 ++i;
1050 }
1051
1052 dbus_free (group_ids);
1053 return FALSE;
1054 }
1055
1056 const char *
bus_connection_get_loginfo(DBusConnection * connection)1057 bus_connection_get_loginfo (DBusConnection *connection)
1058 {
1059 BusConnectionData *d;
1060
1061 d = BUS_CONNECTION_DATA (connection);
1062 _dbus_assert(d != NULL);
1063
1064 if (!bus_connection_is_active (connection))
1065 return "inactive";
1066 return d->cached_loginfo_string;
1067 }
1068
1069 BusClientPolicy*
bus_connection_get_policy(DBusConnection * connection)1070 bus_connection_get_policy (DBusConnection *connection)
1071 {
1072 BusConnectionData *d;
1073
1074 d = BUS_CONNECTION_DATA (connection);
1075
1076 _dbus_assert (d != NULL);
1077 _dbus_assert (d->policy != NULL);
1078
1079 return d->policy;
1080 }
1081
1082 static dbus_bool_t
foreach_active(BusConnections * connections,BusConnectionForeachFunction function,void * data)1083 foreach_active (BusConnections *connections,
1084 BusConnectionForeachFunction function,
1085 void *data)
1086 {
1087 DBusList *link;
1088
1089 link = _dbus_list_get_first_link (&connections->completed);
1090 while (link != NULL)
1091 {
1092 DBusConnection *connection = link->data;
1093 DBusList *next = _dbus_list_get_next_link (&connections->completed, link);
1094
1095 if (!(* function) (connection, data))
1096 return FALSE;
1097
1098 link = next;
1099 }
1100
1101 return TRUE;
1102 }
1103
1104 static dbus_bool_t
foreach_inactive(BusConnections * connections,BusConnectionForeachFunction function,void * data)1105 foreach_inactive (BusConnections *connections,
1106 BusConnectionForeachFunction function,
1107 void *data)
1108 {
1109 DBusList *link;
1110
1111 link = _dbus_list_get_first_link (&connections->incomplete);
1112 while (link != NULL)
1113 {
1114 DBusConnection *connection = link->data;
1115 DBusList *next = _dbus_list_get_next_link (&connections->incomplete, link);
1116
1117 if (!(* function) (connection, data))
1118 return FALSE;
1119
1120 link = next;
1121 }
1122
1123 return TRUE;
1124 }
1125
1126 /**
1127 * Calls function on each active connection; if the function returns
1128 * #FALSE, stops iterating. Active connections are authenticated
1129 * and have sent a Hello message.
1130 *
1131 * @param connections the connections object
1132 * @param function the function
1133 * @param data data to pass to it as a second arg
1134 */
1135 void
bus_connections_foreach_active(BusConnections * connections,BusConnectionForeachFunction function,void * data)1136 bus_connections_foreach_active (BusConnections *connections,
1137 BusConnectionForeachFunction function,
1138 void *data)
1139 {
1140 foreach_active (connections, function, data);
1141 }
1142
1143 /**
1144 * Calls function on each connection; if the function returns
1145 * #FALSE, stops iterating.
1146 *
1147 * @param connections the connections object
1148 * @param function the function
1149 * @param data data to pass to it as a second arg
1150 */
1151 void
bus_connections_foreach(BusConnections * connections,BusConnectionForeachFunction function,void * data)1152 bus_connections_foreach (BusConnections *connections,
1153 BusConnectionForeachFunction function,
1154 void *data)
1155 {
1156 if (!foreach_active (connections, function, data))
1157 return;
1158
1159 foreach_inactive (connections, function, data);
1160 }
1161
1162 BusContext*
bus_connections_get_context(BusConnections * connections)1163 bus_connections_get_context (BusConnections *connections)
1164 {
1165 return connections->context;
1166 }
1167
1168 /*
1169 * This is used to avoid covering the same connection twice when
1170 * traversing connections. Note that it assumes we will
1171 * bus_connection_mark_stamp() each connection at least once per
1172 * INT_MAX increments of the global stamp, or wraparound would break
1173 * things.
1174 */
1175 void
bus_connections_increment_stamp(BusConnections * connections)1176 bus_connections_increment_stamp (BusConnections *connections)
1177 {
1178 connections->stamp += 1;
1179 }
1180
1181 /* Mark connection with current stamp, return TRUE if it
1182 * didn't already have that stamp
1183 */
1184 dbus_bool_t
bus_connection_mark_stamp(DBusConnection * connection)1185 bus_connection_mark_stamp (DBusConnection *connection)
1186 {
1187 BusConnectionData *d;
1188
1189 d = BUS_CONNECTION_DATA (connection);
1190
1191 _dbus_assert (d != NULL);
1192
1193 if (d->stamp == d->connections->stamp)
1194 return FALSE;
1195 else
1196 {
1197 d->stamp = d->connections->stamp;
1198 return TRUE;
1199 }
1200 }
1201
1202 BusContext*
bus_connection_get_context(DBusConnection * connection)1203 bus_connection_get_context (DBusConnection *connection)
1204 {
1205 BusConnectionData *d;
1206
1207 d = BUS_CONNECTION_DATA (connection);
1208
1209 _dbus_assert (d != NULL);
1210
1211 return d->connections->context;
1212 }
1213
1214 BusConnections*
bus_connection_get_connections(DBusConnection * connection)1215 bus_connection_get_connections (DBusConnection *connection)
1216 {
1217 BusConnectionData *d;
1218
1219 d = BUS_CONNECTION_DATA (connection);
1220
1221 _dbus_assert (d != NULL);
1222
1223 return d->connections;
1224 }
1225
1226 BusRegistry*
bus_connection_get_registry(DBusConnection * connection)1227 bus_connection_get_registry (DBusConnection *connection)
1228 {
1229 BusConnectionData *d;
1230
1231 d = BUS_CONNECTION_DATA (connection);
1232
1233 _dbus_assert (d != NULL);
1234
1235 return bus_context_get_registry (d->connections->context);
1236 }
1237
1238 BusActivation*
bus_connection_get_activation(DBusConnection * connection)1239 bus_connection_get_activation (DBusConnection *connection)
1240 {
1241 BusConnectionData *d;
1242
1243 d = BUS_CONNECTION_DATA (connection);
1244
1245 _dbus_assert (d != NULL);
1246
1247 return bus_context_get_activation (d->connections->context);
1248 }
1249
1250 BusMatchmaker*
bus_connection_get_matchmaker(DBusConnection * connection)1251 bus_connection_get_matchmaker (DBusConnection *connection)
1252 {
1253 BusConnectionData *d;
1254
1255 d = BUS_CONNECTION_DATA (connection);
1256
1257 _dbus_assert (d != NULL);
1258
1259 return bus_context_get_matchmaker (d->connections->context);
1260 }
1261
1262 BusSELinuxID*
bus_connection_get_selinux_id(DBusConnection * connection)1263 bus_connection_get_selinux_id (DBusConnection *connection)
1264 {
1265 BusConnectionData *d;
1266
1267 d = BUS_CONNECTION_DATA (connection);
1268
1269 _dbus_assert (d != NULL);
1270
1271 return d->selinux_id;
1272 }
1273
1274 BusAppArmorConfinement*
bus_connection_dup_apparmor_confinement(DBusConnection * connection)1275 bus_connection_dup_apparmor_confinement (DBusConnection *connection)
1276 {
1277 BusConnectionData *d;
1278
1279 d = BUS_CONNECTION_DATA (connection);
1280
1281 _dbus_assert (d != NULL);
1282
1283 bus_apparmor_confinement_ref (d->apparmor_confinement);
1284 return d->apparmor_confinement;
1285 }
1286
1287 /**
1288 * Checks whether the connection is registered with the message bus.
1289 *
1290 * @param connection the connection
1291 * @returns #TRUE if we're an active message bus participant
1292 */
1293 dbus_bool_t
bus_connection_is_active(DBusConnection * connection)1294 bus_connection_is_active (DBusConnection *connection)
1295 {
1296 BusConnectionData *d;
1297
1298 d = BUS_CONNECTION_DATA (connection);
1299 _dbus_assert(d != NULL);
1300
1301 return d->name != NULL;
1302 }
1303
1304 dbus_bool_t
bus_connection_preallocate_oom_error(DBusConnection * connection)1305 bus_connection_preallocate_oom_error (DBusConnection *connection)
1306 {
1307 DBusMessage *message;
1308 DBusPreallocatedSend *preallocated;
1309 BusConnectionData *d;
1310
1311 d = BUS_CONNECTION_DATA (connection);
1312
1313 _dbus_assert (d != NULL);
1314
1315 if (d->oom_preallocated != NULL)
1316 return TRUE;
1317
1318 preallocated = dbus_connection_preallocate_send (connection);
1319 if (preallocated == NULL)
1320 return FALSE;
1321
1322 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
1323
1324 if (message == NULL)
1325 {
1326 dbus_connection_free_preallocated_send (connection, preallocated);
1327 return FALSE;
1328 }
1329
1330 /* d->name may be NULL, but that is OK */
1331 if (!dbus_message_set_error_name (message, DBUS_ERROR_NO_MEMORY) ||
1332 !dbus_message_set_destination (message, d->name) ||
1333 !dbus_message_set_sender (message,
1334 DBUS_SERVICE_DBUS))
1335 {
1336 dbus_connection_free_preallocated_send (connection, preallocated);
1337 dbus_message_unref (message);
1338 return FALSE;
1339 }
1340
1341 /* set reply serial to placeholder value just so space is already allocated
1342 * for it.
1343 */
1344 if (!dbus_message_set_reply_serial (message, 14))
1345 {
1346 dbus_connection_free_preallocated_send (connection, preallocated);
1347 dbus_message_unref (message);
1348 return FALSE;
1349 }
1350
1351 d->oom_message = message;
1352 d->oom_preallocated = preallocated;
1353
1354 return TRUE;
1355 }
1356
1357 void
bus_connection_send_oom_error(DBusConnection * connection,DBusMessage * in_reply_to)1358 bus_connection_send_oom_error (DBusConnection *connection,
1359 DBusMessage *in_reply_to)
1360 {
1361 BusConnectionData *d;
1362
1363 d = BUS_CONNECTION_DATA (connection);
1364
1365 _dbus_assert (d != NULL);
1366 _dbus_assert (d->oom_message != NULL);
1367
1368 bus_context_log (d->connections->context, DBUS_SYSTEM_LOG_WARNING,
1369 "dbus-daemon transaction failed (OOM), sending error to "
1370 "sender %s", bus_connection_get_loginfo (connection));
1371
1372 /* should always succeed since we set it to a placeholder earlier */
1373 if (!dbus_message_set_reply_serial (d->oom_message,
1374 dbus_message_get_serial (in_reply_to)))
1375 _dbus_assert_not_reached ("Failed to set reply serial for preallocated oom message");
1376
1377 _dbus_assert (dbus_message_get_sender (d->oom_message) != NULL);
1378
1379 dbus_connection_send_preallocated (connection, d->oom_preallocated,
1380 d->oom_message, NULL);
1381
1382 dbus_message_unref (d->oom_message);
1383 d->oom_message = NULL;
1384 d->oom_preallocated = NULL;
1385 }
1386
1387 #ifdef DBUS_ENABLE_STATS
1388 static void
update_peak(int * peak,int n)1389 update_peak (int *peak,
1390 int n)
1391 {
1392 if (*peak < n)
1393 *peak = n;
1394 }
1395 #endif
1396
1397 void
bus_connection_add_match_rule_link(DBusConnection * connection,DBusList * link)1398 bus_connection_add_match_rule_link (DBusConnection *connection,
1399 DBusList *link)
1400 {
1401 BusConnectionData *d;
1402
1403 d = BUS_CONNECTION_DATA (connection);
1404 _dbus_assert (d != NULL);
1405
1406 _dbus_list_append_link (&d->match_rules, link);
1407
1408 d->n_match_rules += 1;
1409
1410 #ifdef DBUS_ENABLE_STATS
1411 update_peak (&d->peak_match_rules, d->n_match_rules);
1412 update_peak (&d->connections->peak_match_rules_per_conn, d->n_match_rules);
1413
1414 d->connections->total_match_rules += 1;
1415 update_peak (&d->connections->peak_match_rules,
1416 d->connections->total_match_rules);
1417 #endif
1418 }
1419
1420 dbus_bool_t
bus_connection_add_match_rule(DBusConnection * connection,BusMatchRule * rule)1421 bus_connection_add_match_rule (DBusConnection *connection,
1422 BusMatchRule *rule)
1423 {
1424 DBusList *link;
1425
1426 link = _dbus_list_alloc_link (rule);
1427
1428 if (link == NULL)
1429 return FALSE;
1430
1431 bus_connection_add_match_rule_link (connection, link);
1432
1433 return TRUE;
1434 }
1435
1436 void
bus_connection_remove_match_rule(DBusConnection * connection,BusMatchRule * rule)1437 bus_connection_remove_match_rule (DBusConnection *connection,
1438 BusMatchRule *rule)
1439 {
1440 BusConnectionData *d;
1441
1442 d = BUS_CONNECTION_DATA (connection);
1443 _dbus_assert (d != NULL);
1444
1445 _dbus_list_remove_last (&d->match_rules, rule);
1446
1447 d->n_match_rules -= 1;
1448 _dbus_assert (d->n_match_rules >= 0);
1449
1450 #ifdef DBUS_ENABLE_STATS
1451 d->connections->total_match_rules -= 1;
1452 #endif
1453 }
1454
1455 int
bus_connection_get_n_match_rules(DBusConnection * connection)1456 bus_connection_get_n_match_rules (DBusConnection *connection)
1457 {
1458 BusConnectionData *d;
1459
1460 d = BUS_CONNECTION_DATA (connection);
1461 _dbus_assert (d != NULL);
1462
1463 return d->n_match_rules;
1464 }
1465
1466 void
bus_connection_add_owned_service_link(DBusConnection * connection,DBusList * link)1467 bus_connection_add_owned_service_link (DBusConnection *connection,
1468 DBusList *link)
1469 {
1470 BusConnectionData *d;
1471
1472 d = BUS_CONNECTION_DATA (connection);
1473 _dbus_assert (d != NULL);
1474
1475 _dbus_list_append_link (&d->services_owned, link);
1476
1477 d->n_services_owned += 1;
1478
1479 #ifdef DBUS_ENABLE_STATS
1480 update_peak (&d->peak_bus_names, d->n_services_owned);
1481 update_peak (&d->connections->peak_bus_names_per_conn,
1482 d->n_services_owned);
1483
1484 d->connections->total_bus_names += 1;
1485 update_peak (&d->connections->peak_bus_names,
1486 d->connections->total_bus_names);
1487 #endif
1488 }
1489
1490 dbus_bool_t
bus_connection_add_owned_service(DBusConnection * connection,BusService * service)1491 bus_connection_add_owned_service (DBusConnection *connection,
1492 BusService *service)
1493 {
1494 DBusList *link;
1495
1496 link = _dbus_list_alloc_link (service);
1497
1498 if (link == NULL)
1499 return FALSE;
1500
1501 bus_connection_add_owned_service_link (connection, link);
1502
1503 return TRUE;
1504 }
1505
1506 void
bus_connection_remove_owned_service(DBusConnection * connection,BusService * service)1507 bus_connection_remove_owned_service (DBusConnection *connection,
1508 BusService *service)
1509 {
1510 BusConnectionData *d;
1511
1512 d = BUS_CONNECTION_DATA (connection);
1513 _dbus_assert (d != NULL);
1514
1515 _dbus_list_remove_last (&d->services_owned, service);
1516
1517 d->n_services_owned -= 1;
1518 _dbus_assert (d->n_services_owned >= 0);
1519
1520 #ifdef DBUS_ENABLE_STATS
1521 d->connections->total_bus_names -= 1;
1522 #endif
1523 }
1524
1525 int
bus_connection_get_n_services_owned(DBusConnection * connection)1526 bus_connection_get_n_services_owned (DBusConnection *connection)
1527 {
1528 BusConnectionData *d;
1529
1530 d = BUS_CONNECTION_DATA (connection);
1531 _dbus_assert (d != NULL);
1532
1533 return d->n_services_owned;
1534 }
1535
1536 dbus_bool_t
bus_connection_complete(DBusConnection * connection,const DBusString * name,DBusError * error)1537 bus_connection_complete (DBusConnection *connection,
1538 const DBusString *name,
1539 DBusError *error)
1540 {
1541 BusConnectionData *d;
1542 unsigned long uid;
1543
1544 d = BUS_CONNECTION_DATA (connection);
1545 _dbus_assert (d != NULL);
1546 _dbus_assert (d->name == NULL);
1547 _dbus_assert (d->policy == NULL);
1548
1549 _dbus_assert (!bus_connection_is_active (connection));
1550
1551 if (!_dbus_string_copy_data (name, &d->name))
1552 {
1553 BUS_SET_OOM (error);
1554 return FALSE;
1555 }
1556
1557 _dbus_assert (d->name != NULL);
1558
1559 _dbus_verbose ("Name %s assigned to %p\n", d->name, connection);
1560
1561 d->policy = bus_context_create_client_policy (d->connections->context,
1562 connection,
1563 error);
1564
1565 /* we may have a NULL policy on OOM or error getting list of
1566 * groups for a user. In the latter case we don't handle it so
1567 * well currently, as it will just keep failing over and over.
1568 */
1569
1570 if (d->policy == NULL)
1571 {
1572 _dbus_verbose ("Failed to create security policy for connection %p\n",
1573 connection);
1574 _DBUS_ASSERT_ERROR_IS_SET (error);
1575 dbus_free (d->name);
1576 d->name = NULL;
1577 return FALSE;
1578 }
1579
1580 if (dbus_connection_get_unix_user (connection, &uid))
1581 {
1582 if (!adjust_connections_for_uid (d->connections,
1583 uid, 1))
1584 goto fail;
1585 }
1586
1587 /* Create and cache a string which holds information about the
1588 * peer process; used for logging purposes.
1589 */
1590 if (!cache_peer_loginfo_string (d, connection))
1591 goto fail;
1592
1593 /* Now the connection is active, move it between lists */
1594 _dbus_list_unlink (&d->connections->incomplete,
1595 d->link_in_connection_list);
1596 d->connections->n_incomplete -= 1;
1597 _dbus_list_append_link (&d->connections->completed,
1598 d->link_in_connection_list);
1599 d->connections->n_completed += 1;
1600
1601 _dbus_assert (d->connections->n_incomplete >= 0);
1602 _dbus_assert (d->connections->n_completed > 0);
1603
1604 /* If we have dropped below the max. number of incomplete
1605 * connections, start accept()ing again */
1606 bus_context_check_all_watches (d->connections->context);
1607
1608 /* See if we can remove the timeout */
1609 bus_connections_expire_incomplete (d->connections);
1610
1611 _dbus_assert (bus_connection_is_active (connection));
1612
1613 return TRUE;
1614 fail:
1615 BUS_SET_OOM (error);
1616 dbus_free (d->name);
1617 d->name = NULL;
1618 if (d->policy)
1619 bus_client_policy_unref (d->policy);
1620 d->policy = NULL;
1621 return FALSE;
1622 }
1623
1624 dbus_bool_t
bus_connections_reload_policy(BusConnections * connections,DBusError * error)1625 bus_connections_reload_policy (BusConnections *connections,
1626 DBusError *error)
1627 {
1628 BusConnectionData *d;
1629 DBusConnection *connection;
1630 DBusList *link;
1631
1632 _dbus_assert (connections != NULL);
1633 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
1634
1635 for (link = _dbus_list_get_first_link (&(connections->completed));
1636 link;
1637 link = _dbus_list_get_next_link (&(connections->completed), link))
1638 {
1639 connection = link->data;
1640 d = BUS_CONNECTION_DATA (connection);
1641 _dbus_assert (d != NULL);
1642 _dbus_assert (d->policy != NULL);
1643
1644 bus_client_policy_unref (d->policy);
1645 d->policy = bus_context_create_client_policy (connections->context,
1646 connection,
1647 error);
1648 if (d->policy == NULL)
1649 {
1650 _dbus_verbose ("Failed to create security policy for connection %p\n",
1651 connection);
1652 _DBUS_ASSERT_ERROR_IS_SET (error);
1653 return FALSE;
1654 }
1655 }
1656
1657 return TRUE;
1658 }
1659
1660 const char *
bus_connection_get_name(DBusConnection * connection)1661 bus_connection_get_name (DBusConnection *connection)
1662 {
1663 BusConnectionData *d;
1664
1665 d = BUS_CONNECTION_DATA (connection);
1666 _dbus_assert (d != NULL);
1667
1668 return d->name;
1669 }
1670
1671 /**
1672 * Check whether completing the passed-in connection would
1673 * exceed limits, and if so set error and return #FALSE
1674 */
1675 dbus_bool_t
bus_connections_check_limits(BusConnections * connections,DBusConnection * requesting_completion,const char ** limit_name_out,int * limit_out,DBusError * error)1676 bus_connections_check_limits (BusConnections *connections,
1677 DBusConnection *requesting_completion,
1678 const char **limit_name_out,
1679 int *limit_out,
1680 DBusError *error)
1681 {
1682 unsigned long uid;
1683 int limit;
1684
1685 limit = bus_context_get_max_completed_connections (connections->context);
1686
1687 if (connections->n_completed >= limit)
1688 {
1689 if (limit_name_out != NULL)
1690 *limit_name_out = "max_completed_connections";
1691
1692 if (limit_out != NULL)
1693 *limit_out = limit;
1694
1695 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
1696 "The maximum number of active connections has been reached");
1697 return FALSE;
1698 }
1699
1700 if (dbus_connection_get_unix_user (requesting_completion, &uid))
1701 {
1702 limit = bus_context_get_max_connections_per_user (connections->context);
1703
1704 if (get_connections_for_uid (connections, uid) >= limit)
1705 {
1706 if (limit_name_out != NULL)
1707 *limit_name_out = "max_connections_per_user";
1708
1709 if (limit_out != NULL)
1710 *limit_out = limit;
1711
1712 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
1713 "The maximum number of active connections for UID %lu has been reached",
1714 uid);
1715 return FALSE;
1716 }
1717 }
1718
1719 return TRUE;
1720 }
1721
1722 static void
bus_pending_reply_free(BusPendingReply * pending)1723 bus_pending_reply_free (BusPendingReply *pending)
1724 {
1725 _dbus_verbose ("Freeing pending reply %p, replier %p receiver %p serial %u\n",
1726 pending,
1727 pending->will_send_reply,
1728 pending->will_get_reply,
1729 pending->reply_serial);
1730
1731 dbus_free (pending);
1732 }
1733
1734 static dbus_bool_t
bus_pending_reply_send_no_reply(BusConnections * connections,BusTransaction * transaction,BusPendingReply * pending)1735 bus_pending_reply_send_no_reply (BusConnections *connections,
1736 BusTransaction *transaction,
1737 BusPendingReply *pending)
1738 {
1739 DBusMessage *message;
1740 DBusMessageIter iter;
1741 dbus_bool_t retval;
1742 const char *errmsg;
1743
1744 retval = FALSE;
1745
1746 message = dbus_message_new (DBUS_MESSAGE_TYPE_ERROR);
1747 if (message == NULL)
1748 return FALSE;
1749
1750 dbus_message_set_no_reply (message, TRUE);
1751
1752 if (!dbus_message_set_reply_serial (message,
1753 pending->reply_serial))
1754 goto out;
1755
1756 if (!dbus_message_set_error_name (message,
1757 DBUS_ERROR_NO_REPLY))
1758 goto out;
1759
1760 /* If you change these messages, adjust test/dbus-daemon.c to match */
1761 if (pending->will_send_reply == NULL)
1762 errmsg = "Message recipient disconnected from message bus without replying";
1763 else
1764 errmsg = "Message did not receive a reply (timeout by message bus)";
1765
1766 dbus_message_iter_init_append (message, &iter);
1767 if (!dbus_message_iter_append_basic (&iter, DBUS_TYPE_STRING, &errmsg))
1768 goto out;
1769
1770 if (!bus_transaction_send_from_driver (transaction, pending->will_get_reply,
1771 message))
1772 goto out;
1773
1774 retval = TRUE;
1775
1776 out:
1777 dbus_message_unref (message);
1778 return retval;
1779 }
1780
1781 static dbus_bool_t
bus_pending_reply_expired(BusExpireList * list,DBusList * link,void * data)1782 bus_pending_reply_expired (BusExpireList *list,
1783 DBusList *link,
1784 void *data)
1785 {
1786 BusPendingReply *pending = link->data;
1787 BusConnections *connections = data;
1788 BusTransaction *transaction;
1789
1790 /* No reply is forthcoming. So nuke it if we can. If not,
1791 * leave it in the list to try expiring again later when we
1792 * get more memory.
1793 */
1794
1795 _dbus_verbose ("Expiring pending reply %p, replier %p receiver %p serial %u\n",
1796 pending,
1797 pending->will_send_reply,
1798 pending->will_get_reply,
1799 pending->reply_serial);
1800
1801 transaction = bus_transaction_new (connections->context);
1802 if (transaction == NULL)
1803 return FALSE;
1804
1805 if (!bus_pending_reply_send_no_reply (connections,
1806 transaction,
1807 pending))
1808 {
1809 bus_transaction_cancel_and_free (transaction);
1810 return FALSE;
1811 }
1812
1813 bus_expire_list_remove_link (connections->pending_replies, link);
1814
1815 bus_pending_reply_free (pending);
1816 bus_transaction_execute_and_free (transaction);
1817
1818 return TRUE;
1819 }
1820
1821 static void
bus_connection_drop_pending_replies(BusConnections * connections,DBusConnection * connection)1822 bus_connection_drop_pending_replies (BusConnections *connections,
1823 DBusConnection *connection)
1824 {
1825 /* The DBusConnection is almost 100% finalized here, so you can't
1826 * do anything with it except check for pointer equality
1827 */
1828 DBusList *link;
1829
1830 _dbus_verbose ("Dropping pending replies that involve connection %p\n",
1831 connection);
1832
1833 link = bus_expire_list_get_first_link (connections->pending_replies);
1834 while (link != NULL)
1835 {
1836 DBusList *next;
1837 BusPendingReply *pending;
1838
1839 next = bus_expire_list_get_next_link (connections->pending_replies,
1840 link);
1841 pending = link->data;
1842
1843 if (pending->will_get_reply == connection)
1844 {
1845 /* We don't need to track this pending reply anymore */
1846
1847 _dbus_verbose ("Dropping pending reply %p, replier %p receiver %p serial %u\n",
1848 pending,
1849 pending->will_send_reply,
1850 pending->will_get_reply,
1851 pending->reply_serial);
1852
1853 bus_expire_list_remove_link (connections->pending_replies,
1854 link);
1855 bus_pending_reply_free (pending);
1856 }
1857 else if (pending->will_send_reply == connection)
1858 {
1859 /* The reply isn't going to be sent, so set things
1860 * up so it will be expired right away
1861 */
1862 _dbus_verbose ("Will expire pending reply %p, replier %p receiver %p serial %u\n",
1863 pending,
1864 pending->will_send_reply,
1865 pending->will_get_reply,
1866 pending->reply_serial);
1867
1868 pending->will_send_reply = NULL;
1869 pending->expire_item.added_tv_sec = 0;
1870 pending->expire_item.added_tv_usec = 0;
1871
1872 bus_expire_list_recheck_immediately (connections->pending_replies);
1873 }
1874
1875 link = next;
1876 }
1877 }
1878
1879
1880 typedef struct
1881 {
1882 BusPendingReply *pending;
1883 BusConnections *connections;
1884 } CancelPendingReplyData;
1885
1886 static void
cancel_pending_reply(void * data)1887 cancel_pending_reply (void *data)
1888 {
1889 CancelPendingReplyData *d = data;
1890
1891 _dbus_verbose ("d = %p\n", d);
1892
1893 if (!bus_expire_list_remove (d->connections->pending_replies,
1894 &d->pending->expire_item))
1895 _dbus_assert_not_reached ("pending reply did not exist to be cancelled");
1896
1897 bus_pending_reply_free (d->pending); /* since it's been cancelled */
1898 }
1899
1900 static void
cancel_pending_reply_data_free(void * data)1901 cancel_pending_reply_data_free (void *data)
1902 {
1903 CancelPendingReplyData *d = data;
1904
1905 _dbus_verbose ("d = %p\n", d);
1906
1907 /* d->pending should be either freed or still
1908 * in the list of pending replies (owned by someone
1909 * else)
1910 */
1911
1912 dbus_free (d);
1913 }
1914
1915 /*
1916 * Record that a reply is allowed; return TRUE on success.
1917 */
1918 dbus_bool_t
bus_connections_expect_reply(BusConnections * connections,BusTransaction * transaction,DBusConnection * will_get_reply,DBusConnection * will_send_reply,DBusMessage * reply_to_this,DBusError * error)1919 bus_connections_expect_reply (BusConnections *connections,
1920 BusTransaction *transaction,
1921 DBusConnection *will_get_reply,
1922 DBusConnection *will_send_reply,
1923 DBusMessage *reply_to_this,
1924 DBusError *error)
1925 {
1926 BusPendingReply *pending;
1927 dbus_uint32_t reply_serial;
1928 DBusList *link;
1929 CancelPendingReplyData *cprd;
1930 int count;
1931 int limit;
1932
1933 _dbus_assert (will_get_reply != NULL);
1934 _dbus_assert (will_send_reply != NULL);
1935 _dbus_assert (reply_to_this != NULL);
1936
1937 if (dbus_message_get_no_reply (reply_to_this))
1938 return TRUE; /* we won't allow a reply, since client doesn't care for one. */
1939
1940 reply_serial = dbus_message_get_serial (reply_to_this);
1941
1942 link = bus_expire_list_get_first_link (connections->pending_replies);
1943 count = 0;
1944 while (link != NULL)
1945 {
1946 pending = link->data;
1947
1948 if (pending->reply_serial == reply_serial &&
1949 pending->will_get_reply == will_get_reply &&
1950 pending->will_send_reply == will_send_reply)
1951 {
1952 dbus_set_error (error, DBUS_ERROR_ACCESS_DENIED,
1953 "Message has the same reply serial as a currently-outstanding existing method call");
1954 return FALSE;
1955 }
1956
1957 link = bus_expire_list_get_next_link (connections->pending_replies,
1958 link);
1959 if (pending->will_get_reply == will_get_reply)
1960 ++count;
1961 }
1962
1963 limit = bus_context_get_max_replies_per_connection (connections->context);
1964
1965 if (count >= limit)
1966 {
1967 bus_context_log (connections->context, DBUS_SYSTEM_LOG_WARNING,
1968 "The maximum number of pending replies for "
1969 "\"%s\" (%s) has been reached "
1970 "(max_replies_per_connection=%d)",
1971 bus_connection_get_name (will_get_reply),
1972 bus_connection_get_loginfo (will_get_reply),
1973 limit);
1974
1975 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED,
1976 "The maximum number of pending replies per connection has been reached");
1977 return FALSE;
1978 }
1979
1980 pending = dbus_new0 (BusPendingReply, 1);
1981 if (pending == NULL)
1982 {
1983 BUS_SET_OOM (error);
1984 return FALSE;
1985 }
1986
1987 #ifdef DBUS_ENABLE_VERBOSE_MODE
1988 /* so we can see a not-yet-added pending reply */
1989 pending->expire_item.added_tv_sec = 1;
1990 pending->expire_item.added_tv_usec = 1;
1991 #endif
1992
1993 pending->will_get_reply = will_get_reply;
1994 pending->will_send_reply = will_send_reply;
1995 pending->reply_serial = reply_serial;
1996
1997 cprd = dbus_new0 (CancelPendingReplyData, 1);
1998 if (cprd == NULL)
1999 {
2000 BUS_SET_OOM (error);
2001 bus_pending_reply_free (pending);
2002 return FALSE;
2003 }
2004
2005 if (!bus_expire_list_add (connections->pending_replies,
2006 &pending->expire_item))
2007 {
2008 BUS_SET_OOM (error);
2009 dbus_free (cprd);
2010 bus_pending_reply_free (pending);
2011 return FALSE;
2012 }
2013
2014 if (!bus_transaction_add_cancel_hook (transaction,
2015 cancel_pending_reply,
2016 cprd,
2017 cancel_pending_reply_data_free))
2018 {
2019 BUS_SET_OOM (error);
2020 bus_expire_list_remove (connections->pending_replies, &pending->expire_item);
2021 dbus_free (cprd);
2022 bus_pending_reply_free (pending);
2023 return FALSE;
2024 }
2025
2026 cprd->pending = pending;
2027 cprd->connections = connections;
2028
2029 _dbus_get_monotonic_time (&pending->expire_item.added_tv_sec,
2030 &pending->expire_item.added_tv_usec);
2031
2032 _dbus_verbose ("Added pending reply %p, replier %p receiver %p serial %u\n",
2033 pending,
2034 pending->will_send_reply,
2035 pending->will_get_reply,
2036 pending->reply_serial);
2037
2038 return TRUE;
2039 }
2040
2041 typedef struct
2042 {
2043 DBusList *link;
2044 BusConnections *connections;
2045 } CheckPendingReplyData;
2046
2047 static void
cancel_check_pending_reply(void * data)2048 cancel_check_pending_reply (void *data)
2049 {
2050 CheckPendingReplyData *d = data;
2051
2052 _dbus_verbose ("d = %p\n",d);
2053
2054 bus_expire_list_add_link (d->connections->pending_replies,
2055 d->link);
2056 d->link = NULL;
2057 }
2058
2059 static void
check_pending_reply_data_free(void * data)2060 check_pending_reply_data_free (void *data)
2061 {
2062 CheckPendingReplyData *d = data;
2063
2064 _dbus_verbose ("d = %p\n",d);
2065
2066 if (d->link != NULL)
2067 {
2068 BusPendingReply *pending = d->link->data;
2069
2070 _dbus_assert (!bus_expire_list_contains_item (d->connections->pending_replies,
2071 &pending->expire_item));
2072
2073 bus_pending_reply_free (pending);
2074 _dbus_list_free_link (d->link);
2075 }
2076
2077 dbus_free (d);
2078 }
2079
2080 /*
2081 * Check whether a reply is allowed, remove BusPendingReply
2082 * if so, return TRUE if so.
2083 */
2084 dbus_bool_t
bus_connections_check_reply(BusConnections * connections,BusTransaction * transaction,DBusConnection * sending_reply,DBusConnection * receiving_reply,DBusMessage * reply,DBusError * error)2085 bus_connections_check_reply (BusConnections *connections,
2086 BusTransaction *transaction,
2087 DBusConnection *sending_reply,
2088 DBusConnection *receiving_reply,
2089 DBusMessage *reply,
2090 DBusError *error)
2091 {
2092 CheckPendingReplyData *cprd;
2093 DBusList *link;
2094 dbus_uint32_t reply_serial;
2095
2096 _dbus_assert (sending_reply != NULL);
2097 _dbus_assert (receiving_reply != NULL);
2098
2099 reply_serial = dbus_message_get_reply_serial (reply);
2100
2101 link = bus_expire_list_get_first_link (connections->pending_replies);
2102 while (link != NULL)
2103 {
2104 BusPendingReply *pending = link->data;
2105
2106 if (pending->reply_serial == reply_serial &&
2107 pending->will_get_reply == receiving_reply &&
2108 pending->will_send_reply == sending_reply)
2109 {
2110 _dbus_verbose ("Found pending reply with serial %u\n", reply_serial);
2111 break;
2112 }
2113
2114 link = bus_expire_list_get_next_link (connections->pending_replies,
2115 link);
2116 }
2117
2118 if (link == NULL)
2119 {
2120 _dbus_verbose ("No pending reply expected\n");
2121
2122 return FALSE;
2123 }
2124
2125 cprd = dbus_new0 (CheckPendingReplyData, 1);
2126 if (cprd == NULL)
2127 {
2128 BUS_SET_OOM (error);
2129 return FALSE;
2130 }
2131
2132 if (!bus_transaction_add_cancel_hook (transaction,
2133 cancel_check_pending_reply,
2134 cprd,
2135 check_pending_reply_data_free))
2136 {
2137 BUS_SET_OOM (error);
2138 dbus_free (cprd);
2139 return FALSE;
2140 }
2141
2142 cprd->link = link;
2143 cprd->connections = connections;
2144
2145 bus_expire_list_unlink (connections->pending_replies,
2146 link);
2147
2148 _dbus_assert (!bus_expire_list_contains_item (connections->pending_replies, link->data));
2149
2150 return TRUE;
2151 }
2152
2153 /*
2154 * Transactions
2155 *
2156 * Note that this is fairly fragile; in particular, don't try to use
2157 * one transaction across any main loop iterations.
2158 */
2159
2160 typedef struct
2161 {
2162 BusTransaction *transaction;
2163 DBusMessage *message;
2164 DBusPreallocatedSend *preallocated;
2165 } MessageToSend;
2166
2167 typedef struct
2168 {
2169 BusTransactionCancelFunction cancel_function;
2170 DBusFreeFunction free_data_function;
2171 void *data;
2172 } CancelHook;
2173
2174 struct BusTransaction
2175 {
2176 DBusList *connections;
2177 BusContext *context;
2178 DBusList *cancel_hooks;
2179 };
2180
2181 static void
message_to_send_free(DBusConnection * connection,MessageToSend * to_send)2182 message_to_send_free (DBusConnection *connection,
2183 MessageToSend *to_send)
2184 {
2185 if (to_send->message)
2186 dbus_message_unref (to_send->message);
2187
2188 if (to_send->preallocated)
2189 dbus_connection_free_preallocated_send (connection, to_send->preallocated);
2190
2191 dbus_free (to_send);
2192 }
2193
2194 static void
cancel_hook_cancel(void * element,void * data)2195 cancel_hook_cancel (void *element,
2196 void *data)
2197 {
2198 CancelHook *ch = element;
2199
2200 _dbus_verbose ("Running transaction cancel hook\n");
2201
2202 if (ch->cancel_function)
2203 (* ch->cancel_function) (ch->data);
2204 }
2205
2206 static void
cancel_hook_free(void * element,void * data)2207 cancel_hook_free (void *element,
2208 void *data)
2209 {
2210 CancelHook *ch = element;
2211
2212 if (ch->free_data_function)
2213 (* ch->free_data_function) (ch->data);
2214
2215 dbus_free (ch);
2216 }
2217
2218 static void
free_cancel_hooks(BusTransaction * transaction)2219 free_cancel_hooks (BusTransaction *transaction)
2220 {
2221 _dbus_list_foreach (&transaction->cancel_hooks,
2222 cancel_hook_free, NULL);
2223
2224 _dbus_list_clear (&transaction->cancel_hooks);
2225 }
2226
2227 BusTransaction*
bus_transaction_new(BusContext * context)2228 bus_transaction_new (BusContext *context)
2229 {
2230 BusTransaction *transaction;
2231
2232 transaction = dbus_new0 (BusTransaction, 1);
2233 if (transaction == NULL)
2234 return NULL;
2235
2236 transaction->context = context;
2237
2238 return transaction;
2239 }
2240
2241 BusContext*
bus_transaction_get_context(BusTransaction * transaction)2242 bus_transaction_get_context (BusTransaction *transaction)
2243 {
2244 return transaction->context;
2245 }
2246
2247 /**
2248 * Reserve enough memory to capture the given message if the
2249 * transaction goes through.
2250 */
2251 dbus_bool_t
bus_transaction_capture(BusTransaction * transaction,DBusConnection * sender,DBusConnection * addressed_recipient,DBusMessage * message)2252 bus_transaction_capture (BusTransaction *transaction,
2253 DBusConnection *sender,
2254 DBusConnection *addressed_recipient,
2255 DBusMessage *message)
2256 {
2257 BusConnections *connections;
2258 BusMatchmaker *mm;
2259 DBusList *link;
2260 DBusList *recipients = NULL;
2261 dbus_bool_t ret = FALSE;
2262
2263 connections = bus_context_get_connections (transaction->context);
2264
2265 /* shortcut: don't compose the message unless someone wants it */
2266 if (connections->monitors == NULL)
2267 return TRUE;
2268
2269 mm = connections->monitor_matchmaker;
2270 /* This is non-null if there has ever been a monitor - we don't GC it.
2271 * There's little point, since there is up to 1 per process. */
2272 _dbus_assert (mm != NULL);
2273
2274 if (!bus_matchmaker_get_recipients (mm, connections, sender,
2275 addressed_recipient, message, &recipients))
2276 goto out;
2277
2278 for (link = _dbus_list_get_first_link (&recipients);
2279 link != NULL;
2280 link = _dbus_list_get_next_link (&recipients, link))
2281 {
2282 DBusConnection *recipient = link->data;
2283
2284 if (!bus_transaction_send (transaction, recipient, message))
2285 goto out;
2286 }
2287
2288 ret = TRUE;
2289
2290 out:
2291 _dbus_list_clear (&recipients);
2292 return ret;
2293 }
2294
2295 dbus_bool_t
bus_transaction_capture_error_reply(BusTransaction * transaction,DBusConnection * addressed_recipient,const DBusError * error,DBusMessage * in_reply_to)2296 bus_transaction_capture_error_reply (BusTransaction *transaction,
2297 DBusConnection *addressed_recipient,
2298 const DBusError *error,
2299 DBusMessage *in_reply_to)
2300 {
2301 BusConnections *connections;
2302 DBusMessage *reply;
2303 dbus_bool_t ret = FALSE;
2304
2305 _dbus_assert (error != NULL);
2306 _DBUS_ASSERT_ERROR_IS_SET (error);
2307
2308 connections = bus_context_get_connections (transaction->context);
2309
2310 /* shortcut: don't compose the message unless someone wants it */
2311 if (connections->monitors == NULL)
2312 return TRUE;
2313
2314 reply = dbus_message_new_error (in_reply_to,
2315 error->name,
2316 error->message);
2317
2318 if (reply == NULL)
2319 return FALSE;
2320
2321 if (!dbus_message_set_sender (reply, DBUS_SERVICE_DBUS))
2322 goto out;
2323
2324 ret = bus_transaction_capture (transaction, NULL, addressed_recipient, reply);
2325
2326 out:
2327 dbus_message_unref (reply);
2328 return ret;
2329 }
2330
2331 dbus_bool_t
bus_transaction_send_from_driver(BusTransaction * transaction,DBusConnection * connection,DBusMessage * message)2332 bus_transaction_send_from_driver (BusTransaction *transaction,
2333 DBusConnection *connection,
2334 DBusMessage *message)
2335 {
2336 DBusError error = DBUS_ERROR_INIT;
2337
2338 /* We have to set the sender to the driver, and have
2339 * to check security policy since it was not done in
2340 * dispatch.c
2341 */
2342 _dbus_verbose ("Sending %s %s %s from driver\n",
2343 dbus_message_get_interface (message) ?
2344 dbus_message_get_interface (message) : "(no interface)",
2345 dbus_message_get_member (message) ?
2346 dbus_message_get_member (message) : "(no member)",
2347 dbus_message_get_error_name (message) ?
2348 dbus_message_get_error_name (message) : "(no error name)");
2349
2350 if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS))
2351 return FALSE;
2352
2353 if (bus_connection_is_active (connection))
2354 {
2355 if (!dbus_message_set_destination (message,
2356 bus_connection_get_name (connection)))
2357 return FALSE;
2358 }
2359
2360 /* bus driver never wants a reply */
2361 dbus_message_set_no_reply (message, TRUE);
2362
2363 /* Capture it for monitors, even if the real recipient's receive policy
2364 * does not allow it to receive this message from us (which would be odd).
2365 */
2366 if (!bus_transaction_capture (transaction, NULL, connection, message))
2367 return FALSE;
2368
2369 /* If security policy doesn't allow the message, we would silently
2370 * eat it; the driver doesn't care about getting a reply. However,
2371 * if we're actively capturing messages, it's nice to log that we
2372 * tried to send it and did not allow ourselves to do so.
2373 */
2374 if (!bus_context_check_security_policy (bus_transaction_get_context (transaction),
2375 transaction,
2376 NULL, connection, connection,
2377 message, NULL, &error))
2378 {
2379 if (!bus_transaction_capture_error_reply (transaction, connection,
2380 &error, message))
2381 {
2382 bus_context_log (transaction->context, DBUS_SYSTEM_LOG_WARNING,
2383 "message from dbus-daemon rejected but not enough "
2384 "memory to capture it");
2385 }
2386
2387 /* This is not fatal to the transaction so silently eat the disallowed
2388 * message (see reasoning above) */
2389 dbus_error_free (&error);
2390 return TRUE;
2391 }
2392
2393 return bus_transaction_send (transaction, connection, message);
2394 }
2395
2396 dbus_bool_t
bus_transaction_send(BusTransaction * transaction,DBusConnection * connection,DBusMessage * message)2397 bus_transaction_send (BusTransaction *transaction,
2398 DBusConnection *connection,
2399 DBusMessage *message)
2400 {
2401 MessageToSend *to_send;
2402 BusConnectionData *d;
2403 DBusList *link;
2404
2405 _dbus_verbose (" trying to add %s interface=%s member=%s error=%s to transaction%s\n",
2406 dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_ERROR ? "error" :
2407 dbus_message_get_reply_serial (message) != 0 ? "reply" :
2408 "message",
2409 dbus_message_get_interface (message) ?
2410 dbus_message_get_interface (message) : "(unset)",
2411 dbus_message_get_member (message) ?
2412 dbus_message_get_member (message) : "(unset)",
2413 dbus_message_get_error_name (message) ?
2414 dbus_message_get_error_name (message) : "(unset)",
2415 dbus_connection_get_is_connected (connection) ?
2416 "" : " (disconnected)");
2417
2418 _dbus_assert (dbus_message_get_sender (message) != NULL);
2419
2420 if (!dbus_connection_get_is_connected (connection))
2421 return TRUE; /* silently ignore disconnected connections */
2422
2423 d = BUS_CONNECTION_DATA (connection);
2424 _dbus_assert (d != NULL);
2425
2426 to_send = dbus_new (MessageToSend, 1);
2427 if (to_send == NULL)
2428 {
2429 return FALSE;
2430 }
2431
2432 to_send->preallocated = dbus_connection_preallocate_send (connection);
2433 if (to_send->preallocated == NULL)
2434 {
2435 dbus_free (to_send);
2436 return FALSE;
2437 }
2438
2439 dbus_message_ref (message);
2440 to_send->message = message;
2441 to_send->transaction = transaction;
2442
2443 _dbus_verbose ("about to prepend message\n");
2444
2445 if (!_dbus_list_prepend (&d->transaction_messages, to_send))
2446 {
2447 message_to_send_free (connection, to_send);
2448 return FALSE;
2449 }
2450
2451 _dbus_verbose ("prepended message\n");
2452
2453 /* See if we already had this connection in the list
2454 * for this transaction. If we have a pending message,
2455 * then we should already be in transaction->connections
2456 */
2457 link = _dbus_list_get_first_link (&d->transaction_messages);
2458 _dbus_assert (link->data == to_send);
2459 link = _dbus_list_get_next_link (&d->transaction_messages, link);
2460 while (link != NULL)
2461 {
2462 MessageToSend *m = link->data;
2463 DBusList *next = _dbus_list_get_next_link (&d->transaction_messages, link);
2464
2465 if (m->transaction == transaction)
2466 break;
2467
2468 link = next;
2469 }
2470
2471 if (link == NULL)
2472 {
2473 if (!_dbus_list_prepend (&transaction->connections, connection))
2474 {
2475 _dbus_list_remove (&d->transaction_messages, to_send);
2476 message_to_send_free (connection, to_send);
2477 return FALSE;
2478 }
2479 }
2480
2481 return TRUE;
2482 }
2483
2484 static void
transaction_free(BusTransaction * transaction)2485 transaction_free (BusTransaction *transaction)
2486 {
2487 _dbus_assert (transaction->connections == NULL);
2488
2489 free_cancel_hooks (transaction);
2490
2491 dbus_free (transaction);
2492 }
2493
2494 static void
connection_cancel_transaction(DBusConnection * connection,BusTransaction * transaction)2495 connection_cancel_transaction (DBusConnection *connection,
2496 BusTransaction *transaction)
2497 {
2498 DBusList *link;
2499 BusConnectionData *d;
2500
2501 d = BUS_CONNECTION_DATA (connection);
2502 _dbus_assert (d != NULL);
2503
2504 link = _dbus_list_get_first_link (&d->transaction_messages);
2505 while (link != NULL)
2506 {
2507 MessageToSend *m = link->data;
2508 DBusList *next = _dbus_list_get_next_link (&d->transaction_messages, link);
2509
2510 if (m->transaction == transaction)
2511 {
2512 _dbus_list_remove_link (&d->transaction_messages,
2513 link);
2514
2515 message_to_send_free (connection, m);
2516 }
2517
2518 link = next;
2519 }
2520 }
2521
2522 void
bus_transaction_cancel_and_free(BusTransaction * transaction)2523 bus_transaction_cancel_and_free (BusTransaction *transaction)
2524 {
2525 DBusConnection *connection;
2526
2527 _dbus_verbose ("TRANSACTION: cancelled\n");
2528
2529 while ((connection = _dbus_list_pop_first (&transaction->connections)))
2530 connection_cancel_transaction (connection, transaction);
2531
2532 _dbus_list_foreach (&transaction->cancel_hooks,
2533 cancel_hook_cancel, NULL);
2534
2535 transaction_free (transaction);
2536 }
2537
2538 static void
connection_execute_transaction(DBusConnection * connection,BusTransaction * transaction)2539 connection_execute_transaction (DBusConnection *connection,
2540 BusTransaction *transaction)
2541 {
2542 DBusList *link;
2543 BusConnectionData *d;
2544
2545 d = BUS_CONNECTION_DATA (connection);
2546 _dbus_assert (d != NULL);
2547
2548 /* Send the queue in order (FIFO) */
2549 link = _dbus_list_get_last_link (&d->transaction_messages);
2550 while (link != NULL)
2551 {
2552 MessageToSend *m = link->data;
2553 DBusList *prev = _dbus_list_get_prev_link (&d->transaction_messages, link);
2554
2555 if (m->transaction == transaction)
2556 {
2557 _dbus_list_remove_link (&d->transaction_messages,
2558 link);
2559
2560 _dbus_assert (dbus_message_get_sender (m->message) != NULL);
2561
2562 dbus_connection_send_preallocated (connection,
2563 m->preallocated,
2564 m->message,
2565 NULL);
2566
2567 m->preallocated = NULL; /* so we don't double-free it */
2568
2569 message_to_send_free (connection, m);
2570 }
2571
2572 link = prev;
2573 }
2574 }
2575
2576 void
bus_transaction_execute_and_free(BusTransaction * transaction)2577 bus_transaction_execute_and_free (BusTransaction *transaction)
2578 {
2579 /* For each connection in transaction->connections
2580 * send the messages
2581 */
2582 DBusConnection *connection;
2583
2584 _dbus_verbose ("TRANSACTION: executing\n");
2585
2586 while ((connection = _dbus_list_pop_first (&transaction->connections)))
2587 connection_execute_transaction (connection, transaction);
2588
2589 transaction_free (transaction);
2590 }
2591
2592 static void
bus_connection_remove_transactions(DBusConnection * connection)2593 bus_connection_remove_transactions (DBusConnection *connection)
2594 {
2595 MessageToSend *to_send;
2596 BusConnectionData *d;
2597
2598 d = BUS_CONNECTION_DATA (connection);
2599 _dbus_assert (d != NULL);
2600
2601 while ((to_send = _dbus_list_get_first (&d->transaction_messages)))
2602 {
2603 /* only has an effect for the first MessageToSend listing this transaction */
2604 _dbus_list_remove (&to_send->transaction->connections,
2605 connection);
2606
2607 _dbus_list_remove (&d->transaction_messages, to_send);
2608 message_to_send_free (connection, to_send);
2609 }
2610 }
2611
2612 /**
2613 * Converts the DBusError to a message reply
2614 */
2615 dbus_bool_t
bus_transaction_send_error_reply(BusTransaction * transaction,DBusConnection * connection,const DBusError * error,DBusMessage * in_reply_to)2616 bus_transaction_send_error_reply (BusTransaction *transaction,
2617 DBusConnection *connection,
2618 const DBusError *error,
2619 DBusMessage *in_reply_to)
2620 {
2621 DBusMessage *reply;
2622
2623 _dbus_assert (error != NULL);
2624 _DBUS_ASSERT_ERROR_IS_SET (error);
2625
2626 _dbus_verbose ("Sending error reply %s \"%s\"\n",
2627 error->name, error->message);
2628
2629 reply = dbus_message_new_error (in_reply_to,
2630 error->name,
2631 error->message);
2632 if (reply == NULL)
2633 return FALSE;
2634
2635 if (!bus_transaction_send_from_driver (transaction, connection, reply))
2636 {
2637 dbus_message_unref (reply);
2638 return FALSE;
2639 }
2640
2641 dbus_message_unref (reply);
2642
2643 return TRUE;
2644 }
2645
2646 dbus_bool_t
bus_transaction_add_cancel_hook(BusTransaction * transaction,BusTransactionCancelFunction cancel_function,void * data,DBusFreeFunction free_data_function)2647 bus_transaction_add_cancel_hook (BusTransaction *transaction,
2648 BusTransactionCancelFunction cancel_function,
2649 void *data,
2650 DBusFreeFunction free_data_function)
2651 {
2652 CancelHook *ch;
2653
2654 ch = dbus_new (CancelHook, 1);
2655 if (ch == NULL)
2656 return FALSE;
2657
2658 _dbus_verbose (" adding cancel hook function = %p data = %p\n",
2659 cancel_function, data);
2660
2661 ch->cancel_function = cancel_function;
2662 ch->data = data;
2663 ch->free_data_function = free_data_function;
2664
2665 /* It's important that the hooks get run in reverse order that they
2666 * were added
2667 */
2668 if (!_dbus_list_prepend (&transaction->cancel_hooks, ch))
2669 {
2670 dbus_free (ch);
2671 return FALSE;
2672 }
2673
2674 return TRUE;
2675 }
2676
2677 int
bus_connections_get_n_active(BusConnections * connections)2678 bus_connections_get_n_active (BusConnections *connections)
2679 {
2680 return connections->n_completed;
2681 }
2682
2683 int
bus_connections_get_n_incomplete(BusConnections * connections)2684 bus_connections_get_n_incomplete (BusConnections *connections)
2685 {
2686 return connections->n_incomplete;
2687 }
2688
2689 #ifdef DBUS_ENABLE_STATS
2690 int
bus_connections_get_total_match_rules(BusConnections * connections)2691 bus_connections_get_total_match_rules (BusConnections *connections)
2692 {
2693 return connections->total_match_rules;
2694 }
2695
2696 int
bus_connections_get_peak_match_rules(BusConnections * connections)2697 bus_connections_get_peak_match_rules (BusConnections *connections)
2698 {
2699 return connections->peak_match_rules;
2700 }
2701
2702 int
bus_connections_get_peak_match_rules_per_conn(BusConnections * connections)2703 bus_connections_get_peak_match_rules_per_conn (BusConnections *connections)
2704 {
2705 return connections->peak_match_rules_per_conn;
2706 }
2707
2708 int
bus_connections_get_total_bus_names(BusConnections * connections)2709 bus_connections_get_total_bus_names (BusConnections *connections)
2710 {
2711 return connections->total_bus_names;
2712 }
2713
2714 int
bus_connections_get_peak_bus_names(BusConnections * connections)2715 bus_connections_get_peak_bus_names (BusConnections *connections)
2716 {
2717 return connections->peak_bus_names;
2718 }
2719
2720 int
bus_connections_get_peak_bus_names_per_conn(BusConnections * connections)2721 bus_connections_get_peak_bus_names_per_conn (BusConnections *connections)
2722 {
2723 return connections->peak_bus_names_per_conn;
2724 }
2725
2726 int
bus_connection_get_peak_match_rules(DBusConnection * connection)2727 bus_connection_get_peak_match_rules (DBusConnection *connection)
2728 {
2729 BusConnectionData *d;
2730
2731 d = BUS_CONNECTION_DATA (connection);
2732 _dbus_assert(d != NULL);
2733
2734 return d->peak_match_rules;
2735 }
2736
2737 int
bus_connection_get_peak_bus_names(DBusConnection * connection)2738 bus_connection_get_peak_bus_names (DBusConnection *connection)
2739 {
2740 BusConnectionData *d;
2741
2742 d = BUS_CONNECTION_DATA (connection);
2743 _dbus_assert(d != NULL);
2744
2745 return d->peak_bus_names;
2746 }
2747 #endif /* DBUS_ENABLE_STATS */
2748
2749 dbus_bool_t
bus_connection_is_monitor(DBusConnection * connection)2750 bus_connection_is_monitor (DBusConnection *connection)
2751 {
2752 BusConnectionData *d;
2753
2754 d = BUS_CONNECTION_DATA (connection);
2755 _dbus_assert(d != NULL);
2756
2757 return d->link_in_monitors != NULL;
2758 }
2759
2760 static dbus_bool_t
bcd_add_monitor_rules(BusConnectionData * d,DBusConnection * connection,DBusList ** rules)2761 bcd_add_monitor_rules (BusConnectionData *d,
2762 DBusConnection *connection,
2763 DBusList **rules)
2764 {
2765 BusMatchmaker *mm = d->connections->monitor_matchmaker;
2766 DBusList *iter;
2767
2768 if (mm == NULL)
2769 {
2770 mm = bus_matchmaker_new ();
2771
2772 if (mm == NULL)
2773 return FALSE;
2774
2775 d->connections->monitor_matchmaker = mm;
2776 }
2777
2778 for (iter = _dbus_list_get_first_link (rules);
2779 iter != NULL;
2780 iter = _dbus_list_get_next_link (rules, iter))
2781 {
2782 if (!bus_matchmaker_add_rule (mm, iter->data))
2783 {
2784 bus_matchmaker_disconnected (mm, connection);
2785 return FALSE;
2786 }
2787 }
2788
2789 return TRUE;
2790 }
2791
2792 static void
bcd_drop_monitor_rules(BusConnectionData * d,DBusConnection * connection)2793 bcd_drop_monitor_rules (BusConnectionData *d,
2794 DBusConnection *connection)
2795 {
2796 BusMatchmaker *mm = d->connections->monitor_matchmaker;
2797
2798 if (mm != NULL)
2799 bus_matchmaker_disconnected (mm, connection);
2800 }
2801
2802 dbus_bool_t
bus_connection_be_monitor(DBusConnection * connection,BusTransaction * transaction,DBusList ** rules,DBusError * error)2803 bus_connection_be_monitor (DBusConnection *connection,
2804 BusTransaction *transaction,
2805 DBusList **rules,
2806 DBusError *error)
2807 {
2808 BusConnectionData *d;
2809 DBusList *link;
2810 DBusList *tmp;
2811 DBusList *iter;
2812
2813 d = BUS_CONNECTION_DATA (connection);
2814 _dbus_assert (d != NULL);
2815
2816 link = _dbus_list_alloc_link (connection);
2817
2818 if (link == NULL)
2819 {
2820 BUS_SET_OOM (error);
2821 return FALSE;
2822 }
2823
2824 if (!bcd_add_monitor_rules (d, connection, rules))
2825 {
2826 _dbus_list_free_link (link);
2827 BUS_SET_OOM (error);
2828 return FALSE;
2829 }
2830
2831 /* release all its names */
2832 if (!_dbus_list_copy (&d->services_owned, &tmp))
2833 {
2834 bcd_drop_monitor_rules (d, connection);
2835 _dbus_list_free_link (link);
2836 BUS_SET_OOM (error);
2837 return FALSE;
2838 }
2839
2840 for (iter = _dbus_list_get_first_link (&tmp);
2841 iter != NULL;
2842 iter = _dbus_list_get_next_link (&tmp, iter))
2843 {
2844 BusService *service = iter->data;
2845
2846 /* This call is transactional: if there isn't enough memory to
2847 * do everything, then the service gets all its names back when
2848 * the transaction is cancelled due to OOM. */
2849 if (!bus_service_remove_owner (service, connection, transaction, error))
2850 {
2851 bcd_drop_monitor_rules (d, connection);
2852 _dbus_list_free_link (link);
2853 _dbus_list_clear (&tmp);
2854 return FALSE;
2855 }
2856 }
2857
2858 /* We have now done everything that can fail, so there is no problem
2859 * with doing the irrevocable stuff. */
2860
2861 _dbus_list_clear (&tmp);
2862
2863 bus_context_log (transaction->context, DBUS_SYSTEM_LOG_INFO,
2864 "Connection %s (%s) became a monitor.", d->name,
2865 d->cached_loginfo_string);
2866
2867 if (d->n_match_rules > 0)
2868 {
2869 BusMatchmaker *mm;
2870
2871 mm = bus_context_get_matchmaker (d->connections->context);
2872 bus_matchmaker_disconnected (mm, connection);
2873 }
2874
2875 /* flag it as a monitor */
2876 d->link_in_monitors = link;
2877 _dbus_list_append_link (&d->connections->monitors, link);
2878
2879 /* it isn't allowed to reply, and it is no longer relevant whether it
2880 * receives replies */
2881 bus_connection_drop_pending_replies (d->connections, connection);
2882
2883 return TRUE;
2884 }
2885