1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2 /* driver.c Bus client (driver) 3 * 4 * Copyright (C) 2003 CodeFactory AB 5 * Copyright (C) 2003, 2004, 2005 Red Hat, Inc. 6 * 7 * Licensed under the Academic Free License version 2.1 8 * 9 * This program is free software; you can redistribute it and/or modify 10 * it under the terms of the GNU General Public License as published by 11 * the Free Software Foundation; either version 2 of the License, or 12 * (at your option) any later version. 13 * 14 * This program is distributed in the hope that it will be useful, 15 * but WITHOUT ANY WARRANTY; without even the implied warranty of 16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 17 * GNU General Public License for more details. 18 * 19 * You should have received a copy of the GNU General Public License 20 * along with this program; if not, write to the Free Software 21 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 22 * 23 */ 24 25 #include <config.h> 26 #include "activation.h" 27 #include "connection.h" 28 #include "driver.h" 29 #include "dispatch.h" 30 #include "services.h" 31 #include "selinux.h" 32 #include "signals.h" 33 #include "stats.h" 34 #include "utils.h" 35 #include <dbus/dbus-string.h> 36 #include <dbus/dbus-internals.h> 37 #include <dbus/dbus-message.h> 38 #include <dbus/dbus-marshal-recursive.h> 39 #include <string.h> 40 41 static dbus_bool_t bus_driver_send_welcome_message (DBusConnection *connection, 42 DBusMessage *hello_message, 43 BusTransaction *transaction, 44 DBusError *error); 45 46 dbus_bool_t 47 bus_driver_send_service_owner_changed (const char *service_name, 48 const char *old_owner, 49 const char *new_owner, 50 BusTransaction *transaction, 51 DBusError *error) 52 { 53 DBusMessage *message; 54 dbus_bool_t retval; 55 const char *null_service; 56 57 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 58 59 null_service = ""; 60 _dbus_verbose ("sending name owner changed: %s [%s -> %s]\n", 61 service_name, 62 old_owner ? old_owner : null_service, 63 new_owner ? new_owner : null_service); 64 65 message = dbus_message_new_signal (DBUS_PATH_DBUS, 66 DBUS_INTERFACE_DBUS, 67 "NameOwnerChanged"); 68 69 if (message == NULL) 70 { 71 BUS_SET_OOM (error); 72 return FALSE; 73 } 74 75 if (!dbus_message_set_sender (message, DBUS_SERVICE_DBUS)) 76 goto oom; 77 78 if (!dbus_message_append_args (message, 79 DBUS_TYPE_STRING, &service_name, 80 DBUS_TYPE_STRING, old_owner ? &old_owner : &null_service, 81 DBUS_TYPE_STRING, new_owner ? &new_owner : &null_service, 82 DBUS_TYPE_INVALID)) 83 goto oom; 84 85 _dbus_assert (dbus_message_has_signature (message, "sss")); 86 87 retval = bus_dispatch_matches (transaction, NULL, NULL, message, error); 88 dbus_message_unref (message); 89 90 return retval; 91 92 oom: 93 dbus_message_unref (message); 94 BUS_SET_OOM (error); 95 return FALSE; 96 } 97 98 dbus_bool_t 99 bus_driver_send_service_lost (DBusConnection *connection, 100 const char *service_name, 101 BusTransaction *transaction, 102 DBusError *error) 103 { 104 DBusMessage *message; 105 106 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 107 108 message = dbus_message_new_signal (DBUS_PATH_DBUS, 109 DBUS_INTERFACE_DBUS, 110 "NameLost"); 111 112 if (message == NULL) 113 { 114 BUS_SET_OOM (error); 115 return FALSE; 116 } 117 118 if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) || 119 !dbus_message_append_args (message, 120 DBUS_TYPE_STRING, &service_name, 121 DBUS_TYPE_INVALID)) 122 { 123 dbus_message_unref (message); 124 BUS_SET_OOM (error); 125 return FALSE; 126 } 127 128 if (!bus_transaction_send_from_driver (transaction, connection, message)) 129 { 130 dbus_message_unref (message); 131 BUS_SET_OOM (error); 132 return FALSE; 133 } 134 else 135 { 136 dbus_message_unref (message); 137 return TRUE; 138 } 139 } 140 141 dbus_bool_t 142 bus_driver_send_service_acquired (DBusConnection *connection, 143 const char *service_name, 144 BusTransaction *transaction, 145 DBusError *error) 146 { 147 DBusMessage *message; 148 149 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 150 151 message = dbus_message_new_signal (DBUS_PATH_DBUS, 152 DBUS_INTERFACE_DBUS, 153 "NameAcquired"); 154 155 if (message == NULL) 156 { 157 BUS_SET_OOM (error); 158 return FALSE; 159 } 160 161 if (!dbus_message_set_destination (message, bus_connection_get_name (connection)) || 162 !dbus_message_append_args (message, 163 DBUS_TYPE_STRING, &service_name, 164 DBUS_TYPE_INVALID)) 165 { 166 dbus_message_unref (message); 167 BUS_SET_OOM (error); 168 return FALSE; 169 } 170 171 if (!bus_transaction_send_from_driver (transaction, connection, message)) 172 { 173 dbus_message_unref (message); 174 BUS_SET_OOM (error); 175 return FALSE; 176 } 177 else 178 { 179 dbus_message_unref (message); 180 return TRUE; 181 } 182 } 183 184 static dbus_bool_t 185 create_unique_client_name (BusRegistry *registry, 186 DBusString *str) 187 { 188 /* We never want to use the same unique client name twice, because 189 * we want to guarantee that if you send a message to a given unique 190 * name, you always get the same application. So we use two numbers 191 * for INT_MAX * INT_MAX combinations, should be pretty safe against 192 * wraparound. 193 */ 194 /* FIXME these should be in BusRegistry rather than static vars */ 195 static int next_major_number = 0; 196 static int next_minor_number = 0; 197 int len; 198 199 len = _dbus_string_get_length (str); 200 201 while (TRUE) 202 { 203 /* start out with 1-0, go to 1-1, 1-2, 1-3, 204 * up to 1-MAXINT, then 2-0, 2-1, etc. 205 */ 206 if (next_minor_number <= 0) 207 { 208 next_major_number += 1; 209 next_minor_number = 0; 210 if (next_major_number <= 0) 211 _dbus_assert_not_reached ("INT_MAX * INT_MAX clients were added"); 212 } 213 214 _dbus_assert (next_major_number > 0); 215 _dbus_assert (next_minor_number >= 0); 216 217 /* appname:MAJOR-MINOR */ 218 219 if (!_dbus_string_append (str, ":")) 220 return FALSE; 221 222 if (!_dbus_string_append_int (str, next_major_number)) 223 return FALSE; 224 225 if (!_dbus_string_append (str, ".")) 226 return FALSE; 227 228 if (!_dbus_string_append_int (str, next_minor_number)) 229 return FALSE; 230 231 next_minor_number += 1; 232 233 /* Check if a client with the name exists */ 234 if (bus_registry_lookup (registry, str) == NULL) 235 break; 236 237 /* drop the number again, try the next one. */ 238 _dbus_string_set_length (str, len); 239 } 240 241 return TRUE; 242 } 243 244 static dbus_bool_t 245 bus_driver_handle_hello (DBusConnection *connection, 246 BusTransaction *transaction, 247 DBusMessage *message, 248 DBusError *error) 249 { 250 DBusString unique_name; 251 BusService *service; 252 dbus_bool_t retval; 253 BusRegistry *registry; 254 BusConnections *connections; 255 256 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 257 258 if (bus_connection_is_active (connection)) 259 { 260 /* We already handled an Hello message for this connection. */ 261 dbus_set_error (error, DBUS_ERROR_FAILED, 262 "Already handled an Hello message"); 263 return FALSE; 264 } 265 266 /* Note that when these limits are exceeded we don't disconnect the 267 * connection; we just sort of leave it hanging there until it times 268 * out or disconnects itself or is dropped due to the max number of 269 * incomplete connections. It's even OK if the connection wants to 270 * retry the hello message, we support that. 271 */ 272 connections = bus_connection_get_connections (connection); 273 if (!bus_connections_check_limits (connections, connection, 274 error)) 275 { 276 _DBUS_ASSERT_ERROR_IS_SET (error); 277 return FALSE; 278 } 279 280 if (!_dbus_string_init (&unique_name)) 281 { 282 BUS_SET_OOM (error); 283 return FALSE; 284 } 285 286 retval = FALSE; 287 288 registry = bus_connection_get_registry (connection); 289 290 if (!create_unique_client_name (registry, &unique_name)) 291 { 292 BUS_SET_OOM (error); 293 goto out_0; 294 } 295 296 if (!bus_connection_complete (connection, &unique_name, error)) 297 { 298 _DBUS_ASSERT_ERROR_IS_SET (error); 299 goto out_0; 300 } 301 302 if (!dbus_message_set_sender (message, 303 bus_connection_get_name (connection))) 304 { 305 BUS_SET_OOM (error); 306 goto out_0; 307 } 308 309 if (!bus_driver_send_welcome_message (connection, message, transaction, error)) 310 goto out_0; 311 312 /* Create the service */ 313 service = bus_registry_ensure (registry, 314 &unique_name, connection, 0, transaction, error); 315 if (service == NULL) 316 goto out_0; 317 318 _dbus_assert (bus_connection_is_active (connection)); 319 retval = TRUE; 320 321 out_0: 322 _dbus_string_free (&unique_name); 323 return retval; 324 } 325 326 static dbus_bool_t 327 bus_driver_send_welcome_message (DBusConnection *connection, 328 DBusMessage *hello_message, 329 BusTransaction *transaction, 330 DBusError *error) 331 { 332 DBusMessage *welcome; 333 const char *name; 334 335 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 336 337 name = bus_connection_get_name (connection); 338 _dbus_assert (name != NULL); 339 340 welcome = dbus_message_new_method_return (hello_message); 341 if (welcome == NULL) 342 { 343 BUS_SET_OOM (error); 344 return FALSE; 345 } 346 347 if (!dbus_message_append_args (welcome, 348 DBUS_TYPE_STRING, &name, 349 DBUS_TYPE_INVALID)) 350 { 351 dbus_message_unref (welcome); 352 BUS_SET_OOM (error); 353 return FALSE; 354 } 355 356 _dbus_assert (dbus_message_has_signature (welcome, DBUS_TYPE_STRING_AS_STRING)); 357 358 if (!bus_transaction_send_from_driver (transaction, connection, welcome)) 359 { 360 dbus_message_unref (welcome); 361 BUS_SET_OOM (error); 362 return FALSE; 363 } 364 else 365 { 366 dbus_message_unref (welcome); 367 return TRUE; 368 } 369 } 370 371 static dbus_bool_t 372 bus_driver_handle_list_services (DBusConnection *connection, 373 BusTransaction *transaction, 374 DBusMessage *message, 375 DBusError *error) 376 { 377 DBusMessage *reply; 378 int len; 379 char **services; 380 BusRegistry *registry; 381 int i; 382 DBusMessageIter iter; 383 DBusMessageIter sub; 384 385 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 386 387 registry = bus_connection_get_registry (connection); 388 389 reply = dbus_message_new_method_return (message); 390 if (reply == NULL) 391 { 392 BUS_SET_OOM (error); 393 return FALSE; 394 } 395 396 if (!bus_registry_list_services (registry, &services, &len)) 397 { 398 dbus_message_unref (reply); 399 BUS_SET_OOM (error); 400 return FALSE; 401 } 402 403 dbus_message_iter_init_append (reply, &iter); 404 405 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 406 DBUS_TYPE_STRING_AS_STRING, 407 &sub)) 408 { 409 dbus_free_string_array (services); 410 dbus_message_unref (reply); 411 BUS_SET_OOM (error); 412 return FALSE; 413 } 414 415 { 416 /* Include the bus driver in the list */ 417 const char *v_STRING = DBUS_SERVICE_DBUS; 418 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING, 419 &v_STRING)) 420 { 421 dbus_free_string_array (services); 422 dbus_message_unref (reply); 423 BUS_SET_OOM (error); 424 return FALSE; 425 } 426 } 427 428 i = 0; 429 while (i < len) 430 { 431 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING, 432 &services[i])) 433 { 434 dbus_free_string_array (services); 435 dbus_message_unref (reply); 436 BUS_SET_OOM (error); 437 return FALSE; 438 } 439 ++i; 440 } 441 442 dbus_free_string_array (services); 443 444 if (!dbus_message_iter_close_container (&iter, &sub)) 445 { 446 dbus_message_unref (reply); 447 BUS_SET_OOM (error); 448 return FALSE; 449 } 450 451 if (!bus_transaction_send_from_driver (transaction, connection, reply)) 452 { 453 dbus_message_unref (reply); 454 BUS_SET_OOM (error); 455 return FALSE; 456 } 457 else 458 { 459 dbus_message_unref (reply); 460 return TRUE; 461 } 462 } 463 464 static dbus_bool_t 465 bus_driver_handle_list_activatable_services (DBusConnection *connection, 466 BusTransaction *transaction, 467 DBusMessage *message, 468 DBusError *error) 469 { 470 DBusMessage *reply; 471 int len; 472 char **services; 473 BusActivation *activation; 474 int i; 475 DBusMessageIter iter; 476 DBusMessageIter sub; 477 478 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 479 480 activation = bus_connection_get_activation (connection); 481 482 reply = dbus_message_new_method_return (message); 483 if (reply == NULL) 484 { 485 BUS_SET_OOM (error); 486 return FALSE; 487 } 488 489 if (!bus_activation_list_services (activation, &services, &len)) 490 { 491 dbus_message_unref (reply); 492 BUS_SET_OOM (error); 493 return FALSE; 494 } 495 496 dbus_message_iter_init_append (reply, &iter); 497 498 if (!dbus_message_iter_open_container (&iter, DBUS_TYPE_ARRAY, 499 DBUS_TYPE_STRING_AS_STRING, 500 &sub)) 501 { 502 dbus_free_string_array (services); 503 dbus_message_unref (reply); 504 BUS_SET_OOM (error); 505 return FALSE; 506 } 507 508 { 509 /* Include the bus driver in the list */ 510 const char *v_STRING = DBUS_SERVICE_DBUS; 511 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING, 512 &v_STRING)) 513 { 514 dbus_free_string_array (services); 515 dbus_message_unref (reply); 516 BUS_SET_OOM (error); 517 return FALSE; 518 } 519 } 520 521 i = 0; 522 while (i < len) 523 { 524 if (!dbus_message_iter_append_basic (&sub, DBUS_TYPE_STRING, 525 &services[i])) 526 { 527 dbus_free_string_array (services); 528 dbus_message_unref (reply); 529 BUS_SET_OOM (error); 530 return FALSE; 531 } 532 ++i; 533 } 534 535 dbus_free_string_array (services); 536 537 if (!dbus_message_iter_close_container (&iter, &sub)) 538 { 539 dbus_message_unref (reply); 540 BUS_SET_OOM (error); 541 return FALSE; 542 } 543 544 if (!bus_transaction_send_from_driver (transaction, connection, reply)) 545 { 546 dbus_message_unref (reply); 547 BUS_SET_OOM (error); 548 return FALSE; 549 } 550 else 551 { 552 dbus_message_unref (reply); 553 return TRUE; 554 } 555 } 556 557 static dbus_bool_t 558 bus_driver_handle_acquire_service (DBusConnection *connection, 559 BusTransaction *transaction, 560 DBusMessage *message, 561 DBusError *error) 562 { 563 DBusMessage *reply; 564 DBusString service_name; 565 const char *name; 566 dbus_uint32_t service_reply; 567 dbus_uint32_t flags; 568 dbus_bool_t retval; 569 BusRegistry *registry; 570 571 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 572 573 registry = bus_connection_get_registry (connection); 574 575 if (!dbus_message_get_args (message, error, 576 DBUS_TYPE_STRING, &name, 577 DBUS_TYPE_UINT32, &flags, 578 DBUS_TYPE_INVALID)) 579 return FALSE; 580 581 _dbus_verbose ("Trying to own name %s with flags 0x%x\n", name, flags); 582 583 retval = FALSE; 584 reply = NULL; 585 586 _dbus_string_init_const (&service_name, name); 587 588 if (!bus_registry_acquire_service (registry, connection, 589 &service_name, flags, 590 &service_reply, transaction, 591 error)) 592 goto out; 593 594 reply = dbus_message_new_method_return (message); 595 if (reply == NULL) 596 { 597 BUS_SET_OOM (error); 598 goto out; 599 } 600 601 if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID)) 602 { 603 BUS_SET_OOM (error); 604 goto out; 605 } 606 607 if (!bus_transaction_send_from_driver (transaction, connection, reply)) 608 { 609 BUS_SET_OOM (error); 610 goto out; 611 } 612 613 retval = TRUE; 614 615 out: 616 if (reply) 617 dbus_message_unref (reply); 618 return retval; 619 } 620 621 static dbus_bool_t 622 bus_driver_handle_release_service (DBusConnection *connection, 623 BusTransaction *transaction, 624 DBusMessage *message, 625 DBusError *error) 626 { 627 DBusMessage *reply; 628 DBusString service_name; 629 const char *name; 630 dbus_uint32_t service_reply; 631 dbus_bool_t retval; 632 BusRegistry *registry; 633 634 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 635 636 registry = bus_connection_get_registry (connection); 637 638 if (!dbus_message_get_args (message, error, 639 DBUS_TYPE_STRING, &name, 640 DBUS_TYPE_INVALID)) 641 return FALSE; 642 643 _dbus_verbose ("Trying to release name %s\n", name); 644 645 retval = FALSE; 646 reply = NULL; 647 648 _dbus_string_init_const (&service_name, name); 649 650 if (!bus_registry_release_service (registry, connection, 651 &service_name, &service_reply, 652 transaction, error)) 653 goto out; 654 655 reply = dbus_message_new_method_return (message); 656 if (reply == NULL) 657 { 658 BUS_SET_OOM (error); 659 goto out; 660 } 661 662 if (!dbus_message_append_args (reply, DBUS_TYPE_UINT32, &service_reply, DBUS_TYPE_INVALID)) 663 { 664 BUS_SET_OOM (error); 665 goto out; 666 } 667 668 if (!bus_transaction_send_from_driver (transaction, connection, reply)) 669 { 670 BUS_SET_OOM (error); 671 goto out; 672 } 673 674 retval = TRUE; 675 676 out: 677 if (reply) 678 dbus_message_unref (reply); 679 return retval; 680 } 681 682 static dbus_bool_t 683 bus_driver_handle_service_exists (DBusConnection *connection, 684 BusTransaction *transaction, 685 DBusMessage *message, 686 DBusError *error) 687 { 688 DBusMessage *reply; 689 DBusString service_name; 690 BusService *service; 691 dbus_bool_t service_exists; 692 const char *name; 693 dbus_bool_t retval; 694 BusRegistry *registry; 695 696 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 697 698 registry = bus_connection_get_registry (connection); 699 700 if (!dbus_message_get_args (message, error, 701 DBUS_TYPE_STRING, &name, 702 DBUS_TYPE_INVALID)) 703 return FALSE; 704 705 retval = FALSE; 706 707 if (strcmp (name, DBUS_SERVICE_DBUS) == 0) 708 { 709 service_exists = TRUE; 710 } 711 else 712 { 713 _dbus_string_init_const (&service_name, name); 714 service = bus_registry_lookup (registry, &service_name); 715 service_exists = service != NULL; 716 } 717 718 reply = dbus_message_new_method_return (message); 719 if (reply == NULL) 720 { 721 BUS_SET_OOM (error); 722 goto out; 723 } 724 725 if (!dbus_message_append_args (reply, 726 DBUS_TYPE_BOOLEAN, &service_exists, 727 0)) 728 { 729 BUS_SET_OOM (error); 730 goto out; 731 } 732 733 if (!bus_transaction_send_from_driver (transaction, connection, reply)) 734 { 735 BUS_SET_OOM (error); 736 goto out; 737 } 738 739 retval = TRUE; 740 741 out: 742 if (reply) 743 dbus_message_unref (reply); 744 745 return retval; 746 } 747 748 static dbus_bool_t 749 bus_driver_handle_activate_service (DBusConnection *connection, 750 BusTransaction *transaction, 751 DBusMessage *message, 752 DBusError *error) 753 { 754 dbus_uint32_t flags; 755 const char *name; 756 dbus_bool_t retval; 757 BusActivation *activation; 758 759 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 760 761 activation = bus_connection_get_activation (connection); 762 763 if (!dbus_message_get_args (message, error, 764 DBUS_TYPE_STRING, &name, 765 DBUS_TYPE_UINT32, &flags, 766 DBUS_TYPE_INVALID)) 767 { 768 _DBUS_ASSERT_ERROR_IS_SET (error); 769 _dbus_verbose ("No memory to get arguments to StartServiceByName\n"); 770 return FALSE; 771 } 772 773 retval = FALSE; 774 775 if (!bus_activation_activate_service (activation, connection, transaction, FALSE, 776 message, name, error)) 777 { 778 _DBUS_ASSERT_ERROR_IS_SET (error); 779 _dbus_verbose ("bus_activation_activate_service() failed\n"); 780 goto out; 781 } 782 783 retval = TRUE; 784 785 out: 786 return retval; 787 } 788 789 static dbus_bool_t 790 send_ack_reply (DBusConnection *connection, 791 BusTransaction *transaction, 792 DBusMessage *message, 793 DBusError *error) 794 { 795 DBusMessage *reply; 796 797 if (dbus_message_get_no_reply (message)) 798 return TRUE; 799 800 reply = dbus_message_new_method_return (message); 801 if (reply == NULL) 802 { 803 BUS_SET_OOM (error); 804 return FALSE; 805 } 806 807 if (!bus_transaction_send_from_driver (transaction, connection, reply)) 808 { 809 BUS_SET_OOM (error); 810 dbus_message_unref (reply); 811 return FALSE; 812 } 813 814 dbus_message_unref (reply); 815 816 return TRUE; 817 } 818 819 static dbus_bool_t 820 bus_driver_handle_update_activation_environment (DBusConnection *connection, 821 BusTransaction *transaction, 822 DBusMessage *message, 823 DBusError *error) 824 { 825 dbus_bool_t retval; 826 BusActivation *activation; 827 DBusMessageIter iter; 828 DBusMessageIter dict_iter; 829 DBusMessageIter dict_entry_iter; 830 int array_type; 831 int key_type; 832 DBusList *keys, *key_link; 833 DBusList *values, *value_link; 834 835 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 836 837 activation = bus_connection_get_activation (connection); 838 839 dbus_message_iter_init (message, &iter); 840 841 /* The message signature has already been checked for us, 842 * so let's just assert it's right. 843 */ 844 #ifndef DBUS_DISABLE_ASSERT 845 { 846 int msg_type = dbus_message_iter_get_arg_type (&iter); 847 848 _dbus_assert (msg_type == DBUS_TYPE_ARRAY); 849 } 850 #endif 851 852 dbus_message_iter_recurse (&iter, &dict_iter); 853 854 retval = FALSE; 855 856 /* Then loop through the sent dictionary, add the location of 857 * the environment keys and values to lists. The result will 858 * be in reverse order, so we don't have to constantly search 859 * for the end of the list in a loop. 860 */ 861 keys = NULL; 862 values = NULL; 863 while ((array_type = dbus_message_iter_get_arg_type (&dict_iter)) == DBUS_TYPE_DICT_ENTRY) 864 { 865 dbus_message_iter_recurse (&dict_iter, &dict_entry_iter); 866 867 while ((key_type = dbus_message_iter_get_arg_type (&dict_entry_iter)) == DBUS_TYPE_STRING) 868 { 869 char *key; 870 char *value; 871 int value_type; 872 873 dbus_message_iter_get_basic (&dict_entry_iter, &key); 874 dbus_message_iter_next (&dict_entry_iter); 875 876 value_type = dbus_message_iter_get_arg_type (&dict_entry_iter); 877 878 if (value_type != DBUS_TYPE_STRING) 879 break; 880 881 dbus_message_iter_get_basic (&dict_entry_iter, &value); 882 883 if (!_dbus_list_append (&keys, key)) 884 { 885 BUS_SET_OOM (error); 886 break; 887 } 888 889 if (!_dbus_list_append (&values, value)) 890 { 891 BUS_SET_OOM (error); 892 break; 893 } 894 895 dbus_message_iter_next (&dict_entry_iter); 896 } 897 898 if (key_type != DBUS_TYPE_INVALID) 899 break; 900 901 dbus_message_iter_next (&dict_iter); 902 } 903 904 if (array_type != DBUS_TYPE_INVALID) 905 goto out; 906 907 _dbus_assert (_dbus_list_get_length (&keys) == _dbus_list_get_length (&values)); 908 909 key_link = keys; 910 value_link = values; 911 while (key_link != NULL) 912 { 913 const char *key; 914 const char *value; 915 916 key = key_link->data; 917 value = value_link->data; 918 919 if (!bus_activation_set_environment_variable (activation, 920 key, value, error)) 921 { 922 _DBUS_ASSERT_ERROR_IS_SET (error); 923 _dbus_verbose ("bus_activation_set_environment_variable() failed\n"); 924 break; 925 } 926 key_link = _dbus_list_get_next_link (&keys, key_link); 927 value_link = _dbus_list_get_next_link (&values, value_link); 928 } 929 930 /* FIXME: We can fail early having set only some of the environment variables, 931 * (because of OOM failure). It's sort of hard to fix and it doesn't really 932 * matter, so we're punting for now. 933 */ 934 if (key_link != NULL) 935 goto out; 936 937 if (!send_ack_reply (connection, transaction, 938 message, error)) 939 goto out; 940 941 retval = TRUE; 942 943 out: 944 _dbus_list_clear (&keys); 945 _dbus_list_clear (&values); 946 return retval; 947 } 948 949 static dbus_bool_t 950 bus_driver_handle_add_match (DBusConnection *connection, 951 BusTransaction *transaction, 952 DBusMessage *message, 953 DBusError *error) 954 { 955 BusMatchRule *rule; 956 const char *text; 957 DBusString str; 958 BusMatchmaker *matchmaker; 959 960 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 961 962 text = NULL; 963 rule = NULL; 964 965 if (bus_connection_get_n_match_rules (connection) >= 966 bus_context_get_max_match_rules_per_connection (bus_transaction_get_context (transaction))) 967 { 968 dbus_set_error (error, DBUS_ERROR_LIMITS_EXCEEDED, 969 "Connection \"%s\" is not allowed to add more match rules " 970 "(increase limits in configuration file if required)", 971 bus_connection_is_active (connection) ? 972 bus_connection_get_name (connection) : 973 "(inactive)"); 974 goto failed; 975 } 976 977 if (!dbus_message_get_args (message, error, 978 DBUS_TYPE_STRING, &text, 979 DBUS_TYPE_INVALID)) 980 { 981 _dbus_verbose ("No memory to get arguments to AddMatch\n"); 982 goto failed; 983 } 984 985 _dbus_string_init_const (&str, text); 986 987 rule = bus_match_rule_parse (connection, &str, error); 988 if (rule == NULL) 989 goto failed; 990 991 matchmaker = bus_connection_get_matchmaker (connection); 992 993 if (!bus_matchmaker_add_rule (matchmaker, rule)) 994 { 995 BUS_SET_OOM (error); 996 goto failed; 997 } 998 999 if (!send_ack_reply (connection, transaction, 1000 message, error)) 1001 { 1002 bus_matchmaker_remove_rule (matchmaker, rule); 1003 goto failed; 1004 } 1005 1006 bus_match_rule_unref (rule); 1007 1008 return TRUE; 1009 1010 failed: 1011 _DBUS_ASSERT_ERROR_IS_SET (error); 1012 if (rule) 1013 bus_match_rule_unref (rule); 1014 return FALSE; 1015 } 1016 1017 static dbus_bool_t 1018 bus_driver_handle_remove_match (DBusConnection *connection, 1019 BusTransaction *transaction, 1020 DBusMessage *message, 1021 DBusError *error) 1022 { 1023 BusMatchRule *rule; 1024 const char *text; 1025 DBusString str; 1026 BusMatchmaker *matchmaker; 1027 1028 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1029 1030 text = NULL; 1031 rule = NULL; 1032 1033 if (!dbus_message_get_args (message, error, 1034 DBUS_TYPE_STRING, &text, 1035 DBUS_TYPE_INVALID)) 1036 { 1037 _dbus_verbose ("No memory to get arguments to RemoveMatch\n"); 1038 goto failed; 1039 } 1040 1041 _dbus_string_init_const (&str, text); 1042 1043 rule = bus_match_rule_parse (connection, &str, error); 1044 if (rule == NULL) 1045 goto failed; 1046 1047 /* Send the ack before we remove the rule, since the ack is undone 1048 * on transaction cancel, but rule removal isn't. 1049 */ 1050 if (!send_ack_reply (connection, transaction, 1051 message, error)) 1052 goto failed; 1053 1054 matchmaker = bus_connection_get_matchmaker (connection); 1055 1056 if (!bus_matchmaker_remove_rule_by_value (matchmaker, rule, error)) 1057 goto failed; 1058 1059 bus_match_rule_unref (rule); 1060 1061 return TRUE; 1062 1063 failed: 1064 _DBUS_ASSERT_ERROR_IS_SET (error); 1065 if (rule) 1066 bus_match_rule_unref (rule); 1067 return FALSE; 1068 } 1069 1070 static dbus_bool_t 1071 bus_driver_handle_get_service_owner (DBusConnection *connection, 1072 BusTransaction *transaction, 1073 DBusMessage *message, 1074 DBusError *error) 1075 { 1076 const char *text; 1077 const char *base_name; 1078 DBusString str; 1079 BusRegistry *registry; 1080 BusService *service; 1081 DBusMessage *reply; 1082 1083 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1084 1085 registry = bus_connection_get_registry (connection); 1086 1087 text = NULL; 1088 reply = NULL; 1089 1090 if (! dbus_message_get_args (message, error, 1091 DBUS_TYPE_STRING, &text, 1092 DBUS_TYPE_INVALID)) 1093 goto failed; 1094 1095 _dbus_string_init_const (&str, text); 1096 service = bus_registry_lookup (registry, &str); 1097 if (service == NULL && 1098 _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS)) 1099 { 1100 /* ORG_FREEDESKTOP_DBUS owns itself */ 1101 base_name = DBUS_SERVICE_DBUS; 1102 } 1103 else if (service == NULL) 1104 { 1105 dbus_set_error (error, 1106 DBUS_ERROR_NAME_HAS_NO_OWNER, 1107 "Could not get owner of name '%s': no such name", text); 1108 goto failed; 1109 } 1110 else 1111 { 1112 base_name = bus_connection_get_name (bus_service_get_primary_owners_connection (service)); 1113 if (base_name == NULL) 1114 { 1115 /* FIXME - how is this error possible? */ 1116 dbus_set_error (error, 1117 DBUS_ERROR_FAILED, 1118 "Could not determine unique name for '%s'", text); 1119 goto failed; 1120 } 1121 _dbus_assert (*base_name == ':'); 1122 } 1123 1124 _dbus_assert (base_name != NULL); 1125 1126 reply = dbus_message_new_method_return (message); 1127 if (reply == NULL) 1128 goto oom; 1129 1130 if (! dbus_message_append_args (reply, 1131 DBUS_TYPE_STRING, &base_name, 1132 DBUS_TYPE_INVALID)) 1133 goto oom; 1134 1135 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1136 goto oom; 1137 1138 dbus_message_unref (reply); 1139 1140 return TRUE; 1141 1142 oom: 1143 BUS_SET_OOM (error); 1144 1145 failed: 1146 _DBUS_ASSERT_ERROR_IS_SET (error); 1147 if (reply) 1148 dbus_message_unref (reply); 1149 return FALSE; 1150 } 1151 1152 static dbus_bool_t 1153 bus_driver_handle_list_queued_owners (DBusConnection *connection, 1154 BusTransaction *transaction, 1155 DBusMessage *message, 1156 DBusError *error) 1157 { 1158 const char *text; 1159 DBusList *base_names; 1160 DBusList *link; 1161 DBusString str; 1162 BusRegistry *registry; 1163 BusService *service; 1164 DBusMessage *reply; 1165 DBusMessageIter iter, array_iter; 1166 char *dbus_service_name = DBUS_SERVICE_DBUS; 1167 1168 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1169 1170 registry = bus_connection_get_registry (connection); 1171 1172 base_names = NULL; 1173 text = NULL; 1174 reply = NULL; 1175 1176 if (! dbus_message_get_args (message, error, 1177 DBUS_TYPE_STRING, &text, 1178 DBUS_TYPE_INVALID)) 1179 goto failed; 1180 1181 _dbus_string_init_const (&str, text); 1182 service = bus_registry_lookup (registry, &str); 1183 if (service == NULL && 1184 _dbus_string_equal_c_str (&str, DBUS_SERVICE_DBUS)) 1185 { 1186 /* ORG_FREEDESKTOP_DBUS owns itself */ 1187 if (! _dbus_list_append (&base_names, dbus_service_name)) 1188 goto oom; 1189 } 1190 else if (service == NULL) 1191 { 1192 dbus_set_error (error, 1193 DBUS_ERROR_NAME_HAS_NO_OWNER, 1194 "Could not get owners of name '%s': no such name", text); 1195 goto failed; 1196 } 1197 else 1198 { 1199 if (!bus_service_list_queued_owners (service, 1200 &base_names, 1201 error)) 1202 goto failed; 1203 } 1204 1205 _dbus_assert (base_names != NULL); 1206 1207 reply = dbus_message_new_method_return (message); 1208 if (reply == NULL) 1209 goto oom; 1210 1211 dbus_message_iter_init_append (reply, &iter); 1212 if (!dbus_message_iter_open_container (&iter, 1213 DBUS_TYPE_ARRAY, 1214 DBUS_TYPE_STRING_AS_STRING, 1215 &array_iter)) 1216 goto oom; 1217 1218 link = _dbus_list_get_first_link (&base_names); 1219 while (link != NULL) 1220 { 1221 char *uname; 1222 1223 _dbus_assert (link->data != NULL); 1224 uname = (char *)link->data; 1225 1226 if (!dbus_message_iter_append_basic (&array_iter, 1227 DBUS_TYPE_STRING, 1228 &uname)) 1229 goto oom; 1230 1231 link = _dbus_list_get_next_link (&base_names, link); 1232 } 1233 1234 if (! dbus_message_iter_close_container (&iter, &array_iter)) 1235 goto oom; 1236 1237 1238 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1239 goto oom; 1240 1241 dbus_message_unref (reply); 1242 1243 return TRUE; 1244 1245 oom: 1246 BUS_SET_OOM (error); 1247 1248 failed: 1249 _DBUS_ASSERT_ERROR_IS_SET (error); 1250 if (reply) 1251 dbus_message_unref (reply); 1252 1253 if (base_names) 1254 _dbus_list_clear (&base_names); 1255 1256 return FALSE; 1257 } 1258 1259 static dbus_bool_t 1260 bus_driver_handle_get_connection_unix_user (DBusConnection *connection, 1261 BusTransaction *transaction, 1262 DBusMessage *message, 1263 DBusError *error) 1264 { 1265 const char *service; 1266 DBusString str; 1267 BusRegistry *registry; 1268 BusService *serv; 1269 DBusConnection *conn; 1270 DBusMessage *reply; 1271 unsigned long uid; 1272 dbus_uint32_t uid32; 1273 1274 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1275 1276 registry = bus_connection_get_registry (connection); 1277 1278 service = NULL; 1279 reply = NULL; 1280 1281 if (! dbus_message_get_args (message, error, 1282 DBUS_TYPE_STRING, &service, 1283 DBUS_TYPE_INVALID)) 1284 goto failed; 1285 1286 _dbus_verbose ("asked for UID of connection %s\n", service); 1287 1288 _dbus_string_init_const (&str, service); 1289 serv = bus_registry_lookup (registry, &str); 1290 if (serv == NULL) 1291 { 1292 dbus_set_error (error, 1293 DBUS_ERROR_NAME_HAS_NO_OWNER, 1294 "Could not get UID of name '%s': no such name", service); 1295 goto failed; 1296 } 1297 1298 conn = bus_service_get_primary_owners_connection (serv); 1299 1300 reply = dbus_message_new_method_return (message); 1301 if (reply == NULL) 1302 goto oom; 1303 1304 if (!dbus_connection_get_unix_user (conn, &uid)) 1305 { 1306 dbus_set_error (error, 1307 DBUS_ERROR_FAILED, 1308 "Could not determine UID for '%s'", service); 1309 goto failed; 1310 } 1311 1312 uid32 = uid; 1313 if (! dbus_message_append_args (reply, 1314 DBUS_TYPE_UINT32, &uid32, 1315 DBUS_TYPE_INVALID)) 1316 goto oom; 1317 1318 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1319 goto oom; 1320 1321 dbus_message_unref (reply); 1322 1323 return TRUE; 1324 1325 oom: 1326 BUS_SET_OOM (error); 1327 1328 failed: 1329 _DBUS_ASSERT_ERROR_IS_SET (error); 1330 if (reply) 1331 dbus_message_unref (reply); 1332 return FALSE; 1333 } 1334 1335 static dbus_bool_t 1336 bus_driver_handle_get_connection_unix_process_id (DBusConnection *connection, 1337 BusTransaction *transaction, 1338 DBusMessage *message, 1339 DBusError *error) 1340 { 1341 const char *service; 1342 DBusString str; 1343 BusRegistry *registry; 1344 BusService *serv; 1345 DBusConnection *conn; 1346 DBusMessage *reply; 1347 unsigned long pid; 1348 dbus_uint32_t pid32; 1349 1350 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1351 1352 registry = bus_connection_get_registry (connection); 1353 1354 service = NULL; 1355 reply = NULL; 1356 1357 if (! dbus_message_get_args (message, error, 1358 DBUS_TYPE_STRING, &service, 1359 DBUS_TYPE_INVALID)) 1360 goto failed; 1361 1362 _dbus_verbose ("asked for PID of connection %s\n", service); 1363 1364 _dbus_string_init_const (&str, service); 1365 serv = bus_registry_lookup (registry, &str); 1366 if (serv == NULL) 1367 { 1368 dbus_set_error (error, 1369 DBUS_ERROR_NAME_HAS_NO_OWNER, 1370 "Could not get PID of name '%s': no such name", service); 1371 goto failed; 1372 } 1373 1374 conn = bus_service_get_primary_owners_connection (serv); 1375 1376 reply = dbus_message_new_method_return (message); 1377 if (reply == NULL) 1378 goto oom; 1379 1380 if (!dbus_connection_get_unix_process_id (conn, &pid)) 1381 { 1382 dbus_set_error (error, 1383 DBUS_ERROR_UNIX_PROCESS_ID_UNKNOWN, 1384 "Could not determine PID for '%s'", service); 1385 goto failed; 1386 } 1387 1388 pid32 = pid; 1389 if (! dbus_message_append_args (reply, 1390 DBUS_TYPE_UINT32, &pid32, 1391 DBUS_TYPE_INVALID)) 1392 goto oom; 1393 1394 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1395 goto oom; 1396 1397 dbus_message_unref (reply); 1398 1399 return TRUE; 1400 1401 oom: 1402 BUS_SET_OOM (error); 1403 1404 failed: 1405 _DBUS_ASSERT_ERROR_IS_SET (error); 1406 if (reply) 1407 dbus_message_unref (reply); 1408 return FALSE; 1409 } 1410 1411 static dbus_bool_t 1412 bus_driver_handle_get_adt_audit_session_data (DBusConnection *connection, 1413 BusTransaction *transaction, 1414 DBusMessage *message, 1415 DBusError *error) 1416 { 1417 const char *service; 1418 DBusString str; 1419 BusRegistry *registry; 1420 BusService *serv; 1421 DBusConnection *conn; 1422 DBusMessage *reply; 1423 void *data = NULL; 1424 dbus_uint32_t data_size; 1425 1426 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1427 1428 registry = bus_connection_get_registry (connection); 1429 1430 service = NULL; 1431 reply = NULL; 1432 1433 if (! dbus_message_get_args (message, error, 1434 DBUS_TYPE_STRING, &service, 1435 DBUS_TYPE_INVALID)) 1436 goto failed; 1437 1438 _dbus_verbose ("asked for audit session data for connection %s\n", service); 1439 1440 _dbus_string_init_const (&str, service); 1441 serv = bus_registry_lookup (registry, &str); 1442 if (serv == NULL) 1443 { 1444 dbus_set_error (error, 1445 DBUS_ERROR_NAME_HAS_NO_OWNER, 1446 "Could not get audit session data for name '%s': no such name", service); 1447 goto failed; 1448 } 1449 1450 conn = bus_service_get_primary_owners_connection (serv); 1451 1452 reply = dbus_message_new_method_return (message); 1453 if (reply == NULL) 1454 goto oom; 1455 1456 if (!dbus_connection_get_adt_audit_session_data (conn, &data, &data_size) || data == NULL) 1457 { 1458 dbus_set_error (error, 1459 DBUS_ERROR_ADT_AUDIT_DATA_UNKNOWN, 1460 "Could not determine audit session data for '%s'", service); 1461 goto failed; 1462 } 1463 1464 if (! dbus_message_append_args (reply, 1465 DBUS_TYPE_ARRAY, DBUS_TYPE_BYTE, &data, data_size, 1466 DBUS_TYPE_INVALID)) 1467 goto oom; 1468 1469 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1470 goto oom; 1471 1472 dbus_message_unref (reply); 1473 1474 return TRUE; 1475 1476 oom: 1477 BUS_SET_OOM (error); 1478 1479 failed: 1480 _DBUS_ASSERT_ERROR_IS_SET (error); 1481 if (reply) 1482 dbus_message_unref (reply); 1483 return FALSE; 1484 } 1485 1486 static dbus_bool_t 1487 bus_driver_handle_get_connection_selinux_security_context (DBusConnection *connection, 1488 BusTransaction *transaction, 1489 DBusMessage *message, 1490 DBusError *error) 1491 { 1492 const char *service; 1493 DBusString str; 1494 BusRegistry *registry; 1495 BusService *serv; 1496 DBusConnection *conn; 1497 DBusMessage *reply; 1498 BusSELinuxID *context; 1499 1500 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1501 1502 registry = bus_connection_get_registry (connection); 1503 1504 service = NULL; 1505 reply = NULL; 1506 1507 if (! dbus_message_get_args (message, error, 1508 DBUS_TYPE_STRING, &service, 1509 DBUS_TYPE_INVALID)) 1510 goto failed; 1511 1512 _dbus_verbose ("asked for security context of connection %s\n", service); 1513 1514 _dbus_string_init_const (&str, service); 1515 serv = bus_registry_lookup (registry, &str); 1516 if (serv == NULL) 1517 { 1518 dbus_set_error (error, 1519 DBUS_ERROR_NAME_HAS_NO_OWNER, 1520 "Could not get security context of name '%s': no such name", service); 1521 goto failed; 1522 } 1523 1524 conn = bus_service_get_primary_owners_connection (serv); 1525 1526 reply = dbus_message_new_method_return (message); 1527 if (reply == NULL) 1528 goto oom; 1529 1530 context = bus_connection_get_selinux_id (conn); 1531 if (!context) 1532 { 1533 dbus_set_error (error, 1534 DBUS_ERROR_SELINUX_SECURITY_CONTEXT_UNKNOWN, 1535 "Could not determine security context for '%s'", service); 1536 goto failed; 1537 } 1538 1539 if (! bus_selinux_append_context (reply, context, error)) 1540 goto failed; 1541 1542 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1543 goto oom; 1544 1545 dbus_message_unref (reply); 1546 1547 return TRUE; 1548 1549 oom: 1550 BUS_SET_OOM (error); 1551 1552 failed: 1553 _DBUS_ASSERT_ERROR_IS_SET (error); 1554 if (reply) 1555 dbus_message_unref (reply); 1556 return FALSE; 1557 } 1558 1559 static dbus_bool_t 1560 bus_driver_handle_reload_config (DBusConnection *connection, 1561 BusTransaction *transaction, 1562 DBusMessage *message, 1563 DBusError *error) 1564 { 1565 BusContext *context; 1566 DBusMessage *reply; 1567 1568 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1569 1570 reply = NULL; 1571 1572 context = bus_connection_get_context (connection); 1573 if (!bus_context_reload_config (context, error)) 1574 goto failed; 1575 1576 reply = dbus_message_new_method_return (message); 1577 if (reply == NULL) 1578 goto oom; 1579 1580 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1581 goto oom; 1582 1583 dbus_message_unref (reply); 1584 return TRUE; 1585 1586 oom: 1587 BUS_SET_OOM (error); 1588 1589 failed: 1590 _DBUS_ASSERT_ERROR_IS_SET (error); 1591 if (reply) 1592 dbus_message_unref (reply); 1593 return FALSE; 1594 } 1595 1596 static dbus_bool_t 1597 bus_driver_handle_get_id (DBusConnection *connection, 1598 BusTransaction *transaction, 1599 DBusMessage *message, 1600 DBusError *error) 1601 { 1602 BusContext *context; 1603 DBusMessage *reply; 1604 DBusString uuid; 1605 const char *v_STRING; 1606 1607 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1608 1609 if (!_dbus_string_init (&uuid)) 1610 { 1611 BUS_SET_OOM (error); 1612 return FALSE; 1613 } 1614 1615 reply = NULL; 1616 1617 context = bus_connection_get_context (connection); 1618 if (!bus_context_get_id (context, &uuid)) 1619 goto oom; 1620 1621 reply = dbus_message_new_method_return (message); 1622 if (reply == NULL) 1623 goto oom; 1624 1625 v_STRING = _dbus_string_get_const_data (&uuid); 1626 if (!dbus_message_append_args (reply, 1627 DBUS_TYPE_STRING, &v_STRING, 1628 DBUS_TYPE_INVALID)) 1629 goto oom; 1630 1631 _dbus_assert (dbus_message_has_signature (reply, "s")); 1632 1633 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1634 goto oom; 1635 1636 _dbus_string_free (&uuid); 1637 dbus_message_unref (reply); 1638 return TRUE; 1639 1640 oom: 1641 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1642 1643 BUS_SET_OOM (error); 1644 1645 if (reply) 1646 dbus_message_unref (reply); 1647 _dbus_string_free (&uuid); 1648 return FALSE; 1649 } 1650 1651 typedef struct 1652 { 1653 const char *name; 1654 const char *in_args; 1655 const char *out_args; 1656 dbus_bool_t (* handler) (DBusConnection *connection, 1657 BusTransaction *transaction, 1658 DBusMessage *message, 1659 DBusError *error); 1660 } MessageHandler; 1661 1662 /* For speed it might be useful to sort this in order of 1663 * frequency of use (but doesn't matter with only a few items 1664 * anyhow) 1665 */ 1666 static const MessageHandler dbus_message_handlers[] = { 1667 { "Hello", 1668 "", 1669 DBUS_TYPE_STRING_AS_STRING, 1670 bus_driver_handle_hello }, 1671 { "RequestName", 1672 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING, 1673 DBUS_TYPE_UINT32_AS_STRING, 1674 bus_driver_handle_acquire_service }, 1675 { "ReleaseName", 1676 DBUS_TYPE_STRING_AS_STRING, 1677 DBUS_TYPE_UINT32_AS_STRING, 1678 bus_driver_handle_release_service }, 1679 { "StartServiceByName", 1680 DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_UINT32_AS_STRING, 1681 DBUS_TYPE_UINT32_AS_STRING, 1682 bus_driver_handle_activate_service }, 1683 { "UpdateActivationEnvironment", 1684 DBUS_TYPE_ARRAY_AS_STRING DBUS_DICT_ENTRY_BEGIN_CHAR_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_TYPE_STRING_AS_STRING DBUS_DICT_ENTRY_END_CHAR_AS_STRING, 1685 "", 1686 bus_driver_handle_update_activation_environment }, 1687 { "NameHasOwner", 1688 DBUS_TYPE_STRING_AS_STRING, 1689 DBUS_TYPE_BOOLEAN_AS_STRING, 1690 bus_driver_handle_service_exists }, 1691 { "ListNames", 1692 "", 1693 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, 1694 bus_driver_handle_list_services }, 1695 { "ListActivatableNames", 1696 "", 1697 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, 1698 bus_driver_handle_list_activatable_services }, 1699 { "AddMatch", 1700 DBUS_TYPE_STRING_AS_STRING, 1701 "", 1702 bus_driver_handle_add_match }, 1703 { "RemoveMatch", 1704 DBUS_TYPE_STRING_AS_STRING, 1705 "", 1706 bus_driver_handle_remove_match }, 1707 { "GetNameOwner", 1708 DBUS_TYPE_STRING_AS_STRING, 1709 DBUS_TYPE_STRING_AS_STRING, 1710 bus_driver_handle_get_service_owner }, 1711 { "ListQueuedOwners", 1712 DBUS_TYPE_STRING_AS_STRING, 1713 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_STRING_AS_STRING, 1714 bus_driver_handle_list_queued_owners }, 1715 { "GetConnectionUnixUser", 1716 DBUS_TYPE_STRING_AS_STRING, 1717 DBUS_TYPE_UINT32_AS_STRING, 1718 bus_driver_handle_get_connection_unix_user }, 1719 { "GetConnectionUnixProcessID", 1720 DBUS_TYPE_STRING_AS_STRING, 1721 DBUS_TYPE_UINT32_AS_STRING, 1722 bus_driver_handle_get_connection_unix_process_id }, 1723 { "GetAdtAuditSessionData", 1724 DBUS_TYPE_STRING_AS_STRING, 1725 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING, 1726 bus_driver_handle_get_adt_audit_session_data }, 1727 { "GetConnectionSELinuxSecurityContext", 1728 DBUS_TYPE_STRING_AS_STRING, 1729 DBUS_TYPE_ARRAY_AS_STRING DBUS_TYPE_BYTE_AS_STRING, 1730 bus_driver_handle_get_connection_selinux_security_context }, 1731 { "ReloadConfig", 1732 "", 1733 "", 1734 bus_driver_handle_reload_config }, 1735 { "GetId", 1736 "", 1737 DBUS_TYPE_STRING_AS_STRING, 1738 bus_driver_handle_get_id }, 1739 { NULL, NULL, NULL, NULL } 1740 }; 1741 1742 static dbus_bool_t bus_driver_handle_introspect (DBusConnection *, 1743 BusTransaction *, DBusMessage *, DBusError *); 1744 1745 static const MessageHandler introspectable_message_handlers[] = { 1746 { "Introspect", "", DBUS_TYPE_STRING_AS_STRING, bus_driver_handle_introspect }, 1747 { NULL, NULL, NULL, NULL } 1748 }; 1749 1750 #ifdef DBUS_ENABLE_STATS 1751 static const MessageHandler stats_message_handlers[] = { 1752 { "GetStats", "", "a{sv}", bus_stats_handle_get_stats }, 1753 { "GetConnectionStats", "s", "a{sv}", bus_stats_handle_get_connection_stats }, 1754 { NULL, NULL, NULL, NULL } 1755 }; 1756 #endif 1757 1758 typedef struct { 1759 const char *name; 1760 const MessageHandler *message_handlers; 1761 const char *extra_introspection; 1762 } InterfaceHandler; 1763 1764 /* These should ideally be sorted by frequency of use, although it 1765 * probably doesn't matter with this few items */ 1766 static InterfaceHandler interface_handlers[] = { 1767 { DBUS_INTERFACE_DBUS, dbus_message_handlers, 1768 " <signal name=\"NameOwnerChanged\">\n" 1769 " <arg type=\"s\"/>\n" 1770 " <arg type=\"s\"/>\n" 1771 " <arg type=\"s\"/>\n" 1772 " </signal>\n" 1773 " <signal name=\"NameLost\">\n" 1774 " <arg type=\"s\"/>\n" 1775 " </signal>\n" 1776 " <signal name=\"NameAcquired\">\n" 1777 " <arg type=\"s\"/>\n" 1778 " </signal>\n" }, 1779 { DBUS_INTERFACE_INTROSPECTABLE, introspectable_message_handlers, NULL }, 1780 #ifdef DBUS_ENABLE_STATS 1781 { BUS_INTERFACE_STATS, stats_message_handlers, NULL }, 1782 #endif 1783 { NULL, NULL, NULL } 1784 }; 1785 1786 static dbus_bool_t 1787 write_args_for_direction (DBusString *xml, 1788 const char *signature, 1789 dbus_bool_t in) 1790 { 1791 DBusTypeReader typereader; 1792 DBusString sigstr; 1793 int current_type; 1794 1795 _dbus_string_init_const (&sigstr, signature); 1796 _dbus_type_reader_init_types_only (&typereader, &sigstr, 0); 1797 1798 while ((current_type = _dbus_type_reader_get_current_type (&typereader)) != DBUS_TYPE_INVALID) 1799 { 1800 const DBusString *subsig; 1801 int start, len; 1802 1803 _dbus_type_reader_get_signature (&typereader, &subsig, &start, &len); 1804 if (!_dbus_string_append_printf (xml, " <arg direction=\"%s\" type=\"", 1805 in ? "in" : "out")) 1806 goto oom; 1807 if (!_dbus_string_append_len (xml, 1808 _dbus_string_get_const_data (subsig) + start, 1809 len)) 1810 goto oom; 1811 if (!_dbus_string_append (xml, "\"/>\n")) 1812 goto oom; 1813 1814 _dbus_type_reader_next (&typereader); 1815 } 1816 return TRUE; 1817 oom: 1818 return FALSE; 1819 } 1820 1821 dbus_bool_t 1822 bus_driver_generate_introspect_string (DBusString *xml) 1823 { 1824 const InterfaceHandler *ih; 1825 const MessageHandler *mh; 1826 1827 if (!_dbus_string_append (xml, DBUS_INTROSPECT_1_0_XML_DOCTYPE_DECL_NODE)) 1828 return FALSE; 1829 if (!_dbus_string_append (xml, "<node>\n")) 1830 return FALSE; 1831 1832 for (ih = interface_handlers; ih->name != NULL; ih++) 1833 { 1834 if (!_dbus_string_append_printf (xml, " <interface name=\"%s\">\n", 1835 ih->name)) 1836 return FALSE; 1837 1838 for (mh = ih->message_handlers; mh->name != NULL; mh++) 1839 { 1840 if (!_dbus_string_append_printf (xml, " <method name=\"%s\">\n", 1841 mh->name)) 1842 return FALSE; 1843 1844 if (!write_args_for_direction (xml, mh->in_args, TRUE)) 1845 return FALSE; 1846 1847 if (!write_args_for_direction (xml, mh->out_args, FALSE)) 1848 return FALSE; 1849 1850 if (!_dbus_string_append (xml, " </method>\n")) 1851 return FALSE; 1852 } 1853 1854 if (ih->extra_introspection != NULL && 1855 !_dbus_string_append (xml, ih->extra_introspection)) 1856 return FALSE; 1857 1858 if (!_dbus_string_append (xml, " </interface>\n")) 1859 return FALSE; 1860 } 1861 1862 if (!_dbus_string_append (xml, "</node>\n")) 1863 return FALSE; 1864 1865 return TRUE; 1866 } 1867 1868 static dbus_bool_t 1869 bus_driver_handle_introspect (DBusConnection *connection, 1870 BusTransaction *transaction, 1871 DBusMessage *message, 1872 DBusError *error) 1873 { 1874 DBusString xml; 1875 DBusMessage *reply; 1876 const char *v_STRING; 1877 1878 _dbus_verbose ("Introspect() on bus driver\n"); 1879 1880 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1881 1882 reply = NULL; 1883 1884 if (! dbus_message_get_args (message, error, 1885 DBUS_TYPE_INVALID)) 1886 { 1887 _DBUS_ASSERT_ERROR_IS_SET (error); 1888 return FALSE; 1889 } 1890 1891 if (!_dbus_string_init (&xml)) 1892 { 1893 BUS_SET_OOM (error); 1894 return FALSE; 1895 } 1896 1897 if (!bus_driver_generate_introspect_string (&xml)) 1898 goto oom; 1899 1900 v_STRING = _dbus_string_get_const_data (&xml); 1901 1902 reply = dbus_message_new_method_return (message); 1903 if (reply == NULL) 1904 goto oom; 1905 1906 if (! dbus_message_append_args (reply, 1907 DBUS_TYPE_STRING, &v_STRING, 1908 DBUS_TYPE_INVALID)) 1909 goto oom; 1910 1911 if (! bus_transaction_send_from_driver (transaction, connection, reply)) 1912 goto oom; 1913 1914 dbus_message_unref (reply); 1915 _dbus_string_free (&xml); 1916 1917 return TRUE; 1918 1919 oom: 1920 BUS_SET_OOM (error); 1921 1922 if (reply) 1923 dbus_message_unref (reply); 1924 1925 _dbus_string_free (&xml); 1926 1927 return FALSE; 1928 } 1929 1930 dbus_bool_t 1931 bus_driver_handle_message (DBusConnection *connection, 1932 BusTransaction *transaction, 1933 DBusMessage *message, 1934 DBusError *error) 1935 { 1936 const char *name, *interface; 1937 const InterfaceHandler *ih; 1938 const MessageHandler *mh; 1939 dbus_bool_t found_interface = FALSE; 1940 1941 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1942 1943 if (dbus_message_is_signal (message, "org.freedesktop.systemd1.Activator", "ActivationFailure")) 1944 { 1945 BusContext *context; 1946 1947 context = bus_connection_get_context (connection); 1948 return dbus_activation_systemd_failure(bus_context_get_activation(context), message); 1949 } 1950 1951 if (dbus_message_get_type (message) != DBUS_MESSAGE_TYPE_METHOD_CALL) 1952 { 1953 _dbus_verbose ("Driver got a non-method-call message, ignoring\n"); 1954 return TRUE; /* we just ignore this */ 1955 } 1956 1957 /* may be NULL, which means "any interface will do" */ 1958 interface = dbus_message_get_interface (message); 1959 1960 _dbus_assert (dbus_message_get_member (message) != NULL); 1961 1962 name = dbus_message_get_member (message); 1963 1964 _dbus_verbose ("Driver got a method call: %s\n", name); 1965 1966 /* security checks should have kept this from getting here */ 1967 #ifndef DBUS_DISABLE_ASSERT 1968 { 1969 const char *sender = dbus_message_get_sender (message); 1970 1971 _dbus_assert (sender != NULL || strcmp (name, "Hello") == 0); 1972 } 1973 #endif 1974 1975 for (ih = interface_handlers; ih->name != NULL; ih++) 1976 { 1977 if (interface != NULL && strcmp (interface, ih->name) != 0) 1978 continue; 1979 1980 found_interface = TRUE; 1981 1982 for (mh = ih->message_handlers; mh->name != NULL; mh++) 1983 { 1984 if (strcmp (mh->name, name) != 0) 1985 continue; 1986 1987 _dbus_verbose ("Found driver handler for %s\n", name); 1988 1989 if (!dbus_message_has_signature (message, mh->in_args)) 1990 { 1991 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 1992 _dbus_verbose ("Call to %s has wrong args (%s, expected %s)\n", 1993 name, dbus_message_get_signature (message), 1994 mh->in_args); 1995 1996 dbus_set_error (error, DBUS_ERROR_INVALID_ARGS, 1997 "Call to %s has wrong args (%s, expected %s)\n", 1998 name, dbus_message_get_signature (message), 1999 mh->in_args); 2000 _DBUS_ASSERT_ERROR_IS_SET (error); 2001 return FALSE; 2002 } 2003 2004 if ((* mh->handler) (connection, transaction, message, error)) 2005 { 2006 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 2007 _dbus_verbose ("Driver handler succeeded\n"); 2008 return TRUE; 2009 } 2010 else 2011 { 2012 _DBUS_ASSERT_ERROR_IS_SET (error); 2013 _dbus_verbose ("Driver handler returned failure\n"); 2014 return FALSE; 2015 } 2016 } 2017 } 2018 2019 _dbus_verbose ("No driver handler for message \"%s\"\n", 2020 name); 2021 2022 dbus_set_error (error, found_interface ? DBUS_ERROR_UNKNOWN_METHOD : DBUS_ERROR_UNKNOWN_INTERFACE, 2023 "%s does not understand message %s", 2024 DBUS_SERVICE_DBUS, name); 2025 2026 return FALSE; 2027 } 2028 2029 void 2030 bus_driver_remove_connection (DBusConnection *connection) 2031 { 2032 /* FIXME 1.0 Does nothing for now, should unregister the connection 2033 * with the bus driver. 2034 */ 2035 } 2036