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 <[email protected]> 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 <[email protected]> + * 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 <[email protected]> * Copyright (c) 2011 Nick Schermer <[email protected]> * Copyright (c) 2014 Xfce Development Team <[email protected]> + * Copyright (c) 2018 Ali Abdallah <[email protected]> * 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. _______________________________________________ Xfce4-commits mailing list [email protected] https://mail.xfce.org/mailman/listinfo/xfce4-commits
