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