# include <termios.h>
#endif
-#if (defined(HAVE_SETEUID) || defined(HAVE_SETREUID)) && !defined(__CYGWIN32__)
-static uid_t saved_euid;
-static gid_t saved_egid;
-#endif
-
-bool
-rxvt_tainted ()
-{
-#if (defined(HAVE_SETEUID) || defined(HAVE_SETREUID)) && !defined(__CYGWIN32__)
- return getuid () != saved_euid || getgid () != saved_egid;
-#else
- return false;
-#endif
-}
-
vector<rxvt_term *> rxvt_term::termlist;
static char curlocale[128], savelocale[128];
if (cmd_pid)
kill (-cmd_pid, SIGHUP);
-#ifdef UTMP_SUPPORT
- privileged_utmp (RESTORE);
-#endif
-
- pty.put ();
+ delete pty; pty = 0;
}
rxvt_term::~rxvt_term ()
|| (rs[Rs_perl_ext_2] && *rs[Rs_perl_ext_2])
|| (rs[Rs_perl_eval] && *rs[Rs_perl_eval]))
{
-#if (defined(HAVE_SETEUID) || defined(HAVE_SETREUID)) && !defined(__CYGWIN32__)
- // ignore some perl-related arguments if some bozo installed us set[ug]id
- if (rxvt_tainted ())
- {
- if ((rs[Rs_perl_lib] && *rs[Rs_perl_lib])
- || (rs[Rs_perl_eval] && *rs[Rs_perl_eval]))
- {
- rxvt_warn ("running with elevated privileges: ignoring perl-lib and perl-eval.\n");
- rs[Rs_perl_lib] = 0;
- rs[Rs_perl_eval] = 0;
- }
- }
-#endif
rxvt_perl.init (this);
HOOK_INVOKE ((this, HOOK_INIT, DT_END));
}
#endif
+ pty = rxvt_new_ptytty ();
+
create_windows (argc, argv);
dDisp;
free (cmd_argv);
- if (pty.pty >= 0)
- pty_ev.start (pty.pty, EVENT_READ);
+ if (pty->pty >= 0)
+ pty_ev.start (pty->pty, EVENT_READ);
check_ev.start ();
void
rxvt_init ()
{
- rxvt_environ = environ;
+ uid_t uid = getuid ();
+ gid_t gid = getgid ();
+
+ // before doing anything else, check for setuid/setgid operation,
+ // start the helper process and drop privileges
+ if (uid != geteuid ()
+ || gid != getegid ())
+ {
+#if PTYTTY_HELPER
+ rxvt_ptytty_server ();
+#else
+ rxvt_warn ("running setuid/setgid without pty helper compiled in, continuing unprivileged.\n");
+#endif
- /*
- * Save and then give up any super-user privileges
- * If we need privileges in any area then we must specifically request it.
- * We should only need to be root in these cases:
- * 1. write utmp entries on some systems
- * 2. chown tty on some systems
- */
- rxvt_privileges (SAVE);
- rxvt_privileges (IGNORE);
+ // drop privileges
+#if HAVE_SETRESUID
+ setresgid (gid, gid, gid);
+ setresuid (uid, uid, uid);
+#elif HAVE_SETREUID
+ setregid (gid, gid);
+ setreuid (uid, uid);
+#elif HAVE_SETUID
+ setgid (gid);
+ setuid (uid);
+#endif
+
+ if (uid != geteuid ()
+ || gid != getegid ())
+ rxvt_fatal ("unable to drop privileges, aborting.\n");
+ }
+
+ rxvt_environ = environ;
signal (SIGHUP, SIG_IGN);
signal (SIGPIPE, SIG_IGN);
return p;
}
-/* ------------------------------------------------------------------------- *
- * PRIVILEGED OPERATIONS *
- * ------------------------------------------------------------------------- */
-/* take care of suid/sgid super-user (root) privileges */
-void
-rxvt_privileges (rxvt_privaction action)
-{
-#if ! defined(__CYGWIN32__)
-# if !defined(HAVE_SETEUID) && defined(HAVE_SETREUID)
- /* setreuid () is the poor man's setuid (), seteuid () */
-# define seteuid(a) setreuid(-1, (a))
-# define setegid(a) setregid(-1, (a))
-# define HAVE_SETEUID
-# endif
-# ifdef HAVE_SETEUID
- switch (action)
- {
- case IGNORE:
- /*
- * change effective uid/gid - not real uid/gid - so we can switch
- * back to root later, as required
- */
- setegid (getgid ());
- seteuid (getuid ());
- break;
- case SAVE:
- saved_egid = getegid ();
- saved_euid = geteuid ();
- break;
- case RESTORE:
- setegid (saved_egid);
- seteuid (saved_euid);
- break;
- }
-# else
- switch (action)
- {
- case IGNORE:
- setgid (getgid ());
- setuid (getuid ());
- /* FALLTHROUGH */
- case SAVE:
- /* FALLTHROUGH */
- case RESTORE:
- break;
- }
-# endif
-#endif
-}
-
-#ifdef UTMP_SUPPORT
-void
-rxvt_term::privileged_utmp (rxvt_privaction action)
-{
- if (OPTION (Opt_utmpInhibit)
- || !pty.name || !*pty.name)
- return;
-
- rxvt_privileges (RESTORE);
-
- if (action == SAVE)
- pty.login (cmd_pid, OPTION (Opt_loginShell), rs[Rs_display_name]);
- else
- pty.logout ();
-
- rxvt_privileges (IGNORE);
-}
-#endif
-
/*----------------------------------------------------------------------*/
/*
* window size/position calculcations for XSizeHint and other storage.
void
rxvt_term::tt_winch ()
{
- if (pty.pty < 0)
+ if (pty->pty < 0)
return;
struct winsize ws;
ws.ws_row = nrow;
ws.ws_xpixel = width;
ws.ws_ypixel = height;
- (void)ioctl (pty.pty, TIOCSWINSZ, &ws);
+ (void)ioctl (pty->pty, TIOCSWINSZ, &ws);
#if 0
// TIOCSWINSZâ is supposed to do this automatically and correctly