summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBrian Cameron <brian.cameron@sun.com>2006-04-07 21:18:13 +0000
committerBrian Cameron <bcameron@src.gnome.org>2006-04-07 21:18:13 +0000
commit5d4149d6a1eed116b9819be2d96350767e0c5519 (patch)
treef63e5266313a59abc4f9d542a0f96ebd40878565
parent71ce348b55249e8a1eccc0979354a28ddbccfa9f (diff)
downloadgdm-5d4149d6a1eed116b9819be2d96350767e0c5519.tar.gz
Add Trusted Solaris support to GDM. Patch provided by Niall Power
2006-04-07 Brian Cameron <brian.cameron@sun.com> * configure.ac, config/Xsession.in, daemon/slave.c: Add Trusted Solaris support to GDM. Patch provided by Niall Power <Niall.Power@sun.com>.
-rw-r--r--ChangeLog6
-rw-r--r--configure.ac24
-rw-r--r--daemon/slave.c208
3 files changed, 237 insertions, 1 deletions
diff --git a/ChangeLog b/ChangeLog
index a38e0112..df510391 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -1,5 +1,11 @@
2006-04-07 Brian Cameron <brian.cameron@sun.com>
+ * configure.ac, config/Xsession.in, daemon/slave.c: Add Trusted
+ Solaris support to GDM. Patch provided by Niall Power
+ <Niall.Power@sun.com>.
+
+2006-04-07 Brian Cameron <brian.cameron@sun.com>
+
* daemon/slave.c: Now logic unlinks .ICEauthority file if it
looks fishy rather than trying to chown/chmod it. This
is to resolve CVE-2006-1057.
diff --git a/configure.ac b/configure.ac
index a731082e..3f3c2c95 100644
--- a/configure.ac
+++ b/configure.ac
@@ -736,6 +736,24 @@ AC_SUBST(DMX_LIBS)
AM_CONDITIONAL(DMX_SUPPORT, test x$DMX_SUPPORT = xyes)
#
+# Solaris Trusted Extensions stuff
+#
+case "$host" in
+*solaris*)
+ AC_CHECK_HEADERS(sys/tsol/label_macro.h,
+ AC_DEFINE(HAVE_TSOL, ,[Building with TSOL support]) found_tsol=yes,)
+ ;;
+*)
+ ;;
+esac
+
+AM_CONDITIONAL(TSOL_DEFINED, test x$found_tsol = xyes)
+if test "x$found_tsol" = "xyes" ; then
+ EXTRA_DAEMON_LIBS="$EXTRA_DAEMON_LIBS -lsecdb"
+fi
+
+
+#
# SELinux stuff
#
if test "x$with_selinux" = "xyes" ; then
@@ -1173,6 +1191,12 @@ else
echo "SELinux support : NO"
fi
+dnl <= Solaris Trusted Extensions support =>
+if test "x$found_tsol" = "xyes" ; then
+ echo "Solaris Trusted Extensions support : YES"
+else
+ echo "Solaris Trusted Extensions support : NO"
+fi
dnl <= Authentication scheme =>
echo "Authentication scheme : $VRFY"
diff --git a/daemon/slave.c b/daemon/slave.c
index dfad1700..ebf4e95a 100644
--- a/daemon/slave.c
+++ b/daemon/slave.c
@@ -64,6 +64,10 @@
#include <time.h>
#include <syslog.h>
+#ifdef HAVE_TSOL
+#include <user_attr.h>
+#endif
+
#ifdef HAVE_SELINUX
#include <selinux/selinux.h>
#include <selinux/get_context_list.h>
@@ -124,6 +128,10 @@ static gchar *ParsedTimedLogin = NULL;
static int greeter_fd_out = -1;
static int greeter_fd_in = -1;
+#ifdef HAVE_TSOL
+static gboolean have_suntsol_extension = FALSE;
+#endif
+
typedef struct {
pid_t pid;
} GdmWaitPid;
@@ -172,6 +180,10 @@ static void set_xnest_parent_stuff (void);
static void check_notifies_now (void);
static void restart_the_greeter (void);
+#ifdef HAVE_TSOL
+static gboolean gdm_can_i_assume_root_role (struct passwd *pwent);
+#endif
+
/* Yay thread unsafety */
static gboolean x_error_occurred = FALSE;
static gboolean gdm_got_ack = FALSE;
@@ -917,6 +929,23 @@ setup_automatic_session (GdmDisplay *display, const char *name)
return TRUE;
}
+#ifdef HAVE_TSOL
+static void
+gdm_tsol_init (GdmDisplay *display)
+{
+
+ int opcode;
+ int firstevent;
+ int firsterror;
+
+ have_suntsol_extension = XQueryExtension (display->dsp,
+ "SUN_TSOL",
+ &opcode,
+ &firstevent,
+ &firsterror);
+}
+#endif
+
static void
gdm_screen_init (GdmDisplay *display)
{
@@ -1418,6 +1447,12 @@ gdm_slave_run (GdmDisplay *display)
if (d->handled)
gdm_screen_init (d);
+#ifdef HAVE_TSOL
+ /* Check out Solaris Trusted Xserver extension */
+ if (d->handled)
+ gdm_tsol_init (d);
+#endif
+
/* check log stuff for the server, this is done here
* because it's really a race */
if (SERVER_IS_LOCAL (d))
@@ -3318,8 +3353,12 @@ session_child_run (struct passwd *pwent,
{
char *exec;
const char *shell = NULL;
- char *argv[4];
char *greeter;
+#ifndef HAVE_TSOL
+ char *argv[4];
+#else
+ char *argv[7];
+#endif
#ifdef CAN_USE_SETPENV
extern char **newenv;
@@ -3520,6 +3559,11 @@ session_child_run (struct passwd *pwent,
argv[1] = NULL;
argv[2] = NULL;
argv[3] = NULL;
+#ifdef HAVE_TSOL
+ argv[4] = NULL;
+ argv[5] = NULL;
+ argv[6] = NULL;
+#endif
exec = NULL;
if (strcmp (session, GDM_SESSION_FAILSAFE_XTERM) != 0 &&
@@ -3563,13 +3607,54 @@ session_child_run (struct passwd *pwent,
/* This is where everything is OK, and note that
we really DON'T care about leaks, we are going to
exec in just a bit */
+#ifdef HAVE_TSOL
+ if (have_suntsol_extension) {
+ argv[0] = basexsession;
+ argv[1] = g_strdup ("/usr/bin/tsoljdslabel");
+ argv[2] = exec;
+ argv[3] = argv[4] = argv[5] = argv[6] = NULL;
+ } else {
+#endif
argv[0] = basexsession;
argv[1] = exec;
argv[2] = NULL;
+#ifdef HAVE_TSOL
+ argv[3] = argv[4] = argv[5] = argv[6] = NULL;
+ }
+#endif
}
}
if (strcmp (session, GDM_SESSION_FAILSAFE_GNOME) == 0) {
+#ifdef HAVE_TSOL
+ if (have_suntsol_extension == TRUE) {
+ /* Trusted Path will be preserved as long as the sys admin
+ * doesn't put anything stupid in gdm.conf */
+ argv[0] = g_strdup ("/usr/bin/tsoljdslabel");
+ argv[1] = find_prog ("gnome-session");
+ if G_UNLIKELY (argv[1] == NULL) {
+ /* yaikes */
+ gdm_error (_("%s: gnome-session not found for a failsafe GNOME session, trying xterm"),
+ "session_child_run");
+ session = GDM_SESSION_FAILSAFE_XTERM;
+ gdm_error_box
+ (d, GTK_MESSAGE_ERROR,
+ _("Could not find the GNOME installation, "
+ "will try running the \"Failsafe xterm\" "
+ "session."));
+ } else {
+ argv[2] = "--failsafe";
+ argv[3] = NULL;
+ gdm_error_box
+ (d, GTK_MESSAGE_INFO,
+ _("This is the Failsafe GNOME session. "
+ "You will be logged into the 'Default' "
+ "session of GNOME without the startup scripts "
+ "being run. This should be used to fix problems "
+ "in your installation."));
+ }
+ } else {
+#endif
argv[0] = find_prog ("gnome-session");
if G_UNLIKELY (argv[0] == NULL) {
/* yaikes */
@@ -3592,6 +3677,9 @@ session_child_run (struct passwd *pwent,
"being run. This should be used to fix problems "
"in your installation."));
}
+#ifdef HAVE_TSOL
+ }
+#endif
failsafe = TRUE;
}
@@ -3606,12 +3694,67 @@ session_child_run (struct passwd *pwent,
/* nyah nyah nyah nyah nyah */
/* 66 means no "session crashed" examine .xsession-errors dialog */
_exit (66);
+#ifdef HAVE_TSOL
+ } else if (have_suntsol_extension) {
+ argv[1] = "-geometry";
+ argv[2] = g_strdup_printf ("80x24-%d-%d",
+ d->lrh_offsetx,
+ d->lrh_offsety);
+ /*
+ * In a Solaris Trusted Extensions environment, failsafe xterms should
+ * be restricted to the root user, or users who have the root role.
+ * This is necessary to prevent normal users and evil terrorists
+ * bypassing their assigned clearance and getting direct access
+ * to the global zone.
+ */
+ if (pwent->pw_uid == 0) {
+ argv[3] = argv[4] = argv[5] = argv[6] = NULL;
+ gdm_error_box
+ (d, GTK_MESSAGE_INFO,
+ _("This is the Failsafe xterm session. "
+ "You will be logged into a terminal "
+ "console so that you may fix your system "
+ "if you cannot log in any other way. "
+ "To exit the terminal emulator, type "
+ "'exit' and an enter into the window."));
+ focus_first_x_window ("xterm");
+ } else if (gdm_can_i_assume_root_role (pwent) == TRUE) {
+ argv[3] = "-C";
+ argv[4] = "-e";
+ argv[5] = "su";
+ argv[6] = NULL;
+ gdm_error_box
+ (d, GTK_MESSAGE_INFO,
+ _("This is the Failsafe xterm session. "
+ "You will be logged into a terminal "
+ "console and be prompted to enter the "
+ "password for root so that you may fix "
+ "your system if you cannot log in any "
+ "other way. To exit the terminal "
+ "emulator, type 'exit' and an enter "
+ "into the window."));
+ focus_first_x_window ("xterm");
+ } else {
+ /* Normal user without root role - get lost */
+ gdm_error_box
+ (d, GTK_MESSAGE_INFO,
+ _("The failsafe session is restricted to "
+ "users who have been assigned the root "
+ "role. If you cannot log in any other "
+ "way please contact your system "
+ "administrator"));
+ _exit (66);
+ }
+#endif /* HAVE_TSOL */
} else {
argv[1] = "-geometry";
argv[2] = g_strdup_printf ("80x24-%d-%d",
d->lrh_offsetx,
d->lrh_offsety);
argv[3] = NULL;
+#ifdef HAVE_TSOL
+ argv[4] = argv[5] = argv[6] = NULL;
+#endif
gdm_error_box
(d, GTK_MESSAGE_INFO,
_("This is the Failsafe xterm session. "
@@ -3625,11 +3768,22 @@ session_child_run (struct passwd *pwent,
failsafe = TRUE;
}
+#ifdef HAVE_TSOL
+ gdm_debug ("Running %s %s %s %s %s %s for %s on %s",
+ argv[0],
+ ve_sure_string (argv[1]),
+ ve_sure_string (argv[2]),
+ ve_sure_string (argv[3]),
+ ve_sure_string (argv[4]),
+ ve_sure_string (argv[5]),
+ login, d->name);
+#else
gdm_debug ("Running %s %s %s for %s on %s",
argv[0],
ve_sure_string (argv[1]),
ve_sure_string (argv[2]),
login, d->name);
+#endif
if ( ! ve_string_empty (pwent->pw_shell)) {
shell = pwent->pw_shell;
@@ -3683,6 +3837,25 @@ session_child_run (struct passwd *pwent,
VE_IGNORE_EINTR (execv (argv[0], argv));
/* will go to .xsession-errors */
+#ifdef HAVE_TSOL
+ fprintf (stderr, _("%s: Could not exec %s %s %s %s %s %s"),
+ "session_child_run",
+ argv[0],
+ ve_sure_string (argv[1]),
+ ve_sure_string (argv[2]),
+ ve_sure_string (argv[3]),
+ ve_sure_string (argv[4]),
+ ve_sure_string (argv[5]));
+
+ gdm_error ( _("%s: Could not exec %s %s %s %s %s %s"),
+ "session_child_run",
+ argv[0],
+ ve_sure_string (argv[1]),
+ ve_sure_string (argv[2]),
+ ve_sure_string (argv[3]),
+ ve_sure_string (argv[4]),
+ ve_sure_string (argv[5]));
+#else
fprintf (stderr, _("%s: Could not exec %s %s %s"),
"session_child_run",
argv[0],
@@ -3693,6 +3866,7 @@ session_child_run (struct passwd *pwent,
argv[0],
ve_sure_string (argv[1]),
ve_sure_string (argv[2]));
+#endif
/* if we can't read and exec the session, then make a nice
* error dialog */
@@ -5433,4 +5607,36 @@ gdm_slave_final_cleanup (void)
return TRUE;
}
+#ifdef HAVE_TSOL
+static gboolean
+gdm_can_i_assume_root_role (struct passwd *pwent)
+{
+ userattr_t *uattr = NULL;
+ char *freeroles = NULL;
+ char *roles = NULL;
+ char *role = NULL;
+
+ uattr = getuseruid (pwent->pw_uid);
+ if G_UNLIKELY (uattr == NULL)
+ return FALSE;
+
+ freeroles = roles = g_strdup (kva_match (uattr->attr, USERATTR_ROLES_KW));
+ if (roles == NULL) {
+ return FALSE;
+ }
+
+ while ((role = strtok (roles, ",")) != NULL) {
+ roles = NULL;
+ if (!strncmp (role, "root", 4)) {
+ g_free (freeroles);
+ g_free (role);
+ return TRUE;
+ }
+ }
+ g_free (freeroles);
+ g_free (role);
+ return FALSE;
+}
+#endif /* HAVE_TSOL */
+
/* EOF */