aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--.bzrignore3
-rw-r--r--configure.ac3
-rw-r--r--src/gtk-dialog/Makefile.am2
-rw-r--r--src/gtk-dialog/ck-pk-helper.c214
-rw-r--r--src/gtk-dialog/ck-pk-helper.h6
-rw-r--r--src/gtk-dialog/logout-dialog.c4
6 files changed, 228 insertions, 4 deletions
diff --git a/.bzrignore b/.bzrignore
index 2ff5ffb..ff3cbaf 100644
--- a/.bzrignore
+++ b/.bzrignore
@@ -25,3 +25,6 @@ indicator-status.service
indicator-users.service
status-service-client.h
status-service-server.h
+gtk-logout-helper
+.deps
+.libs
diff --git a/configure.ac b/configure.ac
index 9d64f40..1e65958 100644
--- a/configure.ac
+++ b/configure.ac
@@ -48,7 +48,8 @@ PKG_CHECK_MODULES(SESSIONSERVICE, dbusmenu-glib >= $DBUSMENUGLIB_REQUIRED_VERSIO
AC_SUBST(SESSIONERVICE_CFLAGS)
AC_SUBST(SESSIONERVICE_LIBS)
-PKG_CHECK_MODULES(GTKLOGOUTHELPER, gtk+-2.0 >= $GTK_REQUIRED_VERSION)
+PKG_CHECK_MODULES(GTKLOGOUTHELPER, gtk+-2.0 >= $GTK_REQUIRED_VERSION
+ polkit-gnome)
AC_SUBST(GTKLOGOUTHELPER_CFLAGS)
AC_SUBST(GTKLOGOUTHELPER_LIBS)
diff --git a/src/gtk-dialog/Makefile.am b/src/gtk-dialog/Makefile.am
index 07b0915..9aa0097 100644
--- a/src/gtk-dialog/Makefile.am
+++ b/src/gtk-dialog/Makefile.am
@@ -3,6 +3,8 @@ libexec_PROGRAMS = gtk-logout-helper
gtk_logout_helper_SOURCES = \
gtk-logout-helper.c \
+ ck-pk-helper.c \
+ ck-pk-helper.h \
logout-dialog.c \
logout-dialog.h
diff --git a/src/gtk-dialog/ck-pk-helper.c b/src/gtk-dialog/ck-pk-helper.c
new file mode 100644
index 0000000..9278905
--- /dev/null
+++ b/src/gtk-dialog/ck-pk-helper.c
@@ -0,0 +1,214 @@
+
+#include <unistd.h>
+#include <glib.h>
+#include <dbus/dbus-glib.h>
+#include <polkit-gnome/polkit-gnome.h>
+
+#include "logout-dialog.h"
+#include "ck-pk-helper.h"
+
+static gboolean
+ck_multiple_users (void)
+{
+ DBusGConnection * sbus = dbus_g_bus_get(DBUS_BUS_SYSTEM, NULL);
+ g_return_val_if_fail(sbus != NULL, TRUE); /* worst case */
+ DBusGProxy * proxy = dbus_g_proxy_new_for_name(sbus, "org.freedesktop.ConsoleKit",
+ "/org/freedesktop/ConsoleKit/Manager",
+ "org.freedesktop.ConsoleKit.Manager");
+
+ if (proxy == NULL) {
+ return TRUE;
+ }
+
+ gboolean result;
+ GPtrArray * seats = NULL;
+
+ result = dbus_g_proxy_call(proxy, "GetSeats", NULL, G_TYPE_INVALID,
+ dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &seats, G_TYPE_INVALID);
+
+ if (!result) {
+ g_warning("Unable to get the seats for ConsoleKit");
+ g_object_unref(proxy);
+ return TRUE;
+ }
+
+ gchar * this_session_id = NULL;
+
+ result = dbus_g_proxy_call(proxy, "GetCurrentSession", NULL, G_TYPE_INVALID,
+ DBUS_TYPE_G_OBJECT_PATH, &this_session_id, G_TYPE_INVALID);
+
+ g_object_unref(proxy);
+
+ if (!result) {
+ g_warning("Unable to get current session from ConsoleKit");
+ return TRUE;
+ }
+
+ proxy = dbus_g_proxy_new_for_name(sbus, "org.freedesktop.ConsoleKit",
+ this_session_id, "org.freedesktop.ConsoleKit.Session");
+
+ if (proxy == NULL) {
+ return TRUE;
+ }
+
+ guint this_session_uid;
+
+ result = dbus_g_proxy_call(proxy, "GetUnixUser", NULL, G_TYPE_INVALID,
+ G_TYPE_UINT, &this_session_uid, G_TYPE_INVALID);
+
+ if (!result) {
+ g_warning("Unable to get UID from ConsoleKit");
+ return TRUE;
+ }
+
+ guint seat;
+ gboolean multiple_users = FALSE;
+ for (seat = 0; seat < seats->len; seat++) {
+ gchar * seat_id = g_ptr_array_index(seats, seat);
+ DBusGProxy * seat_proxy = dbus_g_proxy_new_for_name(sbus, "org.freedesktop.ConsoleKit",
+ seat_id, "org.freedesktop.ConsoleKit.Seat");
+ g_free(seat_id);
+
+ if (seat_proxy == NULL) {
+ continue;
+ }
+
+ GPtrArray * sessions = NULL;
+
+ gboolean result = dbus_g_proxy_call(seat_proxy,
+ "GetSessions", NULL, G_TYPE_INVALID,
+ dbus_g_type_get_collection("GPtrArray", DBUS_TYPE_G_OBJECT_PATH), &sessions, G_TYPE_INVALID);
+
+ g_object_unref(seat_proxy);
+ if (!result) {
+ continue;
+ }
+
+ guint session;
+ for (session = 0; session < sessions->len; session++) {
+ gchar * session_id = g_ptr_array_index(sessions, session);
+ if (g_strcmp0(this_session_id, session_id) == 0) {
+ continue;
+ }
+ DBusGProxy * session_proxy = dbus_g_proxy_new_for_name(sbus, "org.freedesktop.ConsoleKit",
+ session_id, "org.freedesktop.ConsoleKit.Session");
+ g_free(session_id);
+
+ if (session_proxy == NULL) {
+ continue;
+ }
+
+ guint session_uid;
+ result = dbus_g_proxy_call(session_proxy, "GetUnixUser", NULL, G_TYPE_INVALID,
+ G_TYPE_UINT, &session_uid, G_TYPE_INVALID);
+ g_object_unref(session_proxy);
+
+ if (!result) {
+ continue;
+ }
+
+ if (session_uid != this_session_uid) {
+ multiple_users = TRUE;
+ break;
+ }
+ }
+
+ g_ptr_array_free(sessions, TRUE);
+
+ if (multiple_users) {
+ break;
+ }
+ }
+
+ g_ptr_array_free(seats, TRUE);
+ g_object_unref(proxy);
+ g_free(this_session_id);
+
+ return multiple_users;
+}
+
+gboolean
+pk_require_auth (LogoutDialogAction action) {
+ if (action == LOGOUT_DIALOG_LOGOUT) {
+ return FALSE;
+ }
+
+ gchar * pk_action;
+ if (ck_multiple_users()) {
+ if (action == LOGOUT_DIALOG_RESTART) {
+ pk_action = "org.freedesktop.consolekit.system.restart-multiple-users";
+ } else {
+ pk_action = "org.freedesktop.consolekit.system.stop-multiple-users";
+ }
+ } else {
+ if (action == LOGOUT_DIALOG_RESTART) {
+ pk_action = "org.freedesktop.consolekit.system.restart";
+ } else {
+ pk_action = "org.freedesktop.consolekit.system.stop";
+ }
+ }
+
+ PolKitResult polres;
+ if (pk_can_do_action(pk_action, &polres)) {
+ if (polres == POLKIT_RESULT_YES) {
+ return FALSE;
+ }
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+pk_can_do_action (const gchar *action_id, PolKitResult * pol_result)
+{
+ PolKitGnomeContext *gnome_context;
+ PolKitAction *action;
+ PolKitCaller *caller;
+ DBusError dbus_error;
+ PolKitError *error;
+ PolKitResult result;
+
+ gnome_context = polkit_gnome_context_get (NULL);
+
+ if (gnome_context == NULL) {
+ return FALSE;
+ }
+
+ if (gnome_context->pk_tracker == NULL) {
+ return FALSE;
+ }
+
+ dbus_error_init (&dbus_error);
+ caller = polkit_tracker_get_caller_from_pid (gnome_context->pk_tracker,
+ getpid (),
+ &dbus_error);
+ dbus_error_free (&dbus_error);
+
+ if (caller == NULL) {
+ return FALSE;
+ }
+
+ action = polkit_action_new ();
+ if (!polkit_action_set_action_id (action, action_id)) {
+ polkit_action_unref (action);
+ polkit_caller_unref (caller);
+ return FALSE;
+ }
+
+ result = POLKIT_RESULT_UNKNOWN;
+ error = NULL;
+ result = polkit_context_is_caller_authorized (gnome_context->pk_context,
+ action, caller, FALSE,
+ &error);
+ if (polkit_error_is_set (error)) {
+ polkit_error_free (error);
+ }
+ polkit_action_unref (action);
+ polkit_caller_unref (caller);
+
+ if (pol_result != NULL) {
+ *pol_result = result;
+ }
+
+ return result != POLKIT_RESULT_NO && result != POLKIT_RESULT_UNKNOWN;
+}
diff --git a/src/gtk-dialog/ck-pk-helper.h b/src/gtk-dialog/ck-pk-helper.h
new file mode 100644
index 0000000..6a3aa5a
--- /dev/null
+++ b/src/gtk-dialog/ck-pk-helper.h
@@ -0,0 +1,6 @@
+
+#include <polkit-gnome/polkit-gnome.h>
+
+gboolean pk_require_auth (LogoutDialogAction action);
+gboolean pk_can_do_action (const gchar *action_id, PolKitResult * pol_result);
+
diff --git a/src/gtk-dialog/logout-dialog.c b/src/gtk-dialog/logout-dialog.c
index 0cd0f7a..cd49b00 100644
--- a/src/gtk-dialog/logout-dialog.c
+++ b/src/gtk-dialog/logout-dialog.c
@@ -26,10 +26,8 @@
#include <glib/gi18n.h>
#include <X11/XKBlib.h>
-#include "../config.h"
-
#include "logout-dialog.h"
-#include "applet.h"
+#include "ck-pk-helper.h"
enum {
PROP_ZERO,