2003-09-06 Havoc Pennington <hp@pobox.com>
authorHavoc Pennington <hp@redhat.com>
Sat, 6 Sep 2003 21:12:11 +0000 (21:12 +0000)
committerHavoc Pennington <hp@redhat.com>
Sat, 6 Sep 2003 21:12:11 +0000 (21:12 +0000)
* doc/dbus-specification.sgml: partial updates

* bus/dbus-daemon-1.1.in: fix the config file docs for the
zillionth time; hopefully I edited the right file this time.

* bus/config-parser.c (append_rule_from_element): support
send_type, send_path, receive_type, receive_path

* bus/policy.c: add message type and path to the list of things
that can be "firewalled"

ChangeLog
bus/config-parser.c
bus/dbus-daemon-1.1.in
bus/policy.c
bus/policy.h
doc/dbus-specification.sgml
test/data/valid-config-files/many-rules.conf [new file with mode: 0644]

index a9328da..1e60a09 100644 (file)
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,18 @@
 2003-09-06  Havoc Pennington  <hp@pobox.com>
 
+       * doc/dbus-specification.sgml: partial updates
+
+       * bus/dbus-daemon-1.1.in: fix the config file docs for the
+       zillionth time; hopefully I edited the right file this time.
+
+       * bus/config-parser.c (append_rule_from_element): support
+       send_type, send_path, receive_type, receive_path
+
+       * bus/policy.c: add message type and path to the list of things
+       that can be "firewalled"
+
+2003-09-06  Havoc Pennington  <hp@pobox.com>
+
        * dbus/dbus-connection.c (dbus_connection_register_fallback): add this
        (dbus_connection_register_object_path): make this not handle
        messages to paths below the given path
index 471c67d..2a7d075 100644 (file)
@@ -808,6 +808,21 @@ start_busconfig_child (BusConfigParser   *parser,
     }
 }
 
+static int
+message_type_from_string (const char *type_str)
+{
+  if (strcmp (type_str, "method_call") == 0)
+    return DBUS_MESSAGE_TYPE_METHOD_CALL;
+  if (strcmp (type_str, "method_return") == 0)
+    return DBUS_MESSAGE_TYPE_METHOD_RETURN;
+  else if (strcmp (type_str, "signal") == 0)
+    return DBUS_MESSAGE_TYPE_SIGNAL;
+  else if (strcmp (type_str, "error") == 0)
+    return DBUS_MESSAGE_TYPE_ERROR;
+  else
+    return DBUS_MESSAGE_TYPE_INVALID;
+}
+
 static dbus_bool_t
 append_rule_from_element (BusConfigParser   *parser,
                           const char        *element_name,
@@ -820,10 +835,14 @@ append_rule_from_element (BusConfigParser   *parser,
   const char *send_member;
   const char *send_error;
   const char *send_service;
+  const char *send_path;
+  const char *send_type;
   const char *receive_interface;
   const char *receive_member;
   const char *receive_error;
   const char *receive_service;
+  const char *receive_path;
+  const char *receive_type;
   const char *own;
   const char *user;
   const char *group;
@@ -837,10 +856,14 @@ append_rule_from_element (BusConfigParser   *parser,
                           "send_member", &send_member,
                           "send_error", &send_error,
                           "send_service", &send_service,
+                          "send_path", &send_path,
+                          "send_type", &send_type,
                           "receive_interface", &receive_interface,
                           "receive_member", &receive_member,
                           "receive_error", &receive_error,
                           "receive_service", &receive_service,
+                          "receive_path", &receive_path,
+                          "receive_type", &receive_type,
                           "own", &own,
                           "user", &user,
                           "group", &group,
@@ -848,7 +871,9 @@ append_rule_from_element (BusConfigParser   *parser,
     return FALSE;
 
   if (!(send_interface || send_member || send_error || send_service ||
+        send_type || send_path ||
         receive_interface || receive_member || receive_error || receive_service ||
+        receive_type || receive_path ||
         own || user || group))
     {
       dbus_set_error (error, DBUS_ERROR_FAILED,
@@ -857,11 +882,11 @@ append_rule_from_element (BusConfigParser   *parser,
       return FALSE;
     }
 
-  if ((send_member && send_interface == NULL) ||
-      (receive_member && receive_interface == NULL))
+  if ((send_member && (send_interface == NULL && send_path == NULL)) ||
+      (receive_member && (receive_interface == NULL && receive_path == NULL)))
     {
       dbus_set_error (error, DBUS_ERROR_FAILED,
-                      "On element <%s>, if you specify a member you must specify an interface",
+                      "On element <%s>, if you specify a member you must specify an interface or a path. Keep in mind that not all messages have an interface field.",
                       element_name);
       return FALSE;
     }
@@ -869,12 +894,13 @@ append_rule_from_element (BusConfigParser   *parser,
   /* Allowed combinations of elements are:
    *
    *   base, must be all send or all receive:
+   *     nothing
    *     interface
    *     interface + member
    *     error
    * 
-   *   base send_ can combine with send_service,
-   *   base receive_ with receive_service
+   *   base send_ can combine with send_service, send_path, send_type
+   *   base receive_ with receive_service, receive_path, receive_type
    *
    *   user, group, own must occur alone
    */
@@ -913,6 +939,22 @@ append_rule_from_element (BusConfigParser   *parser,
        (send_service && user) ||
        (send_service && group)) ||
 
+      ((send_type && receive_interface) ||
+       (send_type && receive_member) ||
+       (send_type && receive_error) ||
+       (send_type && receive_service) ||
+       (send_type && own) ||
+       (send_type && user) ||
+       (send_type && group)) ||
+
+      ((send_path && receive_interface) ||
+       (send_path && receive_member) ||
+       (send_path && receive_error) ||
+       (send_path && receive_service) ||
+       (send_path && own) ||
+       (send_path && user) ||
+       (send_path && group)) ||
+      
       ((receive_interface && receive_error) ||
        (receive_interface && own) ||
        (receive_interface && user) ||
@@ -938,7 +980,7 @@ append_rule_from_element (BusConfigParser   *parser,
                       element_name);
       return FALSE;
     }
-       
+  
   rule = NULL;
 
   /* In BusPolicyRule, NULL represents wildcard.
@@ -946,11 +988,10 @@ append_rule_from_element (BusConfigParser   *parser,
    */
 #define IS_WILDCARD(str) ((str) && ((str)[0]) == '*' && ((str)[1]) == '\0')
 
-  if (send_interface || send_member || send_error || send_service)
+  if (send_interface || send_member || send_error || send_service ||
+      send_path || send_type)
     {
-      rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow); 
-      if (rule == NULL)
-        goto nomem;
+      int message_type;
       
       if (IS_WILDCARD (send_interface))
         send_interface = NULL;
@@ -960,11 +1001,36 @@ append_rule_from_element (BusConfigParser   *parser,
         send_error = NULL;
       if (IS_WILDCARD (send_service))
         send_service = NULL;
+      if (IS_WILDCARD (send_path))
+        send_path = NULL;
+      if (IS_WILDCARD (send_type))
+        send_type = NULL;
+
+      message_type = DBUS_MESSAGE_TYPE_INVALID;
+      if (send_type != NULL)
+        {
+          message_type = message_type_from_string (send_type);
+          if (message_type == DBUS_MESSAGE_TYPE_INVALID)
+            {
+              dbus_set_error (error, DBUS_ERROR_FAILED,
+                              "Bad message type \"%s\"",
+                              send_type);
+              return FALSE;
+            }
+        }
       
+      rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow); 
+      if (rule == NULL)
+        goto nomem;
+
+      rule->d.send.message_type = message_type;
+      rule->d.send.path = _dbus_strdup (send_path);
       rule->d.send.interface = _dbus_strdup (send_interface);
       rule->d.send.member = _dbus_strdup (send_member);
       rule->d.send.error = _dbus_strdup (send_error);
       rule->d.send.destination = _dbus_strdup (send_service);
+      if (send_path && rule->d.send.path == NULL)
+        goto nomem;
       if (send_interface && rule->d.send.interface == NULL)
         goto nomem;
       if (send_member && rule->d.send.member == NULL)
@@ -974,11 +1040,10 @@ append_rule_from_element (BusConfigParser   *parser,
       if (send_service && rule->d.send.destination == NULL)
         goto nomem;
     }
-  else if (receive_interface || receive_member || receive_error || receive_service)
+  else if (receive_interface || receive_member || receive_error || receive_service ||
+           receive_path || receive_type)
     {
-      rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, allow); 
-      if (rule == NULL)
-        goto nomem;
+      int message_type;
       
       if (IS_WILDCARD (receive_interface))
         receive_interface = NULL;
@@ -988,11 +1053,37 @@ append_rule_from_element (BusConfigParser   *parser,
         receive_error = NULL;
       if (IS_WILDCARD (receive_service))
         receive_service = NULL;
+      if (IS_WILDCARD (receive_path))
+        receive_path = NULL;
+      if (IS_WILDCARD (receive_type))
+        receive_type = NULL;
+
+
+      message_type = DBUS_MESSAGE_TYPE_INVALID;
+      if (receive_type != NULL)
+        {
+          message_type = message_type_from_string (receive_type);
+          if (message_type == DBUS_MESSAGE_TYPE_INVALID)
+            {
+              dbus_set_error (error, DBUS_ERROR_FAILED,
+                              "Bad message type \"%s\"",
+                              receive_type);
+              return FALSE;
+            }
+        }
+      
+      rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, allow); 
+      if (rule == NULL)
+        goto nomem;
 
+      rule->d.receive.message_type = message_type;
+      rule->d.receive.path = _dbus_strdup (receive_path);
       rule->d.receive.interface = _dbus_strdup (receive_interface);
       rule->d.receive.member = _dbus_strdup (receive_member);
       rule->d.receive.error = _dbus_strdup (receive_error);
       rule->d.receive.origin = _dbus_strdup (receive_service);
+      if (receive_path && rule->d.receive.path == NULL)
+        goto nomem;
       if (receive_interface && rule->d.receive.interface == NULL)
         goto nomem;
       if (receive_member && rule->d.receive.member == NULL)
index 73a88c9..ec915ed 100644 (file)
@@ -333,11 +333,22 @@ in the config file.
 A <deny> element appears below a <policy> element and prohibits 
 some action. The possible attributes of a <deny> element are:
 .nf
-   send="messagename"
+   send_interface="interface_name"
+   send_member="method_or_signal_name" 
+   send_error="error_name" 
+   send_service="service_name" 
+   send_type="method_call|method_return|signal|error" 
+   send_path="/path/name"
+
+   receive_interface="interface_name"
+   receive_member="method_or_signal_name" 
+   receive_error="error_name" 
+   receive_service="service_name" 
+   receive_type="method_call|method_return|signal|error" 
+   receive_path="/path/name"
+
    receive="messagename"
    own="servicename"
-   send_to="servicename"
-   receive_from="servicename"
    user="username"
    group="groupname"
 .fi
@@ -345,11 +356,11 @@ some action. The possible attributes of a <deny> element are:
 .PP
 Examples:
 .nf
-   <deny send="org.freedesktop.System.Reboot"/> 
-   <deny receive="org.freedesktop.System.Reboot"/>
+   <deny send_interface="org.freedesktop.System" send_member="Reboot"/> 
+   <deny receive_interface="org.freedesktop.System" receive_member="Reboot"/>
    <deny own="org.freedesktop.System"/>
-   <deny send_to="org.freedesktop.System"/>
-   <deny receive_from="org.freedesktop.System"/>
+   <deny send_service="org.freedesktop.System"/>
+   <deny receive_service="org.freedesktop.System"/>
    <deny user="john"/>
    <deny group="enemies"/>
 .fi
@@ -360,18 +371,22 @@ particular action. If it matches, the action is denied (unless later
 rules in the config file allow it).
 
 .PP
-send_to and receive_from mean that messages may not be sent to or
-received from the *owner* of the given service, not that they may not
-be sent *to that service name*. That is, if a connection owns services
-A, B, C, and sending to A is denied, sending to B or C will not work
-either.
+send_service and receive_service rules mean that messages may not be
+sent to or received from the *owner* of the given service, not that
+they may not be sent *to that service name*. That is, if a connection
+owns services A, B, C, and sending to A is denied, sending to B or C
+will not work either.
+
+.PP
+The other send_* and receive_* attributes are purely textual/by-value
+matches against the given field in the message header.
 
 .PP
 user and group denials mean that the given user or group may 
 not connect to the message bus.
 
 .PP
-For "servicename" or "messagename" or "username" or "groupname"
+For "service_name", "username", "groupname", etc.
 the character "*" can be substituted, meaning "any." Complex globs
 like "foo.bar.*" aren't allowed for now because they'd be work to
 implement and maybe encourage sloppy security anyway.
@@ -382,11 +397,21 @@ for a user or group; user/group denials can only be inside
 context="default" or context="mandatory" policies.
 
 .PP
-A single <deny> rule may specify both send and send_to, OR both
-receive and receive_from. In this case, the denial applies only if
-both attributes match the message being denied.
-e.g. <deny send="foo.bar" send_to="foo.blah"/> would deny 
-messages of the given name AND to the given service.
+A single <deny> rule may specify combinations of attributes such as
+send_service and send_interface and send_type. In this case, the
+denial applies only if both attributes match the message being denied.
+e.g. <deny send_interface="foo.bar" send_service="foo.blah"/> would
+deny messages of the given interface AND to the given service.
+To get an OR effect you specify multiple <deny> rules.
+
+.PP
+You can't include both send_ and receive_ attributes on the same
+rule, since "whether the message can be sent" and "whether it can be
+received" are evaluated separately.
+
+.PP
+Be careful with send_interface/receive_interface, because the 
+interface field in messages is optional.
 
 .TP
 .I "<allow>"
index f7978c0..21d0b02 100644 (file)
@@ -52,7 +52,11 @@ bus_policy_rule_new (BusPolicyRuleType type,
       rule->d.group.gid = DBUS_GID_UNSET;
       break;
     case BUS_POLICY_RULE_SEND:
+      rule->d.send.message_type = DBUS_MESSAGE_TYPE_INVALID;
+      break;
     case BUS_POLICY_RULE_RECEIVE:
+      rule->d.receive.message_type = DBUS_MESSAGE_TYPE_INVALID;
+      break;
     case BUS_POLICY_RULE_OWN:
       break;
     }
@@ -80,12 +84,14 @@ bus_policy_rule_unref (BusPolicyRule *rule)
       switch (rule->type)
         {
         case BUS_POLICY_RULE_SEND:
+          dbus_free (rule->d.send.path);
           dbus_free (rule->d.send.interface);
           dbus_free (rule->d.send.member);
           dbus_free (rule->d.send.error);
           dbus_free (rule->d.send.destination);
           break;
         case BUS_POLICY_RULE_RECEIVE:
+          dbus_free (rule->d.receive.path);
           dbus_free (rule->d.receive.interface);
           dbus_free (rule->d.receive.member);
           dbus_free (rule->d.receive.error);
@@ -717,6 +723,8 @@ bus_client_policy_optimize (BusClientPolicy *policy)
         {
         case BUS_POLICY_RULE_SEND:
           remove_preceding =
+            rule->d.send.message_type == DBUS_MESSAGE_TYPE_INVALID &&
+            rule->d.send.path == NULL &&
             rule->d.send.interface == NULL &&
             rule->d.send.member == NULL &&
             rule->d.send.error == NULL &&
@@ -724,6 +732,8 @@ bus_client_policy_optimize (BusClientPolicy *policy)
           break;
         case BUS_POLICY_RULE_RECEIVE:
           remove_preceding =
+            rule->d.receive.message_type == DBUS_MESSAGE_TYPE_INVALID &&
+            rule->d.receive.path == NULL &&
             rule->d.receive.interface == NULL &&
             rule->d.receive.member == NULL &&
             rule->d.receive.error == NULL &&
@@ -799,6 +809,26 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
           continue;
         }
 
+      if (rule->d.send.message_type != DBUS_MESSAGE_TYPE_INVALID)
+        {
+          if (dbus_message_get_type (message) != rule->d.send.message_type)
+            {
+              _dbus_verbose ("  (policy) skipping rule for different message type\n");
+              continue;
+            }
+        }
+      
+      if (rule->d.send.path != NULL)
+        {
+          if (dbus_message_get_path (message) != NULL &&
+              strcmp (dbus_message_get_path (message),
+                      rule->d.send.path) != 0)
+            {
+              _dbus_verbose ("  (policy) skipping rule for different path\n");
+              continue;
+            }
+        }
+      
       if (rule->d.send.interface != NULL)
         {
           if (dbus_message_get_interface (message) != NULL &&
@@ -911,6 +941,26 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
           _dbus_verbose ("  (policy) skipping non-receive rule\n");
           continue;
         }
+
+      if (rule->d.receive.message_type != DBUS_MESSAGE_TYPE_INVALID)
+        {
+          if (dbus_message_get_type (message) != rule->d.receive.message_type)
+            {
+              _dbus_verbose ("  (policy) skipping rule for different message type\n");
+              continue;
+            }
+        }
+      
+      if (rule->d.receive.path != NULL)
+        {
+          if (dbus_message_get_path (message) != NULL &&
+              strcmp (dbus_message_get_path (message),
+                      rule->d.receive.path) != 0)
+            {
+              _dbus_verbose ("  (policy) skipping rule for different path\n");
+              continue;
+            }
+        }
       
       if (rule->d.receive.interface != NULL)
         {
index 2aa69aa..5824816 100644 (file)
@@ -54,7 +54,10 @@ struct BusPolicyRule
   {
     struct
     {
+      /* message type can be DBUS_MESSAGE_TYPE_INVALID meaning "any" */
+      int   message_type;
       /* any of these can be NULL meaning "any" */
+      char *path;
       char *interface;
       char *member;
       char *error;
@@ -63,7 +66,10 @@ struct BusPolicyRule
 
     struct
     {
+      /* message type can be DBUS_MESSAGE_TYPE_INVALID meaning "any" */
+      int   message_type;
       /* any of these can be NULL meaning "any" */
+      char *path;
       char *interface;
       char *member;
       char *error;
index 031bb32..7800165 100644 (file)
@@ -3,8 +3,8 @@
 <article id="index">
   <artheader>
     <title>D-BUS Specification</title>
-    <releaseinfo>Version 0.7</releaseinfo>
-    <date>26 March 2003</date>
+    <releaseinfo>Version 0.8</releaseinfo>
+    <date>06 September 2003</date>
     <authorgroup>
       <author>
        <firstname>Havoc</firstname>
           <para>
             D-BUS is <emphasis>easy to use</emphasis> because it works in terms
             of <firstterm>messages</firstterm> rather than byte streams, and
-            does not require users to understand any complex concepts such as a
-            new type system or elaborate APIs. Libraries implementing D-BUS 
-            may choose to abstract messages as "method calls" (see 
-            <xref linkend="message-conventions-method">).
+            automatically handles a lot of the hard IPC issues. Also, the D-BUS
+            library is designed to be wrapped in a way that lets users use their
+            framework's existing object/type system, rather than learning a new 
+            one specifically for IPC.
           </para>
         </listitem>
       </itemizedlist>
       forwards messages among them.
     </para>
     <para>
-      Things that D-BUS can be used for is for example notification of
-      system changes (notification of when a camera is plugged in to a
-      computer, or a new version of some software has been installed),
-      or desktop interoperablity, for example a file monitoring
-      service or a configuration service.
+      Uses of D-BUS include notification of system changes (notification of when
+      a camera is plugged in to a computer, or a new version of some software
+      has been installed), or desktop interoperablity, for example a file
+      monitoring service or a configuration service.
     </para>
   </sect1>
 
             </thead>
             <tbody>
               <row>
-                <entry>name</entry>
+                <entry>path</entry>
                 <entry>STRING</entry>
-                <entry>The name of the message, such as org.freedesktop.Peer.Ping</entry>
+                <entry>The object to send the message to; objects are identified by 
+                a path, "/foo/bar"</entry>
+              </row>
+              <row>
+                <entry>ifce</entry>
+                <entry>STRING</entry>
+                <entry>The interface to invoke a method call on, or 
+                that a signal is emitted from. e.g. "org.freedesktop.Introspectable"</entry>
+              </row>
+              <row>
+                <entry>mebr</entry>
+                <entry>STRING</entry>
+                <entry>The member, either the method name or signal name. 
+                e.g. "Frobate"</entry>
+              </row>
+              <row>
+                <entry>ernm</entry>
+                <entry>STRING</entry>
+                <entry>The name of the error that occurred, for errors</entry>
               </row>
               <row>
                 <entry>rply</entry>
                 <xref linkend="message-bus">.</entry>
               </row>
               <row>
-                <entry>sndr</entry>
+                <entry>sdrs</entry>
                 <entry>STRING</entry>
-                <entry>The name of the base service that sent this message. 
-                The message bus fills in this field; the field is 
+                <entry>Sender service. The name of the base service that sent
+                this message.  The message bus fills in this field; the field is
                 only meaningful in combination with the message bus.</entry>
               </row>
             </tbody>
     <sect2 id="message-protocol-names">
       <title>Valid names</title>
       <para>
-        Messages and services have names with type STRING, meaning that 
+        Services have names with type STRING, meaning that 
         they must be valid UTF-8. However, there are also some 
-        additional restrictions that apply to message and service names 
+        additional restrictions that apply to service names 
         specifically:
         <itemizedlist>
          <listitem><para>They must contain at least one '.' (period) character</para></listitem>
diff --git a/test/data/valid-config-files/many-rules.conf b/test/data/valid-config-files/many-rules.conf
new file mode 100644 (file)
index 0000000..57ea5ec
--- /dev/null
@@ -0,0 +1,57 @@
+<!DOCTYPE busconfig PUBLIC "-//freedesktop//DTD D-BUS Bus Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/dbus/1.0/busconfig.dtd">
+<busconfig>
+  <user>mybususer</user>
+  <listen>unix:path=/foo/bar</listen>
+  <listen>tcp:port=1234</listen>
+  <includedir>basic.d</includedir>
+  <servicedir>/usr/share/foo</servicedir>
+  <include ignore_missing="yes">nonexistent.conf</include>
+  <policy context="default">
+    <allow user="*"/>
+    <deny send_interface="org.freedesktop.System" send_member="Reboot"/> 
+    <deny receive_interface="org.freedesktop.System" receive_member="Reboot"/>
+    <deny send_path="/foo/bar/SystemObjectThing" send_member="Reboot"/> 
+    <deny own="org.freedesktop.System"/>
+    <deny send_service="org.freedesktop.System"/>
+    <deny receive_service="org.freedesktop.System"/>
+    <deny user="root"/>
+    <deny group="root"/>
+    <allow send_type="error"/>
+    <allow send_type="method_call"/>
+    <allow send_type="method_return"/>
+    <allow send_type="signal"/>
+    <deny send_service="org.freedesktop.Bar" send_interface="org.freedesktop.Foo"/>
+    <deny send_service="org.freedesktop.Bar" send_interface="org.freedesktop.Foo" send_type="method_call"/>
+  </policy>
+
+  <policy context="mandatory">
+    <allow user="*"/>
+    <deny send_interface="org.freedesktop.System" send_member="Reboot"/> 
+    <deny receive_interface="org.freedesktop.System" receive_member="Reboot"/>
+    <deny send_path="/foo/bar/SystemObjectThing" send_member="Reboot"/> 
+    <deny own="org.freedesktop.System"/>
+    <deny send_service="org.freedesktop.System"/>
+    <deny receive_service="org.freedesktop.System"/>
+    <deny user="root"/>
+    <deny group="root"/>
+    <allow send_type="error"/>
+    <allow send_type="method_call"/>
+    <allow send_type="method_return"/>
+    <allow send_type="signal"/>
+    <deny send_service="org.freedesktop.Bar" send_interface="org.freedesktop.Foo"/>
+    <deny send_service="org.freedesktop.Bar" send_interface="org.freedesktop.Foo" send_type="method_call"/>
+  </policy>
+
+  <limit name="max_incoming_bytes">5000</limit>   
+  <limit name="max_outgoing_bytes">5000</limit>
+  <limit name="max_message_size">300</limit>
+  <limit name="activation_timeout">5000</limit>
+  <limit name="auth_timeout">6000</limit>
+  <limit name="max_completed_connections">50</limit>  
+  <limit name="max_incomplete_connections">80</limit>
+  <limit name="max_connections_per_user">64</limit>
+  <limit name="max_pending_activations">64</limit>
+  <limit name="max_services_per_connection">256</limit>
+                                   
+</busconfig>