[Xfce4-commits] [xfce/xfce4-session] 07/10: Use pkexec for xfsm-shutdown (Bug 9952)
noreply at xfce.org
noreply at xfce.org
Thu Aug 28 17:53:08 CEST 2014
This is an automated email from the git hooks/post-receive script.
eric pushed a commit to branch master
in repository xfce/xfce4-session.
commit 29d87f559aadba51e7bd6afcf4aeeb615ecb2145
Author: Eric Koegel <eric.koegel at gmail.com>
Date: Sun Aug 10 19:16:17 2014 +0300
Use pkexec for xfsm-shutdown (Bug 9952)
Instead of using the sudo helper, this patch calls xfsm-shutdown
using pkexec. This way users can use things like fingerprint
readers for authentication. Also this patch provides suspend/resume
support since UPower 0.99 dropped it.
---
configure.ac.in | 41 +-
po/POTFILES.in | 2 +-
xfce4-session/Makefile.am | 38 +-
xfce4-session/org.xfce.session.policy.in2 | 34 ++
xfce4-session/xfsm-logout-dialog.c | 155 +-----
xfce4-session/xfsm-shutdown.c | 800 +++++++++++------------------
xfce4-session/xfsm-upower.c | 12 +-
xfce4-session/xfsm-upower.h | 4 +
xfsm-shutdown-helper/main.c | 124 ++++-
9 files changed, 536 insertions(+), 674 deletions(-)
diff --git a/configure.ac.in b/configure.ac.in
index d61b59c..5279667 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -96,9 +96,13 @@ XDT_CHECK_PACKAGE([DBUS], [dbus-1], [1.1.0])
XDT_CHECK_PACKAGE([DBUS_GLIB], [dbus-glib-1], [0.84])
XDT_CHECK_PACKAGE([XFCONF], [libxfconf-0], [4.9.0])
-dnl Check for polkit / systemd integration
-XDT_CHECK_OPTIONAL_PACKAGE([SYSTEMD], [polkit-gobject-1], [0.102],
- [systemd], [Systemd support (through polkit)])
+dnl Check for Polkit/PolicyKit
+XDT_CHECK_OPTIONAL_PACKAGE([POLKIT], [polkit-gobject-1], [0.102],
+ [polkit], [Polkit support])
+
+dnl Check for Upower
+XDT_CHECK_OPTIONAL_PACKAGE([UPOWER],[upower-glib], [0.9.7],
+ [upower],[Upower support])
dnl Check for debugging support
XDT_FEATURE_DEBUG([xfsm_debug_default])
@@ -157,6 +161,31 @@ if test "x$linux_ioprio_works" = "xyes"; then
[Defined if linux/ioprio.h not only exists, but works properly])
fi
+dnl Compile time default choice of backend
+AC_ARG_WITH([backend],
+ AS_HELP_STRING([--with-backend=<option>],
+ [Default backend to use linux, freebsd, openbsd]))
+# default to a sane option
+AC_CANONICAL_HOST
+if test x$with_backend = x; then
+ AS_CASE([$host],
+ [*-linux*], [with_backend=linux],
+ [*-*freebsd*], [with_backend=freebsd],
+ [*-openbsd*], [with_backend=openbsd])
+fi
+AC_DEFINE_UNQUOTED(BACKEND, "$with_backend", [backend])
+AC_SUBST(BACKEND, "$with_backend")
+
+if test x$with_backend = xlinux; then
+ AC_DEFINE(BACKEND_TYPE_LINUX, 1, [Linux suspend/hibernate backend])
+fi
+if test x$with_backend = xfreebsd; then
+ AC_DEFINE(BACKEND_TYPE_FREEBSD, 1, [FreeBSD suspend/hibernate backend])
+fi
+if test x$with_backend = xopenbsd; then
+ AC_DEFINE(BACKEND_TYPE_OPENBSD, 1, [OpenBSD suspend/hibernate backend])
+fi
+
dnl check for location Xfce glade files were installed to
XFCE_GLADE_CATALOG_PATH="`pkg-config --variable glade_catalogdir libxfce4ui-1`"
XFCE_GLADE_PIXMAP_PATH="`pkg-config --variable glade_pixmapdir libxfce4ui-1`"
@@ -202,10 +231,6 @@ echo " * Legacy session management: yes"
else
echo " * Legacy session management: no"
fi
-if test x"$SYSTEMD_FOUND" = x"yes"; then
-echo " * Systemd support (through polkit): yes"
-else
-echo " * Systemd support (through polkit): no"
-fi
+echo " * Backend: ${with_backend}"
echo
diff --git a/po/POTFILES.in b/po/POTFILES.in
index d9c62a5..bbedcc9 100644
--- a/po/POTFILES.in
+++ b/po/POTFILES.in
@@ -26,7 +26,7 @@ xfce4-session/xfsm-shutdown.c
xfce4-session/xfsm-upower.c
xfce4-session-logout/main.c
xfce4-session-logout/xfce4-session-logout.desktop.in
-
+xfce4-session/org.xfce.session.policy.in2
# files added by intltool-prepare.
settings/xfce-session-settings.desktop.in
diff --git a/xfce4-session/Makefile.am b/xfce4-session/Makefile.am
index ea706fd..47df3f4 100644
--- a/xfce4-session/Makefile.am
+++ b/xfce4-session/Makefile.am
@@ -63,13 +63,10 @@ xfce4_session_SOURCES = \
xfsm-startup.c \
xfsm-startup.h \
xfsm-upower.c \
- xfsm-upower.h
-
-if HAVE_SYSTEMD
-xfce4_session_SOURCES += \
+ xfsm-upower.h \
xfsm-systemd.c \
xfsm-systemd.h
-endif
+
xfce4_session_CFLAGS = \
$(LIBSM_CFLAGS) \
@@ -78,10 +75,11 @@ xfce4_session_CFLAGS = \
$(DBUS_CFLAGS) \
$(DBUS_GLIB_CFLAGS) \
$(LIBWNCK_CFLAGS) \
- $(SYSTEMD_CFLAGS) \
+ $(POLKIT_CFLAGS) \
$(XFCONF_CFLAGS) \
$(GMODULE_CFLAGS) \
- $(PLATFORM_CFLAGS)
+ $(PLATFORM_CFLAGS) \
+ $(UPOWER_CFLAGS)
xfce4_session_LDFLAGS = \
-no-undefined \
@@ -98,13 +96,26 @@ xfce4_session_LDADD = \
$(DBUS_LIBS) \
$(DBUS_GLIB_LIBS) \
$(LIBWNCK_LIBS) \
- $(SYSTEMD_LIBS) \
+ $(POLKIT_LIBS) \
$(XFCONF_LIBS) \
+ $(UPOWER_LIBS) \
-lm
xfce4_session_DEPENDENCIES = \
$(top_builddir)/libxfsm/libxfsm-4.6.la
+if HAVE_POLKIT
+
+ at INTLTOOL_POLICY_RULE@
+
+polkit_policydir = $(datadir)/polkit-1/actions
+polkit_policy_DATA = \
+ org.xfce.session.policy
+.in2.in:
+ sed "s|[@]HELPER_PATH_PREFIX@|${HELPER_PATH_PREFIX}|" $< > $@
+
+endif
+
if MAINTAINER_MODE
xfsm-chooser-icon.h: $(srcdir)/xfsm-chooser-icon.png
@@ -123,9 +134,6 @@ xfsm-manager-dbus.h: $(srcdir)/xfsm-manager-dbus.xml
xfsm-client-dbus.h: $(srcdir)/xfsm-client-dbus.xml
$(AM_V_GEN) dbus-binding-tool --mode=glib-server --prefix=xfsm_client $< > $@
-DISTCLEANFILES = \
- $(xfce4_session_built_sources)
-
BUILT_SOURCES = \
$(xfce4_session_built_sources)
@@ -136,6 +144,12 @@ EXTRA_DIST = \
xfsm-chooser-icon.png \
xfsm-marshal.list \
xfsm-client-dbus.xml \
- xfsm-manager-dbus.xml
+ xfsm-manager-dbus.xml \
+ org.xfce.session.policy.in2
+
+DISTCLEANFILES = \
+ $(xfce4_session_built_sources) \
+ org.xfce.session.policy \
+ org.xfce.session.policy.in
# vi:set ts=8 sw=8 noet ai nocindent syntax=automake:
diff --git a/xfce4-session/org.xfce.session.policy.in2 b/xfce4-session/org.xfce.session.policy.in2
new file mode 100644
index 0000000..7f7c5ae
--- /dev/null
+++ b/xfce4-session/org.xfce.session.policy.in2
@@ -0,0 +1,34 @@
+<?xml version="1.0" encoding="UTF-8"?>
+<!DOCTYPE policyconfig PUBLIC
+ "-//freedesktop//DTD PolicyKit Policy Configuration 1.0//EN"
+ "http://www.freedesktop.org/standards/PolicyKit/1.0/policyconfig.dtd">
+<policyconfig>
+
+ <!--
+ Policy definitions for XFCE Session Manager system-wide actions.
+ Copyright (c) 2014 Eric Koegel <eric at xfce.org>
+ Based on the XFCE Power Manager policy file.
+ -->
+
+ <vendor>XFCE Session Manager</vendor>
+ <vendor_url>http://xfce.org/</vendor_url>
+ <icon_name>xfce4-session</icon_name>
+
+
+ <action id="org.xfce.session.xfsm-shutdown-helper">
+ <!-- SECURITY:
+ - A normal active user on the local machine does not need permission
+ to suspend or hibernate their system.
+ -->
+ <_description>Shutdown, restart, suspend, or hibernate the system</_description>
+ <_message>Authentication is required to shutdown, restart, suspend, or hibernate the system.</_message>
+ <defaults>
+ <allow_any>auth_admin</allow_any>
+ <allow_inactive>auth_admin</allow_inactive>
+ <allow_active>yes</allow_active>
+ </defaults>
+ <annotate key="org.freedesktop.policykit.exec.path">@HELPER_PATH_PREFIX@/xfce4/session/xfsm-shutdown-helper</annotate>
+ </action>
+
+</policyconfig>
+
diff --git a/xfce4-session/xfsm-logout-dialog.c b/xfce4-session/xfsm-logout-dialog.c
index 549eca6..5374551 100644
--- a/xfce4-session/xfsm-logout-dialog.c
+++ b/xfce4-session/xfsm-logout-dialog.c
@@ -72,14 +72,12 @@ static GtkWidget *xfsm_logout_dialog_button (const gchar *title,
const gchar *icon_name_fallback,
XfsmShutdownType type,
XfsmLogoutDialog *dialog);
-static void xfsm_logout_dialog_activate (XfsmLogoutDialog *dialog);
enum
{
MODE_LOGOUT_BUTTONS,
- MODE_ASK_PASSWORD,
MODE_SHOW_ERROR,
N_MODES
};
@@ -107,9 +105,6 @@ struct _XfsmLogoutDialog
GtkWidget *button_ok;
GtkWidget *button_close;
- /* password entry */
- GtkWidget *password_entry;
-
/* error label */
GtkWidget *error_label;
@@ -155,7 +150,6 @@ xfsm_logout_dialog_init (XfsmLogoutDialog *dialog)
gboolean auth_hibernate = FALSE;
GError *error = NULL;
XfconfChannel *channel;
- GtkWidget *entry;
GtkWidget *image;
GtkWidget *separator;
gboolean upower_not_found = FALSE;
@@ -215,22 +209,6 @@ xfsm_logout_dialog_init (XfsmLogoutDialog *dialog)
GTK_STOCK_CANCEL,
GTK_RESPONSE_CANCEL);
- /**
- * Ok, for password mode
- **/
- dialog->button_ok = gtk_dialog_add_button (GTK_DIALOG (dialog),
- GTK_STOCK_OK,
- GTK_RESPONSE_OK);
- gtk_widget_hide (dialog->button_ok);
-
- /**
- * Close, for password error
- **/
- dialog->button_close = gtk_dialog_add_button (GTK_DIALOG (dialog),
- GTK_STOCK_CLOSE,
- GTK_RESPONSE_CANCEL);
- gtk_widget_hide (dialog->button_close);
-
button_vbox = gtk_vbox_new (TRUE, BORDER);
gtk_box_pack_start (GTK_BOX (vbox), button_vbox, FALSE, TRUE, 0);
gtk_widget_show (button_vbox);
@@ -374,37 +352,6 @@ xfsm_logout_dialog_init (XfsmLogoutDialog *dialog)
attrs = pango_attr_list_new ();
pango_attr_list_insert (attrs, pango_attr_weight_new (PANGO_WEIGHT_BOLD));
- /**
- * Start mode MODE_ASK_PASSWORD
- **/
- dialog->box[MODE_ASK_PASSWORD] = vbox = gtk_vbox_new (FALSE, BORDER);
- gtk_box_pack_start (GTK_BOX (main_vbox), vbox, TRUE, TRUE, 0);
-
- hbox = gtk_hbox_new (FALSE, BORDER * 2);
- gtk_box_pack_start (GTK_BOX (vbox), hbox, FALSE, TRUE, 0);
- gtk_widget_show (hbox);
-
- image = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG);
- gtk_box_pack_start (GTK_BOX (hbox), image, FALSE, FALSE, 0);
- gtk_widget_show (image);
-
- vbox = gtk_vbox_new (FALSE, BORDER);
- gtk_box_pack_start (GTK_BOX (hbox), vbox, TRUE, TRUE, 0);
- gtk_widget_show (vbox);
-
- label = gtk_label_new (_("Please enter your password"));
- gtk_misc_set_alignment (GTK_MISC (label), 0.00, 0.50);
- gtk_label_set_attributes (GTK_LABEL (label), attrs);
- gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, FALSE, 0);
- gtk_widget_show (label);
-
- dialog->password_entry = entry = gtk_entry_new ();
- gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE);
- gtk_entry_set_width_chars (GTK_ENTRY (entry), 30);
- gtk_box_pack_start (GTK_BOX (vbox), entry, TRUE, TRUE, 0);
- g_signal_connect_swapped (G_OBJECT (entry), "activate",
- G_CALLBACK (xfsm_logout_dialog_activate), dialog);
- gtk_widget_show (entry);
/**
* Start mode MODE_SHOW_ERROR
@@ -430,14 +377,6 @@ xfsm_logout_dialog_init (XfsmLogoutDialog *dialog)
gtk_label_set_attributes (GTK_LABEL (label), attrs);
gtk_widget_show (label);
- label = gtk_label_new (_("Either the password you entered is "
- "invalid, or the system administrator "
- "disallows shutting down this computer "
- "with your user account."));
- gtk_label_set_line_wrap (GTK_LABEL (label), TRUE);
- gtk_box_pack_start (GTK_BOX (vbox), label, TRUE, TRUE, 0);
- gtk_widget_show (label);
-
pango_attr_list_unref (attrs);
}
@@ -465,7 +404,6 @@ xfsm_logout_dialog_set_mode (XfsmLogoutDialog *dialog,
gtk_widget_set_visible (dialog->box[i], i == mode);
gtk_widget_set_visible (dialog->button_cancel, mode != MODE_SHOW_ERROR);
- gtk_widget_set_visible (dialog->button_ok, mode == MODE_ASK_PASSWORD);
gtk_widget_set_visible (dialog->button_close, mode == MODE_SHOW_ERROR);
}
@@ -548,15 +486,6 @@ xfsm_logout_dialog_button (const gchar *title,
-static void
-xfsm_logout_dialog_activate (XfsmLogoutDialog *dialog)
-{
- g_return_if_fail (XFSM_IS_LOGOUT_DIALOG (dialog));
- gtk_dialog_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
-}
-
-
-
static GdkPixbuf *
xfsm_logout_dialog_screenshot_new (GdkScreen *screen)
{
@@ -723,8 +652,6 @@ xfsm_logout_dialog (const gchar *session_name,
XfsmLogoutDialog *xfsm_dialog;
XfconfChannel *channel = xfsm_open_config ();
gboolean autosave;
- const gchar *text;
- XfsmPassState state;
XfsmShutdown *shutdown;
g_return_val_if_fail (return_type != NULL, FALSE);
@@ -816,80 +743,16 @@ xfsm_logout_dialog (const gchar *session_name,
if (result == GTK_RESPONSE_OK)
{
- /* check if the sudo helper needs a password */
- if (xfsm_shutdown_password_require (xfsm_dialog->shutdown, xfsm_dialog->type_clicked))
- {
- /* switch mode */
- xfsm_logout_dialog_set_mode (xfsm_dialog, MODE_ASK_PASSWORD);
-
- /* don't leave artifacts on the background window */
- xfsm_fadeout_clear (fadeout);
-
- /* loop for sudo password tries */
- for (;;)
- {
- gtk_widget_grab_focus (xfsm_dialog->password_entry);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK);
- result = xfsm_logout_dialog_run (GTK_DIALOG (dialog), !a11y);
-
- if (result == GTK_RESPONSE_OK)
- {
- /* bit of visual feedback we're processing the password */
- gtk_widget_set_sensitive (xfsm_dialog->button_cancel, FALSE);
- gtk_widget_set_sensitive (xfsm_dialog->button_ok, FALSE);
-
- /* update the widgets before we lock the loop */
- while (gtk_events_pending ())
- g_main_context_iteration (NULL, FALSE);
-
- /* send the password to the helper */
- text = gtk_entry_get_text (GTK_ENTRY (xfsm_dialog->password_entry));
- state = xfsm_shutdown_password_send (xfsm_dialog->shutdown, xfsm_dialog->type_clicked, text);
- gtk_entry_set_text (GTK_ENTRY (xfsm_dialog->password_entry), "");
-
- gtk_widget_set_sensitive (xfsm_dialog->button_cancel, TRUE);
- gtk_widget_set_sensitive (xfsm_dialog->button_ok, TRUE);
-
- if (state == PASSWORD_RETRY)
- continue;
-
- if (state == PASSWORD_FAILED)
- {
- gtk_widget_hide (dialog);
-
- xfsm_logout_dialog_set_mode (xfsm_dialog, MODE_SHOW_ERROR);
- gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL);
-
- /* don't leave artifacts on the background window */
- xfsm_fadeout_clear (fadeout);
-
- /* show error */
- xfsm_logout_dialog_run (GTK_DIALOG (dialog), !a11y);
-
- result = GTK_RESPONSE_CANCEL;
- }
- }
-
- /* cancel clicked, succeeded or helper killed */
- break;
- }
-
- gtk_widget_hide (dialog);
- }
+ /* store autosave state */
+ if (autosave)
+ *return_save_session = TRUE;
+ else if (xfsm_dialog->save_session != NULL)
+ *return_save_session = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (xfsm_dialog->save_session));
+ else
+ *return_save_session = FALSE;
- if (result == GTK_RESPONSE_OK)
- {
- /* store autosave state */
- if (autosave)
- *return_save_session = TRUE;
- else if (xfsm_dialog->save_session != NULL)
- *return_save_session = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (xfsm_dialog->save_session));
- else
- *return_save_session = FALSE;
-
- /* return the clicked action */
- *return_type = xfsm_dialog->type_clicked;
- }
+ /* return the clicked action */
+ *return_type = xfsm_dialog->type_clicked;
}
if (fadeout != NULL)
diff --git a/xfce4-session/xfsm-shutdown.c b/xfce4-session/xfsm-shutdown.c
index 329c4f6..e32dedf 100644
--- a/xfce4-session/xfsm-shutdown.c
+++ b/xfce4-session/xfsm-shutdown.c
@@ -51,12 +51,20 @@
#ifdef HAVE_SIGNAL_H
#include <signal.h>
#endif
-
+#ifdef HAVE_SYS_SYSCTL_H
+#include <sys/sysctl.h>
+#endif
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
#include <libxfce4util/libxfce4util.h>
#include <gtk/gtk.h>
+#ifdef HAVE_UPOWER
+#include <upower.h>
+#endif
+#ifdef HAVE_POLKIT
+#include <polkit/polkit.h>
+#endif
#include <libxfsm/xfsm-util.h>
@@ -68,13 +76,24 @@
#include <xfce4-session/xfsm-global.h>
#include <xfce4-session/xfsm-legacy.h>
#include <xfce4-session/xfsm-upower.h>
-
-#ifdef HAVE_SYSTEMD
#include <xfce4-session/xfsm-systemd.h>
-#endif
+
+
+
+#define POLKIT_AUTH_SHUTDOWN_XFSM "org.xfce.session.xfsm-shutdown-helper"
+#define POLKIT_AUTH_RESTART_XFSM "org.xfce.session.xfsm-shutdown-helper"
+#define POLKIT_AUTH_SUSPEND_XFSM "org.xfce.session.xfsm-shutdown-helper"
+#define POLKIT_AUTH_HIBERNATE_XFSM "org.xfce.session.xfsm-shutdown-helper"
+
+
static void xfsm_shutdown_finalize (GObject *object);
-static void xfsm_shutdown_sudo_free (XfsmShutdown *shutdown);
+static gboolean xfsm_shutdown_fallback_auth_shutdown (void);
+static gboolean xfsm_shutdown_fallback_auth_restart (void);
+static gboolean xfsm_shutdown_fallback_can_hibernate (void);
+static gboolean xfsm_shutdown_fallback_can_suspend (void);
+static gboolean xfsm_shutdown_fallback_auth_hibernate (void);
+static gboolean xfsm_shutdown_fallback_auth_suspend (void);
@@ -83,35 +102,18 @@ struct _XfsmShutdownClass
GObjectClass __parent__;
};
-typedef enum
-{
- SUDO_NOT_INITIAZED,
- SUDO_AVAILABLE,
- SUDO_FAILED
-}
-HelperState;
struct _XfsmShutdown
{
GObject __parent__;
-#ifdef HAVE_SYSTEMD
XfsmSystemd *systemd;
-#endif
XfsmConsolekit *consolekit;
XfsmUPower *upower;
/* kiosk settings */
gboolean kiosk_can_shutdown;
gboolean kiosk_can_save_session;
-
- /* sudo helper */
- HelperState helper_state;
- pid_t helper_pid;
- FILE *helper_infile;
- FILE *helper_outfile;
- guint helper_watchid;
- gboolean helper_require_password;
};
@@ -136,18 +138,14 @@ xfsm_shutdown_init (XfsmShutdown *shutdown)
{
XfceKiosk *kiosk;
-#ifdef HAVE_SYSTEMD
shutdown->consolekit = NULL;
shutdown->systemd = NULL;
if (LOGIND_RUNNING())
shutdown->systemd = xfsm_systemd_get ();
else
-#endif
- shutdown->consolekit = xfsm_consolekit_get ();
+ shutdown->consolekit = xfsm_consolekit_get ();
shutdown->upower = xfsm_upower_get ();
- shutdown->helper_state = SUDO_NOT_INITIAZED;
- shutdown->helper_require_password = FALSE;
/* check kiosk */
kiosk = xfce_kiosk_new ("xfce4-session");
@@ -163,392 +161,18 @@ xfsm_shutdown_finalize (GObject *object)
{
XfsmShutdown *shutdown = XFSM_SHUTDOWN (object);
-#ifdef HAVE_SYSTEMD
if (shutdown->systemd != NULL)
g_object_unref (G_OBJECT (shutdown->systemd));
-#endif
+
if (shutdown->consolekit != NULL)
g_object_unref (G_OBJECT (shutdown->consolekit));
g_object_unref (G_OBJECT (shutdown->upower));
- /* close down helper */
- xfsm_shutdown_sudo_free (shutdown);
-
(*G_OBJECT_CLASS (xfsm_shutdown_parent_class)->finalize) (object);
}
-static void
-xfsm_shutdown_sudo_free (XfsmShutdown *shutdown)
-{
- gint status;
-
- /* close down helper */
- if (shutdown->helper_infile != NULL)
- {
- fclose (shutdown->helper_infile);
- shutdown->helper_infile = NULL;
- }
-
- if (shutdown->helper_outfile != NULL)
- {
- fclose (shutdown->helper_outfile);
- shutdown->helper_outfile = NULL;
- }
-
- if (shutdown->helper_watchid > 0)
- {
- g_source_remove (shutdown->helper_watchid);
- shutdown->helper_watchid = 0;
- }
-
- if (shutdown->helper_pid > 0)
- {
- waitpid (shutdown->helper_pid, &status, 0);
- shutdown->helper_pid = 0;
- }
-
- /* reset state */
- shutdown->helper_state = SUDO_NOT_INITIAZED;
-}
-
-
-
-static void
-xfsm_shutdown_sudo_childwatch (GPid pid,
- gint status,
- gpointer data)
-{
- /* close down sudo stuff */
- xfsm_shutdown_sudo_free (XFSM_SHUTDOWN (data));
-}
-
-
-
-static gboolean
-xfsm_shutdown_sudo_init (XfsmShutdown *shutdown,
- GError **error)
-{
- gchar *cmd;
- struct rlimit rlp;
- gchar buf[15];
- gint parent_pipe[2];
- gint child_pipe[2];
- gint n;
-
- /* return state if we succeeded */
- if (shutdown->helper_state != SUDO_NOT_INITIAZED)
- return shutdown->helper_state == SUDO_AVAILABLE;
-
- g_return_val_if_fail (shutdown->helper_infile == NULL, FALSE);
- g_return_val_if_fail (shutdown->helper_outfile == NULL, FALSE);
- g_return_val_if_fail (shutdown->helper_watchid == 0, FALSE);
- g_return_val_if_fail (shutdown->helper_pid == 0, FALSE);
-
- /* assume it won't work for now */
- shutdown->helper_state = SUDO_FAILED;
-
- cmd = g_find_program_in_path ("sudo");
- if (G_UNLIKELY (cmd == NULL))
- {
- g_set_error_literal (error, 1, 0,
- "The program \"sudo\" was not found");
- return FALSE;
- }
-
- if (pipe (parent_pipe) == -1)
- {
- g_set_error (error, 1, 0,
- "Unable to create parent pipe: %s",
- strerror (errno));
- goto err0;
- }
-
- if (pipe (child_pipe) == -1)
- {
- g_set_error (error, 1, 0,
- "Unable to create child pipe: %s",
- strerror (errno));
- goto err1;
- }
-
- shutdown->helper_pid = fork ();
- if (shutdown->helper_pid < 0)
- {
- g_set_error (error, 1, 0,
- "Unable to fork sudo helper: %s",
- strerror (errno));
- goto err2;
- }
- else if (shutdown->helper_pid == 0)
- {
- /* setup signals */
- signal (SIGPIPE, SIG_IGN);
-
- /* setup environment */
- g_setenv ("LC_ALL", "C", TRUE);
- g_setenv ("LANG", "C", TRUE);
- g_setenv ("LANGUAGE", "C", TRUE);
-
- /* setup the 3 standard file handles */
- dup2 (child_pipe[0], STDIN_FILENO);
- dup2 (parent_pipe[1], STDOUT_FILENO);
- dup2 (parent_pipe[1], STDERR_FILENO);
-
- /* close all other file handles */
- getrlimit (RLIMIT_NOFILE, &rlp);
- for (n = 0; n < (gint) rlp.rlim_cur; ++n)
- {
- if (n != STDIN_FILENO && n != STDOUT_FILENO && n != STDERR_FILENO)
- close (n);
- }
-
- /* execute sudo with the helper */
- execl (cmd, "sudo", "-H", "-S", "-p",
- "XFSM_SUDO_PASS ", "--",
- XFSM_SHUTDOWN_HELPER_CMD, NULL);
-
- g_free (cmd);
- cmd = NULL;
-
- _exit (127);
- }
- else
- {
- /* watch the sudo helper */
- shutdown->helper_watchid = g_child_watch_add (shutdown->helper_pid,
- xfsm_shutdown_sudo_childwatch,
- shutdown);
- }
-
- /* read sudo/helper answer */
- n = read (parent_pipe[0], buf, sizeof (buf));
- if (n < 15)
- {
- g_set_error (error, 1, 0,
- "Unable to read response from sudo helper: %s",
- n < 0 ? strerror (errno) : "Unknown error");
- goto err2;
- }
-
- /* open pipe to receive replies from sudo */
- shutdown->helper_infile = fdopen (parent_pipe[0], "r");
- if (shutdown->helper_infile == NULL)
- {
- g_set_error (error, 1, 0,
- "Unable to open parent pipe: %s",
- strerror (errno));
- goto err2;
- }
- close (parent_pipe[1]);
-
- /* open pipe to send passwords to sudo */
- shutdown->helper_outfile = fdopen (child_pipe[1], "w");
- if (shutdown->helper_outfile == NULL)
- {
- g_set_error (error, 1, 0,
- "Unable to open parent pipe: %s",
- strerror (errno));
- goto err2;
- }
- close (child_pipe[0]);
-
- /* check if NOPASSWD is set in /etc/sudoers */
- if (memcmp (buf, "XFSM_SUDO_PASS ", 15) == 0)
- {
- shutdown->helper_require_password = TRUE;
- }
- else if (memcmp (buf, "XFSM_SUDO_DONE ", 15) == 0)
- {
- shutdown->helper_require_password = FALSE;
- }
- else
- {
- g_set_error (error, 1, 0,
- "Got unexpected reply from sudo shutdown helper");
- goto err2;
- }
-
- /* if we try again */
- shutdown->helper_state = SUDO_AVAILABLE;
-
- return TRUE;
-
-err2:
- xfsm_shutdown_sudo_free (shutdown);
-
- close (child_pipe[0]);
- close (child_pipe[1]);
-
-err1:
- close (parent_pipe[0]);
- close (parent_pipe[1]);
-
-err0:
- g_free (cmd);
-
- shutdown->helper_pid = 0;
-
- return FALSE;
-}
-
-
-
-static gboolean
-xfsm_shutdown_sudo_try_action (XfsmShutdown *shutdown,
- XfsmShutdownType type,
- GError **error)
-{
- const gchar *action;
- gchar reply[256];
-
- g_return_val_if_fail (shutdown->helper_state == SUDO_AVAILABLE, FALSE);
- g_return_val_if_fail (shutdown->helper_outfile != NULL, FALSE);
- g_return_val_if_fail (shutdown->helper_infile != NULL, FALSE);
- g_return_val_if_fail (type == XFSM_SHUTDOWN_SHUTDOWN
- || type == XFSM_SHUTDOWN_RESTART, FALSE);
-
- /* the command we send to sudo */
- if (type == XFSM_SHUTDOWN_SHUTDOWN)
- action = "POWEROFF";
- else if (type == XFSM_SHUTDOWN_RESTART)
- action = "REBOOT";
- else
- return FALSE;
-
- /* write action to sudo helper */
- if (fprintf (shutdown->helper_outfile, "%s\n", action) > 0)
- fflush (shutdown->helper_outfile);
-
- /* check if the write succeeded */
- if (ferror (shutdown->helper_outfile) != 0)
- {
- /* probably succeeded but the helper got killed */
- if (errno == EINTR)
- return TRUE;
-
- g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
- _("Error sending command to shutdown helper: %s"),
- strerror (errno));
- return FALSE;
- }
-
- /* get responce from sudo helper */
- if (fgets (reply, sizeof (reply), shutdown->helper_infile) == NULL)
- {
- /* probably succeeded but the helper got killed */
- if (errno == EINTR)
- return TRUE;
-
- g_set_error (error, G_FILE_ERROR, g_file_error_from_errno (errno),
- _("Error receiving response from shutdown helper: %s"),
- strerror (errno));
- return FALSE;
- }
-
- if (strncmp (reply, "SUCCEED", 7) != 0)
- {
- g_set_error (error, G_FILE_ERROR, G_FILE_ERROR_FAILED,
- _("Shutdown command failed"));
-
- return FALSE;
- }
-
- return TRUE;
-}
-
-
-
-static XfsmPassState
-xfsm_shutdown_sudo_send_password (XfsmShutdown *shutdown,
- const gchar *password)
-{
- gchar buf[1024];
- gsize len_buf, len_send;
- gint fd;
- gsize len;
- gssize result;
- gint attempts;
- const gchar *errmsg = NULL;
-
- g_return_val_if_fail (shutdown->helper_state == SUDO_AVAILABLE, PASSWORD_FAILED);
- g_return_val_if_fail (shutdown->helper_outfile != NULL, PASSWORD_FAILED);
- g_return_val_if_fail (shutdown->helper_infile != NULL, PASSWORD_FAILED);
- g_return_val_if_fail (shutdown->helper_require_password, PASSWORD_FAILED);
- g_return_val_if_fail (password != NULL, PASSWORD_FAILED);
-
- /* write password to sudo helper */
- g_snprintf (buf, sizeof (buf), "%s\n", password);
- len_buf = strlen (buf);
- len_send = fwrite (buf, 1, len_buf, shutdown->helper_outfile);
- fflush (shutdown->helper_outfile);
- bzero (buf, len_buf);
-
- if (len_send != len_buf
- || ferror (shutdown->helper_outfile) != 0)
- {
- errmsg = "Failed to send password to sudo";
- goto err1;
- }
-
- fd = fileno (shutdown->helper_infile);
-
- for (len = 0, attempts = 0;;)
- {
- result = read (fd, buf + len, 256 - len);
-
- if (result < 0)
- {
- errmsg = "Failed to read data from sudo";
- goto err1;
- }
- else if (result == 0)
- {
- /* don't try too often */
- if (++attempts > 20)
- {
- errmsg = "Too many password attempts";
- goto err1;
- }
-
- continue;
- }
- else if (result + len >= sizeof (buf))
- {
- errmsg = "Received too much data from sudo";
- goto err1;
- }
-
- len += result;
- buf[len] = '\0';
-
- if (len >= 15)
- {
- if (g_str_has_suffix (buf, "XFSM_SUDO_PASS "))
- {
- return PASSWORD_RETRY;
- }
- else if (g_str_has_suffix (buf, "XFSM_SUDO_DONE "))
- {
- /* sudo is unlocked, no further passwords required */
- shutdown->helper_require_password = FALSE;
-
- return PASSWORD_SUCCEED;
- }
- }
- }
-
- return PASSWORD_FAILED;
-
- err1:
-
- g_printerr (PACKAGE_NAME ": %s.\n\n", errmsg);
- return PASSWORD_FAILED;
-}
-
-
-
static gboolean
xfsm_shutdown_kiosk_can_shutdown (XfsmShutdown *shutdown,
GError **error)
@@ -585,38 +209,6 @@ xfsm_shutdown_get (void)
gboolean
-xfsm_shutdown_password_require (XfsmShutdown *shutdown,
- XfsmShutdownType type)
-{
- g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
-
- /* the helper only handled shutdown and restart */
- if (type == XFSM_SHUTDOWN_SHUTDOWN || type == XFSM_SHUTDOWN_RESTART)
- return shutdown->helper_require_password;
-
- return FALSE;
-}
-
-
-
-XfsmPassState
-xfsm_shutdown_password_send (XfsmShutdown *shutdown,
- XfsmShutdownType type,
- const gchar *password)
-{
- g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), PASSWORD_FAILED);
- g_return_val_if_fail (password != NULL, PASSWORD_FAILED);
-
- if ((type == XFSM_SHUTDOWN_SHUTDOWN || type == XFSM_SHUTDOWN_RESTART)
- && shutdown->helper_state == SUDO_AVAILABLE)
- return xfsm_shutdown_sudo_send_password (shutdown, password);
-
- return PASSWORD_FAILED;
-}
-
-
-
-gboolean
xfsm_shutdown_try_type (XfsmShutdown *shutdown,
XfsmShutdownType type,
GError **error)
@@ -647,6 +239,36 @@ xfsm_shutdown_try_type (XfsmShutdown *shutdown,
+static gboolean
+xfsm_shutdown_fallback_try_action (XfsmShutdown *shutdown,
+ XfsmShutdownType type,
+ GError **error)
+{
+ const gchar *action;
+ gboolean ret;
+ gint exit_status = 0;
+ gchar *command = NULL;
+
+ if (type == XFSM_SHUTDOWN_SHUTDOWN)
+ action = "shutdown";
+ if (type == XFSM_SHUTDOWN_RESTART)
+ action = "restart";
+ else if (type == XFSM_SHUTDOWN_SUSPEND)
+ action = "suspend";
+ else if (type == XFSM_SHUTDOWN_HIBERNATE)
+ action = "hibernate";
+ else
+ return FALSE;
+
+ command = g_strdup_printf ("pkexec " XFSM_SHUTDOWN_HELPER_CMD " --%s", action);
+ ret = g_spawn_command_line_sync (command, NULL, NULL, &exit_status, error);
+
+ g_free (command);
+ return ret;
+}
+
+
+
gboolean
xfsm_shutdown_try_restart (XfsmShutdown *shutdown,
GError **error)
@@ -656,15 +278,13 @@ xfsm_shutdown_try_restart (XfsmShutdown *shutdown,
if (!xfsm_shutdown_kiosk_can_shutdown (shutdown, error))
return FALSE;
- if (shutdown->helper_state == SUDO_AVAILABLE)
- return xfsm_shutdown_sudo_try_action (shutdown, XFSM_SHUTDOWN_RESTART, error);
- else
-#ifdef HAVE_SYSTEMD
- if (shutdown->systemd != NULL)
- return xfsm_systemd_try_restart (shutdown->systemd, error);
- else
-#endif
+ if (shutdown->systemd != NULL)
+ return xfsm_systemd_try_restart (shutdown->systemd, error);
+
+ if (shutdown->consolekit != NULL)
return xfsm_consolekit_try_restart (shutdown->consolekit, error);
+
+ return xfsm_shutdown_fallback_try_action (shutdown, XFSM_SHUTDOWN_RESTART, error);
}
@@ -678,15 +298,13 @@ xfsm_shutdown_try_shutdown (XfsmShutdown *shutdown,
if (!xfsm_shutdown_kiosk_can_shutdown (shutdown, error))
return FALSE;
- if (shutdown->helper_state == SUDO_AVAILABLE)
- return xfsm_shutdown_sudo_try_action (shutdown, XFSM_SHUTDOWN_SHUTDOWN, error);
- else
-#ifdef HAVE_SYSTEMD
- if (shutdown->systemd != NULL)
- return xfsm_systemd_try_shutdown (shutdown->systemd, error);
- else
-#endif
+ if (shutdown->systemd != NULL)
+ return xfsm_systemd_try_shutdown (shutdown->systemd, error);
+
+ if (shutdown->consolekit != NULL)
return xfsm_consolekit_try_shutdown (shutdown->consolekit, error);
+
+ return xfsm_shutdown_fallback_try_action (shutdown, XFSM_SHUTDOWN_SHUTDOWN, error);
}
@@ -697,12 +315,18 @@ xfsm_shutdown_try_suspend (XfsmShutdown *shutdown,
{
g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
-#ifdef HAVE_SYSTEMD
if (shutdown->systemd != NULL)
return xfsm_systemd_try_suspend (shutdown->systemd, error);
- else
-#endif
- return xfsm_upower_try_suspend (shutdown->upower, error);
+
+#ifdef HAVE_UPOWER
+#if !UP_CHECK_VERSION(0, 99, 0)
+ if (shutdown->upower != NULL)
+ return xfsm_upower_try_suspend (shutdown->upower, error);
+#endif /* UP_CHECK_VERSION */
+#endif /* HAVE_UPOWER */
+
+ xfsm_upower_lock_screen (shutdown->upower, "Suspend", error);
+ return xfsm_shutdown_fallback_try_action (shutdown, XFSM_SHUTDOWN_SUSPEND, error);
}
@@ -713,12 +337,18 @@ xfsm_shutdown_try_hibernate (XfsmShutdown *shutdown,
{
g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
-#ifdef HAVE_SYSTEMD
if (shutdown->systemd != NULL)
return xfsm_systemd_try_hibernate (shutdown->systemd, error);
- else
-#endif
- return xfsm_upower_try_hibernate (shutdown->upower, error);
+
+#ifdef HAVE_UPOWER
+#if !UP_CHECK_VERSION(0, 99, 0)
+ if (shutdown->upower != NULL)
+ return xfsm_upower_try_hibernate (shutdown->upower, error);
+#endif /* UP_CHECK_VERSION */
+#endif /* HAVE_UPOWER */
+
+ xfsm_upower_lock_screen (shutdown->upower, "Hibernate", error);
+ return xfsm_shutdown_fallback_try_action (shutdown, XFSM_SHUTDOWN_HIBERNATE, error);
}
@@ -736,24 +366,19 @@ xfsm_shutdown_can_restart (XfsmShutdown *shutdown,
return TRUE;
}
-#ifdef HAVE_SYSTEMD
if (shutdown->systemd != NULL)
{
if (xfsm_systemd_can_restart (shutdown->systemd, can_restart, error))
return TRUE;
}
- else
-#endif
- if (xfsm_consolekit_can_restart (shutdown->consolekit, can_restart, error))
- return TRUE;
-
- if (xfsm_shutdown_sudo_init (shutdown, error))
+ else if (shutdown->consolekit != NULL)
{
- *can_restart = TRUE;
- return TRUE;
+ if (xfsm_consolekit_can_restart (shutdown->consolekit, can_restart, error))
+ return TRUE;
}
- return FALSE;
+ *can_restart = xfsm_shutdown_fallback_auth_restart ();
+ return TRUE;
}
@@ -771,24 +396,20 @@ xfsm_shutdown_can_shutdown (XfsmShutdown *shutdown,
return TRUE;
}
-#ifdef HAVE_SYSTEMD
if (shutdown->systemd != NULL)
{
if (xfsm_systemd_can_shutdown (shutdown->systemd, can_shutdown, error))
return TRUE;
}
- else
-#endif
- if (xfsm_consolekit_can_shutdown (shutdown->consolekit, can_shutdown, error))
- return TRUE;
- if (xfsm_shutdown_sudo_init (shutdown, error))
+ if (shutdown->consolekit != NULL)
{
- *can_shutdown = TRUE;
- return TRUE;
+ if (xfsm_consolekit_can_shutdown (shutdown->consolekit, can_shutdown, error))
+ return TRUE;
}
- return FALSE;
+ *can_shutdown = xfsm_shutdown_fallback_auth_shutdown ();
+ return TRUE;
}
@@ -807,14 +428,21 @@ xfsm_shutdown_can_suspend (XfsmShutdown *shutdown,
return TRUE;
}
-#ifdef HAVE_SYSTEMD
if (shutdown->systemd != NULL)
return xfsm_systemd_can_suspend (shutdown->systemd, can_suspend,
auth_suspend, error);
- else
-#endif
- return xfsm_upower_can_suspend (shutdown->upower, can_suspend,
- auth_suspend, error);
+
+#ifdef HAVE_UPOWER
+#if !UP_CHECK_VERSION(0, 99, 0)
+ if (shutdown->upower)
+ return xfsm_upower_can_suspend (shutdown->upower, can_suspend,
+ auth_suspend, error);
+#endif /* UP_CHECK_VERSION */
+#endif /* HAVE_UPOWER */
+
+ *can_suspend = xfsm_shutdown_fallback_can_suspend ();
+ *auth_suspend = xfsm_shutdown_fallback_auth_suspend ();
+ return TRUE;
}
@@ -833,14 +461,21 @@ xfsm_shutdown_can_hibernate (XfsmShutdown *shutdown,
return TRUE;
}
-#ifdef HAVE_SYSTEMD
if (shutdown->systemd != NULL)
return xfsm_systemd_can_hibernate (shutdown->systemd, can_hibernate,
auth_hibernate, error);
- else
-#endif
- return xfsm_upower_can_hibernate (shutdown->upower, can_hibernate,
- auth_hibernate, error);
+
+#ifdef HAVE_UPOWER
+#if !UP_CHECK_VERSION(0, 99, 0)
+ if (shutdown->upower != NULL)
+ return xfsm_upower_can_hibernate (shutdown->upower, can_hibernate,
+ auth_hibernate, error);
+#endif /* UP_CHECK_VERSION */
+#endif /* HAVE_UPOWER */
+
+ *can_hibernate = xfsm_shutdown_fallback_can_hibernate ();
+ *auth_hibernate = xfsm_shutdown_fallback_auth_hibernate ();
+ return TRUE;
}
@@ -851,3 +486,194 @@ xfsm_shutdown_can_save_session (XfsmShutdown *shutdown)
g_return_val_if_fail (XFSM_IS_SHUTDOWN (shutdown), FALSE);
return shutdown->kiosk_can_save_session;
}
+
+
+
+#ifdef BACKEND_TYPE_FREEBSD
+static gchar *
+get_string_sysctl (GError **err, const gchar *format, ...)
+{
+ va_list args;
+ gchar *name;
+ size_t value_len;
+ gchar *str = NULL;
+
+ g_return_val_if_fail(format != NULL, FALSE);
+
+ va_start (args, format);
+ name = g_strdup_vprintf (format, args);
+ va_end (args);
+
+ if (sysctlbyname (name, NULL, &value_len, NULL, 0) == 0) {
+ str = g_new (char, value_len + 1);
+ if (sysctlbyname (name, str, &value_len, NULL, 0) == 0)
+ str[value_len] = 0;
+ else {
+ g_free (str);
+ str = NULL;
+ }
+ }
+
+ if (!str)
+ g_set_error (err, 0, 0, "%s", g_strerror(errno));
+
+ g_free(name);
+ return str;
+}
+
+
+
+static gboolean
+freebsd_supports_sleep_state (const gchar *state)
+{
+ gboolean ret = FALSE;
+ gchar *sleep_states;
+
+ sleep_states = get_string_sysctl (NULL, "hw.acpi.supported_sleep_state");
+ if (sleep_states != NULL)
+ {
+ if (strstr (sleep_states, state) != NULL)
+ ret = TRUE;
+ }
+
+ g_free (sleep_states);
+
+ return ret;
+}
+#endif /* BACKEND_TYPE_FREEBSD */
+
+
+
+#ifdef BACKEND_TYPE_LINUX
+static gboolean
+linux_supports_sleep_state (const gchar *state)
+{
+ gboolean ret = FALSE;
+ gchar *command;
+ GError *error = NULL;
+ gint exit_status;
+
+ /* run script from pm-utils */
+ command = g_strdup_printf ("/usr/bin/pm-is-supported --%s", state);
+
+ ret = g_spawn_command_line_sync (command, NULL, NULL, &exit_status, &error);
+ if (!ret)
+ {
+ g_warning ("failed to run script: %s", error->message);
+ g_error_free (error);
+ goto out;
+ }
+ ret = (WIFEXITED(exit_status) && (WEXITSTATUS(exit_status) == EXIT_SUCCESS));
+
+out:
+ g_free (command);
+
+ return ret;
+}
+#endif /* BACKEND_TYPE_LINUX */
+
+
+
+static gboolean
+xfsm_shutdown_fallback_can_suspend (void)
+{
+#ifdef BACKEND_TYPE_FREEBSD
+ return freebsd_supports_sleep_state ("S3");
+#endif
+#ifdef BACKEND_TYPE_LINUX
+ return linux_supports_sleep_state ("suspend");
+#endif
+#ifdef BACKEND_TYPE_OPENBSD
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
+
+
+static gboolean
+xfsm_shutdown_fallback_can_hibernate (void)
+{
+#ifdef BACKEND_TYPE_FREEBSD
+ return freebsd_supports_sleep_state ("S4");
+#endif
+#ifdef BACKEND_TYPE_LINUX
+ return linux_supports_sleep_state ("hibernate");
+#endif
+#ifdef BACKEND_TYPE_OPENBSD
+ return TRUE;
+#endif
+
+ return FALSE;
+}
+
+
+
+static gboolean
+xfsm_shutdown_fallback_check_auth (const gchar *action_id)
+{
+ gboolean auth_result = FALSE;
+#ifdef HAVE_POLKIT
+ GDBusConnection *bus;
+ PolkitAuthority *polkit;
+ PolkitAuthorizationResult *polkit_result;
+ PolkitSubject *polkit_subject;
+
+ bus = g_bus_get_sync (G_BUS_TYPE_SYSTEM, NULL, NULL);
+ polkit = polkit_authority_get_sync (NULL, NULL);
+ if (polkit != NULL && bus != NULL)
+ {
+ polkit_subject = polkit_system_bus_name_new (g_dbus_connection_get_unique_name (bus));
+ polkit_result = polkit_authority_check_authorization_sync (polkit,
+ polkit_subject,
+ action_id,
+ NULL,
+ POLKIT_CHECK_AUTHORIZATION_FLAGS_NONE,
+ NULL,
+ NULL);
+ if (polkit_result != NULL)
+ {
+ auth_result = polkit_authorization_result_get_is_authorized (polkit_result);
+ g_object_unref (polkit_result);
+ }
+
+ g_object_unref (polkit);
+ g_object_unref (bus);
+ }
+#endif /* HAVE_POLKIT */
+
+ return auth_result;
+}
+
+
+
+static gboolean
+xfsm_shutdown_fallback_auth_shutdown (void)
+{
+ return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_SHUTDOWN_XFSM);
+}
+
+
+
+static gboolean
+xfsm_shutdown_fallback_auth_restart (void)
+{
+ return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_RESTART_XFSM);
+}
+
+
+
+static gboolean
+xfsm_shutdown_fallback_auth_suspend (void)
+{
+ return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_SUSPEND_XFSM);
+}
+
+
+
+static gboolean
+xfsm_shutdown_fallback_auth_hibernate (void)
+{
+ return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_HIBERNATE_XFSM);
+}
diff --git a/xfce4-session/xfsm-upower.c b/xfce4-session/xfsm-upower.c
index 57402ec..050872a 100644
--- a/xfce4-session/xfsm-upower.c
+++ b/xfce4-session/xfsm-upower.c
@@ -21,6 +21,9 @@
#include <dbus/dbus-glib.h>
#include <dbus/dbus-glib-lowlevel.h>
+#ifdef HAVE_UPOWER
+#include <upower.h>
+#endif /* HAVE_UPOWER */
#include <libxfsm/xfsm-util.h>
#include <xfce4-session/xfsm-upower.h>
@@ -283,14 +286,13 @@ xfsm_upower_try_method (XfsmUPower *upower,
-static gboolean
+gboolean
xfsm_upower_lock_screen (XfsmUPower *upower,
const gchar *sleep_kind,
GError **error)
{
XfconfChannel *channel;
gboolean ret = TRUE;
- GError *err = NULL;
g_return_val_if_fail (sleep_kind != NULL, FALSE);
@@ -299,6 +301,10 @@ xfsm_upower_lock_screen (XfsmUPower *upower,
{
if (xfsm_upower_proxy_ensure (upower, error))
{
+#ifdef HAVE_UPOWER
+#if !UP_CHECK_VERSION(0, 99, 0)
+ GError *err = NULL;
+
/* tell upower we're going to sleep, this saves some
* time while we sleep 1 second if xflock4 is spawned */
ret = dbus_g_proxy_call (upower->upower_proxy,
@@ -312,6 +318,8 @@ xfsm_upower_lock_screen (XfsmUPower *upower,
g_warning ("Couldn't sent that we were about to sleep: %s", err->message);
g_error_free (err);
}
+#endif /* UP_CHECK_VERSION */
+#endif /* HAVE_UPOWER */
}
else
{
diff --git a/xfce4-session/xfsm-upower.h b/xfce4-session/xfsm-upower.h
index a492f7d..4e6a53b 100644
--- a/xfce4-session/xfsm-upower.h
+++ b/xfce4-session/xfsm-upower.h
@@ -51,4 +51,8 @@ gboolean xfsm_upower_can_hibernate (XfsmUPower *upower,
gboolean *auth_hibernate,
GError **error);
+gboolean xfsm_upower_lock_screen (XfsmUPower *upower,
+ const gchar *sleep_kind,
+ GError **error);
+
#endif /* !__XFSM_UPOWER_HELPER_H__ */
diff --git a/xfsm-shutdown-helper/main.c b/xfsm-shutdown-helper/main.c
index 667f288..2c9bb1a 100644
--- a/xfsm-shutdown-helper/main.c
+++ b/xfsm-shutdown-helper/main.c
@@ -51,12 +51,23 @@
#include <glib.h>
/* XXX */
+#define EXIT_CODE_SUCCESS 0
+#define EXIT_CODE_FAILED 1
+#define EXIT_CODE_ARGUMENTS_INVALID 3
+#define EXIT_CODE_INVALID_USER 4
+
#ifdef POWEROFF_CMD
#undef POWEROFF_CMD
#endif
#ifdef REBOOT_CMD
#undef REBOOT_CMD
#endif
+#ifdef UP_BACKEND_SUSPEND_COMMAND
+#undef UP_BACKEND_SUSPEND_COMMAND
+#endif
+#ifdef UP_BACKEND_HIBERNATE_COMMAND
+#undef UP_BACKEND_HIBERNATE_COMMAND
+#endif
#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
#define POWEROFF_CMD "/sbin/shutdown -p now"
@@ -68,6 +79,18 @@
#define POWEROFF_CMD "/sbin/shutdown -h now"
#define REBOOT_CMD "/sbin/shutdown -r now"
#endif
+#ifdef BACKEND_TYPE_FREEBSD
+#define UP_BACKEND_SUSPEND_COMMAND "/usr/sbin/acpiconf -s 3"
+#define UP_BACKEND_HIBERNATE_COMMAND "/usr/sbin/acpiconf -s 4"
+#endif
+#if BACKEND_TYPE_LINUX
+#define UP_BACKEND_SUSPEND_COMMAND "/usr/sbin/pm-suspend"
+#define UP_BACKEND_HIBERNATE_COMMAND "/usr/sbin/pm-hibernate"
+#endif
+#ifdef BACKEND_TYPE_OPENBSD
+#define UP_BACKEND_SUSPEND_COMMAND "/usr/sbin/zzz"
+#define UP_BACKEND_HIBERNATE_COMMAND "/usr/sbin/ZZZ"
+#endif
static gboolean
@@ -122,36 +145,101 @@ run (const gchar *command)
int
main (int argc, char **argv)
{
- gboolean succeed = FALSE;
- char action[1024];
+ GOptionContext *context;
+ gint uid;
+ gint euid;
+ const gchar *pkexec_uid_str;
+ gboolean shutdown = FALSE;
+ gboolean restart = FALSE;
+ gboolean suspend = FALSE;
+ gboolean hibernate = FALSE;
+
+ const GOptionEntry options[] = {
+ { "shutdown", '\0', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &shutdown, "Shutdown the system", NULL },
+ { "restart", '\0', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &restart, "Restart the system", NULL },
+ { "suspend", '\0', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &suspend, "Suspend the system", NULL },
+ { "hibernate", '\0', G_OPTION_FLAG_IN_MAIN, G_OPTION_ARG_NONE, &hibernate, "Hibernate the system", NULL },
+ { NULL }
+ };
+
+ context = g_option_context_new (NULL);
+ g_option_context_set_summary (context, "XFCE Session Helper");
+ g_option_context_add_main_entries (context, options, NULL);
+ g_option_context_parse (context, &argc, &argv, NULL);
+ g_option_context_free (context);
+
+ /* no input */
+ if (!shutdown && !restart && !suspend && !hibernate)
+ {
+ puts ("No valid option was specified");
+ return EXIT_CODE_ARGUMENTS_INVALID;
+ }
- /* display banner */
- fprintf (stdout, "XFSM_SUDO_DONE ");
- fflush (stdout);
+ /* get calling process */
+ uid = getuid ();
+ euid = geteuid ();
+ if (uid != 0 || euid != 0)
+ {
+ puts ("This program can only be used by the root user");
+ return EXIT_CODE_ARGUMENTS_INVALID;
+ }
- if (fgets (action, 1024, stdin) == NULL)
+ /* check we're not being spoofed */
+ pkexec_uid_str = g_getenv ("PKEXEC_UID");
+ if (pkexec_uid_str == NULL)
{
- fprintf (stdout, "FAILED\n");
- return EXIT_FAILURE;
+ puts ("This program must only be run through pkexec");
+ return EXIT_CODE_INVALID_USER;
}
- if (strncasecmp (action, "POWEROFF", 8) == 0)
+ /* run the command */
+ if(shutdown)
{
- succeed = run (POWEROFF_CMD);
+ if (run (POWEROFF_CMD))
+ {
+ return EXIT_CODE_SUCCESS;
+ }
+ else
+ {
+ return EXIT_CODE_FAILED;
+ }
}
- else if (strncasecmp (action, "REBOOT", 6) == 0)
+ else if(restart)
{
- succeed = run (REBOOT_CMD);
+ if (run (REBOOT_CMD))
+ {
+ return EXIT_CODE_SUCCESS;
+ }
+ else
+ {
+ return EXIT_CODE_FAILED;
+ }
}
-
- if (succeed)
+ else if(suspend)
+ {
+ if (run (UP_BACKEND_SUSPEND_COMMAND))
+ {
+ return EXIT_CODE_SUCCESS;
+ }
+ else
+ {
+ return EXIT_CODE_FAILED;
+ }
+ }
+ else if(hibernate)
{
- fprintf (stdout, "SUCCEED\n");
- return EXIT_SUCCESS;
+ if (run (UP_BACKEND_HIBERNATE_COMMAND))
+ {
+ return EXIT_CODE_SUCCESS;
+ }
+ else
+ {
+ return EXIT_CODE_FAILED;
+ }
}
- fprintf (stdout, "FAILED\n");
- return EXIT_FAILURE;
+ /* how did we get here? */
+ return EXIT_CODE_FAILED;
}
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the Xfce4-commits
mailing list