1 /* -*- mode: C; c-file-style: "gnu"; indent-tabs-mode: nil; -*- */ 2 /* policy.c Bus security policy 3 * 4 * Copyright (C) 2003, 2004 Red Hat, Inc. 5 * 6 * Licensed under the Academic Free License version 2.1 7 * 8 * This program is free software; you can redistribute it and/or modify 9 * it under the terms of the GNU General Public License as published by 10 * the Free Software Foundation; either version 2 of the License, or 11 * (at your option) any later version. 12 * 13 * This program is distributed in the hope that it will be useful, 14 * but WITHOUT ANY WARRANTY; without even the implied warranty of 15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 16 * GNU General Public License for more details. 17 * 18 * You should have received a copy of the GNU General Public License 19 * along with this program; if not, write to the Free Software 20 * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA 21 * 22 */ 23 24 #include <config.h> 25 #include "policy.h" 26 #include "services.h" 27 #include "test.h" 28 #include "utils.h" 29 #include <dbus/dbus-list.h> 30 #include <dbus/dbus-hash.h> 31 #include <dbus/dbus-internals.h> 32 33 BusPolicyRule* 34 bus_policy_rule_new (BusPolicyRuleType type, 35 dbus_bool_t allow) 36 { 37 BusPolicyRule *rule; 38 39 rule = dbus_new0 (BusPolicyRule, 1); 40 if (rule == NULL) 41 return NULL; 42 43 rule->type = type; 44 rule->refcount = 1; 45 rule->allow = allow; 46 47 switch (rule->type) 48 { 49 case BUS_POLICY_RULE_USER: 50 rule->d.user.uid = DBUS_UID_UNSET; 51 break; 52 case BUS_POLICY_RULE_GROUP: 53 rule->d.group.gid = DBUS_GID_UNSET; 54 break; 55 case BUS_POLICY_RULE_SEND: 56 rule->d.send.message_type = DBUS_MESSAGE_TYPE_INVALID; 57 58 /* allow rules default to TRUE (only requested replies allowed) 59 * deny rules default to FALSE (only unrequested replies denied) 60 */ 61 rule->d.send.requested_reply = rule->allow; 62 break; 63 case BUS_POLICY_RULE_RECEIVE: 64 rule->d.receive.message_type = DBUS_MESSAGE_TYPE_INVALID; 65 /* allow rules default to TRUE (only requested replies allowed) 66 * deny rules default to FALSE (only unrequested replies denied) 67 */ 68 rule->d.receive.requested_reply = rule->allow; 69 break; 70 case BUS_POLICY_RULE_OWN: 71 break; 72 } 73 74 return rule; 75 } 76 77 BusPolicyRule * 78 bus_policy_rule_ref (BusPolicyRule *rule) 79 { 80 _dbus_assert (rule->refcount > 0); 81 82 rule->refcount += 1; 83 84 return rule; 85 } 86 87 void 88 bus_policy_rule_unref (BusPolicyRule *rule) 89 { 90 _dbus_assert (rule->refcount > 0); 91 92 rule->refcount -= 1; 93 94 if (rule->refcount == 0) 95 { 96 switch (rule->type) 97 { 98 case BUS_POLICY_RULE_SEND: 99 dbus_free (rule->d.send.path); 100 dbus_free (rule->d.send.interface); 101 dbus_free (rule->d.send.member); 102 dbus_free (rule->d.send.error); 103 dbus_free (rule->d.send.destination); 104 break; 105 case BUS_POLICY_RULE_RECEIVE: 106 dbus_free (rule->d.receive.path); 107 dbus_free (rule->d.receive.interface); 108 dbus_free (rule->d.receive.member); 109 dbus_free (rule->d.receive.error); 110 dbus_free (rule->d.receive.origin); 111 break; 112 case BUS_POLICY_RULE_OWN: 113 dbus_free (rule->d.own.service_name); 114 break; 115 case BUS_POLICY_RULE_USER: 116 break; 117 case BUS_POLICY_RULE_GROUP: 118 break; 119 } 120 121 dbus_free (rule); 122 } 123 } 124 125 struct BusPolicy 126 { 127 int refcount; 128 129 DBusList *default_rules; /**< Default policy rules */ 130 DBusList *mandatory_rules; /**< Mandatory policy rules */ 131 DBusHashTable *rules_by_uid; /**< per-UID policy rules */ 132 DBusHashTable *rules_by_gid; /**< per-GID policy rules */ 133 DBusList *at_console_true_rules; /**< console user policy rules where at_console="true"*/ 134 DBusList *at_console_false_rules; /**< console user policy rules where at_console="false"*/ 135 }; 136 137 static void 138 free_rule_func (void *data, 139 void *user_data) 140 { 141 BusPolicyRule *rule = data; 142 143 bus_policy_rule_unref (rule); 144 } 145 146 static void 147 free_rule_list_func (void *data) 148 { 149 DBusList **list = data; 150 151 if (list == NULL) /* DBusHashTable is on crack */ 152 return; 153 154 _dbus_list_foreach (list, free_rule_func, NULL); 155 156 _dbus_list_clear (list); 157 158 dbus_free (list); 159 } 160 161 BusPolicy* 162 bus_policy_new (void) 163 { 164 BusPolicy *policy; 165 166 policy = dbus_new0 (BusPolicy, 1); 167 if (policy == NULL) 168 return NULL; 169 170 policy->refcount = 1; 171 172 policy->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_UINTPTR, 173 NULL, 174 free_rule_list_func); 175 if (policy->rules_by_uid == NULL) 176 goto failed; 177 178 policy->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_UINTPTR, 179 NULL, 180 free_rule_list_func); 181 if (policy->rules_by_gid == NULL) 182 goto failed; 183 184 return policy; 185 186 failed: 187 bus_policy_unref (policy); 188 return NULL; 189 } 190 191 BusPolicy * 192 bus_policy_ref (BusPolicy *policy) 193 { 194 _dbus_assert (policy->refcount > 0); 195 196 policy->refcount += 1; 197 198 return policy; 199 } 200 201 void 202 bus_policy_unref (BusPolicy *policy) 203 { 204 _dbus_assert (policy->refcount > 0); 205 206 policy->refcount -= 1; 207 208 if (policy->refcount == 0) 209 { 210 _dbus_list_foreach (&policy->default_rules, free_rule_func, NULL); 211 _dbus_list_clear (&policy->default_rules); 212 213 _dbus_list_foreach (&policy->mandatory_rules, free_rule_func, NULL); 214 _dbus_list_clear (&policy->mandatory_rules); 215 216 _dbus_list_foreach (&policy->at_console_true_rules, free_rule_func, NULL); 217 _dbus_list_clear (&policy->at_console_true_rules); 218 219 _dbus_list_foreach (&policy->at_console_false_rules, free_rule_func, NULL); 220 _dbus_list_clear (&policy->at_console_false_rules); 221 222 if (policy->rules_by_uid) 223 { 224 _dbus_hash_table_unref (policy->rules_by_uid); 225 policy->rules_by_uid = NULL; 226 } 227 228 if (policy->rules_by_gid) 229 { 230 _dbus_hash_table_unref (policy->rules_by_gid); 231 policy->rules_by_gid = NULL; 232 } 233 234 dbus_free (policy); 235 } 236 } 237 238 static dbus_bool_t 239 add_list_to_client (DBusList **list, 240 BusClientPolicy *client) 241 { 242 DBusList *link; 243 244 link = _dbus_list_get_first_link (list); 245 while (link != NULL) 246 { 247 BusPolicyRule *rule = link->data; 248 link = _dbus_list_get_next_link (list, link); 249 250 switch (rule->type) 251 { 252 case BUS_POLICY_RULE_USER: 253 case BUS_POLICY_RULE_GROUP: 254 /* These aren't per-connection policies */ 255 break; 256 257 case BUS_POLICY_RULE_OWN: 258 case BUS_POLICY_RULE_SEND: 259 case BUS_POLICY_RULE_RECEIVE: 260 /* These are per-connection */ 261 if (!bus_client_policy_append_rule (client, rule)) 262 return FALSE; 263 break; 264 } 265 } 266 267 return TRUE; 268 } 269 270 BusClientPolicy* 271 bus_policy_create_client_policy (BusPolicy *policy, 272 DBusConnection *connection, 273 DBusError *error) 274 { 275 BusClientPolicy *client; 276 dbus_uid_t uid; 277 dbus_bool_t at_console; 278 279 _dbus_assert (dbus_connection_get_is_authenticated (connection)); 280 _DBUS_ASSERT_ERROR_IS_CLEAR (error); 281 282 client = bus_client_policy_new (); 283 if (client == NULL) 284 goto nomem; 285 286 if (!add_list_to_client (&policy->default_rules, 287 client)) 288 goto nomem; 289 290 /* we avoid the overhead of looking up user's groups 291 * if we don't have any group rules anyway 292 */ 293 if (_dbus_hash_table_get_n_entries (policy->rules_by_gid) > 0) 294 { 295 unsigned long *groups; 296 int n_groups; 297 int i; 298 299 if (!bus_connection_get_unix_groups (connection, &groups, &n_groups, error)) 300 goto failed; 301 302 i = 0; 303 while (i < n_groups) 304 { 305 DBusList **list; 306 307 list = _dbus_hash_table_lookup_uintptr (policy->rules_by_gid, 308 groups[i]); 309 310 if (list != NULL) 311 { 312 if (!add_list_to_client (list, client)) 313 { 314 dbus_free (groups); 315 goto nomem; 316 } 317 } 318 319 ++i; 320 } 321 322 dbus_free (groups); 323 } 324 325 if (dbus_connection_get_unix_user (connection, &uid)) 326 { 327 if (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0) 328 { 329 DBusList **list; 330 331 list = _dbus_hash_table_lookup_uintptr (policy->rules_by_uid, 332 uid); 333 334 if (list != NULL) 335 { 336 if (!add_list_to_client (list, client)) 337 goto nomem; 338 } 339 } 340 341 /* Add console rules */ 342 at_console = _dbus_unix_user_is_at_console (uid, error); 343 344 if (at_console) 345 { 346 if (!add_list_to_client (&policy->at_console_true_rules, client)) 347 goto nomem; 348 } 349 else if (dbus_error_is_set (error) == TRUE) 350 { 351 goto failed; 352 } 353 else if (!add_list_to_client (&policy->at_console_false_rules, client)) 354 { 355 goto nomem; 356 } 357 } 358 359 if (!add_list_to_client (&policy->mandatory_rules, 360 client)) 361 goto nomem; 362 363 bus_client_policy_optimize (client); 364 365 return client; 366 367 nomem: 368 BUS_SET_OOM (error); 369 failed: 370 _DBUS_ASSERT_ERROR_IS_SET (error); 371 if (client) 372 bus_client_policy_unref (client); 373 return NULL; 374 } 375 376 static dbus_bool_t 377 list_allows_user (dbus_bool_t def, 378 DBusList **list, 379 unsigned long uid, 380 const unsigned long *group_ids, 381 int n_group_ids) 382 { 383 DBusList *link; 384 dbus_bool_t allowed; 385 386 allowed = def; 387 388 link = _dbus_list_get_first_link (list); 389 while (link != NULL) 390 { 391 BusPolicyRule *rule = link->data; 392 link = _dbus_list_get_next_link (list, link); 393 394 if (rule->type == BUS_POLICY_RULE_USER) 395 { 396 _dbus_verbose ("List %p user rule uid="DBUS_UID_FORMAT"\n", 397 list, rule->d.user.uid); 398 399 if (rule->d.user.uid == DBUS_UID_UNSET) 400 ; /* '*' wildcard */ 401 else if (rule->d.user.uid != uid) 402 continue; 403 } 404 else if (rule->type == BUS_POLICY_RULE_GROUP) 405 { 406 _dbus_verbose ("List %p group rule uid="DBUS_UID_FORMAT"\n", 407 list, rule->d.user.uid); 408 409 if (rule->d.group.gid == DBUS_GID_UNSET) 410 ; /* '*' wildcard */ 411 else 412 { 413 int i; 414 415 i = 0; 416 while (i < n_group_ids) 417 { 418 if (rule->d.group.gid == group_ids[i]) 419 break; 420 ++i; 421 } 422 423 if (i == n_group_ids) 424 continue; 425 } 426 } 427 else 428 continue; 429 430 allowed = rule->allow; 431 } 432 433 return allowed; 434 } 435 436 dbus_bool_t 437 bus_policy_allow_unix_user (BusPolicy *policy, 438 unsigned long uid) 439 { 440 dbus_bool_t allowed; 441 unsigned long *group_ids; 442 int n_group_ids; 443 444 /* On OOM or error we always reject the user */ 445 if (!_dbus_unix_groups_from_uid (uid, &group_ids, &n_group_ids)) 446 { 447 _dbus_verbose ("Did not get any groups for UID %lu\n", 448 uid); 449 return FALSE; 450 } 451 452 /* Default to "user owning bus" can connect */ 453 allowed = _dbus_unix_user_is_process_owner (uid); 454 455 allowed = list_allows_user (allowed, 456 &policy->default_rules, 457 uid, 458 group_ids, n_group_ids); 459 460 allowed = list_allows_user (allowed, 461 &policy->mandatory_rules, 462 uid, 463 group_ids, n_group_ids); 464 465 dbus_free (group_ids); 466 467 _dbus_verbose ("UID %lu allowed = %d\n", uid, allowed); 468 469 return allowed; 470 } 471 472 /* For now this is never actually called because the default 473 * DBusConnection behavior of 'same user that owns the bus can 474 * connect' is all it would do. Set the windows user function in 475 * connection.c if the config file ever supports doing something 476 * interesting here. 477 */ 478 dbus_bool_t 479 bus_policy_allow_windows_user (BusPolicy *policy, 480 const char *windows_sid) 481 { 482 /* Windows has no policies here since only the session bus 483 * is really used for now, so just checking that the 484 * connecting person is the same as the bus owner is fine. 485 */ 486 return _dbus_windows_user_is_process_owner (windows_sid); 487 } 488 489 dbus_bool_t 490 bus_policy_append_default_rule (BusPolicy *policy, 491 BusPolicyRule *rule) 492 { 493 if (!_dbus_list_append (&policy->default_rules, rule)) 494 return FALSE; 495 496 bus_policy_rule_ref (rule); 497 498 return TRUE; 499 } 500 501 dbus_bool_t 502 bus_policy_append_mandatory_rule (BusPolicy *policy, 503 BusPolicyRule *rule) 504 { 505 if (!_dbus_list_append (&policy->mandatory_rules, rule)) 506 return FALSE; 507 508 bus_policy_rule_ref (rule); 509 510 return TRUE; 511 } 512 513 514 515 static DBusList** 516 get_list (DBusHashTable *hash, 517 unsigned long key) 518 { 519 DBusList **list; 520 521 list = _dbus_hash_table_lookup_uintptr (hash, key); 522 523 if (list == NULL) 524 { 525 list = dbus_new0 (DBusList*, 1); 526 if (list == NULL) 527 return NULL; 528 529 if (!_dbus_hash_table_insert_uintptr (hash, key, list)) 530 { 531 dbus_free (list); 532 return NULL; 533 } 534 } 535 536 return list; 537 } 538 539 dbus_bool_t 540 bus_policy_append_user_rule (BusPolicy *policy, 541 dbus_uid_t uid, 542 BusPolicyRule *rule) 543 { 544 DBusList **list; 545 546 list = get_list (policy->rules_by_uid, uid); 547 548 if (list == NULL) 549 return FALSE; 550 551 if (!_dbus_list_append (list, rule)) 552 return FALSE; 553 554 bus_policy_rule_ref (rule); 555 556 return TRUE; 557 } 558 559 dbus_bool_t 560 bus_policy_append_group_rule (BusPolicy *policy, 561 dbus_gid_t gid, 562 BusPolicyRule *rule) 563 { 564 DBusList **list; 565 566 list = get_list (policy->rules_by_gid, gid); 567 568 if (list == NULL) 569 return FALSE; 570 571 if (!_dbus_list_append (list, rule)) 572 return FALSE; 573 574 bus_policy_rule_ref (rule); 575 576 return TRUE; 577 } 578 579 dbus_bool_t 580 bus_policy_append_console_rule (BusPolicy *policy, 581 dbus_bool_t at_console, 582 BusPolicyRule *rule) 583 { 584 if (at_console) 585 { 586 if (!_dbus_list_append (&policy->at_console_true_rules, rule)) 587 return FALSE; 588 } 589 else 590 { 591 if (!_dbus_list_append (&policy->at_console_false_rules, rule)) 592 return FALSE; 593 } 594 595 bus_policy_rule_ref (rule); 596 597 return TRUE; 598 599 } 600 601 static dbus_bool_t 602 append_copy_of_policy_list (DBusList **list, 603 DBusList **to_append) 604 { 605 DBusList *link; 606 DBusList *tmp_list; 607 608 tmp_list = NULL; 609 610 /* Preallocate all our links */ 611 link = _dbus_list_get_first_link (to_append); 612 while (link != NULL) 613 { 614 if (!_dbus_list_append (&tmp_list, link->data)) 615 { 616 _dbus_list_clear (&tmp_list); 617 return FALSE; 618 } 619 620 link = _dbus_list_get_next_link (to_append, link); 621 } 622 623 /* Now append them */ 624 while ((link = _dbus_list_pop_first_link (&tmp_list))) 625 { 626 bus_policy_rule_ref (link->data); 627 _dbus_list_append_link (list, link); 628 } 629 630 return TRUE; 631 } 632 633 static dbus_bool_t 634 merge_id_hash (DBusHashTable *dest, 635 DBusHashTable *to_absorb) 636 { 637 DBusHashIter iter; 638 639 _dbus_hash_iter_init (to_absorb, &iter); 640 while (_dbus_hash_iter_next (&iter)) 641 { 642 unsigned long id = _dbus_hash_iter_get_uintptr_key (&iter); 643 DBusList **list = _dbus_hash_iter_get_value (&iter); 644 DBusList **target = get_list (dest, id); 645 646 if (target == NULL) 647 return FALSE; 648 649 if (!append_copy_of_policy_list (target, list)) 650 return FALSE; 651 } 652 653 return TRUE; 654 } 655 656 dbus_bool_t 657 bus_policy_merge (BusPolicy *policy, 658 BusPolicy *to_absorb) 659 { 660 /* FIXME Not properly atomic, but as used for configuration files we 661 * don't rely on it quite so much. 662 */ 663 664 if (!append_copy_of_policy_list (&policy->default_rules, 665 &to_absorb->default_rules)) 666 return FALSE; 667 668 if (!append_copy_of_policy_list (&policy->mandatory_rules, 669 &to_absorb->mandatory_rules)) 670 return FALSE; 671 672 if (!append_copy_of_policy_list (&policy->at_console_true_rules, 673 &to_absorb->at_console_true_rules)) 674 return FALSE; 675 676 if (!append_copy_of_policy_list (&policy->at_console_false_rules, 677 &to_absorb->at_console_false_rules)) 678 return FALSE; 679 680 if (!merge_id_hash (policy->rules_by_uid, 681 to_absorb->rules_by_uid)) 682 return FALSE; 683 684 if (!merge_id_hash (policy->rules_by_gid, 685 to_absorb->rules_by_gid)) 686 return FALSE; 687 688 return TRUE; 689 } 690 691 struct BusClientPolicy 692 { 693 int refcount; 694 695 DBusList *rules; 696 }; 697 698 BusClientPolicy* 699 bus_client_policy_new (void) 700 { 701 BusClientPolicy *policy; 702 703 policy = dbus_new0 (BusClientPolicy, 1); 704 if (policy == NULL) 705 return NULL; 706 707 policy->refcount = 1; 708 709 return policy; 710 } 711 712 BusClientPolicy * 713 bus_client_policy_ref (BusClientPolicy *policy) 714 { 715 _dbus_assert (policy->refcount > 0); 716 717 policy->refcount += 1; 718 719 return policy; 720 } 721 722 static void 723 rule_unref_foreach (void *data, 724 void *user_data) 725 { 726 BusPolicyRule *rule = data; 727 728 bus_policy_rule_unref (rule); 729 } 730 731 void 732 bus_client_policy_unref (BusClientPolicy *policy) 733 { 734 _dbus_assert (policy->refcount > 0); 735 736 policy->refcount -= 1; 737 738 if (policy->refcount == 0) 739 { 740 _dbus_list_foreach (&policy->rules, 741 rule_unref_foreach, 742 NULL); 743 744 _dbus_list_clear (&policy->rules); 745 746 dbus_free (policy); 747 } 748 } 749 750 static void 751 remove_rules_by_type_up_to (BusClientPolicy *policy, 752 BusPolicyRuleType type, 753 DBusList *up_to) 754 { 755 DBusList *link; 756 757 link = _dbus_list_get_first_link (&policy->rules); 758 while (link != up_to) 759 { 760 BusPolicyRule *rule = link->data; 761 DBusList *next = _dbus_list_get_next_link (&policy->rules, link); 762 763 if (rule->type == type) 764 { 765 _dbus_list_remove_link (&policy->rules, link); 766 bus_policy_rule_unref (rule); 767 } 768 769 link = next; 770 } 771 } 772 773 void 774 bus_client_policy_optimize (BusClientPolicy *policy) 775 { 776 DBusList *link; 777 778 /* The idea here is that if we have: 779 * 780 * <allow send_interface="foo.bar"/> 781 * <deny send_interface="*"/> 782 * 783 * (for example) the deny will always override the allow. So we 784 * delete the allow. Ditto for deny followed by allow, etc. This is 785 * a dumb thing to put in a config file, but the <include> feature 786 * of files allows for an "inheritance and override" pattern where 787 * it could make sense. If an included file wants to "start over" 788 * with a blanket deny, no point keeping the rules from the parent 789 * file. 790 */ 791 792 _dbus_verbose ("Optimizing policy with %d rules\n", 793 _dbus_list_get_length (&policy->rules)); 794 795 link = _dbus_list_get_first_link (&policy->rules); 796 while (link != NULL) 797 { 798 BusPolicyRule *rule; 799 DBusList *next; 800 dbus_bool_t remove_preceding; 801 802 next = _dbus_list_get_next_link (&policy->rules, link); 803 rule = link->data; 804 805 remove_preceding = FALSE; 806 807 _dbus_assert (rule != NULL); 808 809 switch (rule->type) 810 { 811 case BUS_POLICY_RULE_SEND: 812 remove_preceding = 813 rule->d.send.message_type == DBUS_MESSAGE_TYPE_INVALID && 814 rule->d.send.path == NULL && 815 rule->d.send.interface == NULL && 816 rule->d.send.member == NULL && 817 rule->d.send.error == NULL && 818 rule->d.send.destination == NULL; 819 break; 820 case BUS_POLICY_RULE_RECEIVE: 821 remove_preceding = 822 rule->d.receive.message_type == DBUS_MESSAGE_TYPE_INVALID && 823 rule->d.receive.path == NULL && 824 rule->d.receive.interface == NULL && 825 rule->d.receive.member == NULL && 826 rule->d.receive.error == NULL && 827 rule->d.receive.origin == NULL; 828 break; 829 case BUS_POLICY_RULE_OWN: 830 remove_preceding = 831 rule->d.own.service_name == NULL; 832 break; 833 case BUS_POLICY_RULE_USER: 834 case BUS_POLICY_RULE_GROUP: 835 _dbus_assert_not_reached ("invalid rule"); 836 break; 837 } 838 839 if (remove_preceding) 840 remove_rules_by_type_up_to (policy, rule->type, 841 link); 842 843 link = next; 844 } 845 846 _dbus_verbose ("After optimization, policy has %d rules\n", 847 _dbus_list_get_length (&policy->rules)); 848 } 849 850 dbus_bool_t 851 bus_client_policy_append_rule (BusClientPolicy *policy, 852 BusPolicyRule *rule) 853 { 854 _dbus_verbose ("Appending rule %p with type %d to policy %p\n", 855 rule, rule->type, policy); 856 857 if (!_dbus_list_append (&policy->rules, rule)) 858 return FALSE; 859 860 bus_policy_rule_ref (rule); 861 862 return TRUE; 863 } 864 865 dbus_bool_t 866 bus_client_policy_check_can_send (BusClientPolicy *policy, 867 BusRegistry *registry, 868 dbus_bool_t requested_reply, 869 DBusConnection *receiver, 870 DBusMessage *message, 871 dbus_int32_t *toggles, 872 dbus_bool_t *log) 873 { 874 DBusList *link; 875 dbus_bool_t allowed; 876 877 /* policy->rules is in the order the rules appeared 878 * in the config file, i.e. last rule that applies wins 879 */ 880 881 _dbus_verbose (" (policy) checking send rules\n"); 882 *toggles = 0; 883 884 allowed = FALSE; 885 link = _dbus_list_get_first_link (&policy->rules); 886 while (link != NULL) 887 { 888 BusPolicyRule *rule = link->data; 889 890 link = _dbus_list_get_next_link (&policy->rules, link); 891 892 /* Rule is skipped if it specifies a different 893 * message name from the message, or a different 894 * destination from the message 895 */ 896 897 if (rule->type != BUS_POLICY_RULE_SEND) 898 { 899 _dbus_verbose (" (policy) skipping non-send rule\n"); 900 continue; 901 } 902 903 if (rule->d.send.message_type != DBUS_MESSAGE_TYPE_INVALID) 904 { 905 if (dbus_message_get_type (message) != rule->d.send.message_type) 906 { 907 _dbus_verbose (" (policy) skipping rule for different message type\n"); 908 continue; 909 } 910 } 911 912 /* If it's a reply, the requested_reply flag kicks in */ 913 if (dbus_message_get_reply_serial (message) != 0) 914 { 915 /* for allow, requested_reply=true means the rule applies 916 * only when reply was requested. requested_reply=false means 917 * always allow. 918 */ 919 if (!requested_reply && rule->allow && rule->d.send.requested_reply && !rule->d.send.eavesdrop) 920 { 921 _dbus_verbose (" (policy) skipping allow rule since it only applies to requested replies and does not allow eavesdropping\n"); 922 continue; 923 } 924 925 /* for deny, requested_reply=false means the rule applies only 926 * when the reply was not requested. requested_reply=true means the 927 * rule always applies. 928 */ 929 if (requested_reply && !rule->allow && !rule->d.send.requested_reply) 930 { 931 _dbus_verbose (" (policy) skipping deny rule since it only applies to unrequested replies\n"); 932 continue; 933 } 934 } 935 936 if (rule->d.send.path != NULL) 937 { 938 if (dbus_message_get_path (message) != NULL && 939 strcmp (dbus_message_get_path (message), 940 rule->d.send.path) != 0) 941 { 942 _dbus_verbose (" (policy) skipping rule for different path\n"); 943 continue; 944 } 945 } 946 947 if (rule->d.send.interface != NULL) 948 { 949 /* The interface is optional in messages. For allow rules, if the message 950 * has no interface we want to skip the rule (and thus not allow); 951 * for deny rules, if the message has no interface we want to use the 952 * rule (and thus deny). 953 */ 954 dbus_bool_t no_interface; 955 956 no_interface = dbus_message_get_interface (message) == NULL; 957 958 if ((no_interface && rule->allow) || 959 (!no_interface && 960 strcmp (dbus_message_get_interface (message), 961 rule->d.send.interface) != 0)) 962 { 963 _dbus_verbose (" (policy) skipping rule for different interface\n"); 964 continue; 965 } 966 } 967 968 if (rule->d.send.member != NULL) 969 { 970 if (dbus_message_get_member (message) != NULL && 971 strcmp (dbus_message_get_member (message), 972 rule->d.send.member) != 0) 973 { 974 _dbus_verbose (" (policy) skipping rule for different member\n"); 975 continue; 976 } 977 } 978 979 if (rule->d.send.error != NULL) 980 { 981 if (dbus_message_get_error_name (message) != NULL && 982 strcmp (dbus_message_get_error_name (message), 983 rule->d.send.error) != 0) 984 { 985 _dbus_verbose (" (policy) skipping rule for different error name\n"); 986 continue; 987 } 988 } 989 990 if (rule->d.send.destination != NULL) 991 { 992 /* receiver can be NULL for messages that are sent to the 993 * message bus itself, we check the strings in that case as 994 * built-in services don't have a DBusConnection but messages 995 * to them have a destination service name. 996 */ 997 if (receiver == NULL) 998 { 999 if (!dbus_message_has_destination (message, 1000 rule->d.send.destination)) 1001 { 1002 _dbus_verbose (" (policy) skipping rule because message dest is not %s\n", 1003 rule->d.send.destination); 1004 continue; 1005 } 1006 } 1007 else 1008 { 1009 DBusString str; 1010 BusService *service; 1011 1012 _dbus_string_init_const (&str, rule->d.send.destination); 1013 1014 service = bus_registry_lookup (registry, &str); 1015 if (service == NULL) 1016 { 1017 _dbus_verbose (" (policy) skipping rule because dest %s doesn't exist\n", 1018 rule->d.send.destination); 1019 continue; 1020 } 1021 1022 if (!bus_service_has_owner (service, receiver)) 1023 { 1024 _dbus_verbose (" (policy) skipping rule because dest %s isn't owned by receiver\n", 1025 rule->d.send.destination); 1026 continue; 1027 } 1028 } 1029 } 1030 1031 /* Use this rule */ 1032 allowed = rule->allow; 1033 *log = rule->d.send.log; 1034 (*toggles)++; 1035 1036 _dbus_verbose (" (policy) used rule, allow now = %d\n", 1037 allowed); 1038 } 1039 1040 return allowed; 1041 } 1042 1043 /* See docs on what the args mean on bus_context_check_security_policy() 1044 * comment 1045 */ 1046 dbus_bool_t 1047 bus_client_policy_check_can_receive (BusClientPolicy *policy, 1048 BusRegistry *registry, 1049 dbus_bool_t requested_reply, 1050 DBusConnection *sender, 1051 DBusConnection *addressed_recipient, 1052 DBusConnection *proposed_recipient, 1053 DBusMessage *message, 1054 dbus_int32_t *toggles) 1055 { 1056 DBusList *link; 1057 dbus_bool_t allowed; 1058 dbus_bool_t eavesdropping; 1059 1060 eavesdropping = 1061 addressed_recipient != proposed_recipient && 1062 dbus_message_get_destination (message) != NULL; 1063 1064 /* policy->rules is in the order the rules appeared 1065 * in the config file, i.e. last rule that applies wins 1066 */ 1067 1068 _dbus_verbose (" (policy) checking receive rules, eavesdropping = %d\n", eavesdropping); 1069 *toggles = 0; 1070 1071 allowed = FALSE; 1072 link = _dbus_list_get_first_link (&policy->rules); 1073 while (link != NULL) 1074 { 1075 BusPolicyRule *rule = link->data; 1076 1077 link = _dbus_list_get_next_link (&policy->rules, link); 1078 1079 if (rule->type != BUS_POLICY_RULE_RECEIVE) 1080 { 1081 _dbus_verbose (" (policy) skipping non-receive rule\n"); 1082 continue; 1083 } 1084 1085 if (rule->d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID) 1086 { 1087 if (dbus_message_get_type (message) != rule->d.receive.message_type) 1088 { 1089 _dbus_verbose (" (policy) skipping rule for different message type\n"); 1090 continue; 1091 } 1092 } 1093 1094 /* for allow, eavesdrop=false means the rule doesn't apply when 1095 * eavesdropping. eavesdrop=true means always allow. 1096 */ 1097 if (eavesdropping && rule->allow && !rule->d.receive.eavesdrop) 1098 { 1099 _dbus_verbose (" (policy) skipping allow rule since it doesn't apply to eavesdropping\n"); 1100 continue; 1101 } 1102 1103 /* for deny, eavesdrop=true means the rule applies only when 1104 * eavesdropping; eavesdrop=false means always deny. 1105 */ 1106 if (!eavesdropping && !rule->allow && rule->d.receive.eavesdrop) 1107 { 1108 _dbus_verbose (" (policy) skipping deny rule since it only applies to eavesdropping\n"); 1109 continue; 1110 } 1111 1112 /* If it's a reply, the requested_reply flag kicks in */ 1113 if (dbus_message_get_reply_serial (message) != 0) 1114 { 1115 /* for allow, requested_reply=true means the rule applies 1116 * only when reply was requested. requested_reply=false means 1117 * always allow. 1118 */ 1119 if (!requested_reply && rule->allow && rule->d.receive.requested_reply && !rule->d.receive.eavesdrop) 1120 { 1121 _dbus_verbose (" (policy) skipping allow rule since it only applies to requested replies and does not allow eavesdropping\n"); 1122 continue; 1123 } 1124 1125 /* for deny, requested_reply=false means the rule applies only 1126 * when the reply was not requested. requested_reply=true means the 1127 * rule always applies. 1128 */ 1129 if (requested_reply && !rule->allow && !rule->d.receive.requested_reply) 1130 { 1131 _dbus_verbose (" (policy) skipping deny rule since it only applies to unrequested replies\n"); 1132 continue; 1133 } 1134 } 1135 1136 if (rule->d.receive.path != NULL) 1137 { 1138 if (dbus_message_get_path (message) != NULL && 1139 strcmp (dbus_message_get_path (message), 1140 rule->d.receive.path) != 0) 1141 { 1142 _dbus_verbose (" (policy) skipping rule for different path\n"); 1143 continue; 1144 } 1145 } 1146 1147 if (rule->d.receive.interface != NULL) 1148 { 1149 /* The interface is optional in messages. For allow rules, if the message 1150 * has no interface we want to skip the rule (and thus not allow); 1151 * for deny rules, if the message has no interface we want to use the 1152 * rule (and thus deny). 1153 */ 1154 dbus_bool_t no_interface; 1155 1156 no_interface = dbus_message_get_interface (message) == NULL; 1157 1158 if ((no_interface && rule->allow) || 1159 (!no_interface && 1160 strcmp (dbus_message_get_interface (message), 1161 rule->d.receive.interface) != 0)) 1162 { 1163 _dbus_verbose (" (policy) skipping rule for different interface\n"); 1164 continue; 1165 } 1166 } 1167 1168 if (rule->d.receive.member != NULL) 1169 { 1170 if (dbus_message_get_member (message) != NULL && 1171 strcmp (dbus_message_get_member (message), 1172 rule->d.receive.member) != 0) 1173 { 1174 _dbus_verbose (" (policy) skipping rule for different member\n"); 1175 continue; 1176 } 1177 } 1178 1179 if (rule->d.receive.error != NULL) 1180 { 1181 if (dbus_message_get_error_name (message) != NULL && 1182 strcmp (dbus_message_get_error_name (message), 1183 rule->d.receive.error) != 0) 1184 { 1185 _dbus_verbose (" (policy) skipping rule for different error name\n"); 1186 continue; 1187 } 1188 } 1189 1190 if (rule->d.receive.origin != NULL) 1191 { 1192 /* sender can be NULL for messages that originate from the 1193 * message bus itself, we check the strings in that case as 1194 * built-in services don't have a DBusConnection but will 1195 * still set the sender on their messages. 1196 */ 1197 if (sender == NULL) 1198 { 1199 if (!dbus_message_has_sender (message, 1200 rule->d.receive.origin)) 1201 { 1202 _dbus_verbose (" (policy) skipping rule because message sender is not %s\n", 1203 rule->d.receive.origin); 1204 continue; 1205 } 1206 } 1207 else 1208 { 1209 BusService *service; 1210 DBusString str; 1211 1212 _dbus_string_init_const (&str, rule->d.receive.origin); 1213 1214 service = bus_registry_lookup (registry, &str); 1215 1216 if (service == NULL) 1217 { 1218 _dbus_verbose (" (policy) skipping rule because origin %s doesn't exist\n", 1219 rule->d.receive.origin); 1220 continue; 1221 } 1222 1223 if (!bus_service_has_owner (service, sender)) 1224 { 1225 _dbus_verbose (" (policy) skipping rule because origin %s isn't owned by sender\n", 1226 rule->d.receive.origin); 1227 continue; 1228 } 1229 } 1230 } 1231 1232 /* Use this rule */ 1233 allowed = rule->allow; 1234 (*toggles)++; 1235 1236 _dbus_verbose (" (policy) used rule, allow now = %d\n", 1237 allowed); 1238 } 1239 1240 return allowed; 1241 } 1242 1243 dbus_bool_t 1244 bus_client_policy_check_can_own (BusClientPolicy *policy, 1245 DBusConnection *connection, 1246 const DBusString *service_name) 1247 { 1248 DBusList *link; 1249 dbus_bool_t allowed; 1250 1251 /* policy->rules is in the order the rules appeared 1252 * in the config file, i.e. last rule that applies wins 1253 */ 1254 1255 allowed = FALSE; 1256 link = _dbus_list_get_first_link (&policy->rules); 1257 while (link != NULL) 1258 { 1259 BusPolicyRule *rule = link->data; 1260 1261 link = _dbus_list_get_next_link (&policy->rules, link); 1262 1263 /* Rule is skipped if it specifies a different service name from 1264 * the desired one. 1265 */ 1266 1267 if (rule->type != BUS_POLICY_RULE_OWN) 1268 continue; 1269 1270 if (rule->d.own.service_name != NULL) 1271 { 1272 if (!_dbus_string_equal_c_str (service_name, 1273 rule->d.own.service_name)) 1274 continue; 1275 } 1276 1277 /* Use this rule */ 1278 allowed = rule->allow; 1279 } 1280 1281 return allowed; 1282 } 1283 1284 #ifdef DBUS_BUILD_TESTS 1285 1286 dbus_bool_t 1287 bus_policy_test (const DBusString *test_data_dir) 1288 { 1289 /* This doesn't do anything for now because I decided to do it in 1290 * dispatch.c instead by having some of the clients in dispatch.c 1291 * have particular policies applied to them. 1292 */ 1293 1294 return TRUE; 1295 } 1296 1297 #endif /* DBUS_BUILD_TESTS */ 1298