bus.c revision df008ef97deacd5bb00ac335e5d8671798fa09dd
1/* -*- mode: C; c-file-style: "gnu" -*- */ 2/* bus.c message bus context object 3 * 4 * Copyright (C) 2003 Red Hat, Inc. 5 * 6 * Licensed under the Academic Free License version 1.2 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 21 * 22 */ 23 24#include "bus.h" 25#include "activation.h" 26#include "connection.h" 27#include "services.h" 28#include "utils.h" 29#include "policy.h" 30#include "config-parser.h" 31#include <dbus/dbus-list.h> 32#include <dbus/dbus-hash.h> 33#include <dbus/dbus-internals.h> 34 35struct BusContext 36{ 37 int refcount; 38 char *type; 39 char *address; 40 DBusLoop *loop; 41 DBusList *servers; 42 BusConnections *connections; 43 BusActivation *activation; 44 BusRegistry *registry; 45 DBusList *default_rules; /**< Default policy rules */ 46 DBusList *mandatory_rules; /**< Mandatory policy rules */ 47 DBusHashTable *rules_by_uid; /**< per-UID policy rules */ 48 DBusHashTable *rules_by_gid; /**< per-GID policy rules */ 49 int activation_timeout; /**< How long to wait for an activation to time out */ 50 int auth_timeout; /**< How long to wait for an authentication to time out */ 51 int max_completed_connections; /**< Max number of authorized connections */ 52 int max_incomplete_connections; /**< Max number of incomplete connections */ 53 int max_connections_per_user; /**< Max number of connections auth'd as same user */ 54}; 55 56static int server_data_slot = -1; 57static int server_data_slot_refcount = 0; 58 59typedef struct 60{ 61 BusContext *context; 62} BusServerData; 63 64#define BUS_SERVER_DATA(server) (dbus_server_get_data ((server), server_data_slot)) 65 66static dbus_bool_t 67server_data_slot_ref (void) 68{ 69 if (server_data_slot < 0) 70 { 71 server_data_slot = dbus_server_allocate_data_slot (); 72 73 if (server_data_slot < 0) 74 return FALSE; 75 76 _dbus_assert (server_data_slot_refcount == 0); 77 } 78 79 server_data_slot_refcount += 1; 80 81 return TRUE; 82} 83 84static void 85server_data_slot_unref (void) 86{ 87 _dbus_assert (server_data_slot_refcount > 0); 88 89 server_data_slot_refcount -= 1; 90 91 if (server_data_slot_refcount == 0) 92 { 93 dbus_server_free_data_slot (server_data_slot); 94 server_data_slot = -1; 95 } 96} 97 98static BusContext* 99server_get_context (DBusServer *server) 100{ 101 BusContext *context; 102 BusServerData *bd; 103 104 if (!server_data_slot_ref ()) 105 return NULL; 106 107 bd = BUS_SERVER_DATA (server); 108 if (bd == NULL) 109 { 110 server_data_slot_unref (); 111 return NULL; 112 } 113 114 context = bd->context; 115 116 server_data_slot_unref (); 117 118 return context; 119} 120 121static dbus_bool_t 122server_watch_callback (DBusWatch *watch, 123 unsigned int condition, 124 void *data) 125{ 126 DBusServer *server = data; 127 128 return dbus_server_handle_watch (server, watch, condition); 129} 130 131static dbus_bool_t 132add_server_watch (DBusWatch *watch, 133 void *data) 134{ 135 DBusServer *server = data; 136 BusContext *context; 137 138 context = server_get_context (server); 139 140 return _dbus_loop_add_watch (context->loop, 141 watch, server_watch_callback, server, 142 NULL); 143} 144 145static void 146remove_server_watch (DBusWatch *watch, 147 void *data) 148{ 149 DBusServer *server = data; 150 BusContext *context; 151 152 context = server_get_context (server); 153 154 _dbus_loop_remove_watch (context->loop, 155 watch, server_watch_callback, server); 156} 157 158 159static void 160server_timeout_callback (DBusTimeout *timeout, 161 void *data) 162{ 163 /* can return FALSE on OOM but we just let it fire again later */ 164 dbus_timeout_handle (timeout); 165} 166 167static dbus_bool_t 168add_server_timeout (DBusTimeout *timeout, 169 void *data) 170{ 171 DBusServer *server = data; 172 BusContext *context; 173 174 context = server_get_context (server); 175 176 return _dbus_loop_add_timeout (context->loop, 177 timeout, server_timeout_callback, server, NULL); 178} 179 180static void 181remove_server_timeout (DBusTimeout *timeout, 182 void *data) 183{ 184 DBusServer *server = data; 185 BusContext *context; 186 187 context = server_get_context (server); 188 189 _dbus_loop_remove_timeout (context->loop, 190 timeout, server_timeout_callback, server); 191} 192 193static void 194new_connection_callback (DBusServer *server, 195 DBusConnection *new_connection, 196 void *data) 197{ 198 BusContext *context = data; 199 200 if (!bus_connections_setup_connection (context->connections, new_connection)) 201 { 202 _dbus_verbose ("No memory to setup new connection\n"); 203 204 /* if we don't do this, it will get unref'd without 205 * being disconnected... kind of strange really 206 * that we have to do this, people won't get it right 207 * in general. 208 */ 209 dbus_connection_disconnect (new_connection); 210 } 211 212 /* on OOM, we won't have ref'd the connection so it will die. */ 213} 214 215static void 216free_rule_func (void *data, 217 void *user_data) 218{ 219 BusPolicyRule *rule = data; 220 221 bus_policy_rule_unref (rule); 222} 223 224static void 225free_rule_list_func (void *data) 226{ 227 DBusList **list = data; 228 229 _dbus_list_foreach (list, free_rule_func, NULL); 230 231 _dbus_list_clear (list); 232 233 dbus_free (list); 234} 235 236static void 237free_server_data (void *data) 238{ 239 BusServerData *bd = data; 240 241 dbus_free (bd); 242} 243 244static dbus_bool_t 245setup_server (BusContext *context, 246 DBusServer *server, 247 char **auth_mechanisms, 248 DBusError *error) 249{ 250 BusServerData *bd; 251 252 bd = dbus_new0 (BusServerData, 1); 253 if (!dbus_server_set_data (server, 254 server_data_slot, 255 bd, free_server_data)) 256 { 257 dbus_free (bd); 258 BUS_SET_OOM (error); 259 return FALSE; 260 } 261 262 bd->context = context; 263 264 if (!dbus_server_set_auth_mechanisms (server, (const char**) auth_mechanisms)) 265 { 266 BUS_SET_OOM (error); 267 return FALSE; 268 } 269 270 dbus_server_set_new_connection_function (server, 271 new_connection_callback, 272 context, NULL); 273 274 if (!dbus_server_set_watch_functions (server, 275 add_server_watch, 276 remove_server_watch, 277 NULL, 278 server, 279 NULL)) 280 { 281 BUS_SET_OOM (error); 282 return FALSE; 283 } 284 285 if (!dbus_server_set_timeout_functions (server, 286 add_server_timeout, 287 remove_server_timeout, 288 NULL, 289 server, NULL)) 290 { 291 BUS_SET_OOM (error); 292 return FALSE; 293 } 294 295 return TRUE; 296} 297 298BusContext* 299bus_context_new (const DBusString *config_file, 300 int print_addr_fd, 301 DBusError *error) 302{ 303 BusContext *context; 304 DBusList *link; 305 DBusList **addresses; 306 BusConfigParser *parser; 307 DBusString full_address; 308 const char *user, *pidfile; 309 char **auth_mechanisms; 310 DBusList **auth_mechanisms_list; 311 int len; 312 313 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 314 315 if (!_dbus_string_init (&full_address)) 316 { 317 BUS_SET_OOM (error); 318 return NULL; 319 } 320 321 if (!server_data_slot_ref ()) 322 { 323 BUS_SET_OOM (error); 324 _dbus_string_free (&full_address); 325 return NULL; 326 } 327 328 parser = NULL; 329 context = NULL; 330 auth_mechanisms = NULL; 331 332 parser = bus_config_load (config_file, error); 333 if (parser == NULL) 334 goto failed; 335 336 /* Check for an existing pid file. Of course this is a race; 337 * we'd have to use fcntl() locks on the pid file to 338 * avoid that. But we want to check for the pid file 339 * before overwriting any existing sockets, etc. 340 */ 341 pidfile = bus_config_parser_get_pidfile (parser); 342 if (pidfile != NULL) 343 { 344 DBusString u; 345 DBusStat stbuf; 346 DBusError tmp_error; 347 348 dbus_error_init (&tmp_error); 349 _dbus_string_init_const (&u, pidfile); 350 351 if (_dbus_stat (&u, &stbuf, &tmp_error)) 352 { 353 dbus_set_error (error, DBUS_ERROR_FAILED, 354 "The pid file \"%s\" exists, if the message bus is not running, remove this file", 355 pidfile); 356 dbus_error_free (&tmp_error); 357 goto failed; 358 } 359 } 360 361 context = dbus_new0 (BusContext, 1); 362 if (context == NULL) 363 { 364 BUS_SET_OOM (error); 365 goto failed; 366 } 367 368 context->refcount = 1; 369 370 /* we need another ref of the server data slot for the context 371 * to own 372 */ 373 if (!server_data_slot_ref ()) 374 _dbus_assert_not_reached ("second ref of server data slot failed"); 375 376#ifdef DBUS_BUILD_TESTS 377 context->activation_timeout = 6000; /* 6 seconds */ 378#else 379 context->activation_timeout = 15000; /* 15 seconds */ 380#endif 381 382 /* Making this long risks making a DOS attack easier, but too short 383 * and legitimate auth will fail. If interactive auth (ask user for 384 * password) is allowed, then potentially it has to be quite long. 385 * Ultimately it needs to come from the configuration file. 386 */ 387 context->auth_timeout = 3000; /* 3 seconds */ 388 389 context->max_incomplete_connections = 32; 390 context->max_connections_per_user = 128; 391 392 /* Note that max_completed_connections / max_connections_per_user 393 * is the number of users that would have to work together to 394 * DOS all the other users. 395 */ 396 context->max_completed_connections = 1024; 397 398 context->loop = _dbus_loop_new (); 399 if (context->loop == NULL) 400 { 401 BUS_SET_OOM (error); 402 goto failed; 403 } 404 405 /* Build an array of auth mechanisms */ 406 407 auth_mechanisms_list = bus_config_parser_get_mechanisms (parser); 408 len = _dbus_list_get_length (auth_mechanisms_list); 409 410 if (len > 0) 411 { 412 int i; 413 414 auth_mechanisms = dbus_new0 (char*, len + 1); 415 if (auth_mechanisms == NULL) 416 goto failed; 417 418 i = 0; 419 link = _dbus_list_get_first_link (auth_mechanisms_list); 420 while (link != NULL) 421 { 422 auth_mechanisms[i] = _dbus_strdup (link->data); 423 if (auth_mechanisms[i] == NULL) 424 goto failed; 425 link = _dbus_list_get_next_link (auth_mechanisms_list, link); 426 } 427 } 428 else 429 { 430 auth_mechanisms = NULL; 431 } 432 433 /* Listen on our addresses */ 434 435 addresses = bus_config_parser_get_addresses (parser); 436 437 link = _dbus_list_get_first_link (addresses); 438 while (link != NULL) 439 { 440 DBusServer *server; 441 442 server = dbus_server_listen (link->data, error); 443 if (server == NULL) 444 goto failed; 445 else if (!setup_server (context, server, auth_mechanisms, error)) 446 goto failed; 447 448 if (!_dbus_list_append (&context->servers, server)) 449 { 450 BUS_SET_OOM (error); 451 goto failed; 452 } 453 454 link = _dbus_list_get_next_link (addresses, link); 455 } 456 457 /* Here we change our credentials if required, 458 * as soon as we've set up our sockets 459 */ 460 user = bus_config_parser_get_user (parser); 461 if (user != NULL) 462 { 463 DBusCredentials creds; 464 DBusString u; 465 466 _dbus_string_init_const (&u, user); 467 468 if (!_dbus_credentials_from_username (&u, &creds) || 469 creds.uid < 0 || 470 creds.gid < 0) 471 { 472 dbus_set_error (error, DBUS_ERROR_FAILED, 473 "Could not get UID and GID for username \"%s\"", 474 user); 475 goto failed; 476 } 477 478 if (!_dbus_change_identity (creds.uid, creds.gid, error)) 479 goto failed; 480 } 481 482 /* note that type may be NULL */ 483 context->type = _dbus_strdup (bus_config_parser_get_type (parser)); 484 485 /* We have to build the address backward, so that 486 * <listen> later in the config file have priority 487 */ 488 link = _dbus_list_get_last_link (&context->servers); 489 while (link != NULL) 490 { 491 char *addr; 492 493 addr = dbus_server_get_address (link->data); 494 if (addr == NULL) 495 { 496 BUS_SET_OOM (error); 497 goto failed; 498 } 499 500 if (_dbus_string_get_length (&full_address) > 0) 501 { 502 if (!_dbus_string_append (&full_address, ";")) 503 { 504 BUS_SET_OOM (error); 505 goto failed; 506 } 507 } 508 509 if (!_dbus_string_append (&full_address, addr)) 510 { 511 BUS_SET_OOM (error); 512 goto failed; 513 } 514 515 dbus_free (addr); 516 517 link = _dbus_list_get_prev_link (&context->servers, link); 518 } 519 520 if (!_dbus_string_copy_data (&full_address, &context->address)) 521 { 522 BUS_SET_OOM (error); 523 goto failed; 524 } 525 526 /* Note that we don't know whether the print_addr_fd is 527 * one of the sockets we're using to listen on, or some 528 * other random thing. But I think the answer is "don't do 529 * that then" 530 */ 531 if (print_addr_fd >= 0) 532 { 533 DBusString addr; 534 const char *a = bus_context_get_address (context); 535 int bytes; 536 537 _dbus_assert (a != NULL); 538 if (!_dbus_string_init (&addr)) 539 { 540 BUS_SET_OOM (error); 541 goto failed; 542 } 543 544 if (!_dbus_string_append (&addr, a) || 545 !_dbus_string_append (&addr, "\n")) 546 { 547 _dbus_string_free (&addr); 548 BUS_SET_OOM (error); 549 goto failed; 550 } 551 552 bytes = _dbus_string_get_length (&addr); 553 if (_dbus_write (print_addr_fd, &addr, 0, bytes) != bytes) 554 { 555 dbus_set_error (error, DBUS_ERROR_FAILED, 556 "Printing message bus address: %s\n", 557 _dbus_strerror (errno)); 558 _dbus_string_free (&addr); 559 goto failed; 560 } 561 562 if (print_addr_fd > 2) 563 _dbus_close (print_addr_fd, NULL); 564 565 _dbus_string_free (&addr); 566 } 567 568 /* Create activation subsystem */ 569 570 context->activation = bus_activation_new (context, &full_address, 571 bus_config_parser_get_service_dirs (parser), 572 error); 573 if (context->activation == NULL) 574 { 575 _DBUS_ASSERT_ERROR_IS_SET (error); 576 goto failed; 577 } 578 579 context->connections = bus_connections_new (context); 580 if (context->connections == NULL) 581 { 582 BUS_SET_OOM (error); 583 goto failed; 584 } 585 586 context->registry = bus_registry_new (context); 587 if (context->registry == NULL) 588 { 589 BUS_SET_OOM (error); 590 goto failed; 591 } 592 593 context->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_ULONG, 594 NULL, 595 free_rule_list_func); 596 if (context->rules_by_uid == NULL) 597 { 598 BUS_SET_OOM (error); 599 goto failed; 600 } 601 602 context->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_ULONG, 603 NULL, 604 free_rule_list_func); 605 if (context->rules_by_gid == NULL) 606 { 607 BUS_SET_OOM (error); 608 goto failed; 609 } 610 611 /* Now become a daemon if appropriate */ 612 if (bus_config_parser_get_fork (parser)) 613 { 614 DBusString u; 615 616 if (pidfile) 617 _dbus_string_init_const (&u, pidfile); 618 619 if (!_dbus_become_daemon (pidfile ? &u : NULL, error)) 620 goto failed; 621 } 622 else 623 { 624 /* Need to write PID file for ourselves, not for the child process */ 625 if (pidfile != NULL) 626 { 627 DBusString u; 628 629 _dbus_string_init_const (&u, pidfile); 630 631 if (!_dbus_write_pid_file (&u, _dbus_getpid (), error)) 632 goto failed; 633 } 634 } 635 636 bus_config_parser_unref (parser); 637 _dbus_string_free (&full_address); 638 dbus_free_string_array (auth_mechanisms); 639 server_data_slot_unref (); 640 641 return context; 642 643 failed: 644 if (parser != NULL) 645 bus_config_parser_unref (parser); 646 647 if (context != NULL) 648 bus_context_unref (context); 649 650 _dbus_string_free (&full_address); 651 dbus_free_string_array (auth_mechanisms); 652 653 server_data_slot_unref (); 654 655 return NULL; 656} 657 658static void 659shutdown_server (BusContext *context, 660 DBusServer *server) 661{ 662 if (server == NULL || 663 !dbus_server_get_is_connected (server)) 664 return; 665 666 if (!dbus_server_set_watch_functions (server, 667 NULL, NULL, NULL, 668 context, 669 NULL)) 670 _dbus_assert_not_reached ("setting watch functions to NULL failed"); 671 672 if (!dbus_server_set_timeout_functions (server, 673 NULL, NULL, NULL, 674 context, 675 NULL)) 676 _dbus_assert_not_reached ("setting timeout functions to NULL failed"); 677 678 dbus_server_disconnect (server); 679} 680 681void 682bus_context_shutdown (BusContext *context) 683{ 684 DBusList *link; 685 686 link = _dbus_list_get_first_link (&context->servers); 687 while (link != NULL) 688 { 689 shutdown_server (context, link->data); 690 691 link = _dbus_list_get_next_link (&context->servers, link); 692 } 693} 694 695void 696bus_context_ref (BusContext *context) 697{ 698 _dbus_assert (context->refcount > 0); 699 context->refcount += 1; 700} 701 702void 703bus_context_unref (BusContext *context) 704{ 705 _dbus_assert (context->refcount > 0); 706 context->refcount -= 1; 707 708 if (context->refcount == 0) 709 { 710 DBusList *link; 711 712 _dbus_verbose ("Finalizing bus context %p\n", context); 713 714 bus_context_shutdown (context); 715 716 if (context->connections) 717 { 718 bus_connections_unref (context->connections); 719 context->connections = NULL; 720 } 721 722 if (context->registry) 723 { 724 bus_registry_unref (context->registry); 725 context->registry = NULL; 726 } 727 728 if (context->activation) 729 { 730 bus_activation_unref (context->activation); 731 context->activation = NULL; 732 } 733 734 link = _dbus_list_get_first_link (&context->servers); 735 while (link != NULL) 736 { 737 dbus_server_unref (link->data); 738 739 link = _dbus_list_get_next_link (&context->servers, link); 740 } 741 _dbus_list_clear (&context->servers); 742 743 if (context->rules_by_uid) 744 { 745 _dbus_hash_table_unref (context->rules_by_uid); 746 context->rules_by_uid = NULL; 747 } 748 749 if (context->rules_by_gid) 750 { 751 _dbus_hash_table_unref (context->rules_by_gid); 752 context->rules_by_gid = NULL; 753 } 754 755 if (context->loop) 756 { 757 _dbus_loop_unref (context->loop); 758 context->loop = NULL; 759 } 760 761 dbus_free (context->type); 762 dbus_free (context->address); 763 dbus_free (context); 764 765 server_data_slot_unref (); 766 } 767} 768 769/* type may be NULL */ 770const char* 771bus_context_get_type (BusContext *context) 772{ 773 return context->type; 774} 775 776const char* 777bus_context_get_address (BusContext *context) 778{ 779 return context->address; 780} 781 782BusRegistry* 783bus_context_get_registry (BusContext *context) 784{ 785 return context->registry; 786} 787 788BusConnections* 789bus_context_get_connections (BusContext *context) 790{ 791 return context->connections; 792} 793 794BusActivation* 795bus_context_get_activation (BusContext *context) 796{ 797 return context->activation; 798} 799 800DBusLoop* 801bus_context_get_loop (BusContext *context) 802{ 803 return context->loop; 804} 805 806static dbus_bool_t 807list_allows_user (dbus_bool_t def, 808 DBusList **list, 809 unsigned long uid, 810 const unsigned long *group_ids, 811 int n_group_ids) 812{ 813 DBusList *link; 814 dbus_bool_t allowed; 815 816 allowed = def; 817 818 link = _dbus_list_get_first_link (list); 819 while (link != NULL) 820 { 821 BusPolicyRule *rule = link->data; 822 link = _dbus_list_get_next_link (list, link); 823 824 if (rule->type == BUS_POLICY_RULE_USER) 825 { 826 if (rule->d.user.uid != uid) 827 continue; 828 } 829 else if (rule->type == BUS_POLICY_RULE_GROUP) 830 { 831 int i; 832 833 i = 0; 834 while (i < n_group_ids) 835 { 836 if (rule->d.group.gid == group_ids[i]) 837 break; 838 ++i; 839 } 840 841 if (i == n_group_ids) 842 continue; 843 } 844 else 845 continue; 846 847 allowed = rule->allow; 848 } 849 850 return allowed; 851} 852 853dbus_bool_t 854bus_context_allow_user (BusContext *context, 855 unsigned long uid) 856{ 857 dbus_bool_t allowed; 858 unsigned long *group_ids; 859 int n_group_ids; 860 861 /* On OOM or error we always reject the user */ 862 if (!_dbus_get_groups (uid, &group_ids, &n_group_ids)) 863 { 864 _dbus_verbose ("Did not get any groups for UID %lu\n", 865 uid); 866 return FALSE; 867 } 868 869 allowed = FALSE; 870 871 allowed = list_allows_user (allowed, 872 &context->default_rules, 873 uid, 874 group_ids, n_group_ids); 875 876 allowed = list_allows_user (allowed, 877 &context->mandatory_rules, 878 uid, 879 group_ids, n_group_ids); 880 881 dbus_free (group_ids); 882 883 return allowed; 884} 885 886static dbus_bool_t 887add_list_to_policy (DBusList **list, 888 BusPolicy *policy) 889{ 890 DBusList *link; 891 892 link = _dbus_list_get_first_link (list); 893 while (link != NULL) 894 { 895 BusPolicyRule *rule = link->data; 896 link = _dbus_list_get_next_link (list, link); 897 898 switch (rule->type) 899 { 900 case BUS_POLICY_RULE_USER: 901 case BUS_POLICY_RULE_GROUP: 902 /* These aren't per-connection policies */ 903 break; 904 905 case BUS_POLICY_RULE_OWN: 906 case BUS_POLICY_RULE_SEND: 907 case BUS_POLICY_RULE_RECEIVE: 908 /* These are per-connection */ 909 if (!bus_policy_append_rule (policy, rule)) 910 return FALSE; 911 break; 912 } 913 } 914 915 return TRUE; 916} 917 918BusPolicy* 919bus_context_create_connection_policy (BusContext *context, 920 DBusConnection *connection) 921{ 922 BusPolicy *policy; 923 unsigned long uid; 924 DBusList **list; 925 926 _dbus_assert (dbus_connection_get_is_authenticated (connection)); 927 928 policy = bus_policy_new (); 929 if (policy == NULL) 930 return NULL; 931 932 if (!add_list_to_policy (&context->default_rules, 933 policy)) 934 goto failed; 935 936 /* we avoid the overhead of looking up user's groups 937 * if we don't have any group rules anyway 938 */ 939 if (_dbus_hash_table_get_n_entries (context->rules_by_gid) > 0) 940 { 941 const unsigned long *groups; 942 int n_groups; 943 int i; 944 945 if (!bus_connection_get_groups (connection, &groups, &n_groups)) 946 goto failed; 947 948 i = 0; 949 while (i < n_groups) 950 { 951 list = _dbus_hash_table_lookup_ulong (context->rules_by_gid, 952 groups[i]); 953 954 if (list != NULL) 955 { 956 if (!add_list_to_policy (list, policy)) 957 goto failed; 958 } 959 960 ++i; 961 } 962 } 963 964 if (!dbus_connection_get_unix_user (connection, &uid)) 965 goto failed; 966 967 list = _dbus_hash_table_lookup_ulong (context->rules_by_uid, 968 uid); 969 970 if (!add_list_to_policy (list, policy)) 971 goto failed; 972 973 if (!add_list_to_policy (&context->mandatory_rules, 974 policy)) 975 goto failed; 976 977 bus_policy_optimize (policy); 978 979 return policy; 980 981 failed: 982 bus_policy_unref (policy); 983 return NULL; 984} 985 986int 987bus_context_get_activation_timeout (BusContext *context) 988{ 989 990 return context->activation_timeout; 991} 992