summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Zeuthen <davidz@redhat.com>2007-03-25 15:37:29 -0400
committerDavid Zeuthen <davidz@redhat.com>2007-03-25 15:37:29 -0400
commitf7cb7e7828ae6d54f06dad49b63b0f8c0a553a41 (patch)
treed569dbd93ffb4ec9da5dbcc5a30682196a4e811b
parent77770b83f17122ba6ddb6b4cd484291a90d647d1 (diff)
refactor access control checks into separate files
-rw-r--r--hald/Makefile.am3
-rw-r--r--hald/access-check.c171
-rw-r--r--hald/access-check.h40
-rw-r--r--hald/hald_dbus.c330
4 files changed, 325 insertions, 219 deletions
diff --git a/hald/Makefile.am b/hald/Makefile.am
index f6e7751c..1ca01aca 100644
--- a/hald/Makefile.am
+++ b/hald/Makefile.am
@@ -61,7 +61,8 @@ hald_SOURCES = \
ids.h ids.c \
rule.h mmap_cache.c \
mmap_cache.h \
- ci-tracker.h ci-tracker.c
+ ci-tracker.h ci-tracker.c \
+ access-check.h access-check.c
if HAVE_CONKIT
hald_SOURCES += ck-tracker.h ck-tracker.c
diff --git a/hald/access-check.c b/hald/access-check.c
new file mode 100644
index 00000000..b001eeaa
--- /dev/null
+++ b/hald/access-check.c
@@ -0,0 +1,171 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * access-check.c : Checks whether a D-Bus caller have access
+ *
+ * Copyright (C) 2007 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <sys/time.h>
+
+#include <dbus/dbus.h>
+#include <glib.h>
+
+#include "logger.h"
+#include "access-check.h"
+
+/**
+ * access_check_caller_is_root_or_hal:
+ * @cit: the CITracker object
+ * @caller_unique_sysbus_name: The unique system bus connection name (e.g. ":1.43") of the caller
+ *
+ * Check if the caller has uid 0 (root) or the uid of the hal user.
+ *
+ * Returns: TRUE iff the caller has uid 0 (root) or the uid of the hal user.
+ */
+gboolean
+access_check_caller_is_root_or_hal (CITracker *cit, const char *caller_unique_sysbus_name)
+{
+ gboolean ret;
+ CICallerInfo *ci;
+
+ ret = FALSE;
+
+ ci = ci_tracker_get_info (cit, caller_unique_sysbus_name);
+ if (ci == NULL) {
+ goto out;
+ }
+
+ HAL_INFO (("uid for caller is %ld", ci_tracker_caller_get_uid (ci)));
+
+ if (ci_tracker_caller_get_uid (ci) != 0 && ci_tracker_caller_get_uid (ci) != geteuid ()) {
+ HAL_WARNING (("uid %d is not privileged", ci_tracker_caller_get_uid (ci)));
+ goto out;
+ }
+
+ ret = TRUE;
+
+out:
+ return ret;
+}
+
+/**
+ * access_check_message_caller_is_root_or_hal:
+ * @cit: the CITracker object
+ * @message: the message from the caller
+ *
+ * Check if the sender of the message has uid 0 (root) or the uid of the hal user.
+ *
+ * Returns: TRUE iff the sender of the message has uid 0 (root) or the uid of the hal user.
+ */
+gboolean
+access_check_message_caller_is_root_or_hal (CITracker *cit, DBusMessage *message)
+{
+ gboolean ret;
+ const char *user_base_svc;
+
+ ret = FALSE;
+
+ user_base_svc = dbus_message_get_sender (message);
+ if (user_base_svc == NULL) {
+ HAL_WARNING (("Cannot determine base service of caller"));
+ goto out;
+ }
+
+ ret = access_check_caller_is_root_or_hal (cit, user_base_svc);
+
+out:
+ return ret;
+}
+
+/**
+ * access_check_caller_have_access_to_device:
+ * @device: The device to check for
+ * @caller_unique_sysbus_name: The unique system bus connection name (e.g. ":1.43") of the caller
+ *
+ * Determine if a given caller should have access to a device. This
+ * depends on how the security is set up and may change according to
+ * how the system is configured.
+ *
+ * If ConsoleKit is used this function currently will return TRUE if,
+ * and only if, the caller is in an active session. TODO: once
+ * multi-seat is properly supported it will also depend on what seat
+ * the device belongs to and what seat the caller's session belongs
+ * to.
+ *
+ * If ConsoleKit is not used, this function will just return TRUE; the
+ * OS vendor is supposed to have locked down access to HAL through OS
+ * specific mechanisms and/or D-Bus security configuration directives.
+ *
+ * By convention uid 0 and the hal user will have access to all
+ * devices.
+ *
+ * Returns: TRUE iff the caller have access to the device.
+ */
+gboolean
+access_check_caller_have_access_to_device (CITracker *cit, HalDevice *device, const char *caller_unique_sysbus_name)
+#ifdef HAVE_CONKIT
+{
+ gboolean ret;
+ CICallerInfo *ci;
+
+ ret = FALSE;
+
+ ci = ci_tracker_get_info (cit, caller_unique_sysbus_name);
+ if (ci == NULL) {
+ HAL_ERROR (("Cannot get caller info for %s", caller_unique_sysbus_name));
+ goto out;
+ }
+
+ if (ci_tracker_caller_get_uid (ci) == 0 ||
+ ci_tracker_caller_get_uid (ci) == geteuid ()) {
+ ret = TRUE;
+ goto out;
+ }
+
+ if (ci_tracker_caller_get_ck_session_path (ci) == NULL) {
+ goto out;
+ }
+
+
+ if (!ci_tracker_caller_in_active_session (ci)) {
+ goto out;
+ }
+
+ ret = TRUE;
+out:
+ return ret;
+
+}
+#else /* HAVE_CONKIT */
+{
+ return TRUE;
+}
+#endif
diff --git a/hald/access-check.h b/hald/access-check.h
new file mode 100644
index 00000000..8514824a
--- /dev/null
+++ b/hald/access-check.h
@@ -0,0 +1,40 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * access-check.h : Checks whether a D-Bus caller have access
+ *
+ * Copyright (C) 2007 David Zeuthen, <david@fubar.dk>
+ *
+ * Licensed under the Academic Free License version 2.1
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA
+ *
+ **************************************************************************/
+
+#ifndef ACCESS_CHECK_H
+#define ACCESS_CHECK_H
+
+#include "device.h"
+#include "ci-tracker.h"
+
+gboolean access_check_caller_is_root_or_hal (CITracker *cit,
+ const char *caller_unique_sysbus_name);
+gboolean access_check_message_caller_is_root_or_hal (CITracker *cit,
+ DBusMessage *message);
+gboolean access_check_caller_have_access_to_device (CITracker *cit,
+ HalDevice *device,
+ const char *caller_unique_sysbus_name);
+
+#endif /* ACCESS_CHECK_H */
diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index 6c97862c..798e093e 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -47,8 +47,8 @@
#include "osspec.h"
#include "util.h"
#include "hald_runner.h"
-
#include "ci-tracker.h"
+#include "access-check.h"
#ifdef HAVE_CONKIT
#include "ck-tracker.h"
@@ -933,43 +933,7 @@ device_get_all_properties (DBusConnection * connection,
return DBUS_HANDLER_RESULT_HANDLED;
}
-static dbus_bool_t
-sender_has_privileges (DBusConnection *connection, DBusMessage *message)
-{
- const char *user_base_svc;
- dbus_bool_t ret;
- CICallerInfo *ci;
-
- ret = FALSE;
-
- user_base_svc = dbus_message_get_sender (message);
- if (user_base_svc == NULL) {
- HAL_WARNING (("Cannot determine base service of caller"));
- goto out;
- }
-
- HAL_DEBUG (("base_svc = %s", user_base_svc));
-
- ci = ci_tracker_get_info (ci_tracker, user_base_svc);
- if (ci == NULL) {
- goto out;
- }
-
- HAL_INFO (("uid for caller is %ld", ci_tracker_caller_get_uid (ci)));
-
- if (ci_tracker_caller_get_uid (ci) != 0 && ci_tracker_caller_get_uid (ci) != geteuid()) {
- HAL_WARNING (("uid %d is not privileged", ci_tracker_caller_get_uid (ci)));
- goto out;
- }
-
- ret = TRUE;
-
-out:
- return ret;
-}
-
-
-/** *
+/**
* device_set_multiple_properties:
* @connection: D-BUS connection
* @message: Message
@@ -1007,7 +971,7 @@ device_set_multiple_properties (DBusConnection *connection, DBusMessage *message
return DBUS_HANDLER_RESULT_HANDLED;
}
- if (!local_interface && !sender_has_privileges (connection, message)) {
+ if (!local_interface && !access_check_message_caller_is_root_or_hal (ci_tracker, message)) {
raise_permission_denied (connection, message, "SetProperty: not privileged");
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -1377,7 +1341,7 @@ device_set_property (DBusConnection * connection, DBusMessage * message, dbus_bo
}
dbus_message_iter_get_basic (&iter, &key);
- if (!local_interface && !sender_has_privileges (connection, message)) {
+ if (!local_interface && !access_check_message_caller_is_root_or_hal (ci_tracker, message)) {
raise_permission_denied (connection, message, "SetProperty: not privileged");
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -1497,7 +1461,7 @@ device_add_capability (DBusConnection * connection, DBusMessage * message, dbus_
HAL_TRACE (("entering"));
- if (!local_interface && !sender_has_privileges (connection, message)) {
+ if (!local_interface && !access_check_message_caller_is_root_or_hal (ci_tracker, message)) {
raise_permission_denied (connection, message, "AddCapability: not privileged");
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -1673,7 +1637,7 @@ device_remove_property (DBusConnection * connection, DBusMessage * message, dbus
udi = dbus_message_get_path (message);
- if (!local_interface && !sender_has_privileges (connection, message)) {
+ if (!local_interface && !access_check_message_caller_is_root_or_hal (ci_tracker, message)) {
raise_permission_denied (connection, message, "RemoveProperty: not privileged");
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -2457,7 +2421,7 @@ device_rescan (DBusConnection * connection, DBusMessage * message, dbus_bool_t l
udi = dbus_message_get_path (message);
- if (!local_interface && !sender_has_privileges (connection, message)) {
+ if (!local_interface && !access_check_message_caller_is_root_or_hal (ci_tracker, message)) {
raise_permission_denied (connection, message, "Rescan: not privileged");
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -2501,7 +2465,7 @@ device_reprobe (DBusConnection * connection, DBusMessage * message, dbus_bool_t
udi = dbus_message_get_path (message);
- if (!local_interface && !sender_has_privileges (connection, message)) {
+ if (!local_interface && !access_check_message_caller_is_root_or_hal (ci_tracker, message)) {
raise_permission_denied (connection, message, "Reprobe: not privileged");
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -2752,7 +2716,7 @@ manager_new_device (DBusConnection * connection, DBusMessage * message, dbus_boo
dbus_error_init (&error);
- if (!local_interface && !sender_has_privileges (connection, message)) {
+ if (!local_interface && !access_check_message_caller_is_root_or_hal (ci_tracker, message)) {
raise_permission_denied (connection, message, "NewDevice: not privileged");
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -2821,7 +2785,7 @@ manager_remove (DBusConnection * connection, DBusMessage * message, dbus_bool_t
dbus_error_init (&error);
- if (!local_interface && !sender_has_privileges (connection, message)) {
+ if (!local_interface && !access_check_message_caller_is_root_or_hal (ci_tracker, message)) {
raise_permission_denied (connection, message, "Remove: not privileged");
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -2922,7 +2886,7 @@ manager_commit_to_gdl (DBusConnection * connection, DBusMessage * message, dbus_
dbus_error_init (&error);
- if (!local_interface && !sender_has_privileges (connection, message)) {
+ if (!local_interface && !access_check_message_caller_is_root_or_hal (ci_tracker, message)) {
raise_permission_denied (connection, message, "CommitToGdl: not privileged");
return DBUS_HANDLER_RESULT_HANDLED;
}
@@ -3266,42 +3230,6 @@ hald_exec_method (HalDevice *d, CICallerInfo *ci, DBusConnection *connection, db
extra_env[0] = "HAL_METHOD_INVOKED_BY_UID=0";
extra_env[1] = "HAL_METHOD_INVOKED_BY_SYSTEMBUS_CONNECTION_NAME=0";
} else {
-
-#ifdef HAVE_CONKIT
- /* TODO: we probably should let the handler itself decide if it wants
- * to service the session... by e.g. exporting some env variables
- * set from the CICallerInfo object
- */
- if (ci_tracker_caller_get_uid (ci) != 0) {
- if (ci_tracker_caller_get_ck_session_path (ci) == NULL) {
- HAL_INFO (("Caller %s (uid %d, pid %d) for interface %s on exec'ed method %s for %s "
- "is not in any session; refusing service",
- dbus_message_get_sender (message),
- ci_tracker_caller_get_uid (ci),
- ci_tracker_caller_get_pid (ci),
- dbus_message_get_interface (message),
- dbus_message_get_member (message),
- dbus_message_get_path (message)));
- raise_permission_denied (connection, message, "Not in active session");
- goto out;
- }
-
- if (!ci_tracker_caller_in_active_session (ci)) {
- HAL_INFO (("Caller %s (uid %d, pid %d) for interface %s on exec'ed method %s for %s "
- "is not in an active session (%s); refusing service",
- dbus_message_get_sender (message),
- ci_tracker_caller_get_uid (ci),
- ci_tracker_caller_get_pid (ci),
- dbus_message_get_interface (message),
- dbus_message_get_member (message),
- dbus_message_get_path (message),
- ci_tracker_caller_get_ck_session_path (ci)));
- raise_permission_denied (connection, message, "Not in active session");
- goto out;
- }
- }
-#endif /* HAVE_CONKIT */
-
sprintf (uid_export, "HAL_METHOD_INVOKED_BY_UID=%u", ci_tracker_caller_get_uid (ci));
extra_env[0] = uid_export;
snprintf (sender_export, sizeof (sender_export),
@@ -3431,9 +3359,6 @@ hald_exec_method (HalDevice *d, CICallerInfo *ci, DBusConnection *connection, db
dbus_message_ref (message);
g_string_free (stdin_str, TRUE);
-#ifdef HAVE_CONKIT
-out:
-#endif
return DBUS_HANDLER_RESULT_HANDLED;
error:
@@ -4033,8 +3958,10 @@ hald_dbus_filter_handle_methods (DBusConnection *connection, DBusMessage *messag
const char *method;
const char *signature;
const char *caller;
- CICallerInfo *ci;
HalDevice *d;
+ GSList *i;
+ HalDeviceStrListIter if_iter;
+ CICallerInfo *ci;
/* check for device-specific interfaces that individual objects may support */
@@ -4043,6 +3970,9 @@ hald_dbus_filter_handle_methods (DBusConnection *connection, DBusMessage *messag
method = dbus_message_get_member (message);
signature = dbus_message_get_signature (message);
+ if (udi == NULL || method == NULL || signature == NULL || interface == NULL)
+ goto out;
+
caller = dbus_message_get_sender (message);
if (local_interface) {
ci = NULL;
@@ -4050,141 +3980,105 @@ hald_dbus_filter_handle_methods (DBusConnection *connection, DBusMessage *messag
ci = ci_tracker_get_info (ci_tracker, caller);
if (ci == NULL) {
HAL_ERROR (("Cannot get caller info for %s", caller));
- goto no_caller;
+ goto out;
}
}
d = NULL;
-
- if (udi != NULL) {
- d = hal_device_store_find (hald_get_gdl (), udi);
- if (d == NULL)
- d = hal_device_store_find (hald_get_tdl (), udi);
- }
-
- if (d != NULL && interface != NULL) {
- GSList *i;
-
- for (i = helper_interface_handlers; i != NULL; i = g_slist_next (i)) {
- HelperInterfaceHandler *hih = i->data;
- if (strcmp (hih->udi, udi) == 0 &&
- strcmp (hih->interface_name, interface) == 0) {
- DBusPendingCall *pending_call;
- DBusMessage *copy;
-
-#ifdef HAVE_CONKIT
- /* TODO: we probably should let the add-on itself decide if it wants
- * to service the session...
- */
- if (!local_interface && ci_tracker_caller_get_uid (ci) != 0) {
- if (ci_tracker_caller_get_ck_session_path (ci) == NULL) {
- HAL_INFO (("Caller %s (uid %d, pid %d) for interface %s on "
- "add-on method %s for %s is not in any session; "
- "refusing service",
- caller,
- ci_tracker_caller_get_uid (ci),
- ci_tracker_caller_get_pid (ci),
- interface,
- method,
- udi,
- ci_tracker_caller_get_ck_session_path (ci)));
- raise_permission_denied (connection, message, "Not in active session");
- return DBUS_HANDLER_RESULT_HANDLED;
- }
-
- if (!ci_tracker_caller_in_active_session (ci)) {
- HAL_INFO (("Caller %s (uid %d, pid %d) for interface %s on "
- "add-on method %s for %s is not in an active "
- "session (%s); refusing service",
- caller,
- ci_tracker_caller_get_uid (ci),
- ci_tracker_caller_get_pid (ci),
- interface,
- method,
- udi,
- ci_tracker_caller_get_ck_session_path (ci)));
- raise_permission_denied (connection, message, "Not in active session");
- return DBUS_HANDLER_RESULT_HANDLED;
- }
- }
-#endif /* HAVE_CONKIT */
-
- /*HAL_INFO (("forwarding method to connection 0x%x", hih->connection));*/
-
- dbus_message_ref (message);
-
- /* send a copy of the message */
- copy = dbus_message_copy (message);
- if (!dbus_connection_send_with_reply (hih->connection,
- copy,
- &pending_call,
- /*-1*/ 8000)) {
- /* TODO: handle error */
- } else {
- /*HAL_INFO (("connection=%x message=%x", connection, message));*/
- dbus_pending_call_set_notify (pending_call,
- reply_from_fwd_message,
- (void *) message,
- NULL);
- }
-
- dbus_message_unref (copy);
-
- return DBUS_HANDLER_RESULT_HANDLED;
- }
- }
- }
-
- if (d != NULL && interface != NULL && method != NULL && signature != NULL) {
- HalDeviceStrListIter if_iter;
-
- for (hal_device_property_strlist_iter_init (d, "info.interfaces", &if_iter);
- hal_device_property_strlist_iter_is_valid (&if_iter);
- hal_device_property_strlist_iter_next (&if_iter)) {
- const char *ifname = hal_device_property_strlist_iter_get_value (&if_iter);
-
- if (strcmp (ifname, interface) == 0) {
- guint num;
- HalDeviceStrListIter name_iter;
- char *s;
-
- s = g_strdup_printf ("%s.method_names", interface);
- hal_device_property_strlist_iter_init (d, s, &name_iter);
- g_free (s);
- for (num = 0;
- hal_device_property_strlist_iter_is_valid (&name_iter);
- hal_device_property_strlist_iter_next (&name_iter), num++) {
- const char *methodname;
- methodname = hal_device_property_strlist_iter_get_value (&name_iter);
- if (strcmp (methodname, method) == 0) {
- const char *execpath;
- const char *sig;
-
- s = g_strdup_printf ("%s.method_execpaths", interface);
- execpath = hal_device_property_get_strlist_elem (d, s, num);
- g_free (s);
- s = g_strdup_printf ("%s.method_signatures", interface);
- sig = hal_device_property_get_strlist_elem (d, s, num);
- g_free (s);
-
- if (execpath != NULL && sig != NULL &&
- strcmp (sig, signature) == 0) {
-
- HAL_INFO (("OK for method '%s' with signature '%s' on interface '%s' for UDI '%s' and execpath '%s'", method, signature, interface, udi, execpath));
-
- return hald_exec_method (d, ci, connection,
- local_interface,
- message, execpath);
- }
-
- }
- }
- }
- }
-
- }
- }
-no_caller:
+ d = hal_device_store_find (hald_get_gdl (), udi);
+ if (d == NULL)
+ d = hal_device_store_find (hald_get_tdl (), udi);
+ if (d == NULL)
+ goto out;
+
+ /* bypass security checks on direct connections */
+ if (!local_interface) {
+ if (!access_check_caller_have_access_to_device (ci_tracker, d, caller)) {
+ HAL_INFO (("Caller '%s' does not have access to device '%s'", caller, udi));
+ /* TODO: need to fix up reason */
+ raise_permission_denied (connection, message, "Not in active session");
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ }
+
+ /* first see if an addon grabbed the interface */
+ for (i = helper_interface_handlers; i != NULL; i = g_slist_next (i)) {
+ HelperInterfaceHandler *hih = i->data;
+ if (strcmp (hih->udi, udi) == 0 &&
+ strcmp (hih->interface_name, interface) == 0) {
+ DBusPendingCall *pending_call;
+ DBusMessage *copy;
+
+ /*HAL_INFO (("forwarding method to connection 0x%x", hih->connection));*/
+
+ dbus_message_ref (message);
+
+ /* send a copy of the message */
+ copy = dbus_message_copy (message);
+ if (!dbus_connection_send_with_reply (hih->connection,
+ copy,
+ &pending_call,
+ /*-1*/ 8000)) {
+ /* TODO: handle error */
+ } else {
+ /*HAL_INFO (("connection=%x message=%x", connection, message));*/
+ dbus_pending_call_set_notify (pending_call,
+ reply_from_fwd_message,
+ (void *) message,
+ NULL);
+ }
+
+ dbus_message_unref (copy);
+ return DBUS_HANDLER_RESULT_HANDLED;
+ }
+ }
+
+ /* nope, see if we have a program to run.. */
+ for (hal_device_property_strlist_iter_init (d, "info.interfaces", &if_iter);
+ hal_device_property_strlist_iter_is_valid (&if_iter);
+ hal_device_property_strlist_iter_next (&if_iter)) {
+ const char *ifname = hal_device_property_strlist_iter_get_value (&if_iter);
+
+ if (strcmp (ifname, interface) == 0) {
+ guint num;
+ HalDeviceStrListIter name_iter;
+ char *s;
+
+ s = g_strdup_printf ("%s.method_names", interface);
+ hal_device_property_strlist_iter_init (d, s, &name_iter);
+ g_free (s);
+ for (num = 0;
+ hal_device_property_strlist_iter_is_valid (&name_iter);
+ hal_device_property_strlist_iter_next (&name_iter), num++) {
+ const char *methodname;
+ methodname = hal_device_property_strlist_iter_get_value (&name_iter);
+ if (strcmp (methodname, method) == 0) {
+ const char *execpath;
+ const char *sig;
+
+ s = g_strdup_printf ("%s.method_execpaths", interface);
+ execpath = hal_device_property_get_strlist_elem (d, s, num);
+ g_free (s);
+ s = g_strdup_printf ("%s.method_signatures", interface);
+ sig = hal_device_property_get_strlist_elem (d, s, num);
+ g_free (s);
+
+ if (execpath != NULL && sig != NULL &&
+ strcmp (sig, signature) == 0) {
+
+ HAL_INFO (("OK for method '%s' with signature '%s' on interface '%s' for UDI '%s' and execpath '%s'", method, signature, interface, udi, execpath));
+
+ return hald_exec_method (d, ci, connection,
+ local_interface,
+ message, execpath);
+ }
+
+ }
+ }
+ }
+ }
+ }
+out:
return osspec_filter_function (connection, message, user_data);
}