diff options
author | Eric Koegel <eric.koegel@gmail.com> | 2014-08-10 19:16:17 +0300 |
---|---|---|
committer | Eric Koegel <eric.koegel@gmail.com> | 2014-08-28 18:52:27 +0300 |
commit | 29d87f559aadba51e7bd6afcf4aeeb615ecb2145 (patch) | |
tree | 06868c098165699f518daa3b933ddcaeac7abfe5 /xfsm-shutdown-helper | |
parent | bb0cbd537d72be4dece2ade8a86d76335dfda2dc (diff) | |
download | xfce4-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.c | 124 |
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; } |