19928N/A--- libgksu-2.0.12/libgksu/Makefile.am-orig 2010-12-09 23:59:11.491180288 -0600
19928N/A+++ libgksu-2.0.12/libgksu/Makefile.am 2010-12-10 00:00:22.035013955 -0600
19928N/A@@ -3,7 +3,7 @@ INCLUDES = ${LIBGKSU_CFLAGS}
19928N/A AM_CPPFLAGS = -DLOCALEDIR=\"$(datadir)/locale\" -DDATA_DIR=\"$(datadir)\" -DPREFIX=\"$(prefix)\"
19928N/A
19928N/A lib_LTLIBRARIES = libgksu2.la
19928N/A-libgksu2_la_SOURCES = libgksu.c libgksu.h
19928N/A+libgksu2_la_SOURCES = libgksu.c libgksu.h libgksu-solaris.c
19928N/A # 0.0.0 -> major.minor.micro
19928N/A # major -> breaks backward compatibility (changes to existing ABI)
19928N/A # minor -> keeps compatibility (additions to the API)
19928N/A--- libgksu-2.0.12/libgksu/libgksu.h-orig 2010-12-09 23:57:13.917357883 -0600
19928N/A+++ libgksu-2.0.12/libgksu/libgksu.h 2010-12-09 23:59:22.607325443 -0600
19928N/A@@ -21,9 +21,22 @@
19928N/A #ifndef __LIBGKSU_H__
19928N/A #define __LIBGKSU_H__
19928N/A
19928N/A+#ifdef __sun
19928N/A+#include <exec_attr.h>
19928N/A+#include <user_attr.h>
19928N/A+#include <auth_attr.h>
19928N/A+#include <prof_attr.h>
19928N/A+#define ES_SUCCESS 1
19928N/A+#define ES_ERROR 2
19928N/A+#define ES_PASSWORD 3
19928N/A+#define ES_CONTINUE 4
19928N/A+#endif
19928N/A+
19928N/A #include <glib.h>
19928N/A #include <glib-object.h>
19928N/A
19928N/A+#include <security/pam_appl.h>
19928N/A+
19928N/A #define SN_API_NOT_YET_FROZEN
19928N/A #include <libsn/sn.h>
19928N/A
19928N/A@@ -71,6 +84,25 @@ struct _GksuContext
19928N/A gint ref_count;
19928N/A
19928N/A gboolean debug;
19928N/A+
19928N/A+ int msg_type;
19928N/A+ int msg_num;
19928N/A+ struct pam_message *pam_message;
19928N/A+ struct pam_response *pam_response;
19928N/A+ gchar *privspec;
19928N/A+ gboolean pfexec_mode;
19928N/A+ gboolean elevated_privilege;
19928N/A+ gboolean elevated_role;
19928N/A+ gboolean wait_for_child_to_exit;
19928N/A+ gboolean need_pipe;
19928N/A+ int child_pid;
19928N/A+ int stdin_fd;
19928N/A+ int stdout_fd;
19928N/A+ FILE *stdin_file;
19928N/A+ FILE *stdout_file;
19928N/A+ gchar *saved_home;
19928N/A+ gboolean sn_context_initiated;
19928N/A+ gboolean child_no_a11y;
19928N/A };
19928N/A
19928N/A #define GKSU_TYPE_CONTEXT gksu_context_get_type()
19928N/A@@ -130,11 +162,13 @@ gksu_context_set_login_shell (GksuContex
19928N/A gboolean
19928N/A gksu_context_get_login_shell (GksuContext *context);
19928N/A
19928N/A+#ifndef __sun
19928N/A void
19928N/A gksu_context_set_keep_env (GksuContext *context, gboolean value);
19928N/A
19928N/A gboolean
19928N/A gksu_context_get_keep_env (GksuContext *context);
19928N/A+#endif
19928N/A
19928N/A void
19928N/A gksu_context_set_description (GksuContext *context, gchar *description);
19928N/A@@ -252,6 +286,93 @@ gksu_ask_password_full (GksuContext *con
19928N/A gchar*
19928N/A gksu_ask_password (GError **error);
19928N/A
19928N/A+#ifdef __sun
19928N/A+gboolean
19928N/A+gksu_context_embedded_su_try_need_password (GksuContext *context);
19928N/A+#endif
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_embedded_su_run (GksuContext *context,
19928N/A+ GksuAskPassFunc ask_pass,
19928N/A+ gpointer ask_pass_data,
19928N/A+ GError **error);
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_pfexec_try_run (GksuContext *context);
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_pfexec_run (GksuContext *context, GError **error);
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_set_role (GksuContext *context);
19928N/A+
19928N/A+int
19928N/A+gksu_context_get_child_stdin_fd (GksuContext *context);
19928N/A+
19928N/A+int
19928N/A+gksu_context_get_child_stdout_fd (GksuContext *context);
19928N/A+
19928N/A+FILE*
19928N/A+gksu_context_get_child_stdin_file (GksuContext *context);
19928N/A+
19928N/A+FILE*
19928N/A+gksu_context_get_child_stdout_file (GksuContext *context);
19928N/A+
19928N/A+pid_t
19928N/A+gksu_context_get_child_pid (GksuContext *context);
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_wait_for_child_to_exit (GksuContext *context, gboolean value);
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_get_wait_for_child_to_exit (GksuContext *context);
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_elevated_privilege (GksuContext *context, gboolean value);
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_get_elevated_privilege (GksuContext *context);
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_elevated_role (GksuContext *context, gboolean value);
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_get_elevated_role (GksuContext *context);
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_privspec (GksuContext *context, gchar *privspec);
19928N/A+
19928N/A+const gchar*
19928N/A+gksu_context_get_privspec (GksuContext *context);
19928N/A+
19928N/A+gint
19928N/A+gksu_context_get_num_msg (GksuContext *context);
19928N/A+
19928N/A+const gchar*
19928N/A+gksu_context_get_pam_message (GksuContext *context, gint index);
19928N/A+
19928N/A+const gchar*
19928N/A+gksu_context_get_pam_response (GksuContext *context, gint index);
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_pam_response (GksuContext *context, gint index, gchar *response);
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_get_pfexec_mode (GksuContext *context);
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_need_pipe (GksuContext *context, gboolean value);
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_child_no_a11y (GksuContext *context, gboolean value);
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_get_need_pipe (GksuContext *context);
19928N/A+
19928N/A+gboolean sudo_prepare_xauth (GksuContext *context);
19928N/A+
19928N/A+void sudo_reset_xauth (GksuContext *context, gchar *xauth, gchar *xauth_env);
19928N/A+
19928N/A G_END_DECLS
19928N/A
19928N/A #endif
19928N/A--- libgksu-2.0.12/libgksu/libgksu.c-orig 2010-12-10 00:39:18.265941619 -0600
19928N/A+++ libgksu-2.0.12/libgksu/libgksu.c 2010-12-10 00:39:57.413601210 -0600
19928N/A@@ -24,13 +24,19 @@
19928N/A #include <unistd.h>
19928N/A #include <string.h>
19928N/A #include <fcntl.h>
19928N/A+#ifdef __sun
19928N/A+#include <sys/stropts.h>
19928N/A+#else
19928N/A #include <pty.h>
19928N/A+#endif
19928N/A #include <pwd.h>
19928N/A #include <sys/types.h>
19928N/A #include <sys/wait.h>
19928N/A #include <sys/stat.h>
19928N/A #include <sys/select.h>
19928N/A #include <errno.h>
19928N/A+#include <termios.h>
19928N/A+#include <strings.h>
19928N/A
19928N/A #include <glibtop.h>
19928N/A #include <glibtop/procstate.h>
19928N/A@@ -44,8 +50,10 @@
19928N/A #include <gtk/gtk.h>
19928N/A #include <locale.h>
19928N/A
19928N/A+#if 0
19928N/A #include <gconf/gconf-client.h>
19928N/A #include <gnome-keyring.h>
19928N/A+#endif
19928N/A
19928N/A #include "defines.h"
19928N/A #include "../config.h"
19928N/A@@ -532,7 +540,7 @@ report_failed_grab (FailedGrabWhat what)
19928N/A }
19928N/A
19928N/A int
19928N/A-grab_keyboard_and_mouse (GtkWidget *dialog)
19928N/A+grab_keyboard_and_mouse (GksuContext *context, GtkWidget *dialog)
19928N/A {
19928N/A GdkGrabStatus status;
19928N/A gint grab_tries = 0;
19928N/A@@ -541,7 +549,7 @@ grab_keyboard_and_mouse (GtkWidget *dial
19928N/A
19928N/A gchar *fname = g_strdup (getenv ("GKSU_LOCK_FILE"));
19928N/A if (fname == NULL)
19928N/A- fname = g_strdup_printf ("%s/.gksu.lock", getenv ("HOME"));
19928N/A+ fname = g_strdup_printf ("%s/.gksu.lock", context->saved_home);
19928N/A
19928N/A pid = test_lock (fname);
19928N/A
19928N/A@@ -628,6 +636,7 @@ ungrab_keyboard_and_mouse (int lock)
19928N/A close(lock);
19928N/A }
19928N/A
19928N/A+#if 0
19928N/A static gchar*
19928N/A get_gnome_keyring_password (GksuContext *context)
19928N/A {
19928N/A@@ -805,10 +814,12 @@ unset_gnome_keyring_password (GksuContex
19928N/A }
19928N/A }
19928N/A }
19928N/A+#endif
19928N/A
19928N/A void
19928N/A get_configuration_options (GksuContext *context)
19928N/A {
19928N/A+#if 0
19928N/A GConfClient *gconf_client = context->gconf_client;
19928N/A gboolean force_grab;
19928N/A
19928N/A@@ -821,6 +832,10 @@ get_configuration_options (GksuContext *
19928N/A
19928N/A context->sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
19928N/A NULL);
19928N/A+#endif
19928N/A+
19928N/A+ context->grab = TRUE;
19928N/A+ context->sudo_mode = FALSE;
19928N/A }
19928N/A
19928N/A /**
19928N/A@@ -910,7 +925,7 @@ su_ask_password (GksuContext *context, g
19928N/A gksuui_dialog_set_alert (GKSUUI_DIALOG(dialog), context->alert);
19928N/A
19928N/A if (context->grab)
19928N/A- lock = grab_keyboard_and_mouse (dialog);
19928N/A+ lock = grab_keyboard_and_mouse (context, dialog);
19928N/A retvalue = gtk_dialog_run (GTK_DIALOG(dialog));
19928N/A gtk_widget_hide (dialog);
19928N/A if (context->grab)
19928N/A@@ -953,6 +968,7 @@ su_ask_password (GksuContext *context, g
19928N/A static void
19928N/A cb_toggled_cb (GtkWidget *button, gpointer data)
19928N/A {
19928N/A+#if 0
19928N/A GConfClient *gconf_client;
19928N/A gchar *key;
19928N/A gboolean toggled;
19928N/A@@ -981,6 +997,7 @@ cb_toggled_cb (GtkWidget *button, gpoint
19928N/A g_object_unref (gconf_client);
19928N/A
19928N/A g_free (key);
19928N/A+#endif
19928N/A }
19928N/A
19928N/A void
19928N/A@@ -1084,235 +1101,6 @@ get_process_name (pid_t pid)
19928N/A return strdup(buf.cmd);
19928N/A }
19928N/A
19928N/A-static gchar *
19928N/A-get_xauth_token (GksuContext *context, gchar *display)
19928N/A-{
19928N/A- gchar *xauth_bin = NULL;
19928N/A- FILE *xauth_output;
19928N/A- gchar *tmp = NULL;
19928N/A- gchar *xauth = g_new0 (gchar, 256);
19928N/A-
19928N/A- /* find out where the xauth binary is located */
19928N/A- if (g_file_test ("/usr/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
19928N/A- xauth_bin = "/usr/bin/xauth";
19928N/A- else if (g_file_test ("/usr/X11R6/bin/xauth", G_FILE_TEST_IS_EXECUTABLE))
19928N/A- xauth_bin = "/usr/X11R6/bin/xauth";
19928N/A- else
19928N/A- {
19928N/A- fprintf (stderr,
19928N/A- "Failed to obtain xauth key: xauth binary not found "
19928N/A- "at usual locations");
19928N/A-
19928N/A- return NULL;
19928N/A- }
19928N/A-
19928N/A- /* get the authorization token */
19928N/A- tmp = g_strdup_printf ("%s list %s | "
19928N/A- "head -1 | awk '{ print $3 }'",
19928N/A- xauth_bin,
19928N/A- display);
19928N/A- if ((xauth_output = popen (tmp, "r")) == NULL)
19928N/A- {
19928N/A- fprintf (stderr,
19928N/A- "Failed to obtain xauth key: %s",
19928N/A- strerror(errno));
19928N/A- return NULL;
19928N/A- }
19928N/A- fread (xauth, sizeof(char), 255, xauth_output);
19928N/A- pclose (xauth_output);
19928N/A- g_free (tmp);
19928N/A-
19928N/A- if (context->debug)
19928N/A- {
19928N/A- fprintf(stderr,
19928N/A- "xauth: -%s-\n"
19928N/A- "display: -%s-\n",
19928N/A- xauth, display);
19928N/A- }
19928N/A-
19928N/A- return xauth;
19928N/A-}
19928N/A-
19928N/A-/**
19928N/A- * prepare_xauth:
19928N/A- *
19928N/A- * Sets up the variables with values for the $DISPLAY
19928N/A- * environment variable and xauth-related stuff. Also
19928N/A- * creates a temporary directory to hold a .Xauthority
19928N/A- *
19928N/A- * Returns: TRUE if it suceeds, FALSE if it fails.
19928N/A- */
19928N/A-static int
19928N/A-prepare_xauth (GksuContext *context)
19928N/A-{
19928N/A- gchar *display = NULL;
19928N/A- gchar *xauth = NULL;
19928N/A-
19928N/A- display = g_strdup (getenv ("DISPLAY"));
19928N/A- xauth = get_xauth_token (context, display);
19928N/A- if (xauth == NULL)
19928N/A- {
19928N/A- g_free (display);
19928N/A- return FALSE;
19928N/A- }
19928N/A-
19928N/A- /* If xauth is the empty string, then try striping the
19928N/A- * hostname part of the DISPLAY string for getting the
19928N/A- * auth token; this is needed for ssh-forwarded usage
19928N/A- */
19928N/A- if (!strcmp ("", xauth))
19928N/A- {
19928N/A- gchar *cut_display = NULL;
19928N/A-
19928N/A- g_free (xauth);
19928N/A- cut_display = g_strdup (g_strrstr (display, ":"));
19928N/A- xauth = get_xauth_token (context, cut_display);
19928N/A-
19928N/A- g_free (display);
19928N/A- display = cut_display;
19928N/A- }
19928N/A-
19928N/A- context->xauth = xauth;
19928N/A- context->display = display;
19928N/A-
19928N/A- if (context->debug)
19928N/A- {
19928N/A- fprintf(stderr,
19928N/A- "final xauth: -%s-\n"
19928N/A- "final display: -%s-\n",
19928N/A- context->xauth, context->display);
19928N/A- }
19928N/A-
19928N/A- return TRUE;
19928N/A-}
19928N/A-
19928N/A-/* Write all of buf, even if write(2) is interrupted. */
19928N/A-static ssize_t
19928N/A-full_write (int d, const char *buf, size_t nbytes)
19928N/A-{
19928N/A- ssize_t r, w = 0;
19928N/A-
19928N/A- /* Loop until nbytes of buf have been written. */
19928N/A- while (w < nbytes) {
19928N/A- /* Keep trying until write succeeds without interruption. */
19928N/A- do {
19928N/A- r = write(d, buf + w, nbytes - w);
19928N/A- } while (r < 0 && errno == EINTR);
19928N/A-
19928N/A- if (r < 0) {
19928N/A- return -1;
19928N/A- }
19928N/A-
19928N/A- w += r;
19928N/A- }
19928N/A-
19928N/A- return w;
19928N/A-}
19928N/A-
19928N/A-static gboolean
19928N/A-copy (const char *fn, const char *dir)
19928N/A-{
19928N/A- int in, out;
19928N/A- int r;
19928N/A- char *newfn;
19928N/A- char buf[BUFSIZ] = "";
19928N/A-
19928N/A- newfn = g_strdup_printf("%s/.Xauthority", dir);
19928N/A-
19928N/A- out = open(newfn, O_WRONLY | O_CREAT | O_EXCL, 0600);
19928N/A- if (out == -1)
19928N/A- {
19928N/A- if (errno == EEXIST)
19928N/A- fprintf (stderr,
19928N/A- "Impossible to create the .Xauthority file: a file "
19928N/A- "already exists. This might be a security issue; "
19928N/A- "please investigate.");
19928N/A- else
19928N/A- fprintf (stderr,
19928N/A- "Error copying '%s' to '%s': %s",
19928N/A- fn, dir, strerror(errno));
19928N/A-
19928N/A- return FALSE;
19928N/A- }
19928N/A-
19928N/A- in = open(fn, O_RDONLY);
19928N/A- if (in == -1)
19928N/A- {
19928N/A- fprintf (stderr,
19928N/A- "Error copying '%s' to '%s': %s",
19928N/A- fn, dir, strerror(errno));
19928N/A- return FALSE;
19928N/A- }
19928N/A-
19928N/A- while ((r = read(in, buf, BUFSIZ)) > 0)
19928N/A- {
19928N/A- if (full_write(out, buf, r) == -1)
19928N/A- {
19928N/A- fprintf (stderr,
19928N/A- "Error copying '%s' to '%s': %s",
19928N/A- fn, dir, strerror(errno));
19928N/A- return FALSE;
19928N/A- }
19928N/A- }
19928N/A-
19928N/A- if (r == -1)
19928N/A- {
19928N/A- fprintf (stderr,
19928N/A- "Error copying '%s' to '%s': %s",
19928N/A- fn, dir, strerror(errno));
19928N/A- return FALSE;
19928N/A- }
19928N/A-
19928N/A- return TRUE;
19928N/A-}
19928N/A-
19928N/A-static gboolean
19928N/A-sudo_prepare_xauth (GksuContext *context)
19928N/A-{
19928N/A- gchar template[] = "/tmp/" PACKAGE "-XXXXXX";
19928N/A- gboolean error_copying = FALSE;
19928N/A- gchar *xauth = NULL;
19928N/A-
19928N/A- context->dir = g_strdup (mkdtemp(template));
19928N/A- if (!context->dir)
19928N/A- {
19928N/A- fprintf (stderr, strerror(errno));
19928N/A- return FALSE;
19928N/A- }
19928N/A-
19928N/A- xauth = g_strdup(g_getenv ("XAUTHORITY"));
19928N/A- if (xauth == NULL)
19928N/A- xauth = g_strdup_printf ("%s/.Xauthority", g_get_home_dir());
19928N/A-
19928N/A- error_copying = !copy (xauth, context->dir);
19928N/A- g_free (xauth);
19928N/A-
19928N/A- if (error_copying)
19928N/A- return FALSE;
19928N/A-
19928N/A- return TRUE;
19928N/A-}
19928N/A-
19928N/A-static void
19928N/A-sudo_reset_xauth (GksuContext *context, gchar *xauth,
19928N/A- gchar *xauth_env)
19928N/A-{
19928N/A- /* reset the env var as it was before or clean it */
19928N/A- if (xauth_env)
19928N/A- setenv ("XAUTHORITY", xauth_env, TRUE);
19928N/A- else
19928N/A- unsetenv ("XAUTHORITY");
19928N/A-
19928N/A- if (context->debug)
19928N/A- fprintf (stderr, "xauth: %s\nxauth_env: %s\ndir: %s\n",
19928N/A- xauth, xauth_env, context->dir);
19928N/A-
19928N/A- unlink (xauth);
19928N/A- rmdir (context->dir);
19928N/A-
19928N/A- g_free (xauth);
19928N/A-}
19928N/A-
19928N/A static void
19928N/A startup_notification_initialize (GksuContext *context)
19928N/A {
19928N/A@@ -1344,11 +1132,13 @@ gksu_context_new ()
19928N/A context->dir = NULL;
19928N/A context->display = NULL;
19928N/A
19928N/A+#if 0
19928N/A context->gconf_client = gconf_client_get_default ();
19928N/A+#endif
19928N/A
19928N/A context->sudo_mode = FALSE;
19928N/A
19928N/A- context->user = g_strdup ("root");
19928N/A+ context->user = NULL;
19928N/A context->command = NULL;
19928N/A
19928N/A context->login_shell = FALSE;
19928N/A@@ -1362,10 +1152,27 @@ gksu_context_new ()
19928N/A
19928N/A context->debug = FALSE;
19928N/A
19928N/A+ context->pam_message = NULL;
19928N/A+ context->pam_response = NULL;
19928N/A+ context->privspec = NULL;
19928N/A+ context->msg_type = 0;
19928N/A+ context->msg_num = 0;
19928N/A+ context->pfexec_mode = FALSE;
19928N/A+ context->elevated_privilege = TRUE;
19928N/A+ context->elevated_role = TRUE;
19928N/A+ context->wait_for_child_to_exit = TRUE;
19928N/A+ context->need_pipe = TRUE;
19928N/A+ context->child_pid = 0;
19928N/A+ context->stdin_fd = 0;
19928N/A+ context->stdout_fd = 0;
19928N/A+
19928N/A context->sn_context = NULL;
19928N/A context->sn_id = NULL;
19928N/A
19928N/A context->ref_count = 1;
19928N/A+ context->saved_home = NULL;
19928N/A+ context->sn_context_initiated = FALSE;
19928N/A+ context->child_no_a11y = FALSE;
19928N/A
19928N/A get_configuration_options (context);
19928N/A startup_notification_initialize (context);
19928N/A@@ -1485,7 +1292,9 @@ gksu_context_get_login_shell (GksuContex
19928N/A void
19928N/A gksu_context_set_keep_env (GksuContext *context, gboolean value)
19928N/A {
19928N/A+#ifndef __sun
19928N/A context->keep_env = value;
19928N/A+#endif
19928N/A }
19928N/A
19928N/A /**
19928N/A@@ -1737,6 +1546,7 @@ gksu_context_launch_initiate (GksuContex
19928N/A g_get_prgname (),
19928N/A gksu_context_get_command (context),
19928N/A launch_time);
19928N/A+ context->sn_context_initiated = TRUE;
19928N/A
19928N/A sid = g_strdup_printf ("%s", sn_launcher_context_get_startup_id (context->sn_context));
19928N/A gksu_context_set_launcher_id (context, sid);
19928N/A@@ -1757,7 +1567,10 @@ gksu_context_launch_initiate (GksuContex
19928N/A static void
19928N/A gksu_context_launch_complete (GksuContext *context)
19928N/A {
19928N/A- sn_launcher_context_complete(context->sn_context);
19928N/A+ if (context->sn_context_initiated)
19928N/A+ {
19928N/A+ sn_launcher_context_complete(context->sn_context);
19928N/A+ }
19928N/A }
19928N/A
19928N/A /**
19928N/A@@ -1801,7 +1614,9 @@ gksu_context_free (GksuContext *context)
19928N/A g_free (context->dir);
19928N/A g_free (context->display);
19928N/A
19928N/A+#if 0
19928N/A g_object_unref (context->gconf_client);
19928N/A+#endif
19928N/A
19928N/A g_free (context->description);
19928N/A g_free (context->message);
19928N/A@@ -1810,6 +1625,14 @@ gksu_context_free (GksuContext *context)
19928N/A g_free (context->command);
19928N/A
19928N/A g_free (context);
19928N/A+
19928N/A+ for ( int i = 0; i<context->msg_num; i++ ) {
19928N/A+ g_free (context->pam_message[i].msg);
19928N/A+ g_free (context->pam_response[i].resp);
19928N/A+ }
19928N/A+ g_free (context->pam_message);
19928N/A+ g_free (context->pam_response);
19928N/A+ g_free (context->privspec);
19928N/A }
19928N/A
19928N/A /**
19928N/A@@ -1855,6 +1678,45 @@ gksu_context_get_type (void)
19928N/A return type_gksu_context;
19928N/A }
19928N/A
19928N/A+/* xauth functions */
19928N/A+static void
19928N/A+setup_xauth (XHostAddress *host_entry, XServerInterpretedAddress *si_entry, char *rolename)
19928N/A+{
19928N/A+ si_entry->type = "localuser";
19928N/A+ si_entry->typelength = strlen ("localuser");
19928N/A+ si_entry->value = rolename;
19928N/A+ si_entry->valuelength = strlen (rolename);
19928N/A+ host_entry->family = FamilyServerInterpreted;
19928N/A+ host_entry->address = (char *) si_entry;
19928N/A+ host_entry->length = sizeof (XServerInterpretedAddress);
19928N/A+}
19928N/A+
19928N/A+gboolean
19928N/A+prepare_xauth (GksuContext *context)
19928N/A+{
19928N/A+ Display *display;
19928N/A+ XServerInterpretedAddress si_entry;
19928N/A+ XHostAddress host_entry;
19928N/A+
19928N/A+ display = gdk_x11_get_default_xdisplay ();
19928N/A+ setup_xauth (&host_entry, &si_entry, context->user);
19928N/A+ XAddHost (display, &host_entry);
19928N/A+ XSync (display, False);
19928N/A+ return TRUE;
19928N/A+}
19928N/A+
19928N/A+void
19928N/A+reset_xauth (GksuContext *context)
19928N/A+{
19928N/A+ Display *display;
19928N/A+ XServerInterpretedAddress si_entry;
19928N/A+ XHostAddress host_entry;
19928N/A+
19928N/A+ display = gdk_x11_get_default_xdisplay ();
19928N/A+ setup_xauth (&host_entry, &si_entry, context->user);
19928N/A+ XRemoveHost (display, &host_entry);
19928N/A+ XSync (display, False);
19928N/A+}
19928N/A
19928N/A /**
19928N/A * gksu_su_full:
19928N/A@@ -1934,6 +1796,10 @@ gksu_su_fuller (GksuContext *context,
19928N/A GError **error)
19928N/A {
19928N/A GQuark gksu_quark;
19928N/A+#ifdef __sun
19928N/A+ gchar *home_env;
19928N/A+ gboolean rc;
19928N/A+#else
19928N/A int i = 0;
19928N/A
19928N/A gchar auxcommand[] = PREFIX "/lib/" PACKAGE "/gksu-run-helper";
19928N/A@@ -1942,10 +1808,11 @@ gksu_su_fuller (GksuContext *context,
19928N/A pid_t pid;
19928N/A
19928N/A context->sudo_mode = FALSE;
19928N/A+#endif
19928N/A
19928N/A gksu_quark = g_quark_from_string (PACKAGE);
19928N/A
19928N/A- if (!context->command)
19928N/A+ if (!context->command || context->command[0] == '\0')
19928N/A {
19928N/A g_set_error (error, gksu_quark, GKSU_ERROR_NOCOMMAND,
19928N/A _("gksu_run needs a command to be run, "
19928N/A@@ -1953,9 +1820,54 @@ gksu_su_fuller (GksuContext *context,
19928N/A return FALSE;
19928N/A }
19928N/A
19928N/A- if (!context->user)
19928N/A- context->user = g_strdup ("root");
19928N/A+ if (context->saved_home == NULL)
19928N/A+ {
19928N/A+ home_env = getenv ("HOME");
19928N/A+ context->saved_home = home_env;
19928N/A+ }
19928N/A+
19928N/A+#ifdef __sun
19928N/A+ if (!prepare_xauth (context))
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_XAUTH,
19928N/A+ _("Unable to copy the user's Xauthorization file."));
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ if (context->pfexec_mode) {
19928N/A+ rc = gksu_context_pfexec_run (context, error);
19928N/A+ } else {
19928N/A+ gint count;
19928N/A+
19928N/A+ for (count = 0; count < 3; count++)
19928N/A+ {
19928N/A+ if (*error) /* wrong password was given */
19928N/A+ {
19928N/A+ if (context->alert == NULL) {
19928N/A+ gksu_context_set_alert (context, (*error)->message);
19928N/A+ }
19928N/A+ g_error_free (*error);
19928N/A+ *error = NULL;
19928N/A+ }
19928N/A+
19928N/A+ if (ask_pass == NULL)
19928N/A+ {
19928N/A+ rc = gksu_context_embedded_su_run (context, su_ask_password, NULL, error);
19928N/A+ }
19928N/A+ else
19928N/A+ {
19928N/A+ rc = gksu_context_embedded_su_run (context, ask_pass, ask_pass_data, error);
19928N/A+ }
19928N/A+
19928N/A+ if ((*error == NULL) || ((*error)->code != GKSU_ERROR_WRONGPASS))
19928N/A+ break;
19928N/A+ }
19928N/A+ }
19928N/A
19928N/A+ reset_xauth (context);
19928N/A+
19928N/A+ return rc;
19928N/A+#else
19928N/A if (!g_file_test (auxcommand, G_FILE_TEST_IS_EXECUTABLE))
19928N/A {
19928N/A g_set_error (error, gksu_quark, GKSU_ERROR_HELPER,
19928N/A@@ -2347,6 +2259,7 @@ gksu_su_fuller (GksuContext *context,
19928N/A return FALSE;
19928N/A
19928N/A return TRUE;
19928N/A+#endif
19928N/A }
19928N/A
19928N/A /**
19928N/A@@ -2368,8 +2281,15 @@ gksu_su (gchar *command_line, GError **e
19928N/A GksuContext *context = gksu_context_new ();
19928N/A gboolean retval;
19928N/A
19928N/A- context->command = g_strdup (command_line);
19928N/A+ /* Set defaults to use embedded_su */
19928N/A context->user = g_strdup ("root");
19928N/A+ context->command = g_strdup (command_line);
19928N/A+ context->elevated_privilege = FALSE;
19928N/A+ context->elevated_role = TRUE;
19928N/A+ context->wait_for_child_to_exit = FALSE;
19928N/A+ context->grab = FALSE;
19928N/A+ context->privspec = g_strdup ("All");
19928N/A+
19928N/A retval = gksu_su_full (context,
19928N/A NULL, NULL,
19928N/A NULL, NULL,
19928N/A@@ -2433,6 +2353,29 @@ gksu_sudo_full (GksuContext *context,
19928N/A NULL, error);
19928N/A }
19928N/A
19928N/A+static char *
19928N/A+get_sudo_tok (GksuContext *context, FILE *inf, const char *delimiter)
19928N/A+{
19928N/A+ GString *token;
19928N/A+ char c[2];
19928N/A+
19928N/A+ token = g_string_new ("");
19928N/A+
19928N/A+ c[0] = '\n';
19928N/A+ c[1] = '\0';
19928N/A+
19928N/A+ while ((c[0] = fgetc(inf)) != EOF) {
19928N/A+ token = g_string_append (token, c);
19928N/A+
19928N/A+ if (g_strrstr (token->str, delimiter) ||
19928N/A+ strncmp (token->str, "GNOME_SUDO_PASS", 15) == 0) {
19928N/A+ break;
19928N/A+ }
19928N/A+ }
19928N/A+
19928N/A+ return g_string_free (token, FALSE);
19928N/A+}
19928N/A+
19928N/A /**
19928N/A * gksu_sudo_fuller:
19928N/A * @context: a #GksuContext
19928N/A@@ -2472,7 +2415,7 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A GError **error)
19928N/A {
19928N/A char **cmd;
19928N/A- char buffer[256] = {0};
19928N/A+ char *buffer;
19928N/A char *child_stderr = NULL;
19928N/A /* This command is used to gain a token */
19928N/A char *const verifycmd[] =
19928N/A@@ -2481,22 +2424,21 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A };
19928N/A int argcount = 8;
19928N/A int i, j;
19928N/A+ int parent_pipe[2]; /* For talking to the parent */
19928N/A+ int child_pipe[2]; /* For talking to the child */
19928N/A+ FILE *infile, *outfile;
19928N/A
19928N/A GQuark gksu_quark;
19928N/A
19928N/A- gchar *xauth = NULL,
19928N/A- *xauth_env = NULL;
19928N/A-
19928N/A pid_t pid;
19928N/A int status;
19928N/A- FILE *fdfile = NULL;
19928N/A- int fdpty = -1;
19928N/A+ gchar *home_env;
19928N/A
19928N/A context->sudo_mode = TRUE;
19928N/A
19928N/A gksu_quark = g_quark_from_string (PACKAGE);
19928N/A
19928N/A- if (!context->command)
19928N/A+ if (!context->command || context->command[0] == '\0')
19928N/A {
19928N/A g_set_error (error, gksu_quark, GKSU_ERROR_NOCOMMAND,
19928N/A _("gksu_sudo_run needs a command to be run, "
19928N/A@@ -2504,8 +2446,11 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A return FALSE;
19928N/A }
19928N/A
19928N/A- if (!context->user)
19928N/A- context->user = g_strdup ("root");
19928N/A+ if (context->saved_home == NULL)
19928N/A+ {
19928N/A+ home_env = getenv ("HOME");
19928N/A+ context->saved_home = home_env;
19928N/A+ }
19928N/A
19928N/A if (ask_pass == NULL)
19928N/A {
19928N/A@@ -2524,24 +2469,16 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A g_spawn_command_line_sync("/usr/bin/sudo -K", NULL, NULL, &exit_status, NULL);
19928N/A }
19928N/A
19928N/A-
19928N/A /*
19928N/A FIXME: need to set GError in a more detailed way
19928N/A */
19928N/A- if (!sudo_prepare_xauth (context))
19928N/A+ if (!prepare_xauth (context))
19928N/A {
19928N/A g_set_error (error, gksu_quark, GKSU_ERROR_XAUTH,
19928N/A- _("Unable to copy the user's Xauthorization file."));
19928N/A+ _("Unable to setup the user's Xauthorization file."));
19928N/A return FALSE;
19928N/A }
19928N/A
19928N/A- /* sets XAUTHORITY */
19928N/A- xauth = g_strdup_printf ("%s/.Xauthority", context->dir);
19928N/A- xauth_env = getenv ("XAUTHORITY");
19928N/A- setenv ("XAUTHORITY", xauth, TRUE);
19928N/A- if (context->debug)
19928N/A- fprintf (stderr, "xauth: %s\n", xauth);
19928N/A-
19928N/A /* set startup id */
19928N/A if (context->sn_context)
19928N/A gksu_context_launch_initiate (context);
19928N/A@@ -2647,18 +2584,39 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A fprintf (stderr, "cmd[%d]: %s\n", i, cmd[i]);
19928N/A }
19928N/A
19928N/A- pid = forkpty(&fdpty, NULL, NULL, NULL);
19928N/A- if (pid == 0)
19928N/A+ if ((pipe(parent_pipe)) == -1)
19928N/A+ {
19928N/A+ reset_xauth (context);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ if ((pipe(child_pipe)) == -1)
19928N/A+ {
19928N/A+ reset_xauth (context);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ pid = fork();
19928N/A+ if (pid == -1)
19928N/A+ {
19928N/A+ reset_xauth (context);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+ else if (pid == 0)
19928N/A {
19928N/A // Child
19928N/A setsid(); // make us session leader
19928N/A
19928N/A+ close(child_pipe[1]);
19928N/A+ dup2(child_pipe[0], STDIN_FILENO);
19928N/A+ dup2(parent_pipe[1], STDERR_FILENO);
19928N/A+
19928N/A execv(verifycmd[0], verifycmd);
19928N/A
19928N/A g_set_error (error, gksu_quark, GKSU_ERROR_EXEC,
19928N/A _("Failed to exec new process: %s"),
19928N/A strerror(errno));
19928N/A- sudo_reset_xauth (context, xauth, xauth_env);
19928N/A+ reset_xauth (context);
19928N/A return FALSE;
19928N/A }
19928N/A else if (pid == -1)
19928N/A@@ -2666,29 +2624,45 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A g_set_error (error, gksu_quark, GKSU_ERROR_FORK,
19928N/A _("Failed to fork new process: %s"),
19928N/A strerror(errno));
19928N/A- sudo_reset_xauth (context, xauth, xauth_env);
19928N/A+ reset_xauth (context);
19928N/A return FALSE;
19928N/A }
19928N/A
19928N/A else
19928N/A {
19928N/A+ // Parent
19928N/A gint counter = 0;
19928N/A gchar *cmdline = NULL;
19928N/A struct termios tio;
19928N/A+ gboolean had_error = FALSE;
19928N/A
19928N/A- // Parent
19928N/A- fdfile = fdopen(fdpty, "w+");
19928N/A+ close(parent_pipe[1]);
19928N/A
19928N/A+ infile = fdopen(parent_pipe[0], "r");
19928N/A+ if (!infile)
19928N/A+ {
19928N/A+ reset_xauth (context);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ outfile = fdopen(child_pipe[1], "w");
19928N/A+ if (!outfile)
19928N/A+ {
19928N/A+ reset_xauth (context);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+#if 0
19928N/A /* make sure we notice that ECHO is turned off, if it gets
19928N/A turned off */
19928N/A- tcgetattr (fdpty, &tio);
19928N/A+ tcgetattr (parent_pipe[0], &tio);
19928N/A for (counter = 0; (tio.c_lflag & ECHO) && counter < 15; counter++)
19928N/A {
19928N/A usleep (1000);
19928N/A- tcgetattr (fdpty, &tio);
19928N/A+ tcgetattr (parent_pipe[0], &tio);
19928N/A }
19928N/A
19928N/A- fcntl (fdpty, F_SETFL, O_NONBLOCK);
19928N/A+ fcntl (parent_pipe[0], F_SETFL, O_NONBLOCK);
19928N/A
19928N/A { /* no matter if we can read, since we're using
19928N/A O_NONBLOCK; this is just to avoid the prompt
19928N/A@@ -2697,12 +2671,17 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A struct timeval tv;
19928N/A
19928N/A FD_ZERO(&rfds);
19928N/A- FD_SET(fdpty, &rfds);
19928N/A+ FD_SET(parent_pipe[0], &rfds);
19928N/A tv.tv_sec = 1;
19928N/A tv.tv_usec = 0;
19928N/A
19928N/A- select (fdpty + 1, &rfds, NULL, NULL, &tv);
19928N/A+ select (parent_pipe[0] + 1, &rfds, NULL, NULL, &tv);
19928N/A }
19928N/A+#endif
19928N/A+
19928N/A+ while (1)
19928N/A+ {
19928N/A+ buffer = get_sudo_tok (context, infile, "\n");
19928N/A
19928N/A /* Try hard to find the prompt; it may happen that we're
19928N/A * seeing sudo's lecture, or that some pam module is spitting
19928N/A@@ -2710,30 +2689,42 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A */
19928N/A for (counter = 0; counter < 50; counter++)
19928N/A {
19928N/A+ if (context->debug)
19928N/A+ fprintf (stderr, "buffer: -%s-\n", buffer);
19928N/A+
19928N/A+ if (g_str_has_prefix (buffer, "Sorry, try again."))
19928N/A+ had_error = TRUE;
19928N/A+
19928N/A if (strncmp (buffer, "GNOME_SUDO_PASS", 15) == 0)
19928N/A break;
19928N/A
19928N/A- read_line (fdpty, buffer, 256);
19928N/A-
19928N/A- if (context->debug)
19928N/A- fprintf (stderr, "buffer: -%s-\n", buffer);
19928N/A+ buffer = get_sudo_tok (context, infile, "\n");
19928N/A
19928N/A usleep(1000);
19928N/A }
19928N/A
19928N/A if (context->debug)
19928N/A- fprintf (stderr, "brute force GNOME_SUDO_PASS ended...\n");
19928N/A+ fprintf (stderr, "brute force GNOME_SUDO_PASS ended - count %d...\n", counter);
19928N/A+
19928N/A+ /* If we tried 50 times, stop trying. */
19928N/A+ if (counter == 50)
19928N/A+ break;
19928N/A
19928N/A if (strncmp(buffer, "GNOME_SUDO_PASS", 15) == 0)
19928N/A {
19928N/A gchar *password = NULL;
19928N/A gboolean prompt_grab;
19928N/A
19928N/A+ had_error = FALSE;
19928N/A+
19928N/A if (context->debug)
19928N/A- fprintf (stderr, "Yeah, we're in...\n");
19928N/A+ fprintf (stderr, "Asking for password.\n");
19928N/A
19928N/A+#if 0
19928N/A prompt_grab = gconf_client_get_bool (context->gconf_client, BASE_PATH "prompt",
19928N/A NULL);
19928N/A+#endif
19928N/A+ prompt_grab = FALSE;
19928N/A if (prompt_grab)
19928N/A gksu_prompt_grab (context);
19928N/A
19928N/A@@ -2742,22 +2733,28 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A if (password == NULL || (*error))
19928N/A {
19928N/A nullify_password (password);
19928N/A+ reset_xauth (context);
19928N/A return FALSE;
19928N/A }
19928N/A
19928N/A usleep (1000);
19928N/A
19928N/A- write (fdpty, password, strlen(password) + 1);
19928N/A- write (fdpty, "\n", 1);
19928N/A+ write (child_pipe[1], password, strlen(password));
19928N/A+ write (child_pipe[1], "\n", strlen("\n"));
19928N/A
19928N/A nullify_password (password);
19928N/A
19928N/A- fcntl(fdpty, F_SETFL, fcntl(fdpty, F_GETFL) & ~O_NONBLOCK);
19928N/A+#if 0
19928N/A+ fcntl(parent_pipe[0], F_SETFL, fcntl(parent_pipe[0], F_GETFL) & ~O_NONBLOCK);
19928N/A /* ignore the first newline that comes right after sudo receives
19928N/A the password */
19928N/A- fgets (buffer, 255, fdfile);
19928N/A- /* this is the status we are interested in */
19928N/A- fgets (buffer, 255, fdfile);
19928N/A+ read_line (parent_pipe[0], buffer, 256);
19928N/A+ if (context->debug)
19928N/A+ fprintf (stderr, "buffer: -%s-\n", buffer);
19928N/A+ read_line (parent_pipe[0], buffer, 256);
19928N/A+ if (context->debug)
19928N/A+ fprintf (stderr, "buffer: -%s-\n", buffer);
19928N/A+#endif
19928N/A }
19928N/A else
19928N/A {
19928N/A@@ -2766,10 +2763,15 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A fprintf (stderr, "No password prompt found; we'll assume we don't need a password.\n");
19928N/A
19928N/A /* turn NONBLOCK off, also if have no prompt */
19928N/A- fcntl(fdpty, F_SETFL, fcntl(fdpty, F_GETFL) & ~O_NONBLOCK);
19928N/A+/*
19928N/A+ fcntl(parent_pipe[0], F_SETFL, fcntl(infile, F_GETFL) & ~O_NONBLOCK);
19928N/A+*/
19928N/A
19928N/A+#if 0
19928N/A should_display = gconf_client_get_bool (context->gconf_client,
19928N/A BASE_PATH "display-no-pass-info", NULL);
19928N/A+#endif
19928N/A+ should_display = FALSE;
19928N/A
19928N/A /* configuration tells us to show this message */
19928N/A if (should_display)
19928N/A@@ -2784,30 +2786,17 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A
19928N/A fprintf (stderr, "%s", buffer);
19928N/A }
19928N/A-
19928N/A- if (g_str_has_prefix (buffer, "Sorry, try again."))
19928N/A- g_set_error (error, gksu_quark, GKSU_ERROR_WRONGPASS,
19928N/A- _("Wrong password."));
19928N/A- else
19928N/A- {
19928N/A- gchar *haystack = buffer;
19928N/A- gchar *needle;
19928N/A-
19928N/A- needle = g_strstr_len (haystack, strlen (haystack), " ");
19928N/A- if (needle && (needle + 1))
19928N/A- {
19928N/A- needle += 1;
19928N/A- if (!strncmp (needle, "is not in", 9))
19928N/A- g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
19928N/A- _("The underlying authorization mechanism (sudo) "
19928N/A- "does not allow you to run this program. Contact "
19928N/A- "the system administrator."));
19928N/A- }
19928N/A }
19928N/A
19928N/A+ if (*error == NULL && had_error == TRUE)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_WRONGPASS,
19928N/A+ _("Wrong password."));
19928N/A+ }
19928N/A+
19928N/A /* If we have an error, let's just stop sudo right there. */
19928N/A if (error)
19928N/A- close(fdpty);
19928N/A+ close(parent_pipe[0]);
19928N/A
19928N/A cmdline = g_strdup("sudo");
19928N/A /* wait for the child process to end or become something other
19928N/A@@ -2828,7 +2817,6 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A /* if the process is still active waitpid() on it */
19928N/A if (pid_exited != pid)
19928N/A waitpid(pid, &status, 0);
19928N/A- sudo_reset_xauth (context, xauth, xauth_env);
19928N/A
19928N/A /*
19928N/A * Did token acquisition succeed? If so, spawn sudo in
19928N/A@@ -2841,6 +2829,11 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A NULL, &child_stderr, &status,
19928N/A error);
19928N/A }
19928N/A+ else if (buffer)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
19928N/A+ buffer);
19928N/A+ }
19928N/A
19928N/A if (exit_status)
19928N/A {
19928N/A@@ -2853,7 +2846,7 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A
19928N/A if (WEXITSTATUS(status))
19928N/A {
19928N/A- if (g_str_has_prefix(child_stderr, "Sorry, user "))
19928N/A+ if (child_stderr != NULL && g_str_has_prefix(child_stderr, "Sorry, user "))
19928N/A {
19928N/A g_set_error (error, gksu_quark, GKSU_ERROR_NOT_ALLOWED,
19928N/A _("The underlying authorization mechanism (sudo) "
19928N/A@@ -2869,6 +2862,7 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A {
19928N/A g_free (cmdline);
19928N/A g_free (child_stderr);
19928N/A+ reset_xauth (context);
19928N/A return FALSE;
19928N/A }
19928N/A g_free (cmdline);
19928N/A@@ -2881,7 +2875,7 @@ gksu_sudo_fuller (GksuContext *context,
19928N/A }
19928N/A }
19928N/A
19928N/A- fprintf(stderr, child_stderr);
19928N/A+ reset_xauth (context);
19928N/A g_free(child_stderr);
19928N/A
19928N/A /* if error is set we have found an error condition */
19928N/A@@ -2908,8 +2902,14 @@ gksu_sudo (gchar *command_line,
19928N/A GksuContext *context = gksu_context_new ();
19928N/A gboolean retval;
19928N/A
19928N/A- context->command = g_strdup (command_line);
19928N/A context->user = g_strdup ("root");
19928N/A+ context->command = g_strdup (command_line);
19928N/A+ context->elevated_privilege = FALSE;
19928N/A+ context->elevated_role = TRUE;
19928N/A+ context->wait_for_child_to_exit = FALSE;
19928N/A+ context->grab = FALSE;
19928N/A+ context->privspec = g_strdup ("All");
19928N/A+
19928N/A retval = gksu_sudo_full (context,
19928N/A NULL, NULL,
19928N/A NULL, NULL,
19928N/A@@ -2989,13 +2989,18 @@ gksu_run_fuller (GksuContext *context,
19928N/A gint8 *exit_status,
19928N/A GError **error)
19928N/A {
19928N/A+#if 0
19928N/A GConfClient *gconf_client;
19928N/A+#endif
19928N/A gboolean sudo_mode;
19928N/A
19928N/A+#if 0
19928N/A gconf_client = gconf_client_get_default ();
19928N/A sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
19928N/A NULL);
19928N/A g_object_unref (gconf_client);
19928N/A+#endif
19928N/A+ sudo_mode = FALSE;
19928N/A
19928N/A if (sudo_mode)
19928N/A return gksu_sudo_fuller (context, ask_pass, ask_pass_data,
19928N/A@@ -3024,13 +3029,18 @@ gboolean
19928N/A gksu_run (gchar *command_line,
19928N/A GError **error)
19928N/A {
19928N/A+#if 0
19928N/A GConfClient *gconf_client;
19928N/A+#endif
19928N/A gboolean sudo_mode;
19928N/A
19928N/A+#if 0
19928N/A gconf_client = gconf_client_get_default ();
19928N/A sudo_mode = gconf_client_get_bool (gconf_client, BASE_PATH "sudo-mode",
19928N/A NULL);
19928N/A g_object_unref (gconf_client);
19928N/A+#endif
19928N/A+ sudo_mode = FALSE;
19928N/A
19928N/A if (sudo_mode)
19928N/A return gksu_sudo (command_line, error);
19928N/A--- libgksu-2.0.12/libgksu/test-gksu.c-orig 2010-12-10 00:27:16.598159280 -0600
19928N/A+++ libgksu-2.0.12/libgksu/test-gksu.c 2010-12-10 00:27:50.606354260 -0600
19928N/A@@ -46,6 +46,9 @@ main (int argc, char **argv)
19928N/A gboolean try_su = TRUE;
19928N/A gboolean try_sudo = TRUE;
19928N/A gboolean try_run = TRUE;
19928N/A+ int stdin_fd, stdout_fd;
19928N/A+ FILE *infile, *outfile;
19928N/A+ pid_t child_pid;
19928N/A
19928N/A if (argc > 1)
19928N/A {
19928N/A@@ -62,13 +65,25 @@ main (int argc, char **argv)
19928N/A
19928N/A context = gksu_context_new ();
19928N/A
19928N/A- context->debug = TRUE;
19928N/A- context->command = g_strdup ("/usr/bin/xterm");
19928N/A+ gksu_context_set_user (context, "root");
19928N/A+ gksu_context_set_debug (context, TRUE);
19928N/A+ gksu_context_set_command (context, "/usr/bin/X11/xterm");
19928N/A+ gksu_context_set_elevated_privilege (context, FALSE);
19928N/A+ gksu_context_set_elevated_role (context, TRUE);
19928N/A+ gksu_context_set_wait_for_child_to_exit (context, FALSE);
19928N/A+ gksu_context_set_privspec (context, "All");
19928N/A+ gksu_context_set_command (context, "/usr/bin/ids");
19928N/A+ if ( gksu_context_get_wait_for_child_to_exit (context) ) {
19928N/A+ gksu_context_set_command (context, "/usr/bin/ids");
19928N/A+ } else {
19928N/A+ gksu_context_set_command (context, "/usr/bin/ids --nowait");
19928N/A+ }
19928N/A
19928N/A if (try_su)
19928N/A {
19928N/A+ error = NULL;
19928N/A printf ("Testing gksu_su...\n");
19928N/A- gksu_su ("/usr/bin/xterm", &error);
19928N/A+ gksu_su ("/usr/bin/ids", &error);
19928N/A if (error)
19928N/A fprintf (stderr, "gksu_su failed: %s\n", error->message);
19928N/A
19928N/A@@ -80,6 +95,7 @@ main (int argc, char **argv)
19928N/A &error);
19928N/A }
19928N/A
19928N/A+#if 0
19928N/A /* of course you need to set up /etc/sudoers for this to work */
19928N/A if (try_sudo)
19928N/A {
19928N/A@@ -116,6 +132,7 @@ main (int argc, char **argv)
19928N/A if (error)
19928N/A fprintf (stderr, "gksu_run_full failed: %s\n", error->message);
19928N/A }
19928N/A+#endif
19928N/A
19928N/A return 0;
19928N/A }
19928N/A--- /dev/null 2010-12-10 01:34:03.000000000 -0600
19928N/A+++ libgksu-2.0.12/libgksu/libgksu-solaris.c 2010-12-10 01:33:40.655550663 -0600
20153N/A@@ -0,0 +1,1243 @@
19928N/A+#include "libgksu.h"
19928N/A+#include "config.h"
19928N/A+
19928N/A+#include <sys/types.h>
19928N/A+#include <sys/stat.h>
19928N/A+#include <sys/wait.h>
19928N/A+#include <stdlib.h>
19928N/A+#include <fcntl.h>
19928N/A+#include <unistd.h>
19928N/A+#include <signal.h>
19928N/A+#include <stropts.h>
19928N/A+#include <strings.h>
19928N/A+#include <pwd.h>
19928N/A+#include <errno.h>
19928N/A+#include <dlfcn.h>
19928N/A+
19928N/A+#include <glib.h>
19928N/A+#include <glib/gi18n.h>
19928N/A+
19928N/A+#define MAX_BUFFER_SIZE 1024
19928N/A+#define CONTEXT_DEBUG_ON(context) (context->debug)
19928N/A+
19928N/A+static gchar *
19928N/A+sudo_get_home_dir (GksuContext *context)
19928N/A+{
19928N/A+ struct passwd *pwentry;
19928N/A+
19928N/A+ pwentry = getpwnam (gksu_context_get_user (context));
19928N/A+ return g_strdup (pwentry->pw_dir);
19928N/A+}
19928N/A+
19928N/A+static void
19928N/A+sudo_reset_home_dir (gchar *home_env)
19928N/A+{
19955N/A+ /* reset the env var as it was before or clear it */
19928N/A+ if (home_env)
19928N/A+ setenv ("HOME", home_env, TRUE);
19928N/A+ else
19928N/A+ unsetenv("HOME");
19928N/A+}
19928N/A+
19928N/A+char *
19928N/A+get_tok (GksuContext *context, FILE *inf, const char *delimiter)
19928N/A+{
19928N/A+ GString *token;
19955N/A+ char c[2];
19928N/A+
19955N/A+ token = g_string_new ("");
19928N/A+
19928N/A+ c[0] = '\n';
19928N/A+ c[1] = '\0';
19928N/A+
19928N/A+ while ((c[0] = fgetc(inf)) != EOF) {
19955N/A+ token = g_string_append (token, c);
19928N/A+
19928N/A+ /*
19928N/A+ * Fixed http://defect.opensolaris.org/bz/show_bug.cgi?id=11495
19928N/A+ *
19928N/A+ * If embedded_su returns SUCCESS, then turn off a11y in gksu
19928N/A+ * immediatly so that a11y works for child. We cannot wait
19928N/A+ * for the while loop to exit since this loop hangs until the
19928N/A+ * the child process completes to get any stdout from child.
19928N/A+ */
19955N/A+ if (strcmp (token->str, "SUCCESS\n") == 0) {
19928N/A+ if (atk_get_root() != NULL &&
19928N/A+ context->child_no_a11y == FALSE)
19928N/A+ {
19928N/A+ void *handle;
19928N/A+ void (*exit_func)(void);
19928N/A+
19928N/A+ handle = dlopen("/usr/lib/gtk-2.0/modules/libatk-bridge.so", RTLD_LAZY);
19928N/A+ if (handle)
19928N/A+ {
19928N/A+ exit_func = (void (*)(void))dlsym(handle,
19928N/A+ "gnome_accessibility_module_shutdown");
19928N/A+ if (exit_func)
19928N/A+ (*exit_func)();
19928N/A+ dlclose(handle);
19928N/A+ }
19928N/A+ }
19928N/A+ }
19928N/A+
19955N/A+ if (g_strrstr (token->str, delimiter)) {
19928N/A+ break;
19928N/A+ }
19928N/A+ }
19928N/A+
19955N/A+ return g_string_free (token, FALSE);
19928N/A+}
19928N/A+
19928N/A+void
19928N/A+set_embedded_su_alert (GksuContext *context)
19928N/A+{
19928N/A+ gchar *msg;
19928N/A+
19928N/A+ if (strncmp (context->pam_message->msg, "embedded_su: ", strlen ("embedded_su: ")) == 0) {
19928N/A+ msg = g_strdup_printf ("<b>%s %s</b>",
19928N/A+ /* SUN_BRANDING */
19928N/A+ _("Issue with password."),
19928N/A+ context->pam_message->msg + strlen ("embedded_su: "));
19928N/A+ } else {
19928N/A+ msg = g_strdup_printf ("<b>%s %s</b>",
19928N/A+ /* SUN_BRANDING */
19928N/A+ _("Issue with password."),
19928N/A+ context->pam_message->msg);
19928N/A+ }
19928N/A+
19928N/A+ gksu_context_set_alert (context, msg);
19928N/A+}
19928N/A+
19928N/A+gboolean
19928N/A+parse_embedded_su_output (GksuContext *context, FILE *infile)
19928N/A+{
19928N/A+ const char *block_delimiter = ".\n";
19928N/A+ char *block = NULL;
19928N/A+ char *message;
19928N/A+ int num = 0;
19928N/A+
19928N/A+ while ((block = get_tok (context, infile, block_delimiter)) != NULL) {
19928N/A+ char *message_p = NULL;
19928N/A+ char *childoutput;
19928N/A+ const char *message_delimiter = "\n";
19928N/A+
19928N/A+ message = NULL;
19928N/A+
19928N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ fprintf (stderr, "Output from Child: %s\n", block);
19928N/A+
19928N/A+ childoutput = g_strdup (block);
19928N/A+
19928N/A+ /* Split block. */
19928N/A+ message = strtok_r(block, message_delimiter, &message_p);
19928N/A+
19928N/A+ if (message == NULL) {
19928N/A+ if (context->msg_type == ES_ERROR)
19928N/A+ return FALSE;
19928N/A+ continue;
19928N/A+ }
19928N/A+
19928N/A+ if (strncmp (message, "SUCCESS", strlen("SUCCESS")) == 0) {
19928N/A+ context->msg_type = ES_SUCCESS;
19928N/A+
19928N/A+ /* The message contains "SUCCESS\n" followed by the
19928N/A+ * command output so if you run "gksu ls" this will
19928N/A+ * cause the ls output to echo to the terminal.
19928N/A+ */
19928N/A+ message = childoutput + strlen ("SUCCESS\n");
19928N/A+ context->msg_num = 1;
19928N/A+ context->pam_message = (struct pam_message *)g_malloc (sizeof(struct pam_message));
19928N/A+ context->pam_message->msg_style = PAM_TEXT_INFO;
19928N/A+ context->pam_message->msg = strdup(message);
19955N/A+ break;
19928N/A+
19928N/A+ } else if (strncmp(message, "ERROR", strlen("ERROR")) == 0) {
19928N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ fprintf (stderr, "There are errors...\n");
19928N/A+ context->msg_type = ES_ERROR;
19928N/A+ /* Due embedded_su(1M) there is one TEXT BLOCK
19928N/A+ * need be parsed.
19928N/A+ */
19928N/A+ message = strtok_r(NULL, message_delimiter, &message_p);
19928N/A+ context->msg_num = 1;
19928N/A+ context->pam_message = (struct pam_message *)g_malloc (sizeof(struct pam_message));
19928N/A+ /* Consider all other output as a message. We
19928N/A+ * treat it like an error message because we
19928N/A+ * show error messages to users.
19928N/A+ */
19928N/A+ context->pam_message->msg_style = PAM_ERROR_MSG;
19928N/A+ context->pam_message->msg = strdup(message);
19928N/A+ if (context->alert == NULL) {
19928N/A+ set_embedded_su_alert (context);
19928N/A+ }
19955N/A+ break;
19928N/A+
19928N/A+ } else if (strncmp (message, "CONV", strlen("CONV")) == 0) {
19928N/A+ char *message_header;
19928N/A+ /* Get message number, then parse CONV block. */
19928N/A+ /* Ignore all other info in the same
19928N/A+ * line according to the manpage.
19928N/A+ */
19928N/A+ sscanf(message, "CONV %d", &(context->msg_num));
19928N/A+ /* Read all messages. */
19928N/A+ context->pam_message = (struct pam_message *)g_malloc ( sizeof(struct pam_message)*context->msg_num );
19928N/A+ context->pam_response = (struct pam_response *)g_malloc ( sizeof(struct pam_response)*context->msg_num );
19928N/A+
19928N/A+ for (int i = 0; i < context->msg_num; i++) {
19928N/A+ /* Get header line. */
19928N/A+ message_header = strtok_r(NULL, message_delimiter, &message_p);
19928N/A+ message = strtok_r(NULL, message_delimiter, &message_p);
19928N/A+
19928N/A+ context->pam_message[i].msg = strdup(message);
19928N/A+
19928N/A+ if (CONTEXT_DEBUG_ON(context)) {
19928N/A+ fprintf (stderr, "Got message %d: %s\n", i, message);
19928N/A+ }
19928N/A+
19928N/A+ if (strncmp(message_header, "PAM_PROMPT_ECHO_ON", strlen("PAM_PROMPT_ECHO_ON")) == 0) {
19928N/A+ context->pam_message[i].msg_style = PAM_PROMPT_ECHO_ON;
19928N/A+ context->msg_type = ES_PASSWORD;
19928N/A+
19928N/A+ } else if (strncmp(message_header, "PAM_PROMPT_ECHO_OFF", strlen("PAM_PROMPT_ECHO_OFF")) == 0) {
19928N/A+ context->pam_message[i].msg_style = PAM_PROMPT_ECHO_OFF;
19928N/A+ context->msg_type = ES_PASSWORD;
19928N/A+
19928N/A+ } else if (strncmp(message_header, "PAM_ERROR_MSG", strlen("PAM_ERROR_MSG")) == 0) {
19928N/A+ context->pam_message[i].msg_style = PAM_ERROR_MSG;
19928N/A+ if (context->alert == NULL) {
19928N/A+ set_embedded_su_alert (context);
19928N/A+ }
19928N/A+
19928N/A+ } else if (strncmp(message_header, "PAM_TEXT_INFO", strlen("PAM_TEXT_INFO")) == 0) {
19928N/A+ context->pam_message[i].msg_style = PAM_TEXT_INFO;
19928N/A+ }
19928N/A+ }
19955N/A+ break;
19928N/A+ } else {
19928N/A+ if (CONTEXT_DEBUG_ON(context)) {
19928N/A+ fprintf (stderr, "Output: %s\n", message);
19928N/A+ }
19955N/A+ }
19928N/A+ g_free (childoutput);
19928N/A+ bzero(block, strlen(block));
19928N/A+
19928N/A+ free(block);
19928N/A+ }
19928N/A+
19928N/A+ return TRUE;
19928N/A+}
19928N/A+
19928N/A+/**
19928N/A+ * try_embedded_su_validation
19928N/A+ * @context: a #GksuContext
19928N/A+ *
19928N/A+ * Checks if we need to ask for a password or if we have ways of
19928N/A+ * getting the password for ourselves or we simply don't need it.
19928N/A+ *
19928N/A+ * Returns: TRUE if requesting a password is needed, FALSE otherwise.
19928N/A+ *
19928N/A+ */
19928N/A+static gboolean
19928N/A+try_embedded_su_validation (GksuContext *context)
19928N/A+{
19928N/A+ char **cmd;
19928N/A+ int argcount = 4;
19928N/A+ char buffer[MAX_BUFFER_SIZE];
19928N/A+
19928N/A+ pid_t pid;
19928N/A+ int status;
19928N/A+ size_t r;
19928N/A+ FILE *infile, *outfile;
19928N/A+ int parent_pipe[2]; /* For talking to the parent */
19928N/A+ int child_pipe[2]; /* For talking to the child */
19928N/A+
19928N/A+ gboolean need_pass = TRUE;
19955N/A+
19928N/A+ bzero(buffer, MAX_BUFFER_SIZE);
19928N/A+
19928N/A+ if ((pipe(parent_pipe)) == -1)
19928N/A+ return TRUE;
19928N/A+
19928N/A+ if ((pipe(child_pipe)) == -1)
19928N/A+ return TRUE;
19928N/A+
19928N/A+ cmd = g_new (gchar *, argcount + 1);
19955N/A+
19928N/A+ argcount = 0;
19928N/A+
19928N/A+ /* embedded_su binary */
19928N/A+ cmd[argcount] = g_strdup("/usr/lib/embedded_su");
19928N/A+ argcount++;
19928N/A+
19928N/A+ if (context->login_shell)
19928N/A+ {
19928N/A+ cmd[argcount] = g_strdup ("-"); argcount++;
19928N/A+ }
19928N/A+
19928N/A+ cmd[argcount] = g_strdup (context->user);
19928N/A+ argcount++;
19928N/A+
19928N/A+ cmd[argcount] = g_strdup ("-c");
19928N/A+ argcount++;
19928N/A+
19928N/A+ cmd[argcount] = g_strdup ("echo > /dev/null");
19928N/A+ argcount++;
19928N/A+
19928N/A+ cmd[argcount] = NULL;
19928N/A+
19928N/A+ pid = fork ();
19928N/A+ if (pid == -1)
19928N/A+ return TRUE;
19928N/A+ else if (pid == 0)
19928N/A+ {
19928N/A+ // Child
19928N/A+ close(child_pipe[1]);
19928N/A+ dup2(child_pipe[0], STDIN_FILENO);
19928N/A+ dup2(parent_pipe[1], STDOUT_FILENO);
19955N/A+
19928N/A+ execv(cmd[0], cmd);
19955N/A+
19928N/A+ return TRUE;
19928N/A+ }
19928N/A+ else
19928N/A+ {
19928N/A+ // Parent
19928N/A+ close(parent_pipe[1]);
19955N/A+
19928N/A+ infile = fdopen(parent_pipe[0], "r");
19928N/A+ if (!infile)
19928N/A+ return TRUE;
19928N/A+
19928N/A+ outfile = fdopen(child_pipe[1], "w");
19928N/A+ if (!outfile)
19928N/A+ return TRUE;
19928N/A+
19928N/A+ // start conversation with embedded_su
19928N/A+ write (child_pipe[1], ".\n", 2);
19928N/A+
19928N/A+ /*
19928N/A+ we are expecting to receive a GNOME_SUDO_PASS
19928N/A+ if we don't there are two possibilities: an error
19928N/A+ or a password is not needed
19928N/A+ */
19928N/A+ parse_embedded_su_output(context, infile);
19928N/A+
19928N/A+ switch (context->msg_type) {
19928N/A+ case ES_SUCCESS:
19928N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ fprintf (stderr, "Success!\n");
19928N/A+
19928N/A+ need_pass = FALSE;
19928N/A+ break;
19928N/A+
19928N/A+ case ES_ERROR:
19928N/A+ break;
19928N/A+
19928N/A+ case ES_PASSWORD:
19928N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ fprintf (stderr, "Asking for password...\n");
19928N/A+ break;
19928N/A+
19928N/A+ default:
19928N/A+ break;
19928N/A+ }
19928N/A+
19928N/A+ /* Busy wait. */
19928N/A+ while (!waitpid (pid, &status, WNOHANG)) {
19928N/A+ write (child_pipe[1], "\n", 1);
19928N/A+ kill (pid, SIGKILL);
19928N/A+ fgetc(infile);
19928N/A+ }
19928N/A+
19928N/A+ close(parent_pipe[0]);
19928N/A+ close(child_pipe[1]);
19928N/A+ }
19928N/A+
19928N/A+ return need_pass;
19928N/A+}
19928N/A+
19928N/A+/**
19928N/A+ * gksu_context_embedded_su_run:
19928N/A+ * @context: a #GksuContext
19928N/A+ * @error: a #GError object to be filled with the error code or NULL
19928N/A+ *
19928N/A+ * This could be considered one of the main functions in GKSu.
19928N/A+ * it is responsible for doing the 'user changing' magic by
19928N/A+ * calling gksu_ask_password() if it needs the user's password
19928N/A+ * it behaves like sudo.
19928N/A+ *
19928N/A+ * Returns: the child's error status, TRUE if all went fine, FALSE if failed
19928N/A+ */
19928N/A+gboolean
19928N/A+gksu_context_embedded_su_run (GksuContext *context,
19928N/A+ GksuAskPassFunc ask_pass,
19928N/A+ gpointer ask_pass_data,
19928N/A+ GError **error)
19928N/A+
19928N/A+{
19928N/A+ char **cmd;
19928N/A+ char buffer[MAX_BUFFER_SIZE];
19928N/A+ int argcount = 8;
19928N/A+ int i, j;
19928N/A+
19928N/A+ GQuark gksu_quark;
19928N/A+
19955N/A+ gchar *home = NULL, *home_env = NULL;
19928N/A+ pid_t pid;
19928N/A+ int status;
19928N/A+ size_t r;
19928N/A+ FILE *infile, *outfile;
19928N/A+ int parent_pipe[2]; /* For talking to the parent */
19928N/A+ int child_pipe[2]; /* For talking to the child */
19955N/A+
19928N/A+ gksu_quark = g_quark_from_string (PACKAGE_NAME);
19928N/A+
19928N/A+ if (!context->command)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_NOCOMMAND,
19928N/A+ _("gksu_sudo_run needs a command to be run, "
19928N/A+ "none was provided."));
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ /*
19928N/A+ * Check if the HOME environment variable is set in the user's
19928N/A+ * environment. If so unset it:
19928N/A+ * This will ensure that apps that require write
19928N/A+ * permission eg. gconf client applications, will work.
19928N/A+ */
19928N/A+ home_env = getenv ("HOME");
19928N/A+ home = sudo_get_home_dir (context);
19928N/A+ setenv ("HOME", home, TRUE);
19928N/A+
19928N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ {
19928N/A+ fprintf (stderr, "HOME: %s\n", home);
19928N/A+ }
19928N/A+
19928N/A+ g_free(home);
19928N/A+ cmd = g_new (gchar *, argcount + 1);
19955N/A+
19928N/A+ argcount = 0;
19928N/A+
19928N/A+ /* embedded_su binary */
19928N/A+ cmd[argcount] = g_strdup("/usr/lib/embedded_su");
19928N/A+ argcount++;
19928N/A+
19928N/A+ if (context->login_shell)
19928N/A+ {
19928N/A+ cmd[argcount] = g_strdup("-");
19928N/A+ argcount++;
19928N/A+ }
19928N/A+
19928N/A+ /* user */
19928N/A+ cmd[argcount] = g_strdup(context->user);
19928N/A+ argcount++;
19928N/A+
19928N/A+ /* command */
19928N/A+ cmd[argcount] = g_strdup("-c");
19928N/A+ argcount++;
19928N/A+
19928N/A+ cmd[argcount] = g_strdup_printf("%s", context->command);
19928N/A+ argcount++;
19928N/A+
19928N/A+
19928N/A+ cmd[argcount] = NULL;
19928N/A+
19928N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ {
19928N/A+ for (i = 0; cmd[i] != NULL; i++)
19928N/A+ fprintf (stderr, "cmd[%d]: %s\n", i, cmd[i]);
19928N/A+ }
19928N/A+
19928N/A+ if ((pipe(parent_pipe)) == -1)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
19928N/A+ _("Error creating pipe: %s"),
19928N/A+ strerror(errno));
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ if ((pipe(child_pipe)) == -1)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
19928N/A+ _("Error creating pipe: %s"),
19928N/A+ strerror(errno));
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ pid = fork ();
19928N/A+ if (pid == -1)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_FORK,
19928N/A+ _("Failed to fork new process: %s"),
19928N/A+ strerror(errno));
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+ else if (pid == 0)
19928N/A+ {
19928N/A+ // Child
19928N/A+ setsid(); // make us session leader
19928N/A+ close(child_pipe[1]);
19928N/A+ dup2(child_pipe[0], STDIN_FILENO);
19928N/A+ dup2(parent_pipe[1], STDERR_FILENO);
19928N/A+ dup2(parent_pipe[1], STDOUT_FILENO);
19955N/A+
19928N/A+ execv(cmd[0], cmd);
19955N/A+
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_EXEC,
19928N/A+ _("Failed to exec new process: %s"),
19928N/A+ strerror(errno));
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+ else
19928N/A+ {
19928N/A+ gboolean more_data = TRUE;
19928N/A+
19928N/A+ // Parent
19928N/A+ close(parent_pipe[1]);
19955N/A+
19928N/A+ infile = fdopen(parent_pipe[0], "r");
19928N/A+ if (!infile)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
19928N/A+ _("Error opening pipe: %s"),
19928N/A+ strerror(errno));
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ outfile = fdopen(child_pipe[1], "w");
19928N/A+ if (!outfile)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
19928N/A+ _("Error opening pipe: %s"),
19928N/A+ strerror(errno));
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+ context->stdin_fd = parent_pipe[0];
19928N/A+ context->stdout_fd = child_pipe[1];
19928N/A+ context->stdin_file = infile;
19928N/A+ context->stdout_file = outfile;
19928N/A+ setvbuf (context->stdin_file, NULL, _IONBF, 0);
19928N/A+ fcntl (context->stdin_fd, F_SETFL, 0);
19928N/A+ context->child_pid = pid;
19928N/A+
19928N/A+ // start conversation with embedded_su
19928N/A+ write (child_pipe[1], ".\n", 2);
19928N/A+
19928N/A+ /*
19928N/A+ we are expecting to receive a GNOME_SUDO_PASS
19928N/A+ if we don't there are two possibilities: an error
19928N/A+ or a password is not needed
19928N/A+ */
19928N/A+ /* 6995127 Gksu does not report expired password. We are in PAM
19928N/A+ * conversation, we need handle change the expired password. */
19928N/A+ do {
19928N/A+ gchar *password, *buf;
19928N/A+
19928N/A+ password = NULL;
19928N/A+
19928N/A+ more_data = parse_embedded_su_output(context, infile);
19928N/A+
19928N/A+ switch (context->msg_type) {
19928N/A+ case ES_SUCCESS:
19928N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ fprintf (stderr, "Success!\n");
19928N/A+ break;
19928N/A+
19928N/A+ case ES_ERROR:
19928N/A+ break;
19928N/A+
19928N/A+ case ES_PASSWORD:
19928N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ fprintf (stderr, "Asking for password...\n");
19928N/A+
19928N/A+ if ( context->pam_message[0].msg != NULL ) {
19928N/A+ buf = context->pam_message[0].msg;
19928N/A+ }
19928N/A+
19928N/A+ password = ask_pass (context, buf, ask_pass_data, error);
19928N/A+ context->alert = NULL;
19928N/A+
19928N/A+ if (password == NULL || (!strcmp (password, ""))) {
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ password = g_strchomp (password);
19928N/A+ write (child_pipe[1], password, strlen(password));
19928N/A+ write (child_pipe[1], "\n", strlen("\n"));
19928N/A+
19928N/A+ /* Reset flag so it does not get stuck */
19928N/A+ context->msg_type = 0;
19928N/A+
19928N/A+ usleep(500);
19928N/A+ break;
19928N/A+
19928N/A+ default:
19928N/A+ break;
19928N/A+ }
19928N/A+ } while (context->msg_type != ES_SUCCESS && more_data);
19928N/A+
19928N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ fprintf (stderr, "Done parsing embedded_su output!\n");
19928N/A+
19928N/A+ if (context->msg_type == ES_ERROR && context->msg_num > 0 && context->pam_message[0].msg != NULL)
19928N/A+ {
19928N/A+ gchar *utf8 = NULL;
19928N/A+
19928N/A+ utf8 = g_locale_to_utf8 (context->pam_message[0].msg, -1,
19955N/A+ NULL, NULL, NULL);
19928N/A+ if (utf8 == NULL)
19928N/A+ utf8 = g_strdup (context->pam_message[0].msg);
19928N/A+ *error = NULL;
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_WRONGPASS,
19955N/A+ utf8);
19928N/A+ g_free (utf8);
19928N/A+ }
19928N/A+ if (context->msg_type == ES_SUCCESS && context->pam_message[0].msg)
19928N/A+ fprintf (stdout, "%s", context->pam_message[0].msg);
19928N/A+
19928N/A+ if (!context->wait_for_child_to_exit) {
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ /* make sure we did read everything */
19928N/A+ while (!waitpid (pid, &status, WNOHANG)) {
19928N/A+ if (context->msg_type == ES_ERROR) {
19928N/A+ write (child_pipe[1], "\n", 1);
19928N/A+ kill (pid, SIGKILL);
19928N/A+ }
19928N/A+ fgetc(infile);
19928N/A+ }
19928N/A+
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+
19928N/A+ /* Do not reset error if already set to WRONGPASS */
19928N/A+ if (*error == NULL || (*error)->code != GKSU_ERROR_WRONGPASS)
19928N/A+ {
19928N/A+ if (WIFEXITED(status))
19928N/A+ {
19928N/A+ if (WEXITSTATUS(status))
19928N/A+ {
19928N/A+ *error = NULL;
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_CHILDFAILED,
19928N/A+ _("Child terminated with %d status"),
19928N/A+ WEXITSTATUS(status));
19928N/A+
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+ }
19928N/A+ }
19928N/A+
19928N/A+ }
19928N/A+
19928N/A+ return TRUE;
19928N/A+}
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_try_need_password (GksuContext *context)
19928N/A+{
20153N/A+ if ((context->elevated_privilege) && (gksu_context_pfexec_try_run (context)))
19928N/A+ {
19928N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ fprintf (stderr, "Enter pfexec mode!\n");
19928N/A+ context->pfexec_mode = TRUE;
19928N/A+ return FALSE;
20035N/A+ }
20035N/A+ else
19928N/A+ {
19928N/A+ context->pfexec_mode = FALSE;
19935N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ fprintf (stderr, "Enter embedded_su mode!\n");
20036N/A+ if (context->user != NULL) {
20037N/A+ if (CONTEXT_DEBUG_ON(context))
20037N/A+ fprintf (stderr, "Current user/role = %s\n", context->user);
20036N/A+ return try_embedded_su_validation (context);
20036N/A+ } else {
20036N/A+ return TRUE;
20036N/A+ }
19928N/A+ }
19928N/A+}
19928N/A+
19935N/A+static gchar *
19935N/A+get_stripped_exec (const gchar *full_exec)
19935N/A+{
19955N/A+ gchar *str1, *str2, *retval, *p;
19935N/A+
19955N/A+ str1 = g_strdup (full_exec);
19955N/A+ p = strtok (str1, " ");
19935N/A+
19955N/A+ if (p != NULL)
19955N/A+ str2 = g_strdup (p);
19955N/A+ else
19955N/A+ str2 = g_strdup (full_exec);
19935N/A+
19955N/A+ g_free (str1);
19935N/A+
19955N/A+ if (g_path_is_absolute (str2))
19955N/A+ retval = g_strdup (str2);
19955N/A+ else
19955N/A+ retval = g_strdup (g_find_program_in_path ((const gchar *)str2));
19955N/A+ g_free (str2);
19935N/A+
19955N/A+ return retval;
19935N/A+}
19935N/A+
19928N/A+gboolean
19928N/A+gksu_context_pfexec_try_run (GksuContext *context)
19928N/A+{
19935N/A+ userattr_t *user;
19955N/A+ struct passwd *pwd;
19928N/A+ gint ruid;
19955N/A+ char command_line[MAX_BUFFER_SIZE];
19935N/A+ char *path, *dir;
19935N/A+ char *stripped_cmd;
19928N/A+ int i;
19928N/A+ execattr_t *exec;
19928N/A+
19928N/A+ exec = NULL;
19928N/A+ ruid = getuid();
19955N/A+ pwd = getpwuid(ruid);
19955N/A+ if (pwd == NULL) {
19955N/A+ /* fail if we cannot get password entry */
19955N/A+ return FALSE;
19955N/A+ }
19928N/A+
19935N/A+ stripped_cmd = get_stripped_exec (context->command);
20095N/A+ if (stripped_cmd == NULL)
20095N/A+ return FALSE;
20095N/A+
19955N/A+ path = g_find_program_in_path (g_strstrip (stripped_cmd));
19935N/A+ if (path == NULL)
19935N/A+ return FALSE;
19935N/A+
20251N/A+ exec = getexecuser (pwd->pw_name, KV_COMMAND, stripped_cmd, GET_ONE);
19935N/A+
19928N/A+ if (exec == NULL) {
19955N/A+ if (CONTEXT_DEBUG_ON(context))
19955N/A+ fprintf (stderr, "Error getting exec attr\n");
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ while (exec != NULL) {
19955N/A+ if (CONTEXT_DEBUG_ON(context)) {
19928N/A+ fprintf (stderr, "Exec Name: %s\n", exec->name);
19928N/A+ fprintf (stderr, "Policy Name: %s\n", exec->policy);
19928N/A+ fprintf (stderr, "Exec Type: %s\n", exec->type);
19928N/A+ fprintf (stderr, "Exec Id: %s\n", exec->id);
19928N/A+ }
19955N/A+
20900N/A+ if (exec->attr != NULL) {
19955N/A+ if (CONTEXT_DEBUG_ON(context)) {
19955N/A+ fprintf (stderr, "User has access, using pfexec\n");
19955N/A+ }
19935N/A+ /* Set user value to the existing user */
19935N/A+ if (context->user == NULL) {
19935N/A+ context->user = g_strdup (g_get_user_name ());
19935N/A+ }
19935N/A+
19935N/A+ free_execattr (exec);
19928N/A+ return TRUE;
19928N/A+ }
19928N/A+ exec = exec->next;
19928N/A+ }
19935N/A+
19935N/A+ free_execattr (exec);
19935N/A+
19935N/A+ /*
19935N/A+ * If no user was specified, try to fill in the user with the role value that can
19935N/A+ * run this command.
19935N/A+ */
19935N/A+ if (context->elevated_role) {
19935N/A+ gksu_context_set_role (context);
19935N/A+ }
19935N/A+
19928N/A+ return FALSE;
19928N/A+}
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_set_role (GksuContext *context)
19928N/A+{
19955N/A+ struct passwd *pwd;
19928N/A+ gint ruid;
19928N/A+ execattr_t *exec;
19928N/A+
19928N/A+ char *rolelist = NULL;
19928N/A+ userattr_t *user;
19928N/A+ char *username;
19928N/A+ char *rolename;
19935N/A+ char *stripped_cmd;
19935N/A+ char *path;
19928N/A+ int i;
19928N/A+
19935N/A+ if (context->user != NULL)
19935N/A+ return TRUE;
19935N/A+
19935N/A+ user = getusernam (g_get_user_name ());
19935N/A+
19965N/A+ if (user == NULL) {
19965N/A+ if (CONTEXT_DEBUG_ON(context)) {
19965N/A+ fprintf (stderr, "No roles\n");
19965N/A+ }
19965N/A+ return FALSE;
19965N/A+ }
19965N/A+
19935N/A+ rolelist = kva_match (user->attr, USERATTR_ROLES_KW);
19935N/A+ if (rolelist == NULL) {
19955N/A+ if (CONTEXT_DEBUG_ON(context)) {
19955N/A+ fprintf (stderr, "No roles\n");
19955N/A+ }
19935N/A+ return FALSE;
19928N/A+ }
19928N/A+
19935N/A+ stripped_cmd = get_stripped_exec (context->command);
19955N/A+ path = g_find_program_in_path (g_strstrip (stripped_cmd));
19935N/A+ if (path == NULL)
19935N/A+ return FALSE;
19935N/A+
19928N/A+ /* Parse the rolename from the list and check execution profiles for
19928N/A+ * each role
19955N/A+ */
19928N/A+ rolename = strtok (rolelist, ",");
19928N/A+ while (rolename) {
19935N/A+ if (strcmp (rolename, "root") == 0) {
19955N/A+ if (CONTEXT_DEBUG_ON(context)) {
19955N/A+ fprintf (stderr, "User has root access.\n", rolename);
19955N/A+ }
19935N/A+ context->user = g_strdup (rolename);
19935N/A+ return TRUE;
19935N/A+ }
19935N/A+
19955N/A+ if (CONTEXT_DEBUG_ON(context)) {
19955N/A+ fprintf (stderr, "Checking role %s\n", rolename);
19955N/A+ }
19955N/A+
20251N/A+ exec = getexecuser (rolename, KV_COMMAND, stripped_cmd, GET_ONE);
19955N/A+ while (exec != NULL) {
19955N/A+ if (CONTEXT_DEBUG_ON(context)) {
19955N/A+ fprintf (stderr, "Exec Name: %s\n", exec->name);
19955N/A+ fprintf (stderr, "Policy Name: %s\n", exec->policy);
19955N/A+ fprintf (stderr, "Exec Type: %s\n", exec->type);
19955N/A+ fprintf (stderr, "Exec Id: %s\n", exec->id);
19955N/A+ }
19955N/A+
20900N/A+ if (exec->attr != NULL) {
19928N/A+ if (CONTEXT_DEBUG_ON(context)) {
19955N/A+ fprintf (stderr, "Using role %s\n", rolename);
19928N/A+ }
19928N/A+ context->user = g_strdup (rolename);
19935N/A+ free_execattr (exec);
19928N/A+ return TRUE;
19955N/A+ }
19955N/A+ exec = exec->next;
19928N/A+ }
19935N/A+ free_execattr (exec);
19935N/A+
19928N/A+ rolename = strtok (NULL, ",");
19928N/A+ }
19928N/A+}
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_pfexec_run (GksuContext *context, GError **error)
19928N/A+{
19955N/A+ GQuark gksu_quark;
19928N/A+ char **cmd;
19928N/A+ char buffer[MAX_BUFFER_SIZE];
19928N/A+ int argcount = 8;
19928N/A+ int i, j;
19955N/A+ gchar *home = NULL, *home_env = NULL;
19928N/A+
19928N/A+ pid_t pid;
19928N/A+ int status;
19928N/A+ size_t r;
19928N/A+ FILE *infile, *outfile;
19928N/A+ int parent_pipe[2]; /* For talking to the parent */
19928N/A+ int child_pipe[2]; /* For talking to the child */
19928N/A+ int was_quoted = FALSE;
19955N/A+
19928N/A+ gksu_quark = g_quark_from_string (PACKAGE_NAME);
19928N/A+
19928N/A+ if (!context->command)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_NOCOMMAND,
19928N/A+ _("gksu_sudo_run needs a command to be run, "
19928N/A+ "none was provided."));
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ /*
19928N/A+ * Check if the HOME environment variable is set in the user's
19928N/A+ * environment. If so unset it:
19928N/A+ * This will ensure that apps that require write
19928N/A+ * permission eg. gconf client applications, will work.
19928N/A+ */
19928N/A+ home_env = getenv ("HOME");
19928N/A+ home = sudo_get_home_dir (context);
19928N/A+ setenv ("HOME", home, TRUE);
19928N/A+
19928N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ {
19928N/A+ fprintf (stderr, "HOME: %s\n", home);
19928N/A+ }
19928N/A+
19928N/A+ g_free(home);
19928N/A+ cmd = g_new (gchar *, argcount + 1);
19955N/A+
19928N/A+ argcount = 0;
19928N/A+
19928N/A+ /* pfexec binary */
19928N/A+ cmd[argcount] = g_strdup("/usr/bin/pfexec");
19928N/A+ argcount++;
19928N/A+
19928N/A+ if (context->privspec != NULL)
19928N/A+ {
19935N/A+ cmd[argcount] = g_strdup ("-P");
19928N/A+ argcount++;
19935N/A+ cmd[argcount] = g_strdup (context->privspec);
19928N/A+ argcount++;
19928N/A+ }
19928N/A+
19928N/A+ for (i = j = 0; ; i++)
19928N/A+ {
19928N/A+ if (context->command[i] == ' ' || context->command[i] == '\0')
19928N/A+ {
19928N/A+ buffer[j] = '\0';
19928N/A+ /* Strip the previously added quoting '<arg>' */
19928N/A+ if (was_quoted && j > 1 && buffer[j-1] == '\'')
19928N/A+ {
19928N/A+ buffer[j-1] = '\0';
19928N/A+ was_quoted = FALSE;
19928N/A+ }
19928N/A+ cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
19928N/A+ cmd[argcount] = g_strdup (buffer);
19928N/A+ bzero (buffer, MAX_BUFFER_SIZE);
19928N/A+ argcount = argcount + 1;
19928N/A+ j = 0;
19928N/A+
19928N/A+ if (context->command[i] == '\0')
19928N/A+ break;
19928N/A+ }
19928N/A+ else if ( j == 0 && context->command[i] == '\'' )
19928N/A+ {
19928N/A+ was_quoted = TRUE;
19928N/A+ /* Skip initial quote */
19928N/A+ }
19928N/A+ else
19928N/A+ {
19928N/A+ if (context->command[i] == '\\')
19928N/A+ i = i + 1;
19928N/A+ buffer[j] = context->command[i];
19928N/A+ j = j + 1;
19928N/A+ }
19928N/A+ }
19928N/A+ cmd = g_realloc (cmd, sizeof(gchar*) * (argcount + 1));
19928N/A+ cmd[argcount] = NULL;
19928N/A+
19928N/A+
19928N/A+ if (CONTEXT_DEBUG_ON(context))
19928N/A+ {
19928N/A+ for (i = 0; cmd[i] != NULL; i++)
19928N/A+ fprintf (stderr, "cmd[%d]: %s\n", i, cmd[i]);
19928N/A+ }
19928N/A+
19928N/A+ if (context->need_pipe)
19928N/A+ {
19928N/A+ if ((pipe(parent_pipe)) == -1)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
19928N/A+ _("Error creating pipe: %s"),
19928N/A+ strerror(errno));
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ if ((pipe(child_pipe)) == -1)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
19928N/A+ _("Error creating pipe: %s"),
19928N/A+ strerror(errno));
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+ }
19928N/A+
19928N/A+ pid = fork();
19928N/A+ if (pid == -1)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_FORK,
19928N/A+ _("Failed to fork new process: %s"),
19928N/A+ strerror(errno));
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+ else if (pid == 0)
19928N/A+ {
19928N/A+ // Child
19928N/A+ setsid(); // make us session leader
19928N/A+ if (context->need_pipe)
19928N/A+ {
19928N/A+ close(child_pipe[1]);
19928N/A+ dup2(child_pipe[0], STDIN_FILENO);
19928N/A+ dup2(parent_pipe[1], STDERR_FILENO);
19928N/A+ dup2(parent_pipe[1], STDOUT_FILENO);
19928N/A+ }
19955N/A+
19928N/A+ execv(cmd[0], cmd);
19955N/A+
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+ else
19928N/A+ {
19928N/A+ if (!context->need_pipe)
19928N/A+ return FALSE;
19928N/A+
19928N/A+ // Parent
19928N/A+ close(parent_pipe[1]);
19955N/A+
19928N/A+ infile = fdopen(parent_pipe[0], "r");
19928N/A+ if (!infile)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
19928N/A+ _("Error opening pipe: %s"),
19928N/A+ strerror(errno));
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ outfile = fdopen(child_pipe[1], "w");
19928N/A+ if (!outfile)
19928N/A+ {
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_PIPE,
19928N/A+ _("Error opening pipe: %s"),
19928N/A+ strerror(errno));
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+
19928N/A+ context->stdin_fd = parent_pipe[0];
19928N/A+ context->stdout_fd = child_pipe[1];
19928N/A+ context->stdin_file = infile;
19928N/A+ context->stdout_file = outfile;
19928N/A+ setvbuf (context->stdin_file, NULL, _IONBF, 0);
19928N/A+ fcntl (context->stdin_fd, F_SETFL, 0);
19928N/A+ context->child_pid = pid;
19928N/A+
19928N/A+ if (!context->wait_for_child_to_exit)
19928N/A+ return FALSE;
19928N/A+
19928N/A+ /* make sure we did read everything */
19928N/A+ while (1)
19928N/A+ {
19928N/A+ bzero(buffer, MAX_BUFFER_SIZE);
19928N/A+ if(!fread (buffer, sizeof(gchar), MAX_BUFFER_SIZE-1, infile))
19928N/A+ break;
19928N/A+ fprintf (stderr, "%s", buffer);
19928N/A+ fflush (stderr);
19928N/A+ }
19955N/A+
19928N/A+ sudo_reset_home_dir (home_env);
19928N/A+
19928N/A+ if (WIFEXITED(status))
19928N/A+ {
19928N/A+ if (WEXITSTATUS(status))
19928N/A+ {
19928N/A+ *error = NULL;
19928N/A+ g_set_error (error, gksu_quark, GKSU_ERROR_CHILDFAILED,
19928N/A+ _("Child terminated with %d status"),
19928N/A+ WEXITSTATUS(status));
19928N/A+
19928N/A+ return FALSE;
19928N/A+ }
19928N/A+ }
19928N/A+ }
19955N/A+
19928N/A+ return TRUE;
19928N/A+}
19928N/A+
19928N/A+int
19928N/A+gksu_context_get_child_stdin_fd (GksuContext *context)
19928N/A+{
19928N/A+ return context->stdin_fd;
19928N/A+}
19928N/A+
19928N/A+int
19928N/A+gksu_context_get_child_stdout_fd (GksuContext *context)
19928N/A+{
19928N/A+ return context->stdout_fd;
19928N/A+}
19928N/A+
19928N/A+FILE*
19928N/A+gksu_context_get_child_stdin_file (GksuContext *context)
19928N/A+{
19928N/A+ return context->stdin_file;
19928N/A+}
19928N/A+
19928N/A+FILE*
19928N/A+gksu_context_get_child_stdout_file (GksuContext *context)
19928N/A+{
19928N/A+ return context->stdout_file;
19928N/A+}
19928N/A+
19928N/A+pid_t
19928N/A+gksu_context_get_child_pid (GksuContext *context)
19928N/A+{
19928N/A+ return context->child_pid;
19928N/A+}
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_wait_for_child_to_exit (GksuContext *context, gboolean value)
19928N/A+{
19928N/A+ context->wait_for_child_to_exit = value;
19928N/A+}
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_get_wait_for_child_to_exit (GksuContext *context)
19928N/A+{
19928N/A+ return context->wait_for_child_to_exit;
19928N/A+}
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_elevated_privilege (GksuContext *context, gboolean value)
19928N/A+{
19928N/A+ context->elevated_privilege = value;
19928N/A+}
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_get_elevated_privilege (GksuContext *context)
19928N/A+{
19928N/A+ return context->elevated_privilege;
19928N/A+}
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_elevated_role (GksuContext *context, gboolean value)
19928N/A+{
19928N/A+ context->elevated_role = value;
19928N/A+}
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_get_elevated_role (GksuContext *context)
19928N/A+{
19928N/A+ return context->elevated_role;
19928N/A+}
19928N/A+
19928N/A+/**
19928N/A+ * gksu_context_set_privspec:
19928N/A+ * @context: the #GksuContext you want to modify
19928N/A+ * @privspec: the target privileges specification
19928N/A+ *
19928N/A+ * Sets up privileges specification used by pfexec .
19928N/A+ *
19928N/A+ */
19928N/A+void
19928N/A+gksu_context_set_privspec (GksuContext *context, gchar *privspec)
19928N/A+{
19928N/A+ g_assert (privspec != NULL);
19928N/A+
19928N/A+ if (context->privspec)
19928N/A+ g_free (context->privspec);
19928N/A+ context->privspec = g_strdup (privspec);
19928N/A+}
19928N/A+
19928N/A+/**
19928N/A+ * gksu_context_get_privspec:
19928N/A+ * @context: the #GksuContext from which to grab the information
19928N/A+ *
19928N/A+ * Gets the privileges specification used by pfexec, as set
19928N/A+ * by gksu_context_set_privspec.
19928N/A+ *
19928N/A+ * Returns: a pointer to the string containing the privileges specification.
19928N/A+ */
19928N/A+const gchar*
19928N/A+gksu_context_get_privspec (GksuContext *context)
19928N/A+{
19928N/A+ return context->privspec;
19928N/A+}
19928N/A+
19928N/A+/**
19928N/A+ * gksu_context_get_pam_num_msg:
19928N/A+ * @context: the #GksuContext from which to grab the information
19928N/A+ *
19928N/A+ * Gets the privileges specificddation used by pfexec, as set
19928N/A+ * by gksu_context_set_privspec.
19928N/A+ *
19928N/A+ * Returns: number of pam conversation.
19928N/A+ */
19928N/A+const gint
19928N/A+gksu_context_get_pam_msg_num (GksuContext *context)
19928N/A+{
19928N/A+ return context->msg_num;
19928N/A+}
19928N/A+
19928N/A+/**
19928N/A+ * gksu_context_get_pam_message:
19928N/A+ * @context: the #GksuContext from which to grab the information
19928N/A+ *
19928N/A+ *
19928N/A+ *
19928N/A+ * Returns: a pointer to the string containing the specific pam message.
19928N/A+ */
19928N/A+const gchar*
19928N/A+gksu_context_get_pam_message (GksuContext *context, gint index)
19928N/A+{
19928N/A+ return context->pam_message[index].msg;
19928N/A+}
19928N/A+
19928N/A+/**
19928N/A+ * gksu_context_get_pam_response:
19928N/A+ * @context: the #GksuContext from which to grab the information
19928N/A+ *
19928N/A+ *
19928N/A+ *
19928N/A+ * Returns: a pointer to the string containing the specified pam response.
19928N/A+ */
19928N/A+const gchar*
19928N/A+gksu_context_get_pam_response (GksuContext *context, gint index)
19928N/A+{
19928N/A+ return context->pam_response[index].resp;
19928N/A+}
19928N/A+
19928N/A+/**
19928N/A+ * gksu_context_set_pam_response:
19928N/A+ * @context: the #GksuContext from which to grab the information
19928N/A+ *
19928N/A+ *
19928N/A+ *
19928N/A+ * Returns: void.
19928N/A+ */
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_pam_response (GksuContext *context, gint index, gchar *response)
19928N/A+{
19928N/A+ context->pam_response[index].resp = g_strdup (response);
19928N/A+}
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_get_pfexec_mode (GksuContext *context)
19928N/A+{
19928N/A+ return context->pfexec_mode;
19928N/A+}
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_need_pipe (GksuContext *context, gboolean value)
19928N/A+{
19928N/A+ context->need_pipe = value;
19928N/A+}
19928N/A+
19928N/A+gboolean
19928N/A+gksu_context_get_need_pipe (GksuContext *context)
19928N/A+{
19955N/A+ return context->need_pipe;
19928N/A+}
19928N/A+
19928N/A+void
19928N/A+gksu_context_set_child_no_a11y (GksuContext *context, gboolean value)
19928N/A+{
19928N/A+ context->child_no_a11y = value;
19928N/A+}