summaryrefslogtreecommitdiff
path: root/xfsm-shutdown-helper
diff options
context:
space:
mode:
authorEric Koegel <eric.koegel@gmail.com>2014-08-10 19:16:17 +0300
committerEric Koegel <eric.koegel@gmail.com>2014-08-28 18:52:27 +0300
commit29d87f559aadba51e7bd6afcf4aeeb615ecb2145 (patch)
tree06868c098165699f518daa3b933ddcaeac7abfe5 /xfsm-shutdown-helper
parentbb0cbd537d72be4dece2ade8a86d76335dfda2dc (diff)
downloadxfce4-session-29d87f559aadba51e7bd6afcf4aeeb615ecb2145.tar.gz
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.
Diffstat (limited to 'xfsm-shutdown-helper')
-rw-r--r--xfsm-shutdown-helper/main.c124
1 files changed, 106 insertions, 18 deletions
diff --git a/xfsm-shutdown-helper/main.c b/xfsm-shutdown-helper/main.c
index 667f288c..2c9bb1ae 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;
}