Sophie

Sophie

distrib > Mandriva > 2007.0 > x86_64 > media > main-release > by-pkgid > 926d2d1e3111287cee1b0a4fad4fb4f6 > files > 220

lib64dbus-1_3-devel-0.92-6mdv2007.0.x86_64.rpm

<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.0 Transitional//EN">
<html><head><meta http-equiv="Content-Type" content="text/html;charset=iso-8859-1">
<title>policy.c Source File</title>
<link href="doxygen.css" rel="stylesheet" type="text/css">
</head><body>
<!-- Generated by Doxygen 1.2.15 -->
<center>
<a class="qindex" href="index.html">Main Page</a> &nbsp; <a class="qindex" href="modules.html">Modules</a> &nbsp; <a class="qindex" href="annotated.html">Data Structures</a> &nbsp; <a class="qindex" href="files.html">File List</a> &nbsp; <a class="qindex" href="functions.html">Data Fields</a> &nbsp; <a class="qindex" href="pages.html">Related Pages</a> &nbsp; </center>
<hr><h1>policy.c</h1><div class="fragment"><pre>00001 <font class="comment">/* -*- mode: C; c-file-style: "gnu" -*- */</font>
00002 <font class="comment">/* policy.c  Bus security policy</font>
00003 <font class="comment"> *</font>
00004 <font class="comment"> * Copyright (C) 2003  Red Hat, Inc.</font>
00005 <font class="comment"> *</font>
00006 <font class="comment"> * Licensed under the Academic Free License version 1.2</font>
00007 <font class="comment"> * </font>
00008 <font class="comment"> * This program is free software; you can redistribute it and/or modify</font>
00009 <font class="comment"> * it under the terms of the GNU General Public License as published by</font>
00010 <font class="comment"> * the Free Software Foundation; either version 2 of the License, or</font>
00011 <font class="comment"> * (at your option) any later version.</font>
00012 <font class="comment"> *</font>
00013 <font class="comment"> * This program is distributed in the hope that it will be useful,</font>
00014 <font class="comment"> * but WITHOUT ANY WARRANTY; without even the implied warranty of</font>
00015 <font class="comment"> * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the</font>
00016 <font class="comment"> * GNU General Public License for more details.</font>
00017 <font class="comment"> * </font>
00018 <font class="comment"> * You should have received a copy of the GNU General Public License</font>
00019 <font class="comment"> * along with this program; if not, write to the Free Software</font>
00020 <font class="comment"> * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA</font>
00021 <font class="comment"> *</font>
00022 <font class="comment"> */</font>
00023 
00024 <font class="preprocessor">#include "policy.h"</font>
00025 <font class="preprocessor">#include "services.h"</font>
00026 <font class="preprocessor">#include "test.h"</font>
00027 <font class="preprocessor">#include "utils.h"</font>
00028 <font class="preprocessor">#include &lt;dbus/dbus-list.h&gt;</font>
00029 <font class="preprocessor">#include &lt;dbus/dbus-hash.h&gt;</font>
00030 <font class="preprocessor">#include &lt;dbus/dbus-internals.h&gt;</font>
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   <font class="keywordflow">if</font> (rule == NULL)
00040     <font class="keywordflow">return</font> NULL;
00041 
00042   rule-&gt;type = type;
00043   rule-&gt;refcount = 1;
00044   rule-&gt;allow = allow;
00045 
00046   <font class="keywordflow">switch</font> (rule-&gt;type)
00047     {
00048     <font class="keywordflow">case</font> BUS_POLICY_RULE_USER:
00049       rule-&gt;d.user.uid = DBUS_UID_UNSET;
00050       <font class="keywordflow">break</font>;
00051     <font class="keywordflow">case</font> BUS_POLICY_RULE_GROUP:
00052       rule-&gt;d.group.gid = DBUS_GID_UNSET;
00053       <font class="keywordflow">break</font>;
00054     <font class="keywordflow">case</font> BUS_POLICY_RULE_SEND:
00055       rule-&gt;d.send.message_type = DBUS_MESSAGE_TYPE_INVALID;
00056       <font class="keywordflow">break</font>;
00057     <font class="keywordflow">case</font> BUS_POLICY_RULE_RECEIVE:
00058       rule-&gt;d.receive.message_type = DBUS_MESSAGE_TYPE_INVALID;
00059       <font class="keywordflow">break</font>;
00060     <font class="keywordflow">case</font> BUS_POLICY_RULE_OWN:
00061       <font class="keywordflow">break</font>;
00062     }
00063   
00064   <font class="keywordflow">return</font> rule;
00065 }
00066 
00067 <font class="keywordtype">void</font>
00068 bus_policy_rule_ref (BusPolicyRule *rule)
00069 {
00070   _dbus_assert (rule-&gt;refcount &gt; 0);
00071 
00072   rule-&gt;refcount += 1;
00073 }
00074 
00075 <font class="keywordtype">void</font>
00076 bus_policy_rule_unref (BusPolicyRule *rule)
00077 {
00078   _dbus_assert (rule-&gt;refcount &gt; 0);
00079 
00080   rule-&gt;refcount -= 1;
00081   
00082   <font class="keywordflow">if</font> (rule-&gt;refcount == 0)
00083     {
00084       <font class="keywordflow">switch</font> (rule-&gt;type)
00085         {
00086         <font class="keywordflow">case</font> BUS_POLICY_RULE_SEND:
00087           dbus_free (rule-&gt;d.send.path);
00088           dbus_free (rule-&gt;d.send.interface);
00089           dbus_free (rule-&gt;d.send.member);
00090           dbus_free (rule-&gt;d.send.error);
00091           dbus_free (rule-&gt;d.send.destination);
00092           <font class="keywordflow">break</font>;
00093         <font class="keywordflow">case</font> BUS_POLICY_RULE_RECEIVE:
00094           dbus_free (rule-&gt;d.receive.path);
00095           dbus_free (rule-&gt;d.receive.interface);
00096           dbus_free (rule-&gt;d.receive.member);
00097           dbus_free (rule-&gt;d.receive.error);
00098           dbus_free (rule-&gt;d.receive.origin);
00099           <font class="keywordflow">break</font>;
00100         <font class="keywordflow">case</font> BUS_POLICY_RULE_OWN:
00101           dbus_free (rule-&gt;d.own.service_name);
00102           <font class="keywordflow">break</font>;
00103         <font class="keywordflow">case</font> BUS_POLICY_RULE_USER:
00104           <font class="keywordflow">break</font>;
00105         <font class="keywordflow">case</font> BUS_POLICY_RULE_GROUP:
00106           <font class="keywordflow">break</font>;
00107         }
00108       
00109       dbus_free (rule);
00110     }
00111 }
00112 
00113 <font class="keyword">struct </font>BusPolicy
00114 {
00115   <font class="keywordtype">int</font> refcount;
00116 
00117   <a class="code" href="structDBusList.html">DBusList</a> *default_rules;       
00118   <a class="code" href="structDBusList.html">DBusList</a> *mandatory_rules;     
00119   <a class="code" href="structDBusHashTable.html">DBusHashTable</a> *rules_by_uid;   
00120   <a class="code" href="structDBusHashTable.html">DBusHashTable</a> *rules_by_gid;   
00121 };
00122 
00123 <font class="keyword">static</font> <font class="keywordtype">void</font>
00124 free_rule_func (<font class="keywordtype">void</font> *data,
00125                 <font class="keywordtype">void</font> *user_data)
00126 {
00127   BusPolicyRule *rule = data;
00128 
00129   bus_policy_rule_unref (rule);
00130 }
00131 
00132 <font class="keyword">static</font> <font class="keywordtype">void</font>
00133 free_rule_list_func (<font class="keywordtype">void</font> *data)
00134 {
00135   <a class="code" href="structDBusList.html">DBusList</a> **list = data;
00136 
00137   <font class="keywordflow">if</font> (list == NULL) <font class="comment">/* DBusHashTable is on crack */</font>
00138     <font class="keywordflow">return</font>;
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 (<font class="keywordtype">void</font>)
00149 {
00150   BusPolicy *policy;
00151 
00152   policy = dbus_new0 (BusPolicy, 1);
00153   <font class="keywordflow">if</font> (policy == NULL)
00154     <font class="keywordflow">return</font> NULL;
00155 
00156   policy-&gt;refcount = 1;
00157   
00158   policy-&gt;rules_by_uid = _dbus_hash_table_new (DBUS_HASH_ULONG,
00159                                                NULL,
00160                                                free_rule_list_func);
00161   <font class="keywordflow">if</font> (policy-&gt;rules_by_uid == NULL)
00162     <font class="keywordflow">goto</font> failed;
00163 
00164   policy-&gt;rules_by_gid = _dbus_hash_table_new (DBUS_HASH_ULONG,
00165                                                NULL,
00166                                                free_rule_list_func);
00167   <font class="keywordflow">if</font> (policy-&gt;rules_by_gid == NULL)
00168     <font class="keywordflow">goto</font> failed;
00169   
00170   <font class="keywordflow">return</font> policy;
00171   
00172  failed:
00173   bus_policy_unref (policy);
00174   <font class="keywordflow">return</font> NULL;
00175 }
00176 
00177 <font class="keywordtype">void</font>
00178 bus_policy_ref (BusPolicy *policy)
00179 {
00180   _dbus_assert (policy-&gt;refcount &gt; 0);
00181 
00182   policy-&gt;refcount += 1;
00183 }
00184 
00185 <font class="keywordtype">void</font>
00186 bus_policy_unref (BusPolicy *policy)
00187 {
00188   _dbus_assert (policy-&gt;refcount &gt; 0);
00189 
00190   policy-&gt;refcount -= 1;
00191 
00192   <font class="keywordflow">if</font> (policy-&gt;refcount == 0)
00193     {
00194       _dbus_list_foreach (&amp;policy-&gt;default_rules, free_rule_func, NULL);
00195       _dbus_list_clear (&amp;policy-&gt;default_rules);
00196 
00197       _dbus_list_foreach (&amp;policy-&gt;mandatory_rules, free_rule_func, NULL);
00198       _dbus_list_clear (&amp;policy-&gt;mandatory_rules);
00199       
00200       <font class="keywordflow">if</font> (policy-&gt;rules_by_uid)
00201         {
00202           _dbus_hash_table_unref (policy-&gt;rules_by_uid);
00203           policy-&gt;rules_by_uid = NULL;
00204         }
00205 
00206       <font class="keywordflow">if</font> (policy-&gt;rules_by_gid)
00207         {
00208           _dbus_hash_table_unref (policy-&gt;rules_by_gid);
00209           policy-&gt;rules_by_gid = NULL;
00210         }
00211       
00212       dbus_free (policy);
00213     }
00214 }
00215 
00216 <font class="keyword">static</font> dbus_bool_t
00217 add_list_to_client (<a class="code" href="structDBusList.html">DBusList</a>        **list,
00218                     BusClientPolicy  *client)
00219 {
00220   <a class="code" href="structDBusList.html">DBusList</a> *link;
00221 
00222   link = _dbus_list_get_first_link (list);
00223   <font class="keywordflow">while</font> (link != NULL)
00224     {
00225       BusPolicyRule *rule = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00226       link = _dbus_list_get_next_link (list, link);
00227 
00228       <font class="keywordflow">switch</font> (rule-&gt;type)
00229         {
00230         <font class="keywordflow">case</font> BUS_POLICY_RULE_USER:
00231         <font class="keywordflow">case</font> BUS_POLICY_RULE_GROUP:
00232           <font class="comment">/* These aren't per-connection policies */</font>
00233           <font class="keywordflow">break</font>;
00234 
00235         <font class="keywordflow">case</font> BUS_POLICY_RULE_OWN:
00236         <font class="keywordflow">case</font> BUS_POLICY_RULE_SEND:
00237         <font class="keywordflow">case</font> BUS_POLICY_RULE_RECEIVE:
00238           <font class="comment">/* These are per-connection */</font>
00239           <font class="keywordflow">if</font> (!bus_client_policy_append_rule (client, rule))
00240             <font class="keywordflow">return</font> FALSE;
00241           <font class="keywordflow">break</font>;
00242         }
00243     }
00244   
00245   <font class="keywordflow">return</font> TRUE;
00246 }
00247 
00248 BusClientPolicy*
00249 bus_policy_create_client_policy (BusPolicy      *policy,
00250                                  <a class="code" href="structDBusConnection.html">DBusConnection</a> *connection,
00251                                  <a class="code" href="structDBusError.html">DBusError</a>      *error)
00252 {
00253   BusClientPolicy *client;
00254   <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> 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   <font class="keywordflow">if</font> (client == NULL)
00261     <font class="keywordflow">goto</font> nomem;
00262 
00263   <font class="keywordflow">if</font> (!add_list_to_client (&amp;policy-&gt;default_rules,
00264                            client))
00265     <font class="keywordflow">goto</font> nomem;
00266 
00267   <font class="comment">/* we avoid the overhead of looking up user's groups</font>
00268 <font class="comment">   * if we don't have any group rules anyway</font>
00269 <font class="comment">   */</font>
00270   <font class="keywordflow">if</font> (_dbus_hash_table_get_n_entries (policy-&gt;rules_by_gid) &gt; 0)
00271     {
00272       <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> *groups;
00273       <font class="keywordtype">int</font> n_groups;
00274       <font class="keywordtype">int</font> i;
00275       
00276       <font class="keywordflow">if</font> (!bus_connection_get_groups (connection, &amp;groups, &amp;n_groups, error))
00277         <font class="keywordflow">goto</font> failed;
00278       
00279       i = 0;
00280       <font class="keywordflow">while</font> (i &lt; n_groups)
00281         {
00282           <a class="code" href="structDBusList.html">DBusList</a> **list;
00283           
00284           list = _dbus_hash_table_lookup_ulong (policy-&gt;rules_by_gid,
00285                                                 groups[i]);
00286           
00287           <font class="keywordflow">if</font> (list != NULL)
00288             {
00289               <font class="keywordflow">if</font> (!add_list_to_client (list, client))
00290                 {
00291                   dbus_free (groups);
00292                   <font class="keywordflow">goto</font> nomem;
00293                 }
00294             }
00295           
00296           ++i;
00297         }
00298 
00299       dbus_free (groups);
00300     }
00301 
00302   <font class="keywordflow">if</font> (!dbus_connection_get_unix_user (connection, &amp;uid))
00303     {
00304       dbus_set_error (error, DBUS_ERROR_FAILED,
00305                       <font class="stringliteral">"No user ID known for connection, cannot determine security policy\n"</font>);
00306       <font class="keywordflow">goto</font> failed;
00307     }
00308 
00309   <font class="keywordflow">if</font> (_dbus_hash_table_get_n_entries (policy-&gt;rules_by_uid) &gt; 0)
00310     {
00311       <a class="code" href="structDBusList.html">DBusList</a> **list;
00312       
00313       list = _dbus_hash_table_lookup_ulong (policy-&gt;rules_by_uid,
00314                                             uid);
00315 
00316       <font class="keywordflow">if</font> (list != NULL)
00317         {
00318           <font class="keywordflow">if</font> (!add_list_to_client (list, client))
00319             <font class="keywordflow">goto</font> nomem;
00320         }
00321     }
00322 
00323   <font class="keywordflow">if</font> (!add_list_to_client (&amp;policy-&gt;mandatory_rules,
00324                            client))
00325     <font class="keywordflow">goto</font> nomem;
00326 
00327   bus_client_policy_optimize (client);
00328   
00329   <font class="keywordflow">return</font> client;
00330 
00331  nomem:
00332   BUS_SET_OOM (error);
00333  failed:
00334   _DBUS_ASSERT_ERROR_IS_SET (error);
00335   <font class="keywordflow">if</font> (client)
00336     bus_client_policy_unref (client);
00337   <font class="keywordflow">return</font> NULL;
00338 }
00339 
00340 <font class="keyword">static</font> dbus_bool_t
00341 list_allows_user (dbus_bool_t           def,
00342                   <a class="code" href="structDBusList.html">DBusList</a>            **list,
00343                   <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>         uid,
00344                   <font class="keyword">const</font> <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>  *group_ids,
00345                   <font class="keywordtype">int</font>                   n_group_ids)
00346 {
00347   <a class="code" href="structDBusList.html">DBusList</a> *link;
00348   dbus_bool_t allowed;
00349   
00350   allowed = def;
00351 
00352   link = _dbus_list_get_first_link (list);
00353   <font class="keywordflow">while</font> (link != NULL)
00354     {
00355       BusPolicyRule *rule = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00356       link = _dbus_list_get_next_link (list, link);
00357       
00358       <font class="keywordflow">if</font> (rule-&gt;type == BUS_POLICY_RULE_USER)
00359         {
00360           _dbus_verbose (<font class="stringliteral">"List %p user rule uid="</font>DBUS_UID_FORMAT<font class="stringliteral">"\n"</font>,
00361                          list, rule-&gt;d.user.uid);
00362           
00363           <font class="keywordflow">if</font> (rule-&gt;d.user.uid == DBUS_UID_UNSET)
00364             ; <font class="comment">/* '*' wildcard */</font>
00365           <font class="keywordflow">else</font> <font class="keywordflow">if</font> (rule-&gt;d.user.uid != uid)
00366             <font class="keywordflow">continue</font>;
00367         }
00368       <font class="keywordflow">else</font> <font class="keywordflow">if</font> (rule-&gt;type == BUS_POLICY_RULE_GROUP)
00369         {
00370           _dbus_verbose (<font class="stringliteral">"List %p group rule uid="</font>DBUS_UID_FORMAT<font class="stringliteral">"\n"</font>,
00371                          list, rule-&gt;d.user.uid);
00372           
00373           <font class="keywordflow">if</font> (rule-&gt;d.group.gid == DBUS_GID_UNSET)
00374             ;  <font class="comment">/* '*' wildcard */</font>
00375           <font class="keywordflow">else</font>
00376             {
00377               <font class="keywordtype">int</font> i;
00378               
00379               i = 0;
00380               <font class="keywordflow">while</font> (i &lt; n_group_ids)
00381                 {
00382                   <font class="keywordflow">if</font> (rule-&gt;d.group.gid == group_ids[i])
00383                     <font class="keywordflow">break</font>;
00384                   ++i;
00385                 }
00386               
00387               <font class="keywordflow">if</font> (i == n_group_ids)
00388                 <font class="keywordflow">continue</font>;
00389             }
00390         }
00391       <font class="keywordflow">else</font>
00392         <font class="keywordflow">continue</font>;
00393 
00394       allowed = rule-&gt;allow;
00395     }
00396   
00397   <font class="keywordflow">return</font> allowed;
00398 }
00399 
00400 dbus_bool_t
00401 bus_policy_allow_user (BusPolicy        *policy,
00402                        <a class="code" href="structDBusUserDatabase.html">DBusUserDatabase</a> *user_database,
00403                        <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>     uid)
00404 {
00405   dbus_bool_t allowed;
00406   <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> *group_ids;
00407   <font class="keywordtype">int</font> n_group_ids;
00408 
00409   <font class="comment">/* On OOM or error we always reject the user */</font>
00410   <font class="keywordflow">if</font> (!_dbus_user_database_get_groups (user_database,
00411                                        uid, &amp;group_ids, &amp;n_group_ids, NULL))
00412     {
00413       _dbus_verbose (<font class="stringliteral">"Did not get any groups for UID %lu\n"</font>,
00414                      uid);
00415       <font class="keywordflow">return</font> FALSE;
00416     }
00417   
00418   allowed = FALSE;
00419 
00420   allowed = list_allows_user (allowed,
00421                               &amp;policy-&gt;default_rules,
00422                               uid,
00423                               group_ids, n_group_ids);
00424 
00425   allowed = list_allows_user (allowed,
00426                               &amp;policy-&gt;mandatory_rules,
00427                               uid,
00428                               group_ids, n_group_ids);
00429 
00430   dbus_free (group_ids);
00431 
00432   _dbus_verbose (<font class="stringliteral">"UID %lu allowed = %d\n"</font>, uid, allowed);
00433   
00434   <font class="keywordflow">return</font> allowed;
00435 }
00436 
00437 dbus_bool_t
00438 bus_policy_append_default_rule (BusPolicy      *policy,
00439                                 BusPolicyRule  *rule)
00440 {
00441   <font class="keywordflow">if</font> (!_dbus_list_append (&amp;policy-&gt;default_rules, rule))
00442     <font class="keywordflow">return</font> FALSE;
00443 
00444   bus_policy_rule_ref (rule);
00445 
00446   <font class="keywordflow">return</font> TRUE;
00447 }
00448 
00449 dbus_bool_t
00450 bus_policy_append_mandatory_rule (BusPolicy      *policy,
00451                                   BusPolicyRule  *rule)
00452 {
00453   <font class="keywordflow">if</font> (!_dbus_list_append (&amp;policy-&gt;mandatory_rules, rule))
00454     <font class="keywordflow">return</font> FALSE;
00455 
00456   bus_policy_rule_ref (rule);
00457 
00458   <font class="keywordflow">return</font> TRUE;
00459 }
00460 
00461 <font class="keyword">static</font> <a class="code" href="structDBusList.html">DBusList</a>**
00462 get_list (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *hash,
00463           <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font>  key)
00464 {
00465   <a class="code" href="structDBusList.html">DBusList</a> **list;
00466 
00467   list = _dbus_hash_table_lookup_ulong (hash, key);
00468 
00469   <font class="keywordflow">if</font> (list == NULL)
00470     {
00471       list = dbus_new0 (<a class="code" href="structDBusList.html">DBusList</a>*, 1);
00472       <font class="keywordflow">if</font> (list == NULL)
00473         <font class="keywordflow">return</font> NULL;
00474 
00475       <font class="keywordflow">if</font> (!_dbus_hash_table_insert_ulong (hash, key, list))
00476         {
00477           dbus_free (list);
00478           <font class="keywordflow">return</font> NULL;
00479         }
00480     }
00481 
00482   <font class="keywordflow">return</font> 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   <a class="code" href="structDBusList.html">DBusList</a> **list;
00491 
00492   list = get_list (policy-&gt;rules_by_uid, uid);
00493 
00494   <font class="keywordflow">if</font> (list == NULL)
00495     <font class="keywordflow">return</font> FALSE;
00496 
00497   <font class="keywordflow">if</font> (!_dbus_list_append (list, rule))
00498     <font class="keywordflow">return</font> FALSE;
00499 
00500   bus_policy_rule_ref (rule);
00501 
00502   <font class="keywordflow">return</font> 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   <a class="code" href="structDBusList.html">DBusList</a> **list;
00511 
00512   list = get_list (policy-&gt;rules_by_gid, gid);
00513 
00514   <font class="keywordflow">if</font> (list == NULL)
00515     <font class="keywordflow">return</font> FALSE;
00516 
00517   <font class="keywordflow">if</font> (!_dbus_list_append (list, rule))
00518     <font class="keywordflow">return</font> FALSE;
00519 
00520   bus_policy_rule_ref (rule);
00521 
00522   <font class="keywordflow">return</font> TRUE;
00523 }
00524 
00525 <font class="keyword">static</font> dbus_bool_t
00526 append_copy_of_policy_list (<a class="code" href="structDBusList.html">DBusList</a> **list,
00527                             <a class="code" href="structDBusList.html">DBusList</a> **to_append)
00528 {
00529   <a class="code" href="structDBusList.html">DBusList</a> *link;
00530   <a class="code" href="structDBusList.html">DBusList</a> *tmp_list;
00531 
00532   tmp_list = NULL;
00533 
00534   <font class="comment">/* Preallocate all our links */</font>
00535   link = _dbus_list_get_first_link (to_append);
00536   <font class="keywordflow">while</font> (link != NULL)
00537     {
00538       <font class="keywordflow">if</font> (!_dbus_list_append (&amp;tmp_list, link-&gt;<a class="code" href="structDBusList.html#m2">data</a>))
00539         {
00540           _dbus_list_clear (&amp;tmp_list);
00541           <font class="keywordflow">return</font> FALSE;
00542         }
00543       
00544       link = _dbus_list_get_next_link (to_append, link);
00545     }
00546 
00547   <font class="comment">/* Now append them */</font>
00548   <font class="keywordflow">while</font> ((link = _dbus_list_pop_first_link (&amp;tmp_list)))
00549     {
00550       bus_policy_rule_ref (link-&gt;<a class="code" href="structDBusList.html#m2">data</a>);
00551       _dbus_list_append_link (list, link);
00552     }
00553 
00554   <font class="keywordflow">return</font> TRUE;
00555 }
00556 
00557 <font class="keyword">static</font> dbus_bool_t
00558 merge_id_hash (<a class="code" href="structDBusHashTable.html">DBusHashTable</a> *dest,
00559                <a class="code" href="structDBusHashTable.html">DBusHashTable</a> *to_absorb)
00560 {
00561   <a class="code" href="structDBusHashIter.html">DBusHashIter</a> iter;
00562   
00563   _dbus_hash_iter_init (to_absorb, &amp;iter);
00564   <font class="keywordflow">while</font> (_dbus_hash_iter_next (&amp;iter))
00565     {
00566       <font class="keywordtype">unsigned</font> <font class="keywordtype">long</font> id = _dbus_hash_iter_get_ulong_key (&amp;iter);
00567       <a class="code" href="structDBusList.html">DBusList</a> **list = _dbus_hash_iter_get_value (&amp;iter);
00568       <a class="code" href="structDBusList.html">DBusList</a> **target = get_list (dest, id);
00569 
00570       <font class="keywordflow">if</font> (target == NULL)
00571         <font class="keywordflow">return</font> FALSE;
00572 
00573       <font class="keywordflow">if</font> (!append_copy_of_policy_list (target, list))
00574         <font class="keywordflow">return</font> FALSE;
00575     }
00576 
00577   <font class="keywordflow">return</font> TRUE;
00578 }
00579 
00580 dbus_bool_t
00581 bus_policy_merge (BusPolicy *policy,
00582                   BusPolicy *to_absorb)
00583 {
00584   <font class="comment">/* Not properly atomic, but as used for configuration files</font>
00585 <font class="comment">   * we don't rely on it.</font>
00586 <font class="comment">   */</font>  
00587   <font class="keywordflow">if</font> (!append_copy_of_policy_list (&amp;policy-&gt;default_rules,
00588                                    &amp;to_absorb-&gt;default_rules))
00589     <font class="keywordflow">return</font> FALSE;
00590   
00591   <font class="keywordflow">if</font> (!append_copy_of_policy_list (&amp;policy-&gt;mandatory_rules,
00592                                    &amp;to_absorb-&gt;mandatory_rules))
00593     <font class="keywordflow">return</font> FALSE;
00594 
00595   <font class="keywordflow">if</font> (!merge_id_hash (policy-&gt;rules_by_uid,
00596                       to_absorb-&gt;rules_by_uid))
00597     <font class="keywordflow">return</font> FALSE;
00598   
00599   <font class="keywordflow">if</font> (!merge_id_hash (policy-&gt;rules_by_gid,
00600                       to_absorb-&gt;rules_by_gid))
00601     <font class="keywordflow">return</font> FALSE;
00602 
00603   <font class="keywordflow">return</font> TRUE;
00604 }
00605 
00606 <font class="keyword">struct </font>BusClientPolicy
00607 {
00608   <font class="keywordtype">int</font> refcount;
00609 
00610   <a class="code" href="structDBusList.html">DBusList</a> *rules;
00611 };
00612 
00613 BusClientPolicy*
00614 bus_client_policy_new (<font class="keywordtype">void</font>)
00615 {
00616   BusClientPolicy *policy;
00617 
00618   policy = dbus_new0 (BusClientPolicy, 1);
00619   <font class="keywordflow">if</font> (policy == NULL)
00620     <font class="keywordflow">return</font> NULL;
00621 
00622   policy-&gt;refcount = 1;
00623 
00624   <font class="keywordflow">return</font> policy;
00625 }
00626 
00627 <font class="keywordtype">void</font>
00628 bus_client_policy_ref (BusClientPolicy *policy)
00629 {
00630   _dbus_assert (policy-&gt;refcount &gt; 0);
00631 
00632   policy-&gt;refcount += 1;
00633 }
00634 
00635 <font class="keyword">static</font> <font class="keywordtype">void</font>
00636 rule_unref_foreach (<font class="keywordtype">void</font> *data,
00637                     <font class="keywordtype">void</font> *user_data)
00638 {
00639   BusPolicyRule *rule = data;
00640 
00641   bus_policy_rule_unref (rule);
00642 }
00643 
00644 <font class="keywordtype">void</font>
00645 bus_client_policy_unref (BusClientPolicy *policy)
00646 {
00647   _dbus_assert (policy-&gt;refcount &gt; 0);
00648 
00649   policy-&gt;refcount -= 1;
00650 
00651   <font class="keywordflow">if</font> (policy-&gt;refcount == 0)
00652     {
00653       _dbus_list_foreach (&amp;policy-&gt;rules,
00654                           rule_unref_foreach,
00655                           NULL);
00656 
00657       _dbus_list_clear (&amp;policy-&gt;rules);
00658       
00659       dbus_free (policy);
00660     }
00661 }
00662 
00663 <font class="keyword">static</font> <font class="keywordtype">void</font>
00664 remove_rules_by_type_up_to (BusClientPolicy   *policy,
00665                             BusPolicyRuleType  type,
00666                             <a class="code" href="structDBusList.html">DBusList</a>          *up_to)
00667 {
00668   <a class="code" href="structDBusList.html">DBusList</a> *link;
00669 
00670   link = _dbus_list_get_first_link (&amp;policy-&gt;rules);
00671   <font class="keywordflow">while</font> (link != up_to)
00672     {
00673       BusPolicyRule *rule = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00674       <a class="code" href="structDBusList.html">DBusList</a> *next = _dbus_list_get_next_link (&amp;policy-&gt;rules, link);
00675 
00676       <font class="keywordflow">if</font> (rule-&gt;type == type)
00677         {
00678           _dbus_list_remove_link (&amp;policy-&gt;rules, link);
00679           bus_policy_rule_unref (rule);
00680         }
00681       
00682       link = next;
00683     }
00684 }
00685 
00686 <font class="keywordtype">void</font>
00687 bus_client_policy_optimize (BusClientPolicy *policy)
00688 {
00689   <a class="code" href="structDBusList.html">DBusList</a> *link;
00690 
00691   <font class="comment">/* The idea here is that if we have:</font>
00692 <font class="comment">   * </font>
00693 <font class="comment">   * &lt;allow send_interface="foo.bar"/&gt;</font>
00694 <font class="comment">   * &lt;deny send_interface="*"/&gt;</font>
00695 <font class="comment">   *</font>
00696 <font class="comment">   * (for example) the deny will always override the allow.  So we</font>
00697 <font class="comment">   * delete the allow. Ditto for deny followed by allow, etc. This is</font>
00698 <font class="comment">   * a dumb thing to put in a config file, but the &lt;include&gt; feature</font>
00699 <font class="comment">   * of files allows for an "inheritance and override" pattern where</font>
00700 <font class="comment">   * it could make sense. If an included file wants to "start over"</font>
00701 <font class="comment">   * with a blanket deny, no point keeping the rules from the parent</font>
00702 <font class="comment">   * file.</font>
00703 <font class="comment">   */</font>
00704 
00705   _dbus_verbose (<font class="stringliteral">"Optimizing policy with %d rules\n"</font>,
00706                  _dbus_list_get_length (&amp;policy-&gt;rules));
00707   
00708   link = _dbus_list_get_first_link (&amp;policy-&gt;rules);
00709   <font class="keywordflow">while</font> (link != NULL)
00710     {
00711       BusPolicyRule *rule;
00712       <a class="code" href="structDBusList.html">DBusList</a> *next;
00713       dbus_bool_t remove_preceding;
00714 
00715       next = _dbus_list_get_next_link (&amp;policy-&gt;rules, link);
00716       rule = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00717       
00718       remove_preceding = FALSE;
00719 
00720       _dbus_assert (rule != NULL);
00721       
00722       <font class="keywordflow">switch</font> (rule-&gt;type)
00723         {
00724         <font class="keywordflow">case</font> BUS_POLICY_RULE_SEND:
00725           remove_preceding =
00726             rule-&gt;d.send.message_type == DBUS_MESSAGE_TYPE_INVALID &amp;&amp;
00727             rule-&gt;d.send.path == NULL &amp;&amp;
00728             rule-&gt;d.send.interface == NULL &amp;&amp;
00729             rule-&gt;d.send.member == NULL &amp;&amp;
00730             rule-&gt;d.send.error == NULL &amp;&amp;
00731             rule-&gt;d.send.destination == NULL;
00732           <font class="keywordflow">break</font>;
00733         <font class="keywordflow">case</font> BUS_POLICY_RULE_RECEIVE:
00734           remove_preceding =
00735             rule-&gt;d.receive.message_type == DBUS_MESSAGE_TYPE_INVALID &amp;&amp;
00736             rule-&gt;d.receive.path == NULL &amp;&amp;
00737             rule-&gt;d.receive.interface == NULL &amp;&amp;
00738             rule-&gt;d.receive.member == NULL &amp;&amp;
00739             rule-&gt;d.receive.error == NULL &amp;&amp;
00740             rule-&gt;d.receive.origin == NULL;
00741           <font class="keywordflow">break</font>;
00742         <font class="keywordflow">case</font> BUS_POLICY_RULE_OWN:
00743           remove_preceding =
00744             rule-&gt;d.own.service_name == NULL;
00745           <font class="keywordflow">break</font>;
00746         <font class="keywordflow">case</font> BUS_POLICY_RULE_USER:
00747         <font class="keywordflow">case</font> BUS_POLICY_RULE_GROUP:
00748           _dbus_assert_not_reached (<font class="stringliteral">"invalid rule"</font>);
00749           <font class="keywordflow">break</font>;
00750         }
00751 
00752       <font class="keywordflow">if</font> (remove_preceding)
00753         remove_rules_by_type_up_to (policy, rule-&gt;type,
00754                                     link);
00755       
00756       link = next;
00757     }
00758 
00759   _dbus_verbose (<font class="stringliteral">"After optimization, policy has %d rules\n"</font>,
00760                  _dbus_list_get_length (&amp;policy-&gt;rules));
00761 }
00762 
00763 dbus_bool_t
00764 bus_client_policy_append_rule (BusClientPolicy *policy,
00765                                BusPolicyRule   *rule)
00766 {
00767   _dbus_verbose (<font class="stringliteral">"Appending rule %p with type %d to policy %p\n"</font>,
00768                  rule, rule-&gt;type, policy);
00769   
00770   <font class="keywordflow">if</font> (!_dbus_list_append (&amp;policy-&gt;rules, rule))
00771     <font class="keywordflow">return</font> FALSE;
00772 
00773   bus_policy_rule_ref (rule);
00774 
00775   <font class="keywordflow">return</font> TRUE;
00776 }
00777 
00778 dbus_bool_t
00779 bus_client_policy_check_can_send (BusClientPolicy *policy,
00780                                   BusRegistry     *registry,
00781                                   <a class="code" href="structDBusConnection.html">DBusConnection</a>  *receiver,
00782                                   <a class="code" href="structDBusMessage.html">DBusMessage</a>     *message)
00783 {
00784   <a class="code" href="structDBusList.html">DBusList</a> *link;
00785   dbus_bool_t allowed;
00786   
00787   <font class="comment">/* policy-&gt;rules is in the order the rules appeared</font>
00788 <font class="comment">   * in the config file, i.e. last rule that applies wins</font>
00789 <font class="comment">   */</font>
00790 
00791   _dbus_verbose (<font class="stringliteral">"  (policy) checking send rules\n"</font>);
00792   
00793   allowed = FALSE;
00794   link = _dbus_list_get_first_link (&amp;policy-&gt;rules);
00795   <font class="keywordflow">while</font> (link != NULL)
00796     {
00797       BusPolicyRule *rule = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00798 
00799       link = _dbus_list_get_next_link (&amp;policy-&gt;rules, link);
00800       
00801       <font class="comment">/* Rule is skipped if it specifies a different</font>
00802 <font class="comment">       * message name from the message, or a different</font>
00803 <font class="comment">       * destination from the message</font>
00804 <font class="comment">       */</font>
00805       
00806       <font class="keywordflow">if</font> (rule-&gt;type != BUS_POLICY_RULE_SEND)
00807         {
00808           _dbus_verbose (<font class="stringliteral">"  (policy) skipping non-send rule\n"</font>);
00809           <font class="keywordflow">continue</font>;
00810         }
00811 
00812       <font class="keywordflow">if</font> (rule-&gt;d.send.message_type != DBUS_MESSAGE_TYPE_INVALID)
00813         {
00814           <font class="keywordflow">if</font> (dbus_message_get_type (message) != rule-&gt;d.send.message_type)
00815             {
00816               _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule for different message type\n"</font>);
00817               <font class="keywordflow">continue</font>;
00818             }
00819         }
00820       
00821       <font class="keywordflow">if</font> (rule-&gt;d.send.path != NULL)
00822         {
00823           <font class="keywordflow">if</font> (dbus_message_get_path (message) != NULL &amp;&amp;
00824               strcmp (dbus_message_get_path (message),
00825                       rule-&gt;d.send.path) != 0)
00826             {
00827               _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule for different path\n"</font>);
00828               <font class="keywordflow">continue</font>;
00829             }
00830         }
00831       
00832       <font class="keywordflow">if</font> (rule-&gt;d.send.interface != NULL)
00833         {
00834           <font class="keywordflow">if</font> (dbus_message_get_interface (message) != NULL &amp;&amp;
00835               strcmp (dbus_message_get_interface (message),
00836                       rule-&gt;d.send.interface) != 0)
00837             {
00838               _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule for different interface\n"</font>);
00839               <font class="keywordflow">continue</font>;
00840             }
00841         }
00842 
00843       <font class="keywordflow">if</font> (rule-&gt;d.send.member != NULL)
00844         {
00845           <font class="keywordflow">if</font> (dbus_message_get_member (message) != NULL &amp;&amp;
00846               strcmp (dbus_message_get_member (message),
00847                       rule-&gt;d.send.member) != 0)
00848             {
00849               _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule for different member\n"</font>);
00850               <font class="keywordflow">continue</font>;
00851             }
00852         }
00853 
00854       <font class="keywordflow">if</font> (rule-&gt;d.send.error != NULL)
00855         {
00856           <font class="keywordflow">if</font> (dbus_message_get_error_name (message) != NULL &amp;&amp;
00857               strcmp (dbus_message_get_error_name (message),
00858                       rule-&gt;d.send.error) != 0)
00859             {
00860               _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule for different error name\n"</font>);
00861               <font class="keywordflow">continue</font>;
00862             }
00863         }
00864       
00865       <font class="keywordflow">if</font> (rule-&gt;d.send.destination != NULL)
00866         {
00867           <font class="comment">/* receiver can be NULL for messages that are sent to the</font>
00868 <font class="comment">           * message bus itself, we check the strings in that case as</font>
00869 <font class="comment">           * built-in services don't have a DBusConnection but messages</font>
00870 <font class="comment">           * to them have a destination service name.</font>
00871 <font class="comment">           */</font>
00872           <font class="keywordflow">if</font> (receiver == NULL)
00873             {
00874               <font class="keywordflow">if</font> (!dbus_message_has_destination (message,
00875                                                  rule-&gt;d.send.destination))
00876                 {
00877                   _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule because message dest is not %s\n"</font>,
00878                                  rule-&gt;d.send.destination);
00879                   <font class="keywordflow">continue</font>;
00880                 }
00881             }
00882           <font class="keywordflow">else</font>
00883             {
00884               <a class="code" href="structDBusString.html">DBusString</a> str;
00885               BusService *service;
00886               
00887               _dbus_string_init_const (&amp;str, rule-&gt;d.send.destination);
00888               
00889               service = bus_registry_lookup (registry, &amp;str);
00890               <font class="keywordflow">if</font> (service == NULL)
00891                 {
00892                   _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule because dest %s doesn't exist\n"</font>,
00893                                  rule-&gt;d.send.destination);
00894                   <font class="keywordflow">continue</font>;
00895                 }
00896 
00897               <font class="keywordflow">if</font> (!bus_service_has_owner (service, receiver))
00898                 {
00899                   _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule because dest %s isn't owned by receiver\n"</font>,
00900                                  rule-&gt;d.send.destination);
00901                   <font class="keywordflow">continue</font>;
00902                 }
00903             }
00904         }
00905 
00906       <font class="comment">/* Use this rule */</font>
00907       allowed = rule-&gt;allow;
00908 
00909       _dbus_verbose (<font class="stringliteral">"  (policy) used rule, allow now = %d\n"</font>,
00910                      allowed);
00911     }
00912 
00913   <font class="keywordflow">return</font> allowed;
00914 }
00915 
00916 dbus_bool_t
00917 bus_client_policy_check_can_receive (BusClientPolicy *policy,
00918                                      BusRegistry     *registry,
00919                                      <a class="code" href="structDBusConnection.html">DBusConnection</a>  *sender,
00920                                      <a class="code" href="structDBusConnection.html">DBusConnection</a>  *addressed_recipient,
00921                                      <a class="code" href="structDBusConnection.html">DBusConnection</a>  *proposed_recipient,
00922                                      <a class="code" href="structDBusMessage.html">DBusMessage</a>     *message)
00923 {
00924   <a class="code" href="structDBusList.html">DBusList</a> *link;
00925   dbus_bool_t allowed;
00926   dbus_bool_t eavesdropping;
00927   
00928   <font class="comment">/* NULL sender, proposed_recipient means the bus driver.  NULL</font>
00929 <font class="comment">   * addressed_recipient means the message didn't specify an explicit</font>
00930 <font class="comment">   * target. If proposed_recipient is NULL, then addressed_recipient</font>
00931 <font class="comment">   * is also NULL but is implicitly the bus driver.</font>
00932 <font class="comment">   */</font>
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 || <font class="comment">/* explicitly to bus driver */</font>
00940      (addressed_recipient &amp;&amp; addressed_recipient != proposed_recipient)); <font class="comment">/* explicitly to a different recipient */</font>
00941   
00942   <font class="comment">/* policy-&gt;rules is in the order the rules appeared</font>
00943 <font class="comment">   * in the config file, i.e. last rule that applies wins</font>
00944 <font class="comment">   */</font>
00945 
00946   _dbus_verbose (<font class="stringliteral">"  (policy) checking receive rules, eavesdropping = %d\n"</font>, eavesdropping);
00947   
00948   allowed = FALSE;
00949   link = _dbus_list_get_first_link (&amp;policy-&gt;rules);
00950   <font class="keywordflow">while</font> (link != NULL)
00951     {
00952       BusPolicyRule *rule = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
00953 
00954       link = _dbus_list_get_next_link (&amp;policy-&gt;rules, link);      
00955       
00956       <font class="keywordflow">if</font> (rule-&gt;type != BUS_POLICY_RULE_RECEIVE)
00957         {
00958           _dbus_verbose (<font class="stringliteral">"  (policy) skipping non-receive rule\n"</font>);
00959           <font class="keywordflow">continue</font>;
00960         }
00961 
00962       <font class="keywordflow">if</font> (rule-&gt;d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID)
00963         {
00964           <font class="keywordflow">if</font> (dbus_message_get_type (message) != rule-&gt;d.receive.message_type)
00965             {
00966               _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule for different message type\n"</font>);
00967               <font class="keywordflow">continue</font>;
00968             }
00969         }
00970 
00971       <font class="comment">/* for allow, eavesdrop=false means the rule doesn't apply when</font>
00972 <font class="comment">       * eavesdropping. eavesdrop=true means always allow.</font>
00973 <font class="comment">       */</font>
00974       <font class="keywordflow">if</font> (eavesdropping &amp;&amp; rule-&gt;allow &amp;&amp; !rule-&gt;d.receive.eavesdrop)
00975         {
00976           _dbus_verbose (<font class="stringliteral">"  (policy) skipping allow rule since it doesn't apply to eavesdropping\n"</font>);
00977           <font class="keywordflow">continue</font>;
00978         }
00979 
00980       <font class="comment">/* for deny, eavesdrop=true means the rule applies only when</font>
00981 <font class="comment">       * eavesdropping; eavesdrop=false means always deny.</font>
00982 <font class="comment">       */</font>
00983       <font class="keywordflow">if</font> (!eavesdropping &amp;&amp; !rule-&gt;allow &amp;&amp; rule-&gt;d.receive.eavesdrop)
00984         {
00985           _dbus_verbose (<font class="stringliteral">"  (policy) skipping deny rule since it only applies to eavesdropping\n"</font>);
00986           <font class="keywordflow">continue</font>;
00987         }
00988       
00989       <font class="keywordflow">if</font> (rule-&gt;d.receive.path != NULL)
00990         {
00991           <font class="keywordflow">if</font> (dbus_message_get_path (message) != NULL &amp;&amp;
00992               strcmp (dbus_message_get_path (message),
00993                       rule-&gt;d.receive.path) != 0)
00994             {
00995               _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule for different path\n"</font>);
00996               <font class="keywordflow">continue</font>;
00997             }
00998         }
00999       
01000       <font class="keywordflow">if</font> (rule-&gt;d.receive.interface != NULL)
01001         {
01002           <font class="keywordflow">if</font> (dbus_message_get_interface (message) != NULL &amp;&amp;
01003               strcmp (dbus_message_get_interface (message),
01004                       rule-&gt;d.receive.interface) != 0)
01005             {
01006               _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule for different interface\n"</font>);
01007               <font class="keywordflow">continue</font>;
01008             }
01009         }      
01010 
01011       <font class="keywordflow">if</font> (rule-&gt;d.receive.member != NULL)
01012         {
01013           <font class="keywordflow">if</font> (dbus_message_get_member (message) != NULL &amp;&amp;
01014               strcmp (dbus_message_get_member (message),
01015                       rule-&gt;d.receive.member) != 0)
01016             {
01017               _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule for different member\n"</font>);
01018               <font class="keywordflow">continue</font>;
01019             }
01020         }
01021 
01022       <font class="keywordflow">if</font> (rule-&gt;d.receive.error != NULL)
01023         {
01024           <font class="keywordflow">if</font> (dbus_message_get_error_name (message) != NULL &amp;&amp;
01025               strcmp (dbus_message_get_error_name (message),
01026                       rule-&gt;d.receive.error) != 0)
01027             {
01028               _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule for different error name\n"</font>);
01029               <font class="keywordflow">continue</font>;
01030             }
01031         }
01032       
01033       <font class="keywordflow">if</font> (rule-&gt;d.receive.origin != NULL)
01034         {          
01035           <font class="comment">/* sender can be NULL for messages that originate from the</font>
01036 <font class="comment">           * message bus itself, we check the strings in that case as</font>
01037 <font class="comment">           * built-in services don't have a DBusConnection but will</font>
01038 <font class="comment">           * still set the sender on their messages.</font>
01039 <font class="comment">           */</font>
01040           <font class="keywordflow">if</font> (sender == NULL)
01041             {
01042               <font class="keywordflow">if</font> (!dbus_message_has_sender (message,
01043                                             rule-&gt;d.receive.origin))
01044                 {
01045                   _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule because message sender is not %s\n"</font>,
01046                                  rule-&gt;d.receive.origin);
01047                   <font class="keywordflow">continue</font>;
01048                 }
01049             }
01050           <font class="keywordflow">else</font>
01051             {
01052               BusService *service;
01053               <a class="code" href="structDBusString.html">DBusString</a> str;
01054 
01055               _dbus_string_init_const (&amp;str, rule-&gt;d.receive.origin);
01056               
01057               service = bus_registry_lookup (registry, &amp;str);
01058               
01059               <font class="keywordflow">if</font> (service == NULL)
01060                 {
01061                   _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule because origin %s doesn't exist\n"</font>,
01062                                  rule-&gt;d.receive.origin);
01063                   <font class="keywordflow">continue</font>;
01064                 }
01065 
01066               <font class="keywordflow">if</font> (!bus_service_has_owner (service, sender))
01067                 {
01068                   _dbus_verbose (<font class="stringliteral">"  (policy) skipping rule because origin %s isn't owned by sender\n"</font>,
01069                                  rule-&gt;d.receive.origin);
01070                   <font class="keywordflow">continue</font>;
01071                 }
01072             }
01073         }
01074       
01075       <font class="comment">/* Use this rule */</font>
01076       allowed = rule-&gt;allow;
01077 
01078       _dbus_verbose (<font class="stringliteral">"  (policy) used rule, allow now = %d\n"</font>,
01079                      allowed);
01080     }
01081 
01082   <font class="keywordflow">return</font> allowed;
01083 }
01084 
01085 dbus_bool_t
01086 bus_client_policy_check_can_own (BusClientPolicy  *policy,
01087                                  <a class="code" href="structDBusConnection.html">DBusConnection</a>   *connection,
01088                                  <font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *service_name)
01089 {
01090   <a class="code" href="structDBusList.html">DBusList</a> *link;
01091   dbus_bool_t allowed;
01092   
01093   <font class="comment">/* policy-&gt;rules is in the order the rules appeared</font>
01094 <font class="comment">   * in the config file, i.e. last rule that applies wins</font>
01095 <font class="comment">   */</font>
01096 
01097   allowed = FALSE;
01098   link = _dbus_list_get_first_link (&amp;policy-&gt;rules);
01099   <font class="keywordflow">while</font> (link != NULL)
01100     {
01101       BusPolicyRule *rule = link-&gt;<a class="code" href="structDBusList.html#m2">data</a>;
01102 
01103       link = _dbus_list_get_next_link (&amp;policy-&gt;rules, link);
01104       
01105       <font class="comment">/* Rule is skipped if it specifies a different service name from</font>
01106 <font class="comment">       * the desired one.</font>
01107 <font class="comment">       */</font>
01108       
01109       <font class="keywordflow">if</font> (rule-&gt;type != BUS_POLICY_RULE_OWN)
01110         <font class="keywordflow">continue</font>;
01111 
01112       <font class="keywordflow">if</font> (rule-&gt;d.own.service_name != NULL)
01113         {
01114           <font class="keywordflow">if</font> (!_dbus_string_equal_c_str (service_name,
01115                                          rule-&gt;d.own.service_name))
01116             <font class="keywordflow">continue</font>;
01117         }
01118 
01119       <font class="comment">/* Use this rule */</font>
01120       allowed = rule-&gt;allow;
01121     }
01122 
01123   <font class="keywordflow">return</font> allowed;
01124 }
01125 
01126 <font class="preprocessor">#ifdef DBUS_BUILD_TESTS</font>
01127 <font class="preprocessor"></font>
01128 dbus_bool_t
01129 bus_policy_test (<font class="keyword">const</font> <a class="code" href="structDBusString.html">DBusString</a> *test_data_dir)
01130 {
01131   <font class="comment">/* This doesn't do anything for now because I decided to do it in</font>
01132 <font class="comment">   * dispatch.c instead by having some of the clients in dispatch.c</font>
01133 <font class="comment">   * have particular policies applied to them.</font>
01134 <font class="comment">   */</font>
01135   
01136   <font class="keywordflow">return</font> TRUE;
01137 }
01138 
01139 <font class="preprocessor">#endif </font><font class="comment">/* DBUS_BUILD_TESTS */</font>
</pre></div><hr><address align="right"><small>Generated on Mon Sep 29 21:31:02 2003 for D-BUS by
<a href="http://www.doxygen.org/index.html">
<img src="doxygen.png" alt="doxygen" align="middle" border=0 
width=110 height=53></a>1.2.15 </small></address>
</body>
</html>