[PATCH 3/5] Add argument checks to policy <allow>/<deny> rules.
Pekka Pessi
Pekka.Pessi at nokia.com
Fri Jun 4 09:58:44 PDT 2010
Added attributes send_signature, send_arg<n>, receive_signature, receive_arg<n>.
The type of the argument is determined with the signature. The corresponding
signature attribute is mandatory if *_arg<n> are specified. Only basic types
are supported. However, it is possible to check if an array is empty.
---
bus/bus.h | 1 +
bus/config-parser.c | 370 +++++++++++++++++++++++++++++++++++++++++++++++++--
bus/policy.c | 125 +++++++++++++++++-
bus/policy.h | 20 +++
4 files changed, 506 insertions(+), 10 deletions(-)
diff --git a/bus/bus.h b/bus/bus.h
index 7eb5fd8..b904136 100644
--- a/bus/bus.h
+++ b/bus/bus.h
@@ -36,6 +36,7 @@ typedef struct BusContext BusContext;
typedef struct BusPolicy BusPolicy;
typedef struct BusClientPolicy BusClientPolicy;
typedef struct BusPolicyRule BusPolicyRule;
+typedef struct BusPolicyArgs BusPolicyArgs;
typedef struct BusRegistry BusRegistry;
typedef struct BusSELinuxID BusSELinuxID;
typedef struct BusService BusService;
diff --git a/bus/config-parser.c b/bus/config-parser.c
index 1a091df..398fd5a 100644
--- a/bus/config-parser.c
+++ b/bus/config-parser.c
@@ -31,6 +31,8 @@
#include <dbus/dbus-list.h>
#include <dbus/dbus-internals.h>
#include <string.h>
+#include <stdlib.h>
+#include <stdio.h>
typedef enum
{
@@ -549,6 +551,7 @@ typedef struct
{
const char *name;
const char **retloc;
+ const char *template;
} LocateAttr;
static dbus_bool_t
@@ -564,6 +567,7 @@ locate_attributes (BusConfigParser *parser,
va_list args;
const char *name;
const char **retloc;
+ const char *template;
int n_attrs;
#define MAX_ATTRS 24
LocateAttr attrs[MAX_ATTRS];
@@ -572,10 +576,16 @@ locate_attributes (BusConfigParser *parser,
_dbus_assert (first_attribute_name != NULL);
_dbus_assert (first_attribute_retloc != NULL);
+ template = strchr (first_attribute_name, '%');
+ /* Template can have single %d */
+ _dbus_assert (template == NULL || template[1] == 'd');
+ _dbus_assert (template == NULL || strchr (template + 1, '%') == NULL);
+
n_attrs = 1;
attrs[0].name = first_attribute_name;
attrs[0].retloc = first_attribute_retloc;
*first_attribute_retloc = NULL;
+ attrs[0].template = template;
va_start (args, first_attribute_retloc);
@@ -584,11 +594,16 @@ locate_attributes (BusConfigParser *parser,
while (name != NULL)
{
+ template = strchr (name, '%');
+
_dbus_assert (retloc != NULL);
_dbus_assert (n_attrs < MAX_ATTRS);
+ _dbus_assert (template == NULL || template[1] == 'd');
+ _dbus_assert (template == NULL || strchr (template + 1, '%') == NULL);
attrs[n_attrs].name = name;
attrs[n_attrs].retloc = retloc;
+ attrs[n_attrs].template = template;
n_attrs += 1;
*retloc = NULL;
@@ -601,14 +616,33 @@ locate_attributes (BusConfigParser *parser,
i = 0;
while (attribute_names[i])
{
+ const char *aname = attribute_names[i];
+ const char *avalue = attribute_values[i];
+
for (j = 0; j < n_attrs; ++j)
{
name = attrs[j].name;
+ template = attrs[j].template;
retloc = attrs[j].retloc;
- if (strcmp (name, attribute_names[i]) == 0)
+ if (template)
+ {
+ int offset = template - name;
+ int digits;
+
+ if (strncmp (aname, name, offset) != 0)
+ continue;
+ digits = (int) strspn (aname + offset, "0123456789");
+ if (digits > 1 && aname[offset] == '0')
+ continue;
+ if (digits == 0 || digits > 2)
+ continue;
+ if (strcmp (aname + offset + digits, template + 2) != 0)
+ continue;
+ goto found;
+ }
+ else if (strcmp (name, aname) == 0)
{
- *retloc = attribute_values[i];
goto found;
}
}
@@ -619,12 +653,68 @@ locate_attributes (BusConfigParser *parser,
return FALSE;
found:
+ *retloc = avalue;
++i;
}
return TRUE;
}
+typedef struct
+{
+ int n;
+ struct {
+ const char *name;
+ const char *value;
+ } list[BUS_POLICY_MAX_ARGS];
+} ArgAttrList;
+
+static dbus_bool_t
+template_attributes (BusConfigParser *parser,
+ const char *element_name,
+ const char **attribute_names,
+ const char **attribute_values,
+ DBusError *error,
+ const char *template,
+ ArgAttrList *retlist)
+{
+ const char *percent;
+ int i;
+
+ /* Template can have single %d */
+ _dbus_assert (template != NULL);
+ percent = strchr (template, '%');
+ _dbus_assert (percent != NULL);
+ _dbus_assert (percent[1] == 'd');
+ _dbus_assert (strchr (percent + 1, '%') == NULL);
+ _dbus_assert (retlist != NULL);
+
+ memset (retlist, 0, sizeof *retlist);
+
+ for (i = 0; attribute_names[i]; ++i)
+ {
+ int n;
+ if (strncmp (attribute_names[i], template, percent - template))
+ continue;
+ if (sscanf (attribute_names[i], template, &n) != 1)
+ continue;
+ if (n < 0 || n >= BUS_POLICY_MAX_ARGS)
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Attribute \"%s\" is invalid on <%s> element in this context",
+ attribute_names[i], element_name);
+ return FALSE;
+ }
+ if (n >= retlist->n)
+ retlist->n = n + 1;
+ /* Duplicate attributes are already detected by expat */
+ retlist->list[n].name = attribute_names[i];
+ retlist->list[n].value = attribute_values[i];
+ }
+
+ return TRUE;
+}
+
static dbus_bool_t
check_no_attributes (BusConfigParser *parser,
const char *element_name,
@@ -1106,6 +1196,196 @@ start_busconfig_child (BusConfigParser *parser,
}
}
+static BusPolicyArgs *
+parse_arg_attributes (BusConfigParser *parser,
+ const char *element_name,
+ const char **attribute_names,
+ const char **attribute_values,
+ DBusError *error,
+ char const *signature,
+ char const *template)
+{
+ ArgAttrList argv;
+ BusPolicyArgs *args;
+ DBusSignatureIter si;
+ int i;
+ int type;
+ char const *avalue;
+ char *rest;
+ union value {
+ dbus_uint16_t q;
+ dbus_int16_t n;
+ dbus_uint32_t u;
+ dbus_int32_t i;
+ dbus_uint64_t t;
+ dbus_int64_t x;
+ double d;
+ unsigned char y;
+ dbus_bool_t b;
+ char s[sizeof (double)];
+ char o[sizeof (double)];
+ } *value;
+ long l;
+ unsigned long ul;
+ long long ll;
+ unsigned long long ull;
+ size_t length;
+
+ if (!template_attributes (parser, element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ template,
+ &argv))
+ return NULL;
+
+ args = bus_policy_args_alloc (argv.n);
+ if (args == NULL)
+ goto nomem;
+
+ dbus_signature_iter_init (&si, signature);
+
+ for (i = 0; i < argv.n; i++, dbus_signature_iter_next (&si))
+ {
+ avalue = argv.list[i].value;
+ if (avalue == NULL)
+ continue;
+
+ type = dbus_signature_iter_get_current_type (&si);
+
+ if (type == DBUS_TYPE_OBJECT_PATH
+ || type == DBUS_TYPE_STRING
+ || type == DBUS_TYPE_SIGNATURE)
+ value = (void *)_dbus_strdup (avalue);
+ else
+ value = dbus_new0 (union value, 1);
+
+ if (value == NULL)
+ goto nomem;
+
+ args->n = i + 1;
+ args->args[i].type = type;
+ args->args[i].value = value;
+
+ rest = NULL;
+
+ switch (type)
+ {
+ case DBUS_TYPE_INVALID:
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "On element <%s>, attribute %s is not allowed with signature=\"%s\"",
+ element_name, argv.list[i].name, signature);
+ goto failed;
+
+ case DBUS_TYPE_BOOLEAN:
+ if (strcmp (avalue, "true") == 0)
+ value->b = TRUE;
+ else if (strcmp (avalue, "false") == 0)
+ value->b = FALSE;
+ else
+ goto value_error;
+ length = sizeof value->b;
+ break;
+
+ case DBUS_TYPE_BYTE:
+ ul = strtoul (avalue, &rest, 0);
+ if (ul >= 256)
+ goto value_error;
+ value->y = (unsigned char)ul;
+ length = sizeof value->y;
+ break;
+
+ case DBUS_TYPE_DOUBLE:
+ value->d = strtod (avalue, &rest);
+ length = sizeof value->d;
+ break;
+
+ case DBUS_TYPE_INT16:
+ l = strtol (avalue, &rest, 0);
+ if (l < _DBUS_INT16_MIN || _DBUS_INT16_MAX < l)
+ goto value_error;
+ value->n = (dbus_int16_t)l;
+ length = sizeof value->n;
+ break;
+
+ case DBUS_TYPE_UINT16:
+ ul = strtoul (avalue, &rest, 0);
+ if (_DBUS_UINT16_MAX < ul)
+ goto value_error;
+ value->q = (dbus_uint16_t)ul;
+ length = sizeof value->q;
+ break;
+
+ case DBUS_TYPE_INT32:
+ ll = strtol (avalue, &rest, 0);
+ if (ll < _DBUS_INT32_MIN || _DBUS_INT32_MAX < ll)
+ goto value_error;
+ value->i = (dbus_int32_t)ll;
+ length = sizeof value->i;
+ break;
+
+ case DBUS_TYPE_UINT32:
+ ull = strtoul (avalue, &rest, 0);
+ if (_DBUS_UINT32_MAX < ull)
+ goto value_error;
+ value->u = (dbus_uint32_t)ull;
+ length = sizeof value->u;
+ break;
+
+ case DBUS_TYPE_INT64:
+ value->x = strtoll (avalue, &rest, 0);
+ length = sizeof value->x;
+ break;
+
+ case DBUS_TYPE_UINT64:
+ value->t = strtoull (avalue, &rest, 0);
+ length = sizeof value->t;
+ break;
+
+ case DBUS_TYPE_STRING:
+ case DBUS_TYPE_SIGNATURE:
+ case DBUS_TYPE_OBJECT_PATH:
+ length = strlen (value->o) + 1;
+ break;
+
+ case DBUS_TYPE_ARRAY:
+ /* Empty string indicates empty array */
+ if (strlen (avalue))
+ goto value_error;
+ length = 0;
+ break;
+
+ default:
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "On element <%s>, %s in signature \"%s\" is not supported",
+ element_name, argv.list[i].name,
+ dbus_signature_iter_get_signature (&si));
+ goto failed;
+ }
+
+ if (rest == NULL || rest[0] == '\0')
+ {
+ args->args[i].length = length;
+ continue;
+ }
+
+ value_error:
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "On element <%s>, attribute %s has invalid value '%s'",
+ element_name, argv.list[i].name, avalue);
+ goto failed;
+ }
+
+ return args;
+
+ nomem:
+ BUS_SET_OOM (error);
+ failed:
+ if (args)
+ bus_policy_args_free (args);
+ return NULL;
+}
+
static dbus_bool_t
append_rule_from_element (BusConfigParser *parser,
const char *element_name,
@@ -1122,12 +1402,16 @@ append_rule_from_element (BusConfigParser *parser,
const char *send_destination;
const char *send_path;
const char *send_type;
+ const char *send_signature;
+ const char *send_argv;
const char *receive_interface;
const char *receive_member;
const char *receive_error;
const char *receive_sender;
const char *receive_path;
const char *receive_type;
+ const char *receive_signature;
+ const char *receive_argv;
const char *eavesdrop;
const char *send_requested_reply;
const char *receive_requested_reply;
@@ -1136,7 +1420,10 @@ append_rule_from_element (BusConfigParser *parser,
const char *group;
BusPolicyRule *rule;
-
+
+ ArgAttrList argv;
+ BusPolicyArgs *args;
+
if (!locate_attributes (parser, element_name,
attribute_names,
attribute_values,
@@ -1147,12 +1434,16 @@ append_rule_from_element (BusConfigParser *parser,
"send_destination", &send_destination,
"send_path", &send_path,
"send_type", &send_type,
+ "send_signature", &send_signature,
+ "send_arg%d", &send_argv,
"receive_interface", &receive_interface,
"receive_member", &receive_member,
"receive_error", &receive_error,
"receive_sender", &receive_sender,
"receive_path", &receive_path,
"receive_type", &receive_type,
+ "receive_signature", &receive_signature,
+ "receive_arg%d", &receive_argv,
"eavesdrop", &eavesdrop,
"send_requested_reply", &send_requested_reply,
"receive_requested_reply", &receive_requested_reply,
@@ -1164,9 +1455,11 @@ append_rule_from_element (BusConfigParser *parser,
return FALSE;
send_attr = send_interface || send_member || send_error || send_destination ||
+ send_signature || send_argv ||
send_type || send_path || send_requested_reply;
receive_attr = receive_interface || receive_member || receive_error || receive_sender ||
+ receive_signature || receive_argv ||
receive_type || receive_path || receive_requested_reply;
if (!(send_attr || receive_attr || eavesdrop || own || user || group))
@@ -1186,6 +1479,15 @@ append_rule_from_element (BusConfigParser *parser,
return FALSE;
}
+ if ((send_argv && send_signature == NULL) ||
+ (receive_argv && receive_signature == NULL))
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "On element <%s>, if you specify arguments you must specify a signature.",
+ element_name);
+ return FALSE;
+ }
+
/* Allowed combinations of elements are:
*
* base attributes, must be all send or all receive:
@@ -1216,8 +1518,9 @@ append_rule_from_element (BusConfigParser *parser,
element_name);
return FALSE;
}
-
+
rule = NULL;
+ args = NULL;
/* In BusPolicyRule, NULL represents wildcard.
* In the config file, '*' represents it.
@@ -1270,14 +1573,35 @@ append_rule_from_element (BusConfigParser *parser,
{
dbus_set_error (error, DBUS_ERROR_FAILED,
"Bad value \"%s\" for %s attribute, must be true or false",
- "send_requested_reply", send_requested_reply);
+ send_requested_reply, "send_requested_reply");
return FALSE;
}
-
- rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow);
+
+ if (send_signature && !dbus_signature_validate (send_signature, NULL))
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Bad value \"%s\" for %s attribute",
+ send_signature, "send_signature");
+ return FALSE;
+ }
+
+ rule = bus_policy_rule_new (BUS_POLICY_RULE_SEND, allow);
if (rule == NULL)
goto nomem;
-
+
+ if (send_argv)
+ {
+ args = parse_arg_attributes (parser, element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ send_signature,
+ "send_arg%d");
+ if (args == NULL)
+ goto failed;
+ rule->d.send.args = args;
+ }
+
if (eavesdrop)
rule->d.send.eavesdrop = (strcmp (eavesdrop, "true") == 0);
@@ -1291,6 +1615,7 @@ append_rule_from_element (BusConfigParser *parser,
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.signature = _dbus_strdup (send_signature);
rule->d.send.error = _dbus_strdup (send_error);
rule->d.send.destination = _dbus_strdup (send_destination);
if (send_path && rule->d.send.path == NULL)
@@ -1299,6 +1624,8 @@ append_rule_from_element (BusConfigParser *parser,
goto nomem;
if (send_member && rule->d.send.member == NULL)
goto nomem;
+ if (send_signature && rule->d.send.signature == NULL)
+ goto nomem;
if (send_error && rule->d.send.error == NULL)
goto nomem;
if (send_destination && rule->d.send.destination == NULL)
@@ -1354,11 +1681,32 @@ append_rule_from_element (BusConfigParser *parser,
"receive_requested_reply", receive_requested_reply);
return FALSE;
}
-
+
+ if (receive_signature && !dbus_signature_validate (receive_signature, NULL))
+ {
+ dbus_set_error (error, DBUS_ERROR_FAILED,
+ "Bad value \"%s\" for %s attribute",
+ receive_signature, "receive_signature");
+ return FALSE;
+ }
+
rule = bus_policy_rule_new (BUS_POLICY_RULE_RECEIVE, allow);
if (rule == NULL)
goto nomem;
+ if (receive_argv)
+ {
+ args = parse_arg_attributes (parser, element_name,
+ attribute_names,
+ attribute_values,
+ error,
+ receive_signature,
+ "receive_arg%d");
+ if (args == NULL)
+ goto failed;
+ rule->d.receive.args = args;
+ }
+
if (eavesdrop)
rule->d.receive.eavesdrop = (strcmp (eavesdrop, "true") == 0);
@@ -1369,6 +1717,7 @@ append_rule_from_element (BusConfigParser *parser,
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.signature = _dbus_strdup (receive_signature);
rule->d.receive.error = _dbus_strdup (receive_error);
rule->d.receive.origin = _dbus_strdup (receive_sender);
@@ -1378,6 +1727,8 @@ append_rule_from_element (BusConfigParser *parser,
goto nomem;
if (receive_member && rule->d.receive.member == NULL)
goto nomem;
+ if (receive_signature && rule->d.receive.signature == NULL)
+ goto nomem;
if (receive_error && rule->d.receive.error == NULL)
goto nomem;
if (receive_sender && rule->d.receive.origin == NULL)
@@ -1531,6 +1882,7 @@ append_rule_from_element (BusConfigParser *parser,
failed:
if (rule)
bus_policy_rule_unref (rule);
+
return FALSE;
}
diff --git a/bus/policy.c b/bus/policy.c
index a1fff86..43ebdc5 100644
--- a/bus/policy.c
+++ b/bus/policy.c
@@ -101,6 +101,8 @@ bus_policy_rule_unref (BusPolicyRule *rule)
dbus_free (rule->d.send.member);
dbus_free (rule->d.send.error);
dbus_free (rule->d.send.destination);
+ dbus_free (rule->d.send.signature);
+ bus_policy_args_free (rule->d.send.args);
break;
case BUS_POLICY_RULE_RECEIVE:
dbus_free (rule->d.receive.path);
@@ -108,6 +110,8 @@ bus_policy_rule_unref (BusPolicyRule *rule)
dbus_free (rule->d.receive.member);
dbus_free (rule->d.receive.error);
dbus_free (rule->d.receive.origin);
+ dbus_free (rule->d.receive.signature);
+ bus_policy_args_free (rule->d.receive.args);
break;
case BUS_POLICY_RULE_OWN:
dbus_free (rule->d.own.service_name);
@@ -117,11 +121,39 @@ bus_policy_rule_unref (BusPolicyRule *rule)
case BUS_POLICY_RULE_GROUP:
break;
}
-
+
dbus_free (rule);
}
}
+BusPolicyArgs *
+bus_policy_args_alloc (int n)
+{
+ BusPolicyArgs *args = dbus_new0 (BusPolicyArgs, 1);
+
+ if (args)
+ args->n = n;
+
+ return args;
+}
+
+void
+bus_policy_args_free (BusPolicyArgs *args)
+{
+ if (args)
+ {
+ int i;
+
+ for (i = 0; i < args->n; i++)
+ {
+ if (args->args[i].value)
+ dbus_free (args->args[i].value);
+ }
+
+ dbus_free (args);
+ }
+}
+
struct BusPolicy
{
int refcount;
@@ -862,6 +894,65 @@ bus_client_policy_append_rule (BusClientPolicy *policy,
return TRUE;
}
+static dbus_bool_t
+check_policy_message_args (DBusMessage *message,
+ BusPolicyArgs *args)
+{
+ int i, type;
+ DBusMessageIter iter, subiter;
+ union {
+ void *pointer;
+ dbus_uint64_t data;
+ double d;
+ } basic;
+ void *value;
+
+ dbus_message_iter_init (message, &iter);
+
+ for (i = 0; i < args->n; dbus_message_iter_next (&iter), i++)
+ {
+ if (args->args[i].type == DBUS_TYPE_INVALID)
+ continue;
+
+ type = dbus_message_iter_get_arg_type (&iter);
+
+ if (args->args[i].type != type)
+ {
+ _dbus_verbose (" (policy) skipping rule for inconsistent signature\n");
+ return FALSE;
+ };
+
+ if (type == DBUS_TYPE_ARRAY)
+ {
+ dbus_message_iter_recurse (&iter, &subiter);
+ type = dbus_message_iter_get_arg_type (&subiter);
+ if (type != DBUS_TYPE_INVALID)
+ {
+ _dbus_verbose (" (policy) skipping rule because array is not empty\n");
+ return FALSE;
+ };
+ continue;
+ }
+
+ dbus_message_iter_get_basic (&iter, &basic);
+
+ if (type == DBUS_TYPE_OBJECT_PATH
+ || type == DBUS_TYPE_STRING
+ || type == DBUS_TYPE_SIGNATURE)
+ value = basic.pointer;
+ else
+ value = &basic.data;
+
+ if (memcmp (value, args->args[i].value, args->args[i].length))
+ {
+ _dbus_verbose (" (policy) skipping rule because value does not match\n");
+ return FALSE;
+ }
+ }
+
+ return TRUE;
+}
+
dbus_bool_t
bus_client_policy_check_can_send (BusClientPolicy *policy,
BusRegistry *registry,
@@ -976,6 +1067,22 @@ bus_client_policy_check_can_send (BusClientPolicy *policy,
}
}
+ if (rule->d.send.signature != NULL)
+ {
+ if (!dbus_message_has_signature (message,
+ rule->d.send.signature))
+ {
+ _dbus_verbose (" (policy) skipping rule for different signature\n");
+ continue;
+ }
+ }
+
+ if (rule->d.send.args != NULL)
+ {
+ if (!check_policy_message_args (message, rule->d.send.args))
+ continue;
+ }
+
if (rule->d.send.error != NULL)
{
if (dbus_message_get_error_name (message) != NULL &&
@@ -1176,6 +1283,22 @@ bus_client_policy_check_can_receive (BusClientPolicy *policy,
}
}
+ if (rule->d.receive.signature != NULL)
+ {
+ if (!dbus_message_has_signature (message,
+ rule->d.receive.signature))
+ {
+ _dbus_verbose (" (policy) skipping rule for different signature\n");
+ continue;
+ }
+ }
+
+ if (rule->d.receive.args != NULL)
+ {
+ if (!check_policy_message_args (message, rule->d.receive.args))
+ continue;
+ }
+
if (rule->d.receive.error != NULL)
{
if (dbus_message_get_error_name (message) != NULL &&
diff --git a/bus/policy.h b/bus/policy.h
index 1782dbf..487e429 100644
--- a/bus/policy.h
+++ b/bus/policy.h
@@ -61,8 +61,10 @@ struct BusPolicyRule
char *path;
char *interface;
char *member;
+ char *signature;
char *error;
char *destination;
+ BusPolicyArgs *args;
unsigned int eavesdrop : 1;
unsigned int requested_reply : 1;
unsigned int log : 1;
@@ -76,8 +78,10 @@ struct BusPolicyRule
char *path;
char *interface;
char *member;
+ char *signature;
char *error;
char *origin;
+ BusPolicyArgs *args;
unsigned int eavesdrop : 1;
unsigned int requested_reply : 1;
} receive;
@@ -103,11 +107,27 @@ struct BusPolicyRule
} d;
};
+#define BUS_POLICY_MAX_ARGS (30)
+
+struct BusPolicyArgs
+{
+ int n;
+ struct
+ {
+ int type;
+ size_t length;
+ void *value;
+ } args[BUS_POLICY_MAX_ARGS];
+};
+
BusPolicyRule* bus_policy_rule_new (BusPolicyRuleType type,
dbus_bool_t allow);
BusPolicyRule* bus_policy_rule_ref (BusPolicyRule *rule);
void bus_policy_rule_unref (BusPolicyRule *rule);
+BusPolicyArgs* bus_policy_args_alloc (int n);
+void bus_policy_args_free (BusPolicyArgs *args);
+
BusPolicy* bus_policy_new (void);
BusPolicy* bus_policy_ref (BusPolicy *policy);
void bus_policy_unref (BusPolicy *policy);
--
1.6.3.3
More information about the dbus
mailing list