--- gnome-system-tools-2.14.0/configure.in-orig 2010-12-10 13:05:34.351438641 -0600
+++ gnome-system-tools-2.14.0/configure.in 2010-12-10 13:05:56.067017722 -0600
@@ -144,8 +144,7 @@ dnl ====================================
case $host_os in
solaris*)
PKG_CHECK_MODULES(GKSU,[
- libgksu1.2 >= 1.3.1,
- libgksuui1.0 >= 1.0
+ libgksu2
],[
AC_DEFINE(HAVE_GKSU, 1, [define if you have Gksu library])])
;;
--- gnome-system-tools-2.14.0/src/common/gst-auth.c-orig 2010-12-10 11:55:03.932806214 -0600
+++ gnome-system-tools-2.14.0/src/common/gst-auth.c 2010-12-10 13:23:39.583198213 -0600
@@ -44,8 +44,15 @@
# include <errno.h>
# include <libutil.h>
#else
+#ifdef __sun
+#include <sys/stream.h>
+#include <sys/stropts.h>
+#else
#include <pty.h>
#endif
+#endif
+
+#include <gksu.h>
#include "gst-auth.h"
#include "gst-tool.h"
@@ -53,6 +60,10 @@
#define GST_AUTH_RESPONSE_NP 1
+#ifdef __sun
+#define EMBEDDED_SU "/usr/lib/embedded_su"
+#endif /* __sun */
+
static int root; /* if we are root, no password is
required */
@@ -61,7 +72,7 @@ gst_auth_display_error_message (GstTool
{
GtkWidget *error_dialog;
- error_dialog = gtk_message_dialog_new (GTK_WINDOW (tool->main_dialog),
+ error_dialog = gtk_message_dialog_new_with_markup (GTK_WINDOW (tool->main_dialog),
GTK_DIALOG_MODAL,
GTK_MESSAGE_ERROR,
GTK_BUTTONS_CLOSE,
@@ -118,6 +129,122 @@ gst_auth_wait_child (GstTool *tool)
return TRUE;
}
+#ifdef __sun
+/* forkpty() rmplacement for Solaris.
+ * This ignore the last two arguments
+ * for the moment
+ */
+#ifdef NOPTY
+/*
+ * This is implemented using pipes instead of pseudo tty to avoid
+ * bug 4907342.
+ */
+static
+int forkpty (int *amaster, char *name, void *unused1, void *unused2)
+{
+ pid_t pid;
+ int pp[2];
+
+ pipe (pp);
+ pid = fork ();
+ switch (pid)
+ {
+ case -1: /* Error */
+ return -1;
+ case 0: /* Child */
+ if (setsid() < 0)
+ return -1;
+ close (pp[1]);
+ dup2 (pp[0], 0);
+ return 0;
+ default: /* Parent */
+ close (pp[0]);
+ *amaster = pp[1];
+ return pid;
+ }
+
+ return -1;
+}
+#else
+int forkpty (int *amaster, char *name, void *unused1, void *unused2)
+{
+ int master, slave, fd;
+ char *slave_name;
+ pid_t pid;
+ void (*sig_saved)(int);
+
+ master = open("/dev/ptmx", O_RDWR | O_NOCTTY);
+ if (master < 0)
+ return -1;
+
+ sig_saved = signal (SIGCHLD, SIG_DFL);
+ if (grantpt (master) < 0)
+ {
+ signal (SIGCHLD, sig_saved);
+ close (master);
+ return -1;
+ }
+
+ if (unlockpt (master) < 0)
+ {
+ signal (SIGCHLD, sig_saved);
+ close (master);
+ return -1;
+ }
+ signal (SIGCHLD, sig_saved);
+
+ slave_name = ptsname (master);
+ if (slave_name == NULL)
+ {
+ close (master);
+ return -1;
+ }
+
+ slave = open (slave_name, O_RDWR | O_NOCTTY);
+ if (slave < 0)
+ {
+ close (master);
+ return -1;
+ }
+
+ if (ioctl (slave, I_PUSH, "ptem") < 0
+ || ioctl (slave, I_PUSH, "ldterm") < 0
+ || ioctl (slave, I_PUSH, "ttcompat") < 0)
+ {
+ close (slave);
+ close (master);
+ return -1;
+ }
+
+ if (amaster)
+ *amaster = master;
+
+ if (name)
+ strcpy (name, slave_name);
+
+ pid = fork ();
+ switch (pid)
+ {
+ case -1: /* Error */
+ return -1;
+ case 0: /* Child */
+ if (setsid() < 0)
+ return -1;
+ close (master);
+ dup2 (slave, STDIN_FILENO);
+ dup2 (slave, STDOUT_FILENO);
+ dup2 (slave, STDERR_FILENO);
+ return 0;
+ default: /* Parent */
+ close (slave);
+ return pid;
+ }
+
+ return -1;
+}
+#endif
+#endif
+
/* runs a term with su in it */
static void
gst_auth_run_term (GstTool *tool, gchar *args[])
@@ -177,8 +304,16 @@ gst_auth_get_auth_required (GstTool *too
gchar *s, *str;
gint ret;
+#if defined(__sun) && defined (EMBEDDED_SU)
+ gst_tool_write_to_backend(tool, (gchar*)".\n"); /* Send empty text block to start conversation */
+#endif
+
while (!cont) {
+#if defined(__sun) && defined (EMBEDDED_SU)
+ s = gst_tool_read_from_backend (tool, "SUCCESS", "\n.\n", NULL); /* Look for end of text block - a period (.) on a line by itself */
+#else
s = gst_tool_read_from_backend (tool, "assword:", "/no)?", "\n", NULL);
+#endif /* __sun */
str = g_ascii_strup (s, -1);
/* FIXME: hope that someday we can get rid of this ssh output string parsing */
@@ -189,6 +324,11 @@ gst_auth_get_auth_required (GstTool *too
/* it's asking for the password */
cont = TRUE;
ret = GST_AUTH_PASSWORD;
+#if defined(__sun) && defined (EMBEDDED_SU)
+ } else if (g_strrstr (str, "SUCCESS") != NULL) {
+ cont = TRUE;
+ ret = GST_AUTH_PASSWORDLESS;
+#endif /* __sun */
} else if (g_strrstr (str, "\n") != NULL) {
/* this is the last case to test, it's the CR
used to synchronize communication */
@@ -276,6 +416,216 @@ gst_auth_read_output (GstTool *tool)
g_free (b);
}
+#ifdef HAVE_GKSU
+static void
+gk_dialog (GtkMessageType type, gchar *format, ...)
+{
+ GtkWidget *diag_win;
+
+ va_list ap;
+ gchar *msg;
+
+ va_start(ap, format);
+ msg = g_strdup_vprintf(format, ap);
+ va_end(ap);
+
+ diag_win = gtk_message_dialog_new_with_markup (NULL, GTK_DIALOG_MODAL,
+ type, GTK_BUTTONS_CLOSE,
+ msg);
+
+ gtk_signal_connect_object (GTK_OBJECT(diag_win), "delete_event",
+ GTK_SIGNAL_FUNC(gtk_main_quit),
+ NULL);
+ gtk_window_set_position (GTK_WINDOW(diag_win), GTK_WIN_POS_CENTER);
+ gtk_window_set_resizable (GTK_WINDOW(diag_win), FALSE);
+
+ gtk_widget_show_all (diag_win);
+
+ // we "raise" the window because there is a race here for
+ // focus-follow-mouse and auto-raise WMs that may put the window
+ // in the background and confuse users
+ gtk_window_set_keep_above(GTK_WINDOW (diag_win), TRUE);
+ // reset cursor
+ gdk_window_set_cursor(diag_win->window, gdk_cursor_new(GDK_LEFT_PTR));
+
+
+ gtk_dialog_run (GTK_DIALOG(diag_win));
+
+ g_free (msg);
+
+ gtk_widget_destroy (diag_win);
+}
+
+void
+response_ok_cb (GtkWidget *w, gpointer data)
+{
+ GtkWidget *dialog = (GtkWidget*)data;
+
+ gtk_dialog_response (GTK_DIALOG(dialog),
+ GTK_RESPONSE_OK);
+}
+
+static gboolean
+focus_out_cb (GtkWidget *widget, GdkEventFocus *event, gpointer user_data)
+{
+ gtk_window_present (GTK_WINDOW(widget));
+ return TRUE;
+}
+
+void
+request_command_and_user (GksuContext *context)
+{
+ GtkWidget *dialog;
+ GtkWidget *hbox;
+ GtkWidget *lvbox;
+ GtkWidget *rvbox;
+ GtkWidget *image;
+
+ GtkWidget *label_cmd;
+ GtkWidget *entry_cmd;
+
+ GtkWidget *label_user;
+ GtkWidget *entry_user;
+
+ AtkObject *atk_user_label;
+ AtkObject *atk_user_entry;
+ AtkObject *atk_command_label;
+ AtkObject *atk_command_entry;
+
+ /* advanced stuff */
+ GtkWidget *advanced_button;
+
+ gint response;
+
+ gchar *tmp = NULL;
+
+ dialog = gtk_dialog_new_with_buttons (_("Run program"), NULL, 0,
+ GTK_STOCK_CANCEL,
+ GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OK,
+ GTK_RESPONSE_OK,
+ NULL);
+
+ /* make sure that our window will always have the focus */
+ g_signal_connect (G_OBJECT(dialog), "focus-out-event",
+ G_CALLBACK(focus_out_cb), NULL);
+
+ gtk_dialog_set_has_separator (GTK_DIALOG(dialog), FALSE);
+
+ /* horizontal box */
+ hbox = gtk_hbox_new (FALSE, 4);
+ gtk_container_set_border_width (GTK_CONTAINER(hbox), 5);
+ gtk_box_pack_start (GTK_BOX(GTK_DIALOG(dialog)->vbox),
+ hbox, TRUE, TRUE, 2);
+
+ /* left vertical box */
+ lvbox = gtk_vbox_new (FALSE, 2);
+ gtk_box_pack_start (GTK_BOX(hbox), lvbox, TRUE, TRUE, 0);
+
+ /* command */
+ label_cmd = gtk_label_new (_("Run:"));
+ gtk_label_set_justify (GTK_LABEL(label_cmd), GTK_JUSTIFY_LEFT);
+ gtk_box_pack_start (GTK_BOX(lvbox), label_cmd, TRUE, TRUE, 0);
+
+ entry_cmd = gtk_entry_new ();
+ gtk_signal_connect (GTK_OBJECT(entry_cmd), "activate",
+ GTK_SIGNAL_FUNC(response_ok_cb),
+ dialog);
+ gtk_box_pack_start (GTK_BOX(lvbox), entry_cmd, TRUE, TRUE, 0);
+
+ if (context->command)
+ {
+ gtk_entry_set_text (GTK_ENTRY (entry_cmd), context->command);
+ gtk_editable_set_editable (GTK_EDITABLE (entry_cmd), FALSE);
+ gtk_widget_set_sensitive (entry_cmd, FALSE);
+ }
+
+ atk_command_label = gtk_widget_get_accessible (label_cmd);
+ atk_command_entry = gtk_widget_get_accessible (entry_cmd);
+ atk_object_add_relationship (atk_command_label, ATK_RELATION_LABEL_FOR,
+ atk_command_entry);
+ atk_object_add_relationship (atk_command_entry, ATK_RELATION_LABELLED_BY,
+ atk_command_label);
+
+ /* user name */
+ /* SUN_BRANDING label */
+ label_user = gtk_label_new (_("As user or role:"));
+ gtk_label_set_justify (GTK_LABEL(label_user), GTK_JUSTIFY_LEFT);
+ gtk_box_pack_start (GTK_BOX(lvbox), label_user, TRUE, TRUE, 0);
+
+ entry_user = gtk_entry_new ();
+ gtk_signal_connect (GTK_OBJECT(entry_user), "activate",
+ GTK_SIGNAL_FUNC(response_ok_cb),
+ dialog);
+
+ if (context->user)
+ {
+ gtk_entry_set_text (GTK_ENTRY (entry_user), context->user);
+ }
+
+ atk_user_label = gtk_widget_get_accessible (label_user);
+ atk_user_entry = gtk_widget_get_accessible (entry_user);
+ atk_object_add_relationship (atk_user_label, ATK_RELATION_LABEL_FOR,
+ atk_user_entry);
+ atk_object_add_relationship (atk_user_entry, ATK_RELATION_LABELLED_BY,
+ atk_user_label);
+
+ gtk_box_pack_start (GTK_BOX(lvbox), entry_user, TRUE, TRUE, 0);
+
+ /* right vertical box */
+ rvbox = gtk_vbox_new (FALSE, 2);
+ gtk_box_pack_start (GTK_BOX(hbox), rvbox, TRUE, TRUE, 0);
+
+ /* image */
+ image = gtk_image_new_from_file ("/usr/share/pixmaps/gksu-icon.png");
+ gtk_box_pack_start (GTK_BOX(rvbox), image, TRUE, TRUE, 0);
+
+#if 0
+ /* advanced button */
+ advanced_button = gtk_button_new_with_mnemonic (_("_Advanced"));
+ g_signal_connect (G_OBJECT(advanced_button), "clicked",
+ G_CALLBACK(show_hide_advanced), context);
+ gtk_box_pack_start (GTK_BOX(rvbox), advanced_button, TRUE, FALSE, 0);
+#endif
+
+ /* let the magic begin! */
+ gtk_widget_show_all (dialog);
+
+ while (TRUE)
+ {
+ response = gtk_dialog_run (GTK_DIALOG(dialog));
+
+ switch (response)
+ {
+ case GTK_RESPONSE_CANCEL:
+ case GTK_RESPONSE_DELETE_EVENT:
+ case GTK_RESPONSE_NONE:
+ exit (0);
+ }
+
+ tmp = gtk_editable_get_chars (GTK_EDITABLE(entry_cmd), 0, -1);
+ if (tmp)
+ {
+ gksu_context_set_command (context, tmp);
+ g_free (tmp);
+ }
+
+ tmp = g_strdup (gtk_entry_get_text (GTK_ENTRY (entry_user)));
+ if (tmp)
+ {
+ gksu_context_set_user (context, tmp);
+ g_free (tmp);
+ }
+
+ if (strcmp (gksu_context_get_user (context), ""))
+ {
+ gtk_widget_destroy (dialog);
+ break;
+ }
+ }
+}
+#endif /* HAVE_GKSU */
+
/* it does authentication, first of all it runs su (just to ensure that it's completely run
* when password is sent), then asks for password and sends it to su (if you want to run it
* with root privileges)
@@ -286,7 +636,115 @@ gst_auth_do_authentication (GstTool *too
gchar *password;
gint result;
struct termios t;
+ GksuContext *context;
+ gint8 exit_status = -1;
+ GError *error = NULL;
+ gint response;
+ gchar *primary_text = NULL;
+ gchar *secondary_text = NULL;
+ gint count;
+
+ char **gconf_argv;
+ char *gconf_cmd;
+ char *std_output;
+ char *std_error;
+ struct passwd *pwentry;
+
+#ifdef HAVE_GKSU
+ context = gksu_context_new ();
+ gksu_context_set_child_no_a11y (context, TRUE);
+#ifdef GST_DEBUG
+ gksu_context_set_debug (context, TRUE);
+#endif
+ /*
+ * Disable the grab if accessibility is on, since it causes issues
+ * for GOK, dasher and other AT programs where the user may need to interact
+ * with other GUI programs. Note that we call gconftool-2 instead of using
+ * GConf interfaces since it seems using GConf in gksu causes problems for
+ * a11y if you run a program with gksu that has a GUI. The launched program
+ * will not work with a11y if gksu uses GConf, but calling gconftool-2 works.
+ */
+ gconf_cmd = g_strdup ("/usr/bin/gconftool-2 --get /desktop/gnome/interface/accessibility");
+ error = NULL;
+ std_output = NULL;
+ std_error = NULL;
+
+ g_shell_parse_argv (gconf_cmd, NULL, &gconf_argv, &error);
+
+ error = NULL;
+
+ g_spawn_sync (NULL,
+ gconf_argv,
+ NULL,
+ 0,
+ NULL,
+ NULL,
+ &std_output,
+ &std_error,
+ NULL,
+ &error);
+
+ g_strchomp (std_output);
+
+ if (std_output != NULL && strcmp (std_output, "true") == 0)
+ gksu_context_set_grab (context, FALSE);
+ else
+ gksu_context_set_grab (context, TRUE);
+
+ gksu_context_set_wait_for_child_to_exit (context, FALSE);
+
+ context->command = g_strdup (args[3]);
+ if (gksu_context_try_need_password (context))
+ {
+ request_command_and_user (context);
+ }
+
+ pwentry = getpwnam (gksu_context_get_user (context));
+
+ if (!pwentry)
+ {
+ primary_text = g_strdup_printf (_("User %s does not exist"), gksu_context_get_user (context));
+ gst_auth_display_error_message (tool, primary_text, NULL);
+
+ g_free (primary_text);
+ exit (0);
+ }
+
+ gksu_su_fuller (context,
+ NULL, NULL,
+ NULL, NULL,
+ &exit_status,
+ &error);
+
+ if (error && (error->code != GKSU_ERROR_CANCELED))
+ {
+ if (context->alert != NULL)
+ {
+ primary_text = context->alert;
+ } else {
+ primary_text = g_strdup_printf (_("Authentication failed"));
+ }
+
+ secondary_text = g_strdup (error->message);
+
+ gst_auth_display_error_message (tool, primary_text, secondary_text);
+
+ free (primary_text);
+ g_free (secondary_text);
+ exit (0);
+ }
+
+ tool->read_fd = gksu_context_get_child_stdin_fd (context);
+ tool->write_fd = gksu_context_get_child_stdout_fd (context);
+ tool->backend_pid = gksu_context_get_child_pid (context);
+ tool->timeout_id = g_timeout_add (1000, (GSourceFunc) gst_auth_wait_child, tool);
+#ifdef GST_DEBUG
+ fprintf (stderr, "read_fd = %d, write_fd = %d\n", tool->read_fd, tool->write_fd);
+#endif
+ tool->read_stream = gksu_context_get_child_stdin_file (context);
+ tool->write_stream = gksu_context_get_child_stdout_file (context);
+#else
gst_auth_run_term (tool, args);
result = gst_auth_get_auth_required (tool);
@@ -296,7 +754,14 @@ gst_auth_do_authentication (GstTool *too
if (strlen (password) > 0)
memset (password, 0, strlen (password));
+#if defined(__sun) && defined (EMBEDDED_SU) && 0
+ {
+ gchar *s = gst_tool_read_from_backend (tool, "\n.\n", "SUCCESS", "\n", NULL);
+ g_free(s);
+ }
+#endif /* __sun */
}
+#endif
tool->root_access = ROOT_ACCESS_REAL;
@@ -368,7 +833,7 @@ gst_auth_do_su_authentication (GstTool *
GString *command;
command = g_string_new (NULL);
- gst_auth_save_locale (command);
+// gst_auth_save_locale (command);
command = g_string_append (command, tool->script_path);
command = g_string_append (command, " --report");
@@ -378,7 +843,11 @@ gst_auth_do_su_authentication (GstTool *
}
/* these are the su args */
+#if defined(__sun) && defined (EMBEDDED_SU)
+ su_args[0] = EMBEDDED_SU;
+#else
su_args[0] = SU_PATH;
+#endif /* __sun */
su_args[1] = "root";
su_args[2] = "-c";
su_args[3] = command->str;