const char *send_path;
const char *send_type;
const char *send_requested_reply;
+ const char *send_broadcast;
/* TRUE if any send_ attribute is present */
dbus_bool_t any_send_attribute;
"send_destination", &send_destination,
"send_path", &send_path,
"send_type", &send_type,
+ "send_broadcast", &send_broadcast,
"receive_interface", &receive_interface,
"receive_member", &receive_member,
"receive_error", &receive_error,
return FALSE;
any_send_attribute = (send_destination != NULL ||
+ send_broadcast != NULL ||
send_path != NULL ||
send_type != NULL ||
send_interface != NULL ||
* interface + member
* error
*
- * base send_ can combine with send_destination, send_path, send_type, send_requested_reply, eavesdrop
+ * base send_ can combine with send_destination, send_path, send_type, send_requested_reply, send_broadcast, eavesdrop
* base receive_ with receive_sender, receive_path, receive_type, receive_requested_reply, eavesdrop
*
* user, group, own, own_prefix must occur alone
return FALSE;
}
+ if (send_broadcast &&
+ !(strcmp (send_broadcast, "true") == 0 ||
+ strcmp (send_broadcast, "false") == 0))
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Bad value \"%s\" for %s attribute, must be true or false",
+ send_broadcast, "send_broadcast");
+ return FALSE;
+ }
+
if (send_requested_reply &&
!(strcmp (send_requested_reply, "true") == 0 ||
strcmp (send_requested_reply, "false") == 0))
if (send_requested_reply)
rule->d.send.requested_reply = (strcmp (send_requested_reply, "true") == 0);
+ if (send_broadcast)
+ {
+ if (strcmp (send_broadcast, "true") == 0)
+ rule->d.send.broadcast = BUS_POLICY_TRISTATE_TRUE;
+ else
+ rule->d.send.broadcast = BUS_POLICY_TRISTATE_FALSE;
+ }
+ else
+ {
+ rule->d.send.broadcast = BUS_POLICY_TRISTATE_ANY;
+ }
+
rule->d.send.message_type = message_type;
rule->d.send.path = _dbus_strdup (send_path);
rule->d.send.interface = _dbus_strdup (send_interface);
continue;
}
}
-
+
+ if (rule->d.send.broadcast != BUS_POLICY_TRISTATE_ANY)
+ {
+ if (dbus_message_get_destination (message) == NULL &&
+ dbus_message_get_type (message) == DBUS_MESSAGE_TYPE_SIGNAL)
+ {
+ /* it's a broadcast */
+ if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_FALSE)
+ {
+ _dbus_verbose (" (policy) skipping rule because message is a broadcast\n");
+ continue;
+ }
+ }
+ /* else it isn't a broadcast: there is some destination */
+ else if (rule->d.send.broadcast == BUS_POLICY_TRISTATE_TRUE)
+ {
+ _dbus_verbose (" (policy) skipping rule because message is not a broadcast\n");
+ continue;
+ }
+ }
+
if (rule->d.send.destination != NULL)
{
/* receiver can be NULL for messages that are sent to the
BUS_POLICY_RULE_GROUP
} BusPolicyRuleType;
+typedef enum
+{
+ BUS_POLICY_TRISTATE_ANY = 0,
+ BUS_POLICY_TRISTATE_FALSE,
+ BUS_POLICY_TRISTATE_TRUE
+} BusPolicyTristate;
+
/** determines whether the rule affects a connection, or some global item */
#define BUS_POLICY_RULE_IS_PER_CLIENT(rule) (!((rule)->type == BUS_POLICY_RULE_USER || \
(rule)->type == BUS_POLICY_RULE_GROUP))
unsigned int eavesdrop : 1;
unsigned int requested_reply : 1;
unsigned int log : 1;
+ unsigned int broadcast : 2; /**< really a BusPolicyTristate */
} send;
struct
send_interface="interface_name" | "*"
send_member="method_or_signal_name" | "*"
send_error="error_name" | "*"
+ send_broadcast="true" | "false"
send_destination="name" | "*"
send_type="method_call" | "method_return" | "signal" | "error" | "*"
send_path="/path/name" | "*"
<literal>receive_sender="*"</literal> similarly matches any message.</para>
<para>
+ Rules with <literal>send_broadcast="true"</literal> match signal messages
+ with no destination (broadcasts). Rules with
+ <literal>send_broadcast="false"</literal> are the inverse: they match any
+ unicast destination (unicast signals, together with all method calls, replies
+ and errors) but do not match messages with no destination (broadcasts). This
+ is not the same as <literal>send_destination="*"</literal>, which matches any
+ sent message, regardless of whether it has a destination or not.
+</para>
+
+<para>
The other <literal>send_</literal>* and <literal>receive_</literal>*
attributes are purely textual/by-value matches against the given field in
the message header, except that for the attributes where it is allowed,