--- gnome-system-monitor-2.9.90/configure.in.libgnomesu 2005-01-24 09:06:57.000000000 -0500 +++ gnome-system-monitor-2.9.90/configure.in 2005-02-02 15:03:45.000000000 -0500 @@ -19,9 +19,8 @@ LIBGTOP_REQUIRED=2.9.5 GTK_REQUIRED=2.5.0 GNOME_VFS_REQUIRED=2.6.0 -LIBGNOMESU_REQUIRED=0.9.3 -PKG_CHECK_MODULES(PROCMAN, libgnome-2.0 >= $LIBGNOME_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED gconf-2.0 >= $GCONF_REQUIRED libgtop-2.0 >= $LIBGTOP_REQUIRED libwnck-1.0 >= $LIBWNCK_REQUIRED gtk+-2.0 >= $GTK_REQUIRED gnome-vfs-2.0 >= $GNOME_VFS_REQUIRED libgnomesu-1.0 >= $LIBGNOMESU_REQUIRED) +PKG_CHECK_MODULES(PROCMAN, libgnome-2.0 >= $LIBGNOME_REQUIRED libgnomeui-2.0 >= $LIBGNOMEUI_REQUIRED gconf-2.0 >= $GCONF_REQUIRED libgtop-2.0 >= $LIBGTOP_REQUIRED libwnck-1.0 >= $LIBWNCK_REQUIRED gtk+-2.0 >= $GTK_REQUIRED gnome-vfs-2.0 >= $GNOME_VFS_REQUIRED) AC_ARG_ENABLE(more-warnings, --- gnome-system-monitor-2.9.90/src/procdialogs.c.libgnomesu 2005-01-13 19:05:00.000000000 -0500 +++ gnome-system-monitor-2.9.90/src/procdialogs.c 2005-02-02 15:03:45.000000000 -0500 @@ -23,7 +23,6 @@ #include #include -#include #include "procdialogs.h" #include "favorites.h" #include "proctable.h" @@ -815,13 +814,101 @@ void procdialog_create_root_password_dialog (gint type, ProcData *procdata, gint pid, gint extra_value, gchar *text) { + GtkWidget *dialog; + GtkWidget *error_dialog; + GtkWidget *main_vbox; + GtkWidget *hbox; + GtkWidget *entry; + GtkWidget *label; + gchar *title = NULL, *button_label; gchar *command; + gchar *password, *blank; + gint retval; + + if (type == 0) { + if (extra_value == SIGKILL) { + title = g_strdup (_("Kill Process")); + button_label = g_strdup (_("_Kill Process")); + } + else { + title = g_strdup (_("End Process")); + button_label = g_strdup (_("_End Process")); + } + } + else { + title = g_strdup (_("Change Priority")); + button_label = g_strdup (_("Change _Priority")); + } + + dialog = gtk_dialog_new_with_buttons (title, NULL, GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + button_label, 100, + NULL); + + main_vbox = GTK_DIALOG (dialog)->vbox; + + label = gtk_label_new (_(text)); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_misc_set_padding (GTK_MISC (label), GNOME_PAD, 2 * GNOME_PAD); + gtk_box_pack_start (GTK_BOX (main_vbox), label, FALSE, FALSE, 0); + + hbox = gtk_hbox_new (FALSE, 0); + gtk_container_set_border_width (GTK_CONTAINER (hbox), GNOME_PAD_SMALL); + gtk_box_pack_start (GTK_BOX (main_vbox), hbox, FALSE, FALSE, 0); + + label = gtk_label_new (_("Root Password :")); + gtk_misc_set_padding (GTK_MISC (label), GNOME_PAD_SMALL, 0); + gtk_box_pack_start (GTK_BOX (hbox), label, TRUE, FALSE, 0); + + entry = gtk_entry_new (); + gtk_entry_set_visibility (GTK_ENTRY (entry), FALSE); + gtk_box_pack_start (GTK_BOX (hbox), entry, TRUE, FALSE, 0); + g_signal_connect (G_OBJECT (entry), "activate", + G_CALLBACK (entry_activate_cb), dialog); + + gtk_widget_show_all (main_vbox); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_CANCEL); + gtk_widget_grab_focus (entry); + + g_free (title); + g_free (button_label); + + retval = gtk_dialog_run (GTK_DIALOG (dialog)); + gtk_widget_hide (dialog); + + if (retval == 100) { + password = gtk_editable_get_chars (GTK_EDITABLE (entry), 0, -1); + + if (!password) + password = ""; + blank = g_strdup (password); + if (strlen (blank)) + memset (blank, ' ', strlen (blank)); + + gtk_entry_set_text (GTK_ENTRY (entry), blank); + gtk_entry_set_text (GTK_ENTRY (entry), ""); + g_free (blank); + + if (type == 0) + command = g_strdup_printf ("kill -s %d %d", extra_value, pid); + else + command = g_strdup_printf ("renice %d %d", extra_value, pid); + + if (su_run_with_password (command, password) == -1) { + error_dialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_OK, + "%s", + _("Wrong Password.")); + gtk_dialog_run (GTK_DIALOG (error_dialog)); + gtk_widget_destroy (error_dialog); + } + g_free (command); + + } + gtk_widget_destroy (dialog); - if (type == 0) - command = g_strdup_printf ("kill -s %d %d", extra_value, pid); - else - command = g_strdup_printf ("renice %d %d", extra_value, pid); - gnomesu_exec (command); - g_free (command); } --- gnome-system-monitor-2.9.90/src/util.c.libgnomesu 2005-01-08 17:43:35.000000000 -0500 +++ gnome-system-monitor-2.9.90/src/util.c 2005-02-02 15:08:57.000000000 -0500 @@ -1,10 +1,294 @@ -#include "util.h" +#define _GNU_SOURCE #include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + + +#ifdef __FreeBSD__ +# include +# include +#endif + +#ifdef __sun +# include +# include +# include +# include +# include +# include +#endif + +#include "util.h" + #include -#include +/* ABORT() kills GTK if we're not root, else it just exits. + */ +#define ABORT(root) \ + if (root == 0) \ + GTK_ABORT(); \ + else \ + _exit(-1) + +/* GTK_ABORT() is supposed to kill GTK and exit. + */ +#define GTK_ABORT() do { \ + gtk_main_quit(); \ + _exit(0); \ + } while (0) + +/* OPEN_TTY() is supposed to return a file descriptor to a pseudo-terminal. + */ +#define OPEN_TTY() getpt() + +#ifdef __FreeBSD__ +/* FreeBSD doesn't have getpt(). This function emulates it's behaviour. */ +int getpt (void); + +int +getpt () +{ + int master, slave; + + if (openpty (&master, &slave, NULL, NULL, NULL) < 0) { + /* Simulate getpt()'s only error condition. */ + errno = ENOENT; + return -1; + } + return master; +} +#endif + +#ifdef __sun +/* Sun doesn't have getpt(). This function emulates it's behavior. */ +int getpt (void); + +int +getpt () +{ + int fdm, fds; + extern int errno; + char *slavename; + /* extern char *ptsname(); */ + + /* open master */ + fdm = open("/dev/ptmx", O_RDWR); + if ( fdm < 0 ) { + /* Simulate getpt()'s only error condition. */ + errno = ENOENT; + return -1; + } + if ( grantpt(fdm) < 0 ) { /* change permission ofslave */ + /* Simulate getpt()'s only error condition. */ + errno = ENOENT; + return -1; + } + if ( unlockpt(fdm) < 0 ) { /* unlock slave */ + /* Simulate getpt()'s only error condition. */ + errno = ENOENT; + return -1; + } + slavename = ptsname(fdm); /* get name of slave */ + if ( slavename == NULL ) { + /* Simulate getpt()'s only error condition. */ + errno = ENOENT; + return -1; + } + fds = open(slavename, O_RDWR); /* open slave */ + if ( fds < 0 ) { + /* Simulate getpt()'s only error condition. */ + errno = ENOENT; + return -1; + } + ioctl(fds, I_PUSH, "ptem"); /* push ptem * / + ioctl(fds, I_PUSH, "ldterm"); /* push ldterm */ + + return fds; +} + +/* Handle the fact that solaris doesn't have an asprintf */ +/* pinched from +http://samba.anu.edu.au/rsync/doxygen/head/snprintf_8c-source.html */ + +#ifndef HAVE_VASPRINTF +int vasprintf(char **ptr, const char *format, va_list ap) +{ + int ret; + + ret = vsnprintf(NULL, 0, format, ap); + if (ret <= 0) return ret; + + (*ptr) = (char *)malloc(ret+1); + if (!*ptr) return -1; + ret = vsnprintf(*ptr, ret+1, format, ap); + + return ret; +} +#endif + + +#ifndef HAVE_ASPRINTF + int asprintf(char **ptr, const char *format, ...) +{ + va_list ap; + int ret; + + va_start(ap, format); + ret = vasprintf(ptr, format, ap); + va_end(ap); + + return ret; +} +#endif +#endif + +static int root = 0; /* if we are root, no password is + required */ + +static gint +exec_su (gchar *exec_path, gchar *user, gchar *pwd) +{ + gchar *exec_p, *user_p; /* command to execute, user name */ + pid_t pid; + int t_fd; + + exec_p = g_strdup (exec_path); + +#if 0 + if (asprintf (&exec_p, "%s&", exec_path) < 0) { + perror ("Unable to allocate memory chunk"); + g_free (exec_p); + return 0; + } +#endif + + user_p = (user ? user : "root"); + + if ((pwd == NULL) || (*pwd == '\0')) { + g_free (exec_p); + return 0; + } + + /* + * Make su think we're sending the password from a terminal: + */ + + if (((t_fd = OPEN_TTY()) < 0) || (grantpt(t_fd) < 0) || (unlockpt(t_fd) < 0)) { + fprintf (stderr, "Unable to open a terminal\n"); + ABORT (root); + } + + if ((pid = fork()) < 0) { + perror ("Unable to fork a new process"); + ABORT (root); + } + + if (pid > 0) { /* parent process */ + int status; + + sleep(1); + + /* su(1) won't want a password if we're already root. + */ + if (root == 0) { + write (t_fd, pwd, strlen(pwd)); + + /* Need the \n to flush the password */ + write (t_fd, "\n", 1); + } + + waitpid (pid, &status, 0); + + if (WIFEXITED (status) && WEXITSTATUS (status) && (WEXITSTATUS(status) < 255)) { +/* error_box (_("Incorrect password.")); */ + g_free (exec_p); + return -1; + } + else { + memset (pwd, 0, strlen (pwd)); + } + } + else { /* child process */ + struct passwd *pw; + char *env, *home, *pts; + + /* We have rights to run X (obviously). We need to ensure the + * destination user has the right stuff in the environment + * to be able to continue to run X. + * su will change $HOME to the new users home, so we will + * need an XAUTHORITY / ICEAUTHORITY pointing to the + * authorization files. + */ + + if ((home = getenv ("HOME")) == NULL) { + if ((env = getenv ("USER")) == NULL) + pw = getpwuid(getuid()); + else + pw = getpwnam(env); + if (pw) + home = pw->pw_dir; + else { + perror ("Unable to find home directory"); + _exit (-1); + } + } + + if ((env = getenv ("XAUTHORITY")) == NULL) { + if (asprintf (&env, "XAUTHORITY=%s/.Xauthority", home) > 0) + putenv (env); + else { + perror ("Unable to allocate memory chunk"); + _exit (-1); + } + } + + if ((env = getenv ("ICEAUTHORITY")) == NULL) { + if (asprintf (&env, "ICEAUTHORITY=%s/.ICEauthority", home) > 0) + putenv (env); + else { + perror ("Unable to allocate memory chunk"); + _exit (-1); + } + } + + if(((pts = ptsname(t_fd)) == NULL) || ((t_fd = open(pts, O_RDWR | O_NOCTTY)) < 0)) { + perror ("Unable to open pseudo slave terminal"); + _exit (-1); + } + dup2 (t_fd, 0); + +#if 0 + freopen ("/dev/null", "w", stderr); + freopen ("/dev/null", "w", stdout); +#endif + + execlp ("su", "su", "-m", user_p, "-c", exec_p, NULL); + _exit (0); + + } + + g_free (exec_p); + + return 0; +} + +gint +su_run_with_password (gchar *exec_path, gchar *password) +{ + return exec_su (exec_path, "root", password); +} + +#if 1 void _procman_array_gettext_init(const char * strings[], size_t n) { size_t i; @@ -15,3 +299,4 @@ strings[i] = _(strings[i]); } } +#endif