00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include "policy.h"
00025 #include "services.h"
00026 #include "test.h"
00027 #include "utils.h"
00028 #include <dbus/dbus-list.h>
00029 #include <dbus/dbus-hash.h>
00030 #include <dbus/dbus-internals.h>
00031
00032 BusPolicyRule*
00033 bus_policy_rule_new (BusPolicyRuleType type,
00034 dbus_bool_t allow)
00035 {
00036 BusPolicyRule *rule;
00037
00038 rule = dbus_new0 (BusPolicyRule, 1);
00039 if (rule == NULL)
00040 return NULL;
00041
00042 rule->type = type;
00043 rule->refcount = 1;
00044 rule->allow = allow;
00045
00046 switch (rule->type)
00047 {
00048 case BUS_POLICY_RULE_USER:
00049 rule->d.user.uid = DBUS_UID_UNSET;
00050 break;
00051 case BUS_POLICY_RULE_GROUP:
00052 rule->d.group.gid = DBUS_GID_UNSET;
00053 break;
00054 case BUS_POLICY_RULE_SEND:
00055 rule->d.send.message_type = DBUS_MESSAGE_TYPE_INVALID;
00056 break;
00057 case BUS_POLICY_RULE_RECEIVE:
00058 rule->d.receive.message_type = DBUS_MESSAGE_TYPE_INVALID;
00059 break;
00060 case BUS_POLICY_RULE_OWN:
00061 break;
00062 }
00063
00064 return rule;
00065 }
00066
00067 void
00068 bus_policy_rule_ref (BusPolicyRule *rule)
00069 {
00070 _dbus_assert (rule->refcount > 0);
00071
00072 rule->refcount += 1;
00073 }
00074
00075 void
00076 bus_policy_rule_unref (BusPolicyRule *rule)
00077 {
00078 _dbus_assert (rule->refcount > 0);
00079
00080 rule->refcount -= 1;
00081
00082 if (rule->refcount == 0)
00083 {
00084 switch (rule->type)
00085 {
00086 case BUS_POLICY_RULE_SEND:
00087 dbus_free (rule->d.send.path);
00088 dbus_free (rule->d.send.interface);
00089 dbus_free (rule->d.send.member);
00090 dbus_free (rule->d.send.error);
00091 dbus_free (rule->d.send.destination);
00092 break;
00093 case BUS_POLICY_RULE_RECEIVE:
00094 dbus_free (rule->d.receive.path);
00095 dbus_free (rule->d.receive.interface);
00096 dbus_free (rule->d.receive.member);
00097 dbus_free (rule->d.receive.error);
00098 dbus_free (rule->d.receive.origin);
00099 break;
00100 case BUS_POLICY_RULE_OWN:
00101 dbus_free (rule->d.own.service_name);
00102 break;
00103 case BUS_POLICY_RULE_USER:
00104 break;
00105 case BUS_POLICY_RULE_GROUP:
00106 break;
00107 }
00108
00109 dbus_free (rule);
00110 }
00111 }
00112
00113 struct BusPolicy
00114 {
00115 int refcount;
00116
00117 DBusList *default_rules;
00118 DBusList *mandatory_rules;
00119 DBusHashTable *rules_by_uid;
00120 DBusHashTable *rules_by_gid;
00121 };
00122
00123 static void
00124 free_rule_func (void *data,
00125 void *user_data)
00126 {
00127 BusPolicyRule *rule = data;
00128
00129 bus_policy_rule_unref (rule);
00130 }
00131
00132 static void
00133 free_rule_list_func (void *data)
00134 {
00135 DBusList **list = data;
00136
00137 if (list == NULL)
00138 return;
00139
00140 _dbus_list_foreach (list, free_rule_func, NULL);
00141
00142 _dbus_list_clear (list);
00143
00144 dbus_free (list);
00145 }
00146
00147 BusPolicy*
00148 bus_policy_new (void)
00149 {
00150 BusPolicy *policy;
00151
00152 policy = dbus_new0 (BusPolicy, 1);
00153 if (policy == NULL)
00154 return NULL;
00155
00156 policy->refcount = 1;
00157
00158 policy->rules_by_uid = _dbus_hash_table_new (DBUS_HASH_ULONG,
00159 NULL,
00160 free_rule_list_func);
00161 if (policy->rules_by_uid == NULL)
00162 goto failed;
00163
00164 policy->rules_by_gid = _dbus_hash_table_new (DBUS_HASH_ULONG,
00165 NULL,
00166 free_rule_list_func);
00167 if (policy->rules_by_gid == NULL)
00168 goto failed;
00169
00170 return policy;
00171
00172 failed:
00173 bus_policy_unref (policy);
00174 return NULL;
00175 }
00176
00177 void
00178 bus_policy_ref (BusPolicy *policy)
00179 {
00180 _dbus_assert (policy->refcount > 0);
00181
00182 policy->refcount += 1;
00183 }
00184
00185 void
00186 bus_policy_unref (BusPolicy *policy)
00187 {
00188 _dbus_assert (policy->refcount > 0);
00189
00190 policy->refcount -= 1;
00191
00192 if (policy->refcount == 0)
00193 {
00194 _dbus_list_foreach (&policy->default_rules, free_rule_func, NULL);
00195 _dbus_list_clear (&policy->default_rules);
00196
00197 _dbus_list_foreach (&policy->mandatory_rules, free_rule_func, NULL);
00198 _dbus_list_clear (&policy->mandatory_rules);
00199
00200 if (policy->rules_by_uid)
00201 {
00202 _dbus_hash_table_unref (policy->rules_by_uid);
00203 policy->rules_by_uid = NULL;
00204 }
00205
00206 if (policy->rules_by_gid)
00207 {
00208 _dbus_hash_table_unref (policy->rules_by_gid);
00209 policy->rules_by_gid = NULL;
00210 }
00211
00212 dbus_free (policy);
00213 }
00214 }
00215
00216 static dbus_bool_t
00217 add_list_to_client (DBusList **list,
00218 BusClientPolicy *client)
00219 {
00220 DBusList *link;
00221
00222 link = _dbus_list_get_first_link (list);
00223 while (link != NULL)
00224 {
00225 BusPolicyRule *rule = link->data;
00226 link = _dbus_list_get_next_link (list, link);
00227
00228 switch (rule->type)
00229 {
00230 case BUS_POLICY_RULE_USER:
00231 case BUS_POLICY_RULE_GROUP:
00232
00233 break;
00234
00235 case BUS_POLICY_RULE_OWN:
00236 case BUS_POLICY_RULE_SEND:
00237 case BUS_POLICY_RULE_RECEIVE:
00238
00239 if (!bus_client_policy_append_rule (client, rule))
00240 return FALSE;
00241 break;
00242 }
00243 }
00244
00245 return TRUE;
00246 }
00247
00248 BusClientPolicy*
00249 bus_policy_create_client_policy (BusPolicy *policy,
00250 DBusConnection *connection,
00251 DBusError *error)
00252 {
00253 BusClientPolicy *client;
00254 unsigned long uid;
00255
00256 _dbus_assert (dbus_connection_get_is_authenticated (connection));
00257 _DBUS_ASSERT_ERROR_IS_CLEAR (error);
00258
00259 client = bus_client_policy_new ();
00260 if (client == NULL)
00261 goto nomem;
00262
00263 if (!add_list_to_client (&policy->default_rules,
00264 client))
00265 goto nomem;
00266
00267
00268
00269
00270 if (_dbus_hash_table_get_n_entries (policy->rules_by_gid) > 0)
00271 {
00272 unsigned long *groups;
00273 int n_groups;
00274 int i;
00275
00276 if (!bus_connection_get_groups (connection, &groups, &n_groups, error))
00277 goto failed;
00278
00279 i = 0;
00280 while (i < n_groups)
00281 {
00282 DBusList **list;
00283
00284 list = _dbus_hash_table_lookup_ulong (policy->rules_by_gid,
00285 groups[i]);
00286
00287 if (list != NULL)
00288 {
00289 if (!add_list_to_client (list, client))
00290 {
00291 dbus_free (groups);
00292 goto nomem;
00293 }
00294 }
00295
00296 ++i;
00297 }
00298
00299 dbus_free (groups);
00300 }
00301
00302 if (!dbus_connection_get_unix_user (connection, &uid))
00303 {
00304 dbus_set_error (error, DBUS_ERROR_FAILED,
00305 "No user ID known for connection, cannot determine security policy\n");
00306 goto failed;
00307 }
00308
00309 if (_dbus_hash_table_get_n_entries (policy->rules_by_uid) > 0)
00310 {
00311 DBusList **list;
00312
00313 list = _dbus_hash_table_lookup_ulong (policy->rules_by_uid,
00314 uid);
00315
00316 if (list != NULL)
00317 {
00318 if (!add_list_to_client (list, client))
00319 goto nomem;
00320 }
00321 }
00322
00323 if (!add_list_to_client (&policy->mandatory_rules,
00324 client))
00325 goto nomem;
00326
00327 bus_client_policy_optimize (client);
00328
00329 return client;
00330
00331 nomem:
00332 BUS_SET_OOM (error);
00333 failed:
00334 _DBUS_ASSERT_ERROR_IS_SET (error);
00335 if (client)
00336 bus_client_policy_unref (client);
00337 return NULL;
00338 }
00339
00340 static dbus_bool_t
00341 list_allows_user (dbus_bool_t def,
00342 DBusList **list,
00343 unsigned long uid,
00344 const unsigned long *group_ids,
00345 int n_group_ids)
00346 {
00347 DBusList *link;
00348 dbus_bool_t allowed;
00349
00350 allowed = def;
00351
00352 link = _dbus_list_get_first_link (list);
00353 while (link != NULL)
00354 {
00355 BusPolicyRule *rule = link->data;
00356 link = _dbus_list_get_next_link (list, link);
00357
00358 if (rule->type == BUS_POLICY_RULE_USER)
00359 {
00360 _dbus_verbose ("List %p user rule uid="DBUS_UID_FORMAT"\n",
00361 list, rule->d.user.uid);
00362
00363 if (rule->d.user.uid == DBUS_UID_UNSET)
00364 ;
00365 else if (rule->d.user.uid != uid)
00366 continue;
00367 }
00368 else if (rule->type == BUS_POLICY_RULE_GROUP)
00369 {
00370 _dbus_verbose ("List %p group rule uid="DBUS_UID_FORMAT"\n",
00371 list, rule->d.user.uid);
00372
00373 if (rule->d.group.gid == DBUS_GID_UNSET)
00374 ;
00375 else
00376 {
00377 int i;
00378
00379 i = 0;
00380 while (i < n_group_ids)
00381 {
00382 if (rule->d.group.gid == group_ids[i])
00383 break;
00384 ++i;
00385 }
00386
00387 if (i == n_group_ids)
00388 continue;
00389 }
00390 }
00391 else
00392 continue;
00393
00394 allowed = rule->allow;
00395 }
00396
00397 return allowed;
00398 }
00399
00400 dbus_bool_t
00401 bus_policy_allow_user (BusPolicy *policy,
00402 DBusUserDatabase *user_database,
00403 unsigned long uid)
00404 {
00405 dbus_bool_t allowed;
00406 unsigned long *group_ids;
00407 int n_group_ids;
00408
00409
00410 if (!_dbus_user_database_get_groups (user_database,
00411 uid, &group_ids, &n_group_ids, NULL))
00412 {
00413 _dbus_verbose ("Did not get any groups for UID %lu\n",
00414 uid);
00415 return FALSE;
00416 }
00417
00418 allowed = FALSE;
00419
00420 allowed = list_allows_user (allowed,
00421 &policy->default_rules,
00422 uid,
00423 group_ids, n_group_ids);
00424
00425 allowed = list_allows_user (allowed,
00426 &policy->mandatory_rules,
00427 uid,
00428 group_ids, n_group_ids);
00429
00430 dbus_free (group_ids);
00431
00432 _dbus_verbose ("UID %lu allowed = %d\n", uid, allowed);
00433
00434 return allowed;
00435 }
00436
00437 dbus_bool_t
00438 bus_policy_append_default_rule (BusPolicy *policy,
00439 BusPolicyRule *rule)
00440 {
00441 if (!_dbus_list_append (&policy->default_rules, rule))
00442 return FALSE;
00443
00444 bus_policy_rule_ref (rule);
00445
00446 return TRUE;
00447 }
00448
00449 dbus_bool_t
00450 bus_policy_append_mandatory_rule (BusPolicy *policy,
00451 BusPolicyRule *rule)
00452 {
00453 if (!_dbus_list_append (&policy->mandatory_rules, rule))
00454 return FALSE;
00455
00456 bus_policy_rule_ref (rule);
00457
00458 return TRUE;
00459 }
00460
00461 static DBusList**
00462 get_list (DBusHashTable *hash,
00463 unsigned long key)
00464 {
00465 DBusList **list;
00466
00467 list = _dbus_hash_table_lookup_ulong (hash, key);
00468
00469 if (list == NULL)
00470 {
00471 list = dbus_new0 (DBusList*, 1);
00472 if (list == NULL)
00473 return NULL;
00474
00475 if (!_dbus_hash_table_insert_ulong (hash, key, list))
00476 {
00477 dbus_free (list);
00478 return NULL;
00479 }
00480 }
00481
00482 return list;
00483 }
00484
00485 dbus_bool_t
00486 bus_policy_append_user_rule (BusPolicy *policy,
00487 dbus_uid_t uid,
00488 BusPolicyRule *rule)
00489 {
00490 DBusList **list;
00491
00492 list = get_list (policy->rules_by_uid, uid);
00493
00494 if (list == NULL)
00495 return FALSE;
00496
00497 if (!_dbus_list_append (list, rule))
00498 return FALSE;
00499
00500 bus_policy_rule_ref (rule);
00501
00502 return TRUE;
00503 }
00504
00505 dbus_bool_t
00506 bus_policy_append_group_rule (BusPolicy *policy,
00507 dbus_gid_t gid,
00508 BusPolicyRule *rule)
00509 {
00510 DBusList **list;
00511
00512 list = get_list (policy->rules_by_gid, gid);
00513
00514 if (list == NULL)
00515 return FALSE;
00516
00517 if (!_dbus_list_append (list, rule))
00518 return FALSE;
00519
00520 bus_policy_rule_ref (rule);
00521
00522 return TRUE;
00523 }
00524
00525 static dbus_bool_t
00526 append_copy_of_policy_list (DBusList **list,
00527 DBusList **to_append)
00528 {
00529 DBusList *link;
00530 DBusList *tmp_list;
00531
00532 tmp_list = NULL;
00533
00534
00535 link = _dbus_list_get_first_link (to_append);
00536 while (link != NULL)
00537 {
00538 if (!_dbus_list_append (&tmp_list, link->data))
00539 {
00540 _dbus_list_clear (&tmp_list);
00541 return FALSE;
00542 }
00543
00544 link = _dbus_list_get_next_link (to_append, link);
00545 }
00546
00547
00548 while ((link = _dbus_list_pop_first_link (&tmp_list)))
00549 {
00550 bus_policy_rule_ref (link->data);
00551 _dbus_list_append_link (list, link);
00552 }
00553
00554 return TRUE;
00555 }
00556
00557 static dbus_bool_t
00558 merge_id_hash (DBusHashTable *dest,
00559 DBusHashTable *to_absorb)
00560 {
00561 DBusHashIter iter;
00562
00563 _dbus_hash_iter_init (to_absorb, &iter);
00564 while (_dbus_hash_iter_next (&iter))
00565 {
00566 unsigned long id = _dbus_hash_iter_get_ulong_key (&iter);
00567 DBusList **list = _dbus_hash_iter_get_value (&iter);
00568 DBusList **target = get_list (dest, id);
00569
00570 if (target == NULL)
00571 return FALSE;
00572
00573 if (!append_copy_of_policy_list (target, list))
00574 return FALSE;
00575 }
00576
00577 return TRUE;
00578 }
00579
00580 dbus_bool_t
00581 bus_policy_merge (BusPolicy *policy,
00582 BusPolicy *to_absorb)
00583 {
00584
00585
00586
00587 if (!append_copy_of_policy_list (&policy->default_rules,
00588 &to_absorb->default_rules))
00589 return FALSE;
00590
00591 if (!append_copy_of_policy_list (&policy->mandatory_rules,
00592 &to_absorb->mandatory_rules))
00593 return FALSE;
00594
00595 if (!merge_id_hash (policy->rules_by_uid,
00596 to_absorb->rules_by_uid))
00597 return FALSE;
00598
00599 if (!merge_id_hash (policy->rules_by_gid,
00600 to_absorb->rules_by_gid))
00601 return FALSE;
00602
00603 return TRUE;
00604 }
00605
00606 struct BusClientPolicy
00607 {
00608 int refcount;
00609
00610 DBusList *rules;
00611 };
00612
00613 BusClientPolicy*
00614 bus_client_policy_new (void)
00615 {
00616 BusClientPolicy *policy;
00617
00618 policy = dbus_new0 (BusClientPolicy, 1);
00619 if (policy == NULL)
00620 return NULL;
00621
00622 policy->refcount = 1;
00623
00624 return policy;
00625 }
00626
00627 void
00628 bus_client_policy_ref (BusClientPolicy *policy)
00629 {
00630 _dbus_assert (policy->refcount > 0);
00631
00632 policy->refcount += 1;
00633 }
00634
00635 static void
00636 rule_unref_foreach (void *data,
00637 void *user_data)
00638 {
00639 BusPolicyRule *rule = data;
00640
00641 bus_policy_rule_unref (rule);
00642 }
00643
00644 void
00645 bus_client_policy_unref (BusClientPolicy *policy)
00646 {
00647 _dbus_assert (policy->refcount > 0);
00648
00649 policy->refcount -= 1;
00650
00651 if (policy->refcount == 0)
00652 {
00653 _dbus_list_foreach (&policy->rules,
00654 rule_unref_foreach,
00655 NULL);
00656
00657 _dbus_list_clear (&policy->rules);
00658
00659 dbus_free (policy);
00660 }
00661 }
00662
00663 static void
00664 remove_rules_by_type_up_to (BusClientPolicy *policy,
00665 BusPolicyRuleType type,
00666 DBusList *up_to)
00667 {
00668 DBusList *link;
00669
00670 link = _dbus_list_get_first_link (&policy->rules);
00671 while (link != up_to)
00672 {
00673 BusPolicyRule *rule = link->data;
00674 DBusList *next = _dbus_list_get_next_link (&policy->rules, link);
00675
00676 if (rule->type == type)
00677 {
00678 _dbus_list_remove_link (&policy->rules, link);
00679 bus_policy_rule_unref (rule);
00680 }
00681
00682 link = next;
00683 }
00684 }
00685
00686 void
00687 bus_client_policy_optimize (BusClientPolicy *policy)
00688 {
00689 DBusList *link;
00690
00691
00692
00693
00694
00695
00696
00697
00698
00699
00700
00701
00702
00703
00704
00705 _dbus_verbose ("Optimizing policy with %d rules\n",
00706 _dbus_list_get_length (&policy->rules));
00707
00708 link = _dbus_list_get_first_link (&policy->rules);
00709 while (link != NULL)
00710 {
00711 BusPolicyRule *rule;
00712 DBusList *next;
00713 dbus_bool_t remove_preceding;
00714
00715 next = _dbus_list_get_next_link (&policy->rules, link);
00716 rule = link->data;
00717
00718 remove_preceding = FALSE;
00719
00720 _dbus_assert (rule != NULL);
00721
00722 switch (rule->type)
00723 {
00724 case BUS_POLICY_RULE_SEND:
00725 remove_preceding =
00726 rule->d.send.message_type == DBUS_MESSAGE_TYPE_INVALID &&
00727 rule->d.send.path == NULL &&
00728 rule->d.send.interface == NULL &&
00729 rule->d.send.member == NULL &&
00730 rule->d.send.error == NULL &&
00731 rule->d.send.destination == NULL;
00732 break;
00733 case BUS_POLICY_RULE_RECEIVE:
00734 remove_preceding =
00735 rule->d.receive.message_type == DBUS_MESSAGE_TYPE_INVALID &&
00736 rule->d.receive.path == NULL &&
00737 rule->d.receive.interface == NULL &&
00738 rule->d.receive.member == NULL &&
00739 rule->d.receive.error == NULL &&
00740 rule->d.receive.origin == NULL;
00741 break;
00742 case BUS_POLICY_RULE_OWN:
00743 remove_preceding =
00744 rule->d.own.service_name == NULL;
00745 break;
00746 case BUS_POLICY_RULE_USER:
00747 case BUS_POLICY_RULE_GROUP:
00748 _dbus_assert_not_reached ("invalid rule");
00749 break;
00750 }
00751
00752 if (remove_preceding)
00753 remove_rules_by_type_up_to (policy, rule->type,
00754 link);
00755
00756 link = next;
00757 }
00758
00759 _dbus_verbose ("After optimization, policy has %d rules\n",
00760 _dbus_list_get_length (&policy->rules));
00761 }
00762
00763 dbus_bool_t
00764 bus_client_policy_append_rule (BusClientPolicy *policy,
00765 BusPolicyRule *rule)
00766 {
00767 _dbus_verbose ("Appending rule %p with type %d to policy %p\n",
00768 rule, rule->type, policy);
00769
00770 if (!_dbus_list_append (&policy->rules, rule))
00771 return FALSE;
00772
00773 bus_policy_rule_ref (rule);
00774
00775 return TRUE;
00776 }
00777
00778 dbus_bool_t
00779 bus_client_policy_check_can_send (BusClientPolicy *policy,
00780 BusRegistry *registry,
00781 DBusConnection *receiver,
00782 DBusMessage *message)
00783 {
00784 DBusList *link;
00785 dbus_bool_t allowed;
00786
00787
00788
00789
00790
00791 _dbus_verbose (" (policy) checking send rules\n");
00792
00793 allowed = FALSE;
00794 link = _dbus_list_get_first_link (&policy->rules);
00795 while (link != NULL)
00796 {
00797 BusPolicyRule *rule = link->data;
00798
00799 link = _dbus_list_get_next_link (&policy->rules, link);
00800
00801
00802
00803
00804
00805
00806 if (rule->type != BUS_POLICY_RULE_SEND)
00807 {
00808 _dbus_verbose (" (policy) skipping non-send rule\n");
00809 continue;
00810 }
00811
00812 if (rule->d.send.message_type != DBUS_MESSAGE_TYPE_INVALID)
00813 {
00814 if (dbus_message_get_type (message) != rule->d.send.message_type)
00815 {
00816 _dbus_verbose (" (policy) skipping rule for different message type\n");
00817 continue;
00818 }
00819 }
00820
00821 if (rule->d.send.path != NULL)
00822 {
00823 if (dbus_message_get_path (message) != NULL &&
00824 strcmp (dbus_message_get_path (message),
00825 rule->d.send.path) != 0)
00826 {
00827 _dbus_verbose (" (policy) skipping rule for different path\n");
00828 continue;
00829 }
00830 }
00831
00832 if (rule->d.send.interface != NULL)
00833 {
00834 if (dbus_message_get_interface (message) != NULL &&
00835 strcmp (dbus_message_get_interface (message),
00836 rule->d.send.interface) != 0)
00837 {
00838 _dbus_verbose (" (policy) skipping rule for different interface\n");
00839 continue;
00840 }
00841 }
00842
00843 if (rule->d.send.member != NULL)
00844 {
00845 if (dbus_message_get_member (message) != NULL &&
00846 strcmp (dbus_message_get_member (message),
00847 rule->d.send.member) != 0)
00848 {
00849 _dbus_verbose (" (policy) skipping rule for different member\n");
00850 continue;
00851 }
00852 }
00853
00854 if (rule->d.send.error != NULL)
00855 {
00856 if (dbus_message_get_error_name (message) != NULL &&
00857 strcmp (dbus_message_get_error_name (message),
00858 rule->d.send.error) != 0)
00859 {
00860 _dbus_verbose (" (policy) skipping rule for different error name\n");
00861 continue;
00862 }
00863 }
00864
00865 if (rule->d.send.destination != NULL)
00866 {
00867
00868
00869
00870
00871
00872 if (receiver == NULL)
00873 {
00874 if (!dbus_message_has_destination (message,
00875 rule->d.send.destination))
00876 {
00877 _dbus_verbose (" (policy) skipping rule because message dest is not %s\n",
00878 rule->d.send.destination);
00879 continue;
00880 }
00881 }
00882 else
00883 {
00884 DBusString str;
00885 BusService *service;
00886
00887 _dbus_string_init_const (&str, rule->d.send.destination);
00888
00889 service = bus_registry_lookup (registry, &str);
00890 if (service == NULL)
00891 {
00892 _dbus_verbose (" (policy) skipping rule because dest %s doesn't exist\n",
00893 rule->d.send.destination);
00894 continue;
00895 }
00896
00897 if (!bus_service_has_owner (service, receiver))
00898 {
00899 _dbus_verbose (" (policy) skipping rule because dest %s isn't owned by receiver\n",
00900 rule->d.send.destination);
00901 continue;
00902 }
00903 }
00904 }
00905
00906
00907 allowed = rule->allow;
00908
00909 _dbus_verbose (" (policy) used rule, allow now = %d\n",
00910 allowed);
00911 }
00912
00913 return allowed;
00914 }
00915
00916 dbus_bool_t
00917 bus_client_policy_check_can_receive (BusClientPolicy *policy,
00918 BusRegistry *registry,
00919 DBusConnection *sender,
00920 DBusConnection *addressed_recipient,
00921 DBusConnection *proposed_recipient,
00922 DBusMessage *message)
00923 {
00924 DBusList *link;
00925 dbus_bool_t allowed;
00926 dbus_bool_t eavesdropping;
00927
00928
00929
00930
00931
00932
00933
00934 _dbus_assert (proposed_recipient == NULL ||
00935 (dbus_message_get_destination (message) == NULL ||
00936 addressed_recipient != NULL));
00937
00938 eavesdropping =
00939 (proposed_recipient == NULL ||
00940 (addressed_recipient && addressed_recipient != proposed_recipient));
00941
00942
00943
00944
00945
00946 _dbus_verbose (" (policy) checking receive rules, eavesdropping = %d\n", eavesdropping);
00947
00948 allowed = FALSE;
00949 link = _dbus_list_get_first_link (&policy->rules);
00950 while (link != NULL)
00951 {
00952 BusPolicyRule *rule = link->data;
00953
00954 link = _dbus_list_get_next_link (&policy->rules, link);
00955
00956 if (rule->type != BUS_POLICY_RULE_RECEIVE)
00957 {
00958 _dbus_verbose (" (policy) skipping non-receive rule\n");
00959 continue;
00960 }
00961
00962 if (rule->d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID)
00963 {
00964 if (dbus_message_get_type (message) != rule->d.receive.message_type)
00965 {
00966 _dbus_verbose (" (policy) skipping rule for different message type\n");
00967 continue;
00968 }
00969 }
00970
00971
00972
00973
00974 if (eavesdropping && rule->allow && !rule->d.receive.eavesdrop)
00975 {
00976 _dbus_verbose (" (policy) skipping allow rule since it doesn't apply to eavesdropping\n");
00977 continue;
00978 }
00979
00980
00981
00982
00983 if (!eavesdropping && !rule->allow && rule->d.receive.eavesdrop)
00984 {
00985 _dbus_verbose (" (policy) skipping deny rule since it only applies to eavesdropping\n");
00986 continue;
00987 }
00988
00989 if (rule->d.receive.path != NULL)
00990 {
00991 if (dbus_message_get_path (message) != NULL &&
00992 strcmp (dbus_message_get_path (message),
00993 rule->d.receive.path) != 0)
00994 {
00995 _dbus_verbose (" (policy) skipping rule for different path\n");
00996 continue;
00997 }
00998 }
00999
01000 if (rule->d.receive.interface != NULL)
01001 {
01002 if (dbus_message_get_interface (message) != NULL &&
01003 strcmp (dbus_message_get_interface (message),
01004 rule->d.receive.interface) != 0)
01005 {
01006 _dbus_verbose (" (policy) skipping rule for different interface\n");
01007 continue;
01008 }
01009 }
01010
01011 if (rule->d.receive.member != NULL)
01012 {
01013 if (dbus_message_get_member (message) != NULL &&
01014 strcmp (dbus_message_get_member (message),
01015 rule->d.receive.member) != 0)
01016 {
01017 _dbus_verbose (" (policy) skipping rule for different member\n");
01018 continue;
01019 }
01020 }
01021
01022 if (rule->d.receive.error != NULL)
01023 {
01024 if (dbus_message_get_error_name (message) != NULL &&
01025 strcmp (dbus_message_get_error_name (message),
01026 rule->d.receive.error) != 0)
01027 {
01028 _dbus_verbose (" (policy) skipping rule for different error name\n");
01029 continue;
01030 }
01031 }
01032
01033 if (rule->d.receive.origin != NULL)
01034 {
01035
01036
01037
01038
01039
01040 if (sender == NULL)
01041 {
01042 if (!dbus_message_has_sender (message,
01043 rule->d.receive.origin))
01044 {
01045 _dbus_verbose (" (policy) skipping rule because message sender is not %s\n",
01046 rule->d.receive.origin);
01047 continue;
01048 }
01049 }
01050 else
01051 {
01052 BusService *service;
01053 DBusString str;
01054
01055 _dbus_string_init_const (&str, rule->d.receive.origin);
01056
01057 service = bus_registry_lookup (registry, &str);
01058
01059 if (service == NULL)
01060 {
01061 _dbus_verbose (" (policy) skipping rule because origin %s doesn't exist\n",
01062 rule->d.receive.origin);
01063 continue;
01064 }
01065
01066 if (!bus_service_has_owner (service, sender))
01067 {
01068 _dbus_verbose (" (policy) skipping rule because origin %s isn't owned by sender\n",
01069 rule->d.receive.origin);
01070 continue;
01071 }
01072 }
01073 }
01074
01075
01076 allowed = rule->allow;
01077
01078 _dbus_verbose (" (policy) used rule, allow now = %d\n",
01079 allowed);
01080 }
01081
01082 return allowed;
01083 }
01084
01085 dbus_bool_t
01086 bus_client_policy_check_can_own (BusClientPolicy *policy,
01087 DBusConnection *connection,
01088 const DBusString *service_name)
01089 {
01090 DBusList *link;
01091 dbus_bool_t allowed;
01092
01093
01094
01095
01096
01097 allowed = FALSE;
01098 link = _dbus_list_get_first_link (&policy->rules);
01099 while (link != NULL)
01100 {
01101 BusPolicyRule *rule = link->data;
01102
01103 link = _dbus_list_get_next_link (&policy->rules, link);
01104
01105
01106
01107
01108
01109 if (rule->type != BUS_POLICY_RULE_OWN)
01110 continue;
01111
01112 if (rule->d.own.service_name != NULL)
01113 {
01114 if (!_dbus_string_equal_c_str (service_name,
01115 rule->d.own.service_name))
01116 continue;
01117 }
01118
01119
01120 allowed = rule->allow;
01121 }
01122
01123 return allowed;
01124 }
01125
01126 #ifdef DBUS_BUILD_TESTS
01127
01128 dbus_bool_t
01129 bus_policy_test (const DBusString *test_data_dir)
01130 {
01131
01132
01133
01134
01135
01136 return TRUE;
01137 }
01138
01139 #endif