[Xfce4-commits] [xfce/xfce4-session] 01/03: Added better shutdown fallback support for the BSDs (Bug #14722)
noreply at xfce.org
noreply at xfce.org
Thu May 2 19:50:36 CEST 2019
This is an automated email from the git hooks/post-receive script.
l a n d r y p u s h e d a c o m m i t t o b r a n c h m a s t e r
in repository xfce/xfce4-session.
commit 1d56462b83cf320dff96d5b9ac3a767b019a0dd4
Author: Ali Abdallah <ali at xfce.org>
Date: Mon Sep 24 09:47:55 2018 +0200
Added better shutdown fallback support for the BSDs (Bug #14722)
On the BSDs, users of group operator can shutdown/reboot the machine.
We added some code on the fallback support in case consolekit is not
running.
Also, users with write access to /var/run/apmdev on OpenBSD and to
/dev/acpi on the other BSDs can suspend and hibernate the machine.
So we also support this on the fallback code.
---
libxfsm/Makefile.am | 3 +-
libxfsm/xfsm-shutdown-common.h | 73 +++++++++++++
xfce4-session/xfsm-shutdown-fallback.c | 192 ++++++++++++++++++++++++++++++---
xfsm-shutdown-helper/main.c | 38 +------
4 files changed, 254 insertions(+), 52 deletions(-)
diff --git a/libxfsm/Makefile.am b/libxfsm/Makefile.am
index 538ab84..1b61dca 100644
--- a/libxfsm/Makefile.am
+++ b/libxfsm/Makefile.am
@@ -6,7 +6,8 @@ lib_LTLIBRARIES = libxfsm-4.6.la
libxfsm_4_6_la_SOURCES = \
xfsm-util.h \
- xfsm-util.c
+ xfsm-util.c \
+ xfsm-shutdown-common.h
libxfsm_4_6_la_CFLAGS = \
$(LIBX11_CFLAGS) \
diff --git a/libxfsm/xfsm-shutdown-common.h b/libxfsm/xfsm-shutdown-common.h
new file mode 100644
index 0000000..3b9fbd0
--- /dev/null
+++ b/libxfsm/xfsm-shutdown-common.h
@@ -0,0 +1,73 @@
+/*-
+ * Copyright (c) 2018 Ali Abdallah <ali at xfce.org>
+ * All rights reserved.
+ *
+ * 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, 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 Street, Fifth Floor, Boston,
+ * MA 02110-1301 USA.
+ */
+#ifndef __XFSM_SHUTDOWN_COMMON_H_
+#define __XFSM_SHUTDOWN_COMMON_H_
+
+#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
+
+/* On FreeBSD, NetBSD and DragonFly BSD users with write access to
+ * /dev/acpi can suspend/hibernate the system */
+#define BSD_SLEEP_ACCESS_NODE "/dev/acpi"
+
+/* On OpenBSD this is done via apmd, so we check /var/run/apmdev to see
+ * zzz and ZZZ commands can write to it*/
+#ifdef BACKEND_TYPE_OPENBSD
+#undef BSD_SLEEP_ACCESS_NODE
+#define BSD_SLEEP_ACCESS_NODE "/var/run/apmdev"
+#endif
+
+#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#define POWEROFF_CMD "/sbin/shutdown -p now"
+#define REBOOT_CMD "/sbin/shutdown -r now"
+#elif defined(sun) || defined(__sun)
+#define POWEROFF_CMD "/usr/sbin/shutdown -i 5 -g 0 -y"
+#define REBOOT_CMD "/usr/sbin/shutdown -i 6 -g 0 -y"
+#else
+#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
+
+#ifdef 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
+
+#endif /* __XFSM_SHUTDOWN_COMMON_H_ */
diff --git a/xfce4-session/xfsm-shutdown-fallback.c b/xfce4-session/xfsm-shutdown-fallback.c
index 1903161..28df8f8 100644
--- a/xfce4-session/xfsm-shutdown-fallback.c
+++ b/xfce4-session/xfsm-shutdown-fallback.c
@@ -2,6 +2,7 @@
* Copyright (c) 2003-2004 Benedikt Meurer <benny at xfce.org>
* Copyright (c) 2011 Nick Schermer <nick at xfce.org>
* Copyright (c) 2014 Xfce Development Team <xfce4-dev at xfce.org>
+ * Copyright (c) 2018 Ali Abdallah <ali at xfce.org>
* All rights reserved.
*
* This program is free software; you can redistribute it and/or modify
@@ -59,14 +60,25 @@
#include <gio/gio.h>
#include <libxfce4util/libxfce4util.h>
#include <gtk/gtk.h>
+#include <glib/gstdio.h>
+
#ifdef HAVE_POLKIT
#include <polkit/polkit.h>
#endif
+#include <pwd.h>
+#include <grp.h>
+
+#define MAX_USER_GROUPS 100
+
#include <libxfsm/xfsm-util.h>
+#include <libxfsm/xfsm-shutdown-common.h>
#include <xfce4-session/xfsm-shutdown-fallback.h>
#include <xfce4-session/xfce-screensaver.h>
+#if defined(__DragonFly__) || defined(__FreeBSD__) || defined(__NetBSD__) || defined(__OpenBSD__)
+#define __BACKEND_TYPE_BSD__ 1
+#endif
#define POLKIT_AUTH_SHUTDOWN_XFSM "org.xfce.session.xfsm-shutdown-helper"
#define POLKIT_AUTH_RESTART_XFSM "org.xfce.session.xfsm-shutdown-helper"
@@ -117,6 +129,12 @@ freebsd_supports_sleep_state (const gchar *state)
gboolean ret = FALSE;
gchar *sleep_states;
+#if defined(__FreeBSD__)
+ gboolean status;
+ gint v;
+ size_t value_len = sizeof(int);
+#endif
+
sleep_states = get_string_sysctl (NULL, "hw.acpi.supported_sleep_state");
if (sleep_states != NULL)
{
@@ -124,6 +142,27 @@ freebsd_supports_sleep_state (const gchar *state)
ret = TRUE;
}
+#if defined(__FreeBSD__)
+ /* On FreeBSD, S4 is not supported unless S4BIOS is available.
+ * If S4 will ever be implemented on FreeBSD, we can disable S4bios
+ * check below, using #if __FreeBSD_version >= XXXXXX.
+ **/
+ if (g_strcmp0(state, "S4") == 0)
+ {
+ status = sysctlbyname ("hw.acpi.s4bios", &v, &value_len, NULL, 0) == 0;
+ if (G_UNLIKELY(!status))
+ {
+ g_warning ("sysctl failed on 'hw.acpi.s4bios'");
+ }
+ else
+ {
+ /* No S4Bios support */
+ if (v == 0)
+ ret = FALSE;
+ }
+ }
+#endif /* __FreeBSD__ */
+
g_free (sleep_states);
return ret;
@@ -162,8 +201,86 @@ out:
+#ifdef __BACKEND_TYPE_BSD__
+static gboolean
+xfsm_shutdown_fallback_user_is_operator (void)
+{
+ struct passwd *pw;
+ gid_t groups[MAX_USER_GROUPS];
+ int max_grp = MAX_USER_GROUPS;
+ int i = 0;
+ int ret;
+ static gboolean is_operator = FALSE;
+ static gboolean once = FALSE;
+
+ /* Only check once */
+ if (once == TRUE)
+ goto out;
+
+ pw = getpwuid (getuid());
+
+ ret = getgrouplist (pw->pw_name, pw->pw_gid, groups, &max_grp);
+
+ if (ret < 0)
+ {
+ fprintf (stderr,
+ "Failed to get user group list, user belongs to more than %u groups?\n",
+ MAX_USER_GROUPS);
+ goto out;
+ }
+
+ once = TRUE;
+
+ for (i = 0; i < max_grp; i++)
+ {
+ struct group *gr;
+
+ gr = getgrgid (groups[i]);
+ if (strncmp(gr->gr_name, "operator", 8) == 0)
+ {
+ is_operator = TRUE;
+ break;
+ }
+ }
+out:
+ return is_operator;
+}
+#endif /* __BACKEND_TYPE_BSD__ */
+
+
+
+#ifdef __BACKEND_TYPE_BSD__
static gboolean
-xfsm_shutdown_fallback_check_auth (const gchar *action_id)
+xfsm_shutdown_fallback_bsd_check_auth (XfsmShutdownType shutdown_type)
+{
+ gboolean auth_result = FALSE;
+ switch (shutdown_type)
+ {
+ /* On the BSDs users of the operator group are allowed to shutdown/restart the system */
+ case XFSM_SHUTDOWN_SHUTDOWN:
+ case XFSM_SHUTDOWN_RESTART:
+ auth_result = xfsm_shutdown_fallback_user_is_operator ();
+ break;
+ case XFSM_SHUTDOWN_SUSPEND:
+ case XFSM_SHUTDOWN_HIBERNATE:
+ case XFSM_SHUTDOWN_HYBRID_SLEEP:
+ /* Check rw access on '/var/run/apmdev' on OpenBSD and to /dev/acpi'
+ * for the other BSDs */
+ auth_result = g_access(BSD_SLEEP_ACCESS_NODE, R_OK|W_OK) == 0;
+ break;
+ default:
+ g_warning ("Unexpected shutdow id '%d'\n", shutdown_type);
+ break;
+ }
+
+ return auth_result;
+}
+#endif /* __BACKEND_TYPE_BSD__ */
+
+
+
+static gboolean
+xfsm_shutdown_fallback_check_auth_polkit (const gchar *action_id)
{
gboolean auth_result = FALSE;
#ifdef HAVE_POLKIT
@@ -240,33 +357,41 @@ gboolean
xfsm_shutdown_fallback_try_action (XfsmShutdownType type,
GError **error)
{
- const gchar *action;
- gboolean ret;
+ const gchar *xfsm_helper_action;
+ const gchar *cmd;
+ gboolean ret = FALSE;
gint exit_status = 0;
+#ifdef HAVE_POLKIT
gchar *command = NULL;
+#endif
switch (type)
{
case XFSM_SHUTDOWN_SHUTDOWN:
- action = "shutdown";
+ xfsm_helper_action = "shutdown";
+ cmd = POWEROFF_CMD;
break;
case XFSM_SHUTDOWN_RESTART:
- action = "restart";
+ xfsm_helper_action = "restart";
+ cmd = REBOOT_CMD;
break;
case XFSM_SHUTDOWN_SUSPEND:
- action = "suspend";
+ xfsm_helper_action = "suspend";
+ cmd = UP_BACKEND_SUSPEND_COMMAND;
/* On suspend we try to lock the screen */
if (!lock_screen (error))
return FALSE;
break;
case XFSM_SHUTDOWN_HIBERNATE:
- action = "hibernate";
+ xfsm_helper_action = "hibernate";
+ cmd = UP_BACKEND_HIBERNATE_COMMAND;
/* On hibernate we try to lock the screen */
if (!lock_screen (error))
return FALSE;
break;
case XFSM_SHUTDOWN_HYBRID_SLEEP:
- action = "hybrid-sleep";
+ xfsm_helper_action = "hybrid-sleep";
+ cmd = UP_BACKEND_HIBERNATE_COMMAND;
/* On hybrid sleep we try to lock the screen */
if (!lock_screen (error))
return FALSE;
@@ -275,10 +400,22 @@ xfsm_shutdown_fallback_try_action (XfsmShutdownType type,
return FALSE;
}
- command = g_strdup_printf ("pkexec " XFSM_SHUTDOWN_HELPER_CMD " --%s", action);
+#ifdef __BACKEND_TYPE_BSD__
+ /* Make sure we can use native shutdown commands */
+ if (xfsm_shutdown_fallback_bsd_check_auth (type))
+ {
+ return g_spawn_command_line_sync (cmd, NULL, NULL, &exit_status, error);
+ }
+#endif
+
+ /* xfsm-shutdown-helper requires polkit to run */
+#ifdef HAVE_POLKIT
+ command = g_strdup_printf ("pkexec " XFSM_SHUTDOWN_HELPER_CMD " --%s", xfsm_helper_action);
+
ret = g_spawn_command_line_sync (command, NULL, NULL, &exit_status, error);
g_free (command);
+#endif
return ret;
}
@@ -345,7 +482,7 @@ xfsm_shutdown_fallback_can_hybrid_sleep (void)
return linux_supports_sleep_state ("hibernate");
#endif
#ifdef BACKEND_TYPE_OPENBSD
- return TRUE;
+ return FALSE;
#endif
return FALSE;
@@ -361,7 +498,12 @@ xfsm_shutdown_fallback_can_hybrid_sleep (void)
gboolean
xfsm_shutdown_fallback_auth_shutdown (void)
{
- return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_SHUTDOWN_XFSM);
+#ifdef __BACKEND_TYPE_BSD__
+ gboolean ret_val = xfsm_shutdown_fallback_bsd_check_auth (XFSM_SHUTDOWN_SHUTDOWN);
+ if (ret_val)
+ return TRUE;
+#endif
+ return xfsm_shutdown_fallback_check_auth_polkit (POLKIT_AUTH_SHUTDOWN_XFSM);
}
@@ -374,7 +516,12 @@ xfsm_shutdown_fallback_auth_shutdown (void)
gboolean
xfsm_shutdown_fallback_auth_restart (void)
{
- return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_RESTART_XFSM);
+#ifdef __BACKEND_TYPE_BSD__
+ gboolean ret_val = xfsm_shutdown_fallback_bsd_check_auth (XFSM_SHUTDOWN_RESTART);
+ if (ret_val)
+ return TRUE;
+#endif
+ return xfsm_shutdown_fallback_check_auth_polkit (POLKIT_AUTH_RESTART_XFSM);
}
@@ -387,7 +534,12 @@ xfsm_shutdown_fallback_auth_restart (void)
gboolean
xfsm_shutdown_fallback_auth_suspend (void)
{
- return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_SUSPEND_XFSM);
+#ifdef __BACKEND_TYPE_BSD__
+ gboolean ret_val = xfsm_shutdown_fallback_bsd_check_auth (XFSM_SHUTDOWN_SUSPEND);
+ if (ret_val)
+ return TRUE;
+#endif
+ return xfsm_shutdown_fallback_check_auth_polkit (POLKIT_AUTH_SUSPEND_XFSM);
}
@@ -400,7 +552,12 @@ xfsm_shutdown_fallback_auth_suspend (void)
gboolean
xfsm_shutdown_fallback_auth_hibernate (void)
{
- return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_HIBERNATE_XFSM);
+#ifdef __BACKEND_TYPE_BSD__
+ gboolean ret_val = xfsm_shutdown_fallback_bsd_check_auth (XFSM_SHUTDOWN_HIBERNATE);
+ if (ret_val)
+ return TRUE;
+#endif
+ return xfsm_shutdown_fallback_check_auth_polkit (POLKIT_AUTH_HIBERNATE_XFSM);
}
@@ -413,5 +570,10 @@ xfsm_shutdown_fallback_auth_hibernate (void)
gboolean
xfsm_shutdown_fallback_auth_hybrid_sleep (void)
{
- return xfsm_shutdown_fallback_check_auth (POLKIT_AUTH_HYBRID_SLEEP_XFSM);
+#ifdef __BACKEND_TYPE_BSD__
+ gboolean ret_val = xfsm_shutdown_fallback_bsd_check_auth (XFSM_SHUTDOWN_HYBRID_SLEEP);
+ if (ret_val)
+ return TRUE;
+#endif
+ return xfsm_shutdown_fallback_check_auth_polkit (POLKIT_AUTH_HYBRID_SLEEP_XFSM);
}
diff --git a/xfsm-shutdown-helper/main.c b/xfsm-shutdown-helper/main.c
index 2c9bb1a..793d9fb 100644
--- a/xfsm-shutdown-helper/main.c
+++ b/xfsm-shutdown-helper/main.c
@@ -48,6 +48,8 @@
#include <unistd.h>
#endif
+#include "libxfsm/xfsm-shutdown-common.h"
+
#include <glib.h>
/* XXX */
@@ -56,42 +58,6 @@
#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"
-#define REBOOT_CMD "/sbin/shutdown -r now"
-#elif defined(sun) || defined(__sun)
-#define POWEROFF_CMD "/usr/sbin/shutdown -i 5 -g 0 -y"
-#define REBOOT_CMD "/usr/sbin/shutdown -i 6 -g 0 -y"
-#else
-#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
run (const gchar *command)
--
To stop receiving notification emails like this one, please contact
the administrator of this repository.
More information about the Xfce4-commits
mailing list