hal: Branch 'master' - 2 commits
David Zeuthen
david at kemper.freedesktop.org
Thu Feb 15 11:18:12 PST 2007
configure.in | 11
fdi/policy/10osvendor/20-acl-management.fdi | 34 +
fdi/policy/10osvendor/Makefile.am | 4
hald/Makefile.am | 3
hald/ck-tracker.c | 637 ++++++++++++++++++++++++++++
hald/ck-tracker.h | 86 +++
hald/hald.c | 4
hald/hald_dbus.c | 110 ++++
hald/hald_dbus.h | 2
hald/util.c | 6
tools/Makefile.am | 9
tools/hal-acl-add.c | 91 ++++
tools/hal-acl-remove.c | 15
13 files changed, 991 insertions(+), 21 deletions(-)
New commits:
diff-tree 24b151cd176dc8b2e53209be24bb64c647e65179 (from parents)
Merge: 7368286927bad8b996a53c3b4985df17c2068bcb 64fc3f3974074ca3424ede4ca82d993d4bb8ad46
Author: David Zeuthen <davidz at redhat.com>
Date: Thu Feb 15 13:53:17 2007 -0500
Merge branch 'master' of ssh://david@git.freedesktop.org/git/hal
diff-tree 7368286927bad8b996a53c3b4985df17c2068bcb (from b26ba073131b944b9ad3760ecc7b60834ee585a0)
Author: David Zeuthen <davidz at redhat.com>
Date: Thu Feb 15 13:52:56 2007 -0500
make HAL track ConsoleKit seats and sessions and initial work on ACL mgmt
This is just preliminary work; no ACL's are added nor removed just yet.
diff --git a/configure.in b/configure.in
index 5411b18..73bb40b 100644
--- a/configure.in
+++ b/configure.in
@@ -392,6 +392,16 @@ if test "x$enable_console_kit" != "xno";
msg_conkit=yes
fi
+# check for ACL handling
+AM_CONDITIONAL(HAVE_ACLMGMT, false)
+AC_ARG_ENABLE(acl-management, [ --enable-acl-management ACL management],enable_acl_management=$enableval,enable_acl_management=no)
+msg_aclmgmt=no
+if test "x$enable_acl_management" != "xno"; then
+ AM_CONDITIONAL(HAVE_ACLMGMT, true)
+ AC_DEFINE(HAVE_ACLMGMT, [], [Set if we manage ACL's])
+ msg_aclmgmt=yes
+fi
+
# what extra hotplug backends to use (ACPI, APM, PMU etc)
AC_ARG_ENABLE(have_acpi, [ --disable-acpi Build without ACPI support])
msg_acpi=no
@@ -783,6 +793,7 @@ echo "
use libparted: ${USE_PARTED}
use PolicyKit: ${msg_polkit}
use ConsoleKit: ${msg_conkit}
+ use ACL management: ${msg_aclmgmt}
use ACPI: ${msg_acpi}
use PMU: ${msg_pmu}
use APM: ${msg_apm}
diff --git a/fdi/policy/10osvendor/20-acl-management.fdi b/fdi/policy/10osvendor/20-acl-management.fdi
new file mode 100644
index 0000000..23fbe08
--- /dev/null
+++ b/fdi/policy/10osvendor/20-acl-management.fdi
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+
+<deviceinfo version="0.2">
+ <device>
+
+ <!-- allow local sessions to access ALSA device files -->
+ <match key="info.capabilities" contains="alsa">
+ <merge key="acl.is_managed" type="bool">true</merge>
+ <merge key="acl.grant_local_session" type="bool">true</merge>
+ <merge key="acl.file" type="copy_property">alsa.device_file</merge>
+ </match>
+
+ <!-- allow local sessions to access OSS device files -->
+ <match key="info.capabilities" contains="oss">
+ <merge key="acl.is_managed" type="bool">true</merge>
+ <merge key="acl.grant_local_session" type="bool">true</merge>
+ <merge key="acl.file" type="copy_property">oss.device_file</merge>
+ </match>
+
+ <!-- TODO: add more rules for adding/removing ACL's (e.g. webcam, cd drive etc.) -->
+
+ <!-- remove all previously added ACL's on start-up -->
+ <match key="info.udi" string="/org/freedesktop/Hal/devices/computer">
+ <append key="info.callouts.add" type="strlist">hal-acl-remove --remove-all</append>
+ </match>
+
+ <!-- add and remove ACL's when devices are added and removed -->
+ <match key="acl.is_managed" bool="true">
+ <append key="info.callouts.add" type="strlist">hal-acl-add</append>
+ <append key="info.callouts.remove" type="strlist">hal-acl-remove</append>
+ </match>
+
+ </device>
+</deviceinfo>
diff --git a/fdi/policy/10osvendor/Makefile.am b/fdi/policy/10osvendor/Makefile.am
index 734eead..aed14e1 100644
--- a/fdi/policy/10osvendor/Makefile.am
+++ b/fdi/policy/10osvendor/Makefile.am
@@ -29,6 +29,10 @@ if BUILD_DELL
dist_fdi_DATA += 10-dell-laptop-brightness.fdi
endif
+if HAVE_ACLMGMT
+dist_fdi_DATA += 20-acl-management.fdi
+endif
+
check:
for f in $(dist_fdi_DATA); do \
echo -n "Validate XML in $$f : "; \
diff --git a/hald/Makefile.am b/hald/Makefile.am
index 589832f..3949a79 100644
--- a/hald/Makefile.am
+++ b/hald/Makefile.am
@@ -62,6 +62,9 @@ hald_SOURCES =
rule.h mmap_cache.c \
mmap_cache.h
+if HAVE_CONKIT
+hald_SOURCES += ck-tracker.h ck-tracker.c
+endif
hald_LDADD = @GLIB_LIBS@ @DBUS_LIBS@ -lm @HALD_OS_LIBS@ $(top_builddir)/hald/$(HALD_BACKEND)/libhald_$(HALD_BACKEND).la
diff --git a/hald/ck-tracker.c b/hald/ck-tracker.c
new file mode 100644
index 0000000..fb8417f
--- /dev/null
+++ b/hald/ck-tracker.c
@@ -0,0 +1,637 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * ck-tracker.c : Track seats and sessions via ConsoleKit
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at 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 "ck-tracker.h"
+
+struct CKSeat_s {
+ int refcount;
+ char *seat_objpath; /* obj path of ConsoleKit seat */
+ gboolean is_local; /* whether the seat is local */
+ GSList *sessions; /* list of sessions on this seat */
+};
+
+struct CKSession_s {
+ int refcount;
+ char *session_objpath; /* obj path of ConsoleKit session */
+ CKSeat *seat; /* seat that session belongs to */
+ gboolean is_active; /* whether the session is active */
+ uid_t user; /* user id of the user the session belongs to */
+};
+
+struct CKTracker_s {
+ int refcount;
+ DBusConnection *dbus_connection;
+ void *user_data;
+ CKSessionAddedCB session_added_cb;
+ CKSessionRemovedCB session_removed_cb;
+ CKSessionActiveChangedCB session_active_changed_cb;
+ GSList *seats;
+ GSList *sessions;
+};
+
+static CKSession *
+ck_session_new (const char *session_objpath)
+{
+ CKSession *session;
+ session = g_new0 (CKSession, 1);
+ session->refcount = 1;
+ session->session_objpath = g_strdup (session_objpath);
+ session->seat = NULL;
+ return session;
+}
+
+static void
+ck_session_unref (CKSession *session)
+{
+ session->refcount--;
+ if (session->refcount == 0) {
+ g_free (session->session_objpath);
+ g_free (session);
+ }
+}
+
+static void
+ck_session_ref (CKSession *session)
+{
+ session->refcount++;
+}
+
+static CKSeat *
+ck_seat_new (const char *seat_objpath)
+{
+ CKSeat *seat;
+ seat = g_new0 (CKSeat, 1);
+ seat->refcount = 1;
+ seat->seat_objpath = g_strdup (seat_objpath);
+ seat->sessions = NULL;
+ return seat;
+}
+
+static void
+ck_seat_attach_session (CKSeat *seat, CKSession *session)
+{
+ ck_session_ref (session);
+ session->seat = seat;
+ seat->sessions = g_slist_append (seat->sessions, session);
+}
+
+static void
+ck_seat_detach_session (CKSeat *seat, CKSession *session)
+{
+ seat->sessions = g_slist_remove (seat->sessions, session);
+ session->seat = NULL;
+ ck_session_unref (session);
+}
+
+static void
+ck_seat_unref (CKSeat *seat)
+{
+ seat->refcount--;
+ if (seat->refcount == 0) {
+ GSList *i;
+
+ /* effictively detach all sessions without manually removing each element */
+ for (i = seat->sessions; i != NULL; i = g_slist_next (i)) {
+ CKSession *session = (CKSession *) i->data;
+ session->seat = NULL;
+ ck_session_unref (session);
+ }
+ g_slist_free (seat->sessions);
+
+ g_free (seat->seat_objpath);
+ g_free (seat);
+ }
+}
+
+#if 0
+static void
+ck_seat_ref (CKSeat *seat)
+{
+ seat->refcount++;
+}
+#endif
+
+static gboolean
+ck_seat_get_info (CKTracker *tracker, CKSeat *seat)
+{
+ /* TODO: replace with a D-Bus call to IsLocal() when that appears on ConsoleKit */
+ seat->is_local = TRUE;
+ return TRUE;
+}
+
+static gboolean
+ck_session_get_info (CKTracker *tracker, CKSession *session)
+{
+ gboolean ret;
+ DBusError error;
+ DBusMessage *message;
+ DBusMessage *reply;
+
+ ret = FALSE;
+
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ session->session_objpath,
+ "org.freedesktop.ConsoleKit.Session",
+ "IsActive");
+ dbus_error_init (&error);
+ reply = dbus_connection_send_with_reply_and_block (tracker->dbus_connection, message, -1, &error);
+ if (reply == NULL || dbus_error_is_set (&error)) {
+ HAL_ERROR (("Error doing Session.IsActive on ConsoleKit: %s: %s", error.name, error.message));
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto error;
+ }
+ if (!dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_BOOLEAN, &(session->is_active),
+ DBUS_TYPE_INVALID)) {
+ HAL_ERROR (("Invalid IsActive reply from CK"));
+ goto error;
+ }
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ session->session_objpath,
+ "org.freedesktop.ConsoleKit.Session",
+ "GetUser");
+ dbus_error_init (&error);
+ reply = dbus_connection_send_with_reply_and_block (tracker->dbus_connection, message, -1, &error);
+ if (reply == NULL || dbus_error_is_set (&error)) {
+ HAL_ERROR (("Error doing Session.GetUser on ConsoleKit: %s: %s", error.name, error.message));
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto error;
+ }
+ if (!dbus_message_get_args (reply, NULL,
+ DBUS_TYPE_INT32, &(session->user),
+ DBUS_TYPE_INVALID)) {
+ HAL_ERROR (("Invalid GetUser reply from CK"));
+ goto error;
+ }
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ HAL_INFO (("Got active state (%s) and uid %d on session '%s'",
+ session->is_active ? "ACTIVE" : "INACTIVE",
+ session->user,
+ session->session_objpath));
+
+ ret = TRUE;
+
+error:
+ return ret;
+}
+
+static gboolean
+ck_tracker_init_get_sessions_for_seat (CKTracker *tracker, CKSeat *seat)
+{
+ gboolean ret;
+ DBusError error;
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter iter_array;
+
+ ret = FALSE;
+
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ seat->seat_objpath,
+ "org.freedesktop.ConsoleKit.Seat",
+ "GetSessions");
+ dbus_error_init (&error);
+ reply = dbus_connection_send_with_reply_and_block (tracker->dbus_connection, message, -1, &error);
+ if (reply == NULL || dbus_error_is_set (&error)) {
+ HAL_ERROR (("Error doing GetSeats on ConsoleKit: %s: %s", error.name, error.message));
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto error;
+ }
+
+ dbus_message_iter_init (reply, &iter);
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) {
+ HAL_WARNING (("Expecting an array from GetSessions on ConsoleKit."));
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ goto error;
+ }
+ dbus_message_iter_recurse (&iter, &iter_array);
+ while (dbus_message_iter_get_arg_type (&iter_array) == DBUS_TYPE_OBJECT_PATH) {
+ const char *session_objpath;
+ CKSession *session;
+
+ dbus_message_iter_get_basic (&iter_array, &session_objpath);
+ HAL_INFO (("got session '%s' for seat '%s'", session_objpath, seat->seat_objpath));
+
+ session = ck_session_new (session_objpath);
+
+ /* get information: is_active etc. */
+ if (!ck_session_get_info (tracker, session)) {
+ HAL_ERROR (("Could not get information for session '%s'", session_objpath));
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ goto error;
+ }
+
+ ck_seat_attach_session (seat, session);
+
+ tracker->sessions = g_slist_prepend (tracker->sessions, session);
+
+ dbus_message_iter_next (&iter_array);
+ }
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ HAL_INFO (("Got all sessions on seat '%s'", seat->seat_objpath));
+
+ ret = TRUE;
+
+error:
+ return ret;
+}
+
+static gboolean
+ck_tracker_init_get_seats_and_sessions (CKTracker *tracker)
+{
+ gboolean ret;
+ DBusError error;
+ DBusMessage *message;
+ DBusMessage *reply;
+ DBusMessageIter iter;
+ DBusMessageIter iter_array;
+
+ ret = FALSE;
+
+ /* first build array of existing seats and sessions */
+
+ message = dbus_message_new_method_call ("org.freedesktop.ConsoleKit",
+ "/org/freedesktop/ConsoleKit/Manager",
+ "org.freedesktop.ConsoleKit.Manager",
+ "GetSeats");
+ dbus_error_init (&error);
+ reply = dbus_connection_send_with_reply_and_block (tracker->dbus_connection, message, -1, &error);
+ if (reply == NULL || dbus_error_is_set (&error)) {
+ HAL_ERROR (("Error doing GetSeats on ConsoleKit: %s: %s", error.name, error.message));
+ dbus_message_unref (message);
+ if (reply != NULL)
+ dbus_message_unref (reply);
+ goto error;
+ }
+
+ dbus_message_iter_init (reply, &iter);
+ if (dbus_message_iter_get_arg_type (&iter) != DBUS_TYPE_ARRAY) {
+ HAL_WARNING (("Expecting an array from GetSeats on ConsoleKit."));
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ goto error;
+ }
+ dbus_message_iter_recurse (&iter, &iter_array);
+ while (dbus_message_iter_get_arg_type (&iter_array) == DBUS_TYPE_OBJECT_PATH) {
+ const char *seat_objpath;
+ CKSeat *seat;
+
+ dbus_message_iter_get_basic (&iter_array, &seat_objpath);
+ HAL_INFO (("got seat '%s'", seat_objpath));
+
+ seat = ck_seat_new (seat_objpath);
+
+ /* get information: is_local etc. */
+ if (!ck_seat_get_info (tracker, seat)) {
+ HAL_ERROR (("Could not get information for seat '%s'", seat_objpath));
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ goto error;
+ }
+
+ /* for each seat, get the sessions */
+ if (!ck_tracker_init_get_sessions_for_seat (tracker, seat)) {
+ HAL_ERROR (("Could not get sessions for seat '%s'", seat_objpath));
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+ goto error;
+ }
+
+ tracker->seats = g_slist_prepend (tracker->seats, seat);
+
+ dbus_message_iter_next (&iter_array);
+ }
+ dbus_message_unref (message);
+ dbus_message_unref (reply);
+
+ HAL_INFO (("Got seats"));
+
+ ret = TRUE;
+error:
+ return ret;
+}
+
+void
+ck_tracker_ref (CKTracker *tracker)
+{
+ tracker->refcount++;
+}
+
+void
+ck_tracker_unref (CKTracker *tracker)
+{
+ tracker->refcount--;
+
+ if (tracker->refcount == 0) {
+ GSList *i;
+
+ for (i = tracker->sessions; i != NULL; i = g_slist_next (i)) {
+ CKSession *session = (CKSession *) i->data;
+ ck_session_unref (session);
+ }
+
+ for (i = tracker->seats; i != NULL; i = g_slist_next (i)) {
+ CKSeat *seat = (CKSeat *) i->data;
+ ck_seat_unref (seat);
+ }
+
+ tracker->dbus_connection = NULL;
+ }
+}
+
+void
+ck_tracker_set_system_bus_connection (CKTracker *tracker, DBusConnection *system_bus_connection)
+{
+ tracker->dbus_connection = system_bus_connection;
+}
+
+void
+ck_tracker_set_user_data (CKTracker *tracker, void *user_data)
+{
+ tracker->user_data = user_data;
+}
+
+void
+ck_tracker_set_session_added_cb (CKTracker *tracker, CKSessionAddedCB cb)
+{
+ tracker->session_added_cb = cb;
+}
+
+void
+ck_tracker_set_session_removed_cb (CKTracker *tracker, CKSessionRemovedCB cb)
+{
+ tracker->session_removed_cb = cb;
+}
+
+void
+ck_tracker_set_session_active_changed_cb (CKTracker *tracker, CKSessionActiveChangedCB cb)
+{
+ tracker->session_active_changed_cb = cb;
+}
+
+
+void
+ck_tracker_process_system_bus_message (CKTracker *tracker, DBusMessage *message)
+{
+ const char *seat_objpath;
+ const char *session_objpath;
+ dbus_bool_t session_is_active;
+ GSList *i;
+ CKSeat *seat;
+ CKSession *session;
+
+ HAL_INFO (("In ck_tracker_process_system_bus_message objpath=%s interface=%s method=%s",
+ dbus_message_get_path (message),
+ dbus_message_get_interface (message),
+ dbus_message_get_member (message)));
+
+ /* TODO: also handle SeatRemoved and SeatAdded */
+
+ if (dbus_message_is_signal (message, "org.freedesktop.ConsoleKit.Seat", "SessionAdded")) {
+
+ seat_objpath = dbus_message_get_path (message);
+
+ if (!dbus_message_get_args (message, NULL,
+ DBUS_TYPE_STRING, &session_objpath,
+ DBUS_TYPE_INVALID)) {
+ HAL_ERROR (("Invalid SessionAdded signal from CK"));
+ goto out;
+ }
+
+ HAL_INFO (("Received SessionAdded '%s' from CK on seat '%s'", session_objpath, seat_objpath));
+
+ for (i = tracker->seats; i != NULL; i = g_slist_next (i)) {
+ seat = (CKSeat *) i->data;
+ if (strcmp (seat->seat_objpath, seat_objpath) == 0) {
+ session = ck_session_new (session_objpath);
+
+ /* get information: is_active etc. */
+ if (!ck_session_get_info (tracker, session)) {
+ HAL_ERROR (("Could not get information for session '%s'", session_objpath));
+ goto out;
+ }
+
+ ck_seat_attach_session (seat, session);
+ tracker->sessions = g_slist_prepend (tracker->sessions, session);
+
+ if (tracker->session_added_cb != NULL) {
+ tracker->session_added_cb (tracker, session, tracker->user_data);
+ }
+ break;
+ }
+ }
+ if (i == NULL) {
+ HAL_ERROR (("No seat '%s for session '%s'", seat_objpath, session_objpath));
+ }
+
+
+ } else if (dbus_message_is_signal (message, "org.freedesktop.ConsoleKit.Seat", "SessionRemoved")) {
+
+ seat_objpath = dbus_message_get_path (message);
+
+ if (!dbus_message_get_args (message, NULL,
+ DBUS_TYPE_STRING, &session_objpath,
+ DBUS_TYPE_INVALID)) {
+ HAL_ERROR (("Invalid SessionRemoved signal from CK"));
+ goto out;
+ }
+
+ HAL_INFO (("Received SessionRemoved '%s' from CK on seat '%s'", session_objpath, seat_objpath));
+
+ for (i = tracker->sessions; i != NULL; i = g_slist_next (i)) {
+ session = (CKSession *) i->data;
+ if (strcmp (session->session_objpath, session_objpath) == 0) {
+
+ if (tracker->session_removed_cb != NULL) {
+ tracker->session_removed_cb (tracker, session, tracker->user_data);
+ }
+
+ if (session->seat == NULL) {
+ HAL_ERROR (("Session '%s' to be removed is not attached to a seat",
+ session_objpath));
+ } else {
+ ck_seat_detach_session (session->seat, session);
+ }
+ tracker->sessions = g_slist_remove (tracker->sessions, session);
+ ck_session_unref (session);
+
+ break;
+ }
+ }
+ if (i == NULL) {
+ HAL_ERROR (("No such session '%s'", session_objpath));
+ }
+
+ } else if (dbus_message_is_signal (message, "org.freedesktop.ConsoleKit.Session", "ActiveChanged")) {
+
+ session_objpath = dbus_message_get_path (message);
+
+ if (!dbus_message_get_args (message, NULL,
+ DBUS_TYPE_BOOLEAN, &session_is_active,
+ DBUS_TYPE_INVALID)) {
+ HAL_ERROR (("Invalid SessionRemoved signal from CK"));
+ goto out;
+ }
+
+ HAL_INFO (("Received ActiveChanged to %s from CK on session '%s'",
+ session_is_active ? "ACTIVE" : "INACTIVE", session_objpath));
+
+
+ for (i = tracker->sessions; i != NULL; i = g_slist_next (i)) {
+ session = (CKSession *) i->data;
+ if (strcmp (session->session_objpath, session_objpath) == 0) {
+
+ session->is_active = session_is_active;
+
+ if (tracker->session_active_changed_cb != NULL) {
+ tracker->session_active_changed_cb (tracker, session, tracker->user_data);
+ }
+ break;
+ }
+ }
+ if (i == NULL) {
+ HAL_ERROR (("No such session '%s'", session_objpath));
+ }
+
+ }
+out:
+ ;
+}
+
+GSList *
+ck_tracker_get_seats (CKTracker *tracker)
+{
+ return tracker->seats;
+}
+
+GSList *
+ck_tracker_get_sessions (CKTracker *tracker)
+{
+ return tracker->sessions;
+}
+
+gboolean
+ck_seat_is_local (CKSeat *seat)
+{
+ return seat->is_local;
+}
+
+GSList *
+ck_seat_get_sessions (CKSeat *seat)
+{
+ return seat->sessions;
+}
+
+const char *
+ck_seat_get_id (CKSeat *seat)
+{
+ return seat->seat_objpath;
+}
+
+gboolean
+ck_session_is_active (CKSession *session)
+{
+ return session->is_active;
+}
+
+CKSeat *
+ck_session_get_seat (CKSession *session)
+{
+ return session->seat;
+}
+
+const char *
+ck_session_get_id (CKSession *session)
+{
+ return session->session_objpath;
+}
+
+uid_t
+ck_session_get_user (CKSession *session)
+{
+ return session->user;
+}
+
+gboolean
+ck_tracker_init (CKTracker *tracker)
+{
+ dbus_bool_t ret;
+
+ ret = FALSE;
+
+ if (!ck_tracker_init_get_seats_and_sessions (tracker)) {
+ HAL_ERROR (("Could not get seats and sessions"));
+ goto out;
+ }
+
+ HAL_INFO (("Got seats and sessions"));
+
+ ret = TRUE;
+
+out:
+ return ret;
+}
+
+CKTracker *
+ck_tracker_new (void)
+{
+ CKTracker *tracker;
+
+ tracker = g_new0 (CKTracker, 1);
+ tracker->refcount = 1;
+ return tracker;
+}
diff --git a/hald/ck-tracker.h b/hald/ck-tracker.h
new file mode 100644
index 0000000..6c3147b
--- /dev/null
+++ b/hald/ck-tracker.h
@@ -0,0 +1,86 @@
+/***************************************************************************
+ * CVSID: $Id$
+ *
+ * ck-tracker.h : Track seats and sessions via ConsoleKit
+ *
+ * Copyright (C) 2007 David Zeuthen, <david at 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 CK_TRACKER_H
+#define CK_TRACKER_H
+
+#include <unistd.h>
+#include <sys/types.h>
+#include <dbus/dbus.h>
+#include <glib.h>
+
+struct CKTracker_s;
+typedef struct CKTracker_s CKTracker;
+struct CKSeat_s;
+typedef struct CKSeat_s CKSeat;
+struct CKSession_s;
+typedef struct CKSession_s CKSession;
+
+typedef void (*CKSessionAddedCB) (CKTracker *tracker, CKSession *session, void *user_data);
+typedef void (*CKSessionRemovedCB) (CKTracker *tracker, CKSession *session, void *user_data);
+typedef void (*CKSessionActiveChangedCB) (CKTracker *tracker, CKSession *session, void *user_data);
+
+CKTracker *ck_tracker_new (void);
+void ck_tracker_set_system_bus_connection (CKTracker *tracker, DBusConnection *system_bus_connection);
+void ck_tracker_set_user_data (CKTracker *tracker, void *user_data);
+void ck_tracker_set_session_added_cb (CKTracker *tracker, CKSessionAddedCB cb);
+void ck_tracker_set_session_removed_cb (CKTracker *tracker, CKSessionRemovedCB cb);
+void ck_tracker_set_session_active_changed_cb (CKTracker *tracker, CKSessionActiveChangedCB cb);
+/* TODO: also handle seat_added, seat_removed */
+gboolean ck_tracker_init (CKTracker *tracker);
+
+/* Forward DBusMessage signals for
+ *
+ * org.freedesktop.ConsoleKit.Seat.SessionAdded
+ * org.freedesktop.ConsoleKit.Seat.SessionRemoved
+ * org.freedesktop.ConsoleKit.Session.ActiveChanged
+ *
+ * on all objects on ConsoleKit to this function.
+ *
+ * TODO: need org.freedesktop.DBus.NameOwnerChanged from D-Bus to notice CK going away
+ *
+ * TODO: provide convenience method for letting CKTracker setup matches
+ * with the bus here via dbus_connection_add_filter() and
+ * dbus_bus_add_match(). E.g. just like libhal.
+ */
+void ck_tracker_process_system_bus_message (CKTracker *tracker, DBusMessage *message);
+
+void ck_tracker_ref (CKTracker *tracker);
+void ck_tracker_unref (CKTracker *tracker);
+
+GSList *ck_tracker_get_seats (CKTracker *tracker);
+GSList *ck_tracker_get_sessions (CKTracker *tracker);
+
+gboolean ck_seat_is_local (CKSeat *seat);
+GSList *ck_seat_get_sessions (CKSeat *seat);
+const char *ck_seat_get_id (CKSeat *seat);
+
+gboolean ck_session_is_active (CKSession *session);
+CKSeat *ck_session_get_seat (CKSession *session);
+const char *ck_session_get_id (CKSession *session);
+uid_t ck_session_get_user (CKSession *session);
+
+
+#endif /* CK_TRACKER_H */
diff --git a/hald/hald.c b/hald/hald.c
index 4e4f1c6..2918558 100644
--- a/hald/hald.c
+++ b/hald/hald.c
@@ -597,6 +597,10 @@ main (int argc, char *argv[])
if (!hald_dbus_local_server_init ())
return 1;
+ if (!hald_dbus_init_preprobe ()) {
+ return 1;
+ }
+
/* Start the runner helper daemon */
if (!hald_runner_start_runner ()) {
return 1;
diff --git a/hald/hald_dbus.c b/hald/hald_dbus.c
index ddd6b8e..08c5367 100644
--- a/hald/hald_dbus.c
+++ b/hald/hald_dbus.c
@@ -48,9 +48,12 @@
#include "util.h"
#include "hald_runner.h"
+#include "ck-tracker.h"
+
#define HALD_DBUS_ADDRESS "unix:tmpdir=" HALD_SOCKET_DIR
static DBusConnection *dbus_connection = NULL;
+static CKTracker *ck_tracker = NULL;
static void
raise_error (DBusConnection *connection,
@@ -576,7 +579,7 @@ manager_send_signal_device_added (HalDev
DBusMessage *message;
DBusMessageIter iter;
- if (dbus_connection == NULL)
+ if (dbus_connection == NULL || hald_is_initialising)
goto out;
HAL_TRACE (("entering, udi=%s", udi));
@@ -609,7 +612,7 @@ manager_send_signal_device_removed (HalD
DBusMessage *message;
DBusMessageIter iter;
- if (dbus_connection == NULL)
+ if (dbus_connection == NULL || hald_is_initialising)
goto out;
HAL_TRACE (("entering, udi=%s", udi));
@@ -644,7 +647,7 @@ manager_send_signal_new_capability (HalD
DBusMessage *message;
DBusMessageIter iter;
- if (dbus_connection == NULL)
+ if (dbus_connection == NULL || hald_is_initialising)
goto out;
HAL_TRACE (("entering, udi=%s, cap=%s", udi, capability));
@@ -931,7 +934,8 @@ caller_info_free (CallerInfo *ci)
g_free (ci);
}
-GHashTable *connection_name_to_caller_info;
+static GHashTable *connection_name_to_caller_info;
+
static void
ci_tracker_init (void)
@@ -2364,7 +2368,7 @@ device_send_signal_property_modified (Ha
DBusMessageIter iter_struct;
DBusMessageIter iter_array;
- if (dbus_connection == NULL)
+ if (dbus_connection == NULL || hald_is_initialising)
goto out;
message = dbus_message_new_signal (udi,
@@ -2431,7 +2435,7 @@ device_send_signal_condition (HalDevice
DBusMessage *message;
DBusMessageIter iter;
- if (dbus_connection == NULL)
+ if (dbus_connection == NULL || hald_is_initialising)
goto out;
message = dbus_message_new_signal (udi,
@@ -4159,7 +4163,8 @@ no_caller:
}
/** Message handler for method invocations. All invocations on any object
- * or interface is routed through this function.
+ * or interface is routed through this function. *ONLY* messages from the
+ * system bus goes through this method.
*
* @param connection D-BUS connection
* @param message Message
@@ -4170,6 +4175,13 @@ DBusHandlerResult
hald_dbus_filter_function (DBusConnection * connection,
DBusMessage * message, void *user_data)
{
+#ifdef HAVE_CONKIT
+ /* TODO: only push the appropriate messages to the tracker; see ck-tracker.h */
+ if (ck_tracker != NULL) {
+ ck_tracker_process_system_bus_message (ck_tracker, message);
+ }
+#endif
+
if (dbus_message_is_signal (message, DBUS_INTERFACE_LOCAL, "Disconnected") &&
strcmp (dbus_message_get_path (message), DBUS_PATH_LOCAL) == 0) {
@@ -4388,12 +4400,37 @@ hald_dbus_local_server_shutdown (void)
}
}
+static void
+hald_dbus_session_added (CKTracker *tracker, CKSession *session, void *user_data)
+{
+ HAL_INFO (("In hald_dbus_session_added for session '%s' on seat '%s'",
+ ck_session_get_id (session),
+ ck_session_get_seat (session) != NULL ? ck_seat_get_id (ck_session_get_seat (session)) : "(NONE)"));
+}
+
+static void
+hald_dbus_session_removed (CKTracker *tracker, CKSession *session, void *user_data)
+{
+ HAL_INFO (("In hald_dbus_session_removed for session '%s' on seat '%s'",
+ ck_session_get_id (session),
+ ck_session_get_seat (session) != NULL ? ck_seat_get_id (ck_session_get_seat (session)) : "(NONE)"));
+}
+
+static void
+hald_dbus_session_active_changed (CKTracker *tracker, CKSession *session, void *user_data)
+{
+ HAL_INFO (("In hald_dbus_session_active_changed for session '%s': %s",
+ ck_session_get_id (session),
+ ck_session_is_active (session) ? "ACTIVE" : "INACTIVE"));
+}
+
gboolean
-hald_dbus_init (void)
+hald_dbus_init_preprobe (void)
{
+ gboolean ret;
DBusError dbus_error;
- HAL_INFO (("entering"));
+ ret = FALSE;
dbus_connection_set_change_sigpipe (TRUE);
@@ -4401,22 +4438,15 @@ hald_dbus_init (void)
dbus_connection = dbus_bus_get (DBUS_BUS_SYSTEM, &dbus_error);
if (dbus_connection == NULL) {
HAL_ERROR (("dbus_bus_get(): %s", dbus_error.message));
- return FALSE;
+ goto out;
}
dbus_connection_setup_with_g_main (dbus_connection, NULL);
dbus_connection_set_exit_on_disconnect (dbus_connection, FALSE);
- dbus_bus_request_name (dbus_connection, "org.freedesktop.Hal",
- 0, &dbus_error);
- if (dbus_error_is_set (&dbus_error)) {
- HAL_ERROR (("dbus_bus_request_name(): %s",
- dbus_error.message));
- return FALSE;
- }
-
dbus_connection_add_filter (dbus_connection, hald_dbus_filter_function, NULL, NULL);
+
dbus_bus_add_match (dbus_connection,
"type='signal'"
",interface='"DBUS_INTERFACE_DBUS"'"
@@ -4431,10 +4461,54 @@ hald_dbus_init (void)
",sender='org.freedesktop.ConsoleKit'"
",member='ActiveChanged'",
NULL);
+ dbus_bus_add_match (dbus_connection,
+ "type='signal'"
+ ",interface='org.freedesktop.ConsoleKit.Seat'"
+ ",sender='org.freedesktop.ConsoleKit'"
+ ",member='SessionAdded'",
+ NULL);
+ dbus_bus_add_match (dbus_connection,
+ "type='signal'"
+ ",interface='org.freedesktop.ConsoleKit.Seat'"
+ ",sender='org.freedesktop.ConsoleKit'"
+ ",member='SessionRemoved'",
+ NULL);
+
+ ck_tracker = ck_tracker_new ();
+ ck_tracker_set_system_bus_connection (ck_tracker, dbus_connection);
+ ck_tracker_set_session_added_cb (ck_tracker, hald_dbus_session_added);
+ ck_tracker_set_session_removed_cb (ck_tracker, hald_dbus_session_removed);
+ ck_tracker_set_session_active_changed_cb (ck_tracker, hald_dbus_session_active_changed);
+ if (!ck_tracker_init (ck_tracker)) {
+ ck_tracker_unref (ck_tracker);
+ DIE (("Could not initialize seats and sessions from ConsoleKit"));
+ }
+
#endif /* HAVE_CONKIT */
ci_tracker_init ();
+ ret = TRUE;
+
+out:
+ return ret;
+}
+
+gboolean
+hald_dbus_init (void)
+{
+ DBusError dbus_error;
+
+ HAL_INFO (("entering"));
+
+ dbus_error_init (&dbus_error);
+ dbus_bus_request_name (dbus_connection, "org.freedesktop.Hal", 0, &dbus_error);
+ if (dbus_error_is_set (&dbus_error)) {
+ HAL_ERROR (("dbus_bus_request_name(): %s",
+ dbus_error.message));
+ return FALSE;
+ }
+
return TRUE;
}
diff --git a/hald/hald_dbus.h b/hald/hald_dbus.h
index 439f451..79442be 100644
--- a/hald/hald_dbus.h
+++ b/hald/hald_dbus.h
@@ -87,6 +87,8 @@ void device_send_signal_condition (HalDe
void device_property_atomic_update_begin (void);
void device_property_atomic_update_end (void);
+gboolean hald_dbus_init_preprobe (void);
+
gboolean hald_dbus_init (void);
gboolean hald_dbus_local_server_init (void);
diff --git a/hald/util.c b/hald/util.c
index 6ad4fcf..eaf3b09 100644
--- a/hald/util.c
+++ b/hald/util.c
@@ -942,9 +942,9 @@ callout_do_next (Callout *c)
callback (d, userdata1, userdata2);
} else {
- hald_runner_run(c->d, c->programs[c->next_program], c->extra_env,
- HAL_HELPER_TIMEOUT, callout_terminated,
- (gpointer)c, NULL);
+ hald_runner_run(c->d, c->programs[c->next_program], c->extra_env,
+ HAL_HELPER_TIMEOUT, callout_terminated,
+ (gpointer)c, NULL);
c->next_program++;
}
}
diff --git a/tools/Makefile.am b/tools/Makefile.am
index d820cc8..037b4aa 100644
--- a/tools/Makefile.am
+++ b/tools/Makefile.am
@@ -58,6 +58,15 @@ libexec_PROGRAMS =
hal-storage-cleanup-all-mountpoints \
hal-system-power-pmu
+if HAVE_ACLMGMT
+libexec_PROGRAMS += hal-acl-add hal-acl-remove
+
+hal_acl_add_SOURCES = hal-acl-add.c
+hal_acl_remove_SOURCES = hal-acl-remove.c
+endif
+
+
+
hal_storage_mount_SOURCES = hal-storage-mount.c hal-storage-shared.c hal-storage-shared.h
hal_storage_mount_LDADD = @GLIB_LIBS@ @POLKIT_LIBS@ @DBUS_LIBS@ $(top_builddir)/libhal/libhal.la $(top_builddir)/libhal-storage/libhal-storage.la
diff --git a/tools/hal-acl-add.c b/tools/hal-acl-add.c
new file mode 100644
index 0000000..2767773
--- /dev/null
+++ b/tools/hal-acl-add.c
@@ -0,0 +1,91 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <sys/file.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <errno.h>
+
+#include <glib.h>
+
+#if 0
+static int lock_acl_fd = -1;
+
+static gboolean
+lock_hal_acl (void)
+{
+ if (lock_acl_fd >= 0)
+ return TRUE;
+
+ printf ("%d: attempting to get lock on /var/lib/hal/acl-list\n", getpid ());
+
+ lock_acl_fd = open ("/var/lib/hal/acl-list", O_CREAT | O_RDWR);
+
+ if (lock_acl_fd < 0)
+ return FALSE;
+
+tryagain:
+#if sun
+ if (lockf (lock_acl_fd, F_LOCK, 0) != 0) {
+#else
+ if (flock (lock_acl_fd, LOCK_EX) != 0) {
+#endif
+ if (errno == EINTR)
+ goto tryagain;
+ return FALSE;
+ }
+
+ printf ("%d: got lock on /var/lib/hal/acl-list\n", getpid ());
+
+
+ return TRUE;
+}
+
+static void
+unlock_hal_acl (void)
+{
+#if sun
+ lockf (lock_acl_fd, F_ULOCK, 0);
+#else
+ flock (lock_acl_fd, LOCK_UN);
+#endif
+ close (lock_acl_fd);
+ lock_acl_fd = -1;
+ printf ("%d: released lock on /var/lib/hal/acl-list\n", getpid ());
+}
+
+/* Each entry here represents a line in the acl-list file
+ *
+ * <device-file>\t<hal-udi>\t<uid-as-number>\t<gid-as-number>\t<session-id>
+ *
+ * example:
+ *
+ * /dev/snd/controlC0\t/org/freedesktop/Hal/devices/pci_8086_27d8_alsa_control__1\t500\t\t/org/freedesktop/ConsoleKit/Session0
+ *
+ * This means that the
+ */
+typedef struct HalACL_s {
+ const char *device;
+ const char *uid;
+ uid_t uid; /* 0 if unset */
+ gid_t gid; /* 0 if unset */
+ const char *session; /* NULL if unset */
+} HalACL;
+
+/* hal-acl-grant can run in two modes of operation;
+ *
+ * 1) as a hal callout via info.callouts.add - this will set ACL's on the device file pointed to by acl.file
+ * using the information provided by the other acl.* properties to determine what ACL's to add to the given
+ * device file
+ *
+ * 2)
+ *
+ */
+#endif
+
+int
+main (int argc, char *argv[])
+{
+ fprintf (stderr, "hal-acl-add\n");
+ return 0;
+}
diff --git a/tools/hal-acl-remove.c b/tools/hal-acl-remove.c
new file mode 100644
index 0000000..3f9278b
--- /dev/null
+++ b/tools/hal-acl-remove.c
@@ -0,0 +1,15 @@
+
+#include <stdio.h>
+#include <stdlib.h>
+
+int
+main (int argc, char *argv[])
+{
+ int i;
+
+ fprintf (stderr, "hal-acl-remove %d\n", argc);
+ for (i = 0; i < argc; i++) {
+ fprintf (stderr, " arg %2d: %s\n", i, argv[i]);
+ }
+ return 0;
+}
More information about the hal-commit
mailing list