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