/*
 * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
 *
 * Permission is hereby granted, free of charge, to any person obtaining a
 * copy of this software and associated documentation files (the "Software"),
 * to deal in the Software without restriction, including without limitation
 * the rights to use, copy, modify, merge, publish, distribute, sublicense,
 * and/or sell copies of the Software, and to permit persons to whom the
 * Software is furnished to do so, subject to the following conditions:
 *
 * The above copyright notice and this permission notice (including the next
 * paragraph) shall be included in all copies or substantial portions of the
 * Software.
 *
 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
 * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
 * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
 * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
 * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
 * DEALINGS IN THE SOFTWARE.
 */

Support needed for Solaris Trusted Extensions / Trusted GNOME.
---
 driver/Makefile.in             |   21 +++--
 driver/demo-Gtk.c              |   80 ++++++++++++++++++-
 driver/lock-Gtk.c              |    6 +-
 driver/prefs.c                 |   43 ++++++++++-
 driver/subprocs.c              |   25 ++++++
 driver/trusted-utils.c         |  171 ++++++++++++++++++++++++++++++++++++++++
 driver/trusted-utils.h         |   54 +++++++++++++
 driver/types.h                 |    2 +
 driver/xscreensaver-getimage.c |    3 +-
 driver/xscreensaver.c          |   11 +++
 driver/xscreensaver.h          |    2 +
 11 files changed, 406 insertions(+), 12 deletions(-)
 create mode 100644 driver/trusted-utils.c
 create mode 100644 driver/trusted-utils.h

diff --git xscreensaver-5.12/driver/Makefile.in xscreensaver-5.12/driver/Makefile.in
--- xscreensaver-5.12/driver/Makefile.in
+++ xscreensaver-5.12/driver/Makefile.in
@@ -105,6 +105,10 @@ GTK_OBJS	= demo-Gtk.o demo-Gtk-conf.o @GTK_EXTRA_OBJS@
 GTK_LOCK_SRCS	= lock-Gtk.c atoms.c remote.c
 GTK_LOCK_OBJS	= lock-Gtk.o atoms.o remote.o
 
+TRUSTED_LIBS	= -lglib-2.0 -lsecdb
+TRUSTED_SRCS	= trusted-utils.c
+TRUSTED_OBJS	= trusted-utils.o
+
 PWENT_SRCS	= passwd-pwent.c
 PWENT_OBJS	= passwd-pwent.o
 
@@ -800,9 +804,9 @@ XScreenSaver_Xm_ad.h: XScreenSaver-Xm.ad
 
 # The executables linked in this directory.
 #
-xscreensaver: $(SAVER_OBJS)
-	$(CC) $(LDFLAGS) -o $@ $(SAVER_OBJS) $(SAVER_LIBS) \
-	-lgconf-2 -lgobject-2.0
+xscreensaver: $(SAVER_OBJS) $(TRUSTED_OBJS)
+	$(CC) $(LDFLAGS) -o $@ $(SAVER_OBJS) $(TRUSTED_OBJS) \
+	$(TRUSTED_LIBS) $(SAVER_LIBS) -lgconf-2 -lgobject-2.0
 
 xscreensaver-command: $(CMD_OBJS)
 	$(CC) $(LDFLAGS) -o $@ $(CMD_OBJS) $(CMD_LIBS)
@@ -821,8 +825,9 @@ xscreensaver-demo: @PREFERRED_DEMO_PROGRAM@
 xscreensaver-lock: @PREFERRED_LOCK_PROGRAM@
 	$(INSTALL_PROGRAM) @PREFERRED_LOCK_PROGRAM@ $@
 
-xscreensaver-lock-Gtk: $(GTK_LOCK_OBJS)
+xscreensaver-lock-Gtk: $(GTK_LOCK_OBJS) $(TRUSTED_OBJS)
 	$(CC) $(LDFLAGS) -o $@ $(GTK_LOCK_OBJS) $(LIBS) $(X_LIBS) \
+	$(TRUSTED_OBJS) $(TRUSTED_LIBS) \
 	$(GTK_LIBS) $(XML_LIBS) $(X_PRE_LIBS) -lXt -lX11 \
 	$(XDPMS_LIBS) -lXext \
 	$(X_EXTRA_LIBS)
@@ -832,9 +837,9 @@ xscreensaver-demo-Xm: $(DEMO_OBJS) $(MOTIF_OBJS)
 	$(MOTIF_LIBS) $(INTL_LIBS) $(X_PRE_LIBS) -lXt -lX11 \
 	$(XDPMS_LIBS) $(XINERAMA_LIBS) -lXext $(X_EXTRA_LIBS)
 
-xscreensaver-demo-Gtk: $(DEMO_OBJS) $(GTK_OBJS)
-	$(CC) $(LDFLAGS) -o $@ $(DEMO_OBJS) $(GTK_OBJS) $(LIBS) $(X_LIBS) \
-	$(GTK_LIBS) $(XPM_LIBS) $(XML_LIBS) $(INTL_LIBS) $(X_PRE_LIBS) \
+xscreensaver-demo-Gtk: $(DEMO_OBJS) $(GTK_OBJS) $(TRUSTED_OBJS)
+	$(CC) $(LDFLAGS) -o $@ $(DEMO_OBJS) $(GTK_OBJS) $(TRUSTED_OBJS) $(LIBS) $(X_LIBS) \
+	$(GTK_LIBS) $(XPM_LIBS) $(XML_LIBS) $(INTL_LIBS) $(TRUSTED_LIBS) $(X_PRE_LIBS) \
 	-lXt -lX11 $(XDPMS_LIBS) $(XINERAMA_LIBS) -lXext $(X_EXTRA_LIBS)
 
 demo-Gtk.o: XScreenSaver_ad.h
@@ -843,7 +848,7 @@ xscreensaver.o: XScreenSaver_ad.h
 xscreensaver-getimage.o: XScreenSaver_ad.h
 
 xscreensaver-getimage: $(GETIMG_OBJS)
-	$(CC) $(LDFLAGS) -o $@ $(GETIMG_OBJS) $(GETIMG_LIBS) -lm
+	$(CC) $(LDFLAGS) -o $@ $(GETIMG_OBJS) $(TRUSTED_OBJS) $(GETIMG_LIBS) $(TRUSTED_LIBS) -lm
 
 pdf2jpeg: $(PDF2JPEG_OBJS)
 	$(OBJCC) $(LDFLAGS) -o $@ $(PDF2JPEG_OBJS) $(PDF2JPEG_LIBS) -lm
diff --git xscreensaver-5.12/driver/demo-Gtk.c xscreensaver-5.12/driver/demo-Gtk.c
--- xscreensaver-5.12/driver/demo-Gtk.c
+++ xscreensaver-5.12/driver/demo-Gtk.c
@@ -137,6 +137,14 @@
 #include <string.h>
 #include <ctype.h>
 
+#include <user_attr.h>
+
+#include "trusted-utils.h"
+void XTSOLgetWorkstationOwner(Display *, uid_t *);
+static gboolean tsol_hack_initialized = False;
+static gboolean tsol_multi_label_session = False;
+extern Display *global_dpy;
+
 #ifdef HAVE_GTK2
 enum {
   COL_ENABLED,
@@ -2935,6 +2943,73 @@ populate_prefs_page (state *s)
     SENSITIZE ("fade_spinbutton", (fading_possible &&
                                    (p->fade_p || p->unfade_p)));
 
+    tsol_multi_label_session = tsol_is_multi_label_session ();
+    if (tsol_multi_label_session)
+      {
+        static int idletime = 0;
+        if (!tsol_hack_initialized)
+          {
+            GtkWidget *doc_menu = name_to_widget(s,"doc_menu");
+            GtkWidget *restart_menu = name_to_widget(s,"restart");
+            GtkWidget *kill_menu = name_to_widget(s, "kill_menu");
+            GtkWidget *lock_spinbutton = name_to_widget(s, "lock_spinbutton");
+            GtkWidget *timeout_spinbutton = name_to_widget(s, "timeout_spinbutton");
+            GtkWidget *lock_container = name_to_widget(s, "blanking_table");
+            GtkWidget *lock_button_eventbox = name_to_widget(s, "lock_button_eventbox");
+            Widget *newlabel = g_object_new(GTK_TYPE_LABEL, "label",
+                                            _("_Lock Screen After"),
+                                            "use-underline", TRUE,
+                                            "mnemonic-widget", lock_spinbutton,
+                                            NULL);
+            GValue *gv = g_new0(GValue, 1);
+            GtkAdjustment *adj;
+            userattr_t *uent;
+
+            char *value = NULL;
+            uid_t WorkstationOwner;
+            Display *dpy = GDK_DISPLAY();
+
+            gtk_widget_hide(doc_menu);
+            gtk_widget_set_sensitive(restart_menu, FALSE);
+            gtk_widget_set_sensitive (kill_menu, FALSE);
+
+            XTSOLgetWorkstationOwner(dpy, &WorkstationOwner);
+            uent = getuseruid(WorkstationOwner);
+            value = getusrattrval(uent, USERATTR_IDLETIME_KW);
+            if (value != NULL)
+              {
+                idletime = atoi(value);
+                if (idletime)
+                  {
+                    adj = gtk_spin_button_get_adjustment((GtkSpinButton  *)timeout_spinbutton);
+                    SET_ADJ_UPPER (adj, (gdouble)idletime);
+                    if (GET_ADJ_VALUE (adj) > (gdouble)idletime)
+                      SET_ADJ_VALUE (adj, (gdouble)idletime);
+                    gtk_spin_button_set_adjustment((GtkSpinButton *)timeout_spinbutton, adj);
+                  }
+              }
+
+            gtk_container_add(GTK_CONTAINER(lock_container), GTK_WIDGET(newlabel));
+            g_value_init(gv, G_TYPE_INT);
+            g_value_set_int(gv, 2);
+            gtk_container_child_set_property(GTK_CONTAINER(lock_container), GTK_WIDGET(newlabel), "top_attach", gv);
+            g_value_set_int(gv, 1);
+            gtk_container_child_set_property(GTK_CONTAINER(lock_container), GTK_WIDGET(newlabel), "left_attach", gv);
+            gtk_widget_show(GTK_WIDGET(newlabel));
+            gtk_widget_hide(GTK_WIDGET(lock_button_eventbox));
+            g_object_set(lock_button_eventbox, "active", TRUE, NULL);
+
+            tsol_hack_initialized = True;
+          }
+
+        if (idletime)
+          {
+            SENSITIZE ("lock_spinbutton", 0);
+            SENSITIZE ("lock_mlabel",     0);
+            SENSITIZE ("lock_button",     0);
+          }
+      }
+
 # undef SENSITIZE
   }
 }
@@ -3022,6 +3097,9 @@ sensitize_menu_items (state *s, Bool force_p)
 
   for (i = 0; i < countof(names); i++)
     {
+      if (tsol_is_multi_label_session() && 2==i)
+        continue;
+
       GtkWidget *w = name_to_widget (s, names[i]);
       gtk_widget_set_sensitive (GTK_WIDGET(w), running_p);
     }
@@ -4991,7 +5069,7 @@ main (int argc, char **argv)
                                      applicationShellWidgetClass,
                                      dpy, 0, 0);
 
-  dpy = XtDisplay (toplevel_shell);
+  global_dpy = dpy = XtDisplay (toplevel_shell);
   db = XtDatabase (dpy);
   XtGetApplicationNameAndClass (dpy, &progname, &progclass);
   XSetErrorHandler (demo_ehandler);
diff --git xscreensaver-5.12/driver/lock-Gtk.c xscreensaver-5.12/driver/lock-Gtk.c
--- xscreensaver-5.12/driver/lock-Gtk.c
+++ xscreensaver-5.12/driver/lock-Gtk.c
@@ -72,6 +72,7 @@
 
 #include "remote.h"
 #include "atoms.h"
+#include "trusted-utils.h"
 
 #if GTK_CHECK_VERSION(2,14,0)
 # define GET_WINDOW(w)          gtk_widget_get_window (w)
@@ -151,7 +152,10 @@ load_unlock_logo_image (void)
   const char *logofile;
   struct stat statbuf;
 
-  logofile = DEFAULT_ICONDIR "/unlock-logo.png";
+  if (tsol_is_multi_label_session())
+    logofile = DEFAULT_ICONDIR "/trusted-logo.png";
+  else
+    logofile = DEFAULT_ICONDIR "/unlock-logo.png";
 
   if (stat (logofile, &statbuf) != 0)
     {
diff --git xscreensaver-5.12/driver/prefs.c xscreensaver-5.12/driver/prefs.c
--- xscreensaver-5.12/driver/prefs.c
+++ xscreensaver-5.12/driver/prefs.c
@@ -37,6 +37,8 @@
 # include "vms-pwd.h"
 #endif /* VMS */
 
+#include "trusted-utils.h"
+#include <user_attr.h>
 
 /* This file doesn't need the Xt headers, so stub these types out... */
 #undef XtPointer
@@ -67,6 +69,9 @@
 #include "prefs.h"
 #include "resources.h"
 
+#include "trusted-utils.h"
+Display *global_dpy;
+
 /* don't use realpath() on fedora system */
 #ifdef _FORTIFY_SOURCE
 #undef HAVE_REALPATH
@@ -1046,7 +1051,10 @@ load_init_file (Display *dpy, saver_preferences *p)
   p->xsync_p	    = get_boolean_resource (dpy, "synchronous", "Synchronous");
   p->verbose_p	    = get_boolean_resource (dpy, "verbose", "Boolean");
   p->timestamp_p    = get_boolean_resource (dpy, "timestamp", "Boolean");
-  p->lock_p	    = get_boolean_resource (dpy, "lock", "Boolean");
+  if (tsol_is_multi_label_session())
+    p->lock_p       = True; /* always lock in a Multi Label Session */
+  else
+    p->lock_p       = get_boolean_resource (dpy, "lock", "Boolean");
   p->fade_p	    = get_boolean_resource (dpy, "fade", "Boolean");
   p->unfade_p	    = get_boolean_resource (dpy, "unfade", "Boolean");
   p->fade_seconds   = 1000 * get_seconds_resource (dpy, "fadeSeconds", "Time");
@@ -1070,6 +1078,7 @@ load_init_file (Display *dpy, saver_preferences *p)
   p->lock_timeout    = 1000 * get_minutes_resource (dpy, "lockTimeout", "Time");
   p->cycle           = 1000 * get_minutes_resource (dpy, "cycle", "Time");
   p->passwd_timeout  = 1000 * get_seconds_resource (dpy, "passwdTimeout", "Time");
+
   /* bugid 5077981 */
   p->unlock_timeout_p = get_boolean_resource (dpy, "passwdTimeoutEnabled", "Boolean");
   p->pointer_timeout = 1000 * get_seconds_resource (dpy, "pointerPollTime", "Time");
@@ -1175,6 +1184,38 @@ load_init_file (Display *dpy, saver_preferences *p)
     if (s) free (s);
   }
 
+  if (tsol_is_multi_label_session())
+    {
+      userattr_t *uent;
+      int idletime;
+      char *value = NULL;
+      uid_t WorkstationOwner;
+
+      XTSOLgetWorkstationOwner (global_dpy, &WorkstationOwner);
+      uent = getuseruid (WorkstationOwner);
+      value = getusrattrval (uent, USERATTR_IDLETIME_KW);
+      if (value != NULL)
+        {
+          idletime = atoi(value) * 60 * 1000;
+          if (idletime)
+            {
+              p->lock_timeout = 0;
+              if (p->timeout > idletime)
+                p->timeout = idletime;
+            }
+         }
+
+      /* always lock or logout in a Multi Label Session */
+      if (p->mode == DONT_BLANK)
+        p->mode = BLANK_ONLY;
+
+      value = getusrattrval (uent, USERATTR_IDLECMD_KW);
+      if (value && strcasecmp (value, USERATTR_IDLECMD_LOGOUT_KW) == 0)
+        p->lock_cmd = LOGOUT_CMD;
+      else
+        p->lock_cmd = LOCK_CMD;
+    }
+
   if (system_default_screenhack_count)  /* note: first_time is also true */
     {
       merge_system_screenhacks (dpy, p, system_default_screenhacks,
diff --git xscreensaver-5.12/driver/subprocs.c xscreensaver-5.12/driver/subprocs.c
--- xscreensaver-5.12/driver/subprocs.c
+++ xscreensaver-5.12/driver/subprocs.c
@@ -70,6 +70,7 @@ extern int kill (pid_t, int);		/* signal() is in sys/signal.h... */
 #include "exec.h"
 #include "yarandom.h"
 #include "visual.h"    /* for id_to_visual() */
+#include "trusted-utils.h"
 
 extern saver_info *global_si_kludge;	/* I hate C so much... */
 
@@ -932,6 +933,30 @@ check_if_hacks_dir_exists(Bool verbose_p)
     }
 }
 
+/* Added separate function for logout as we need to find better way to log user
+   out. See CR6422890. For s10 we will use /usr/bin/gnome-session-save --kill
+*/
+void
+logout(saver_screen_info *ssi)
+{
+  saver_info *si = ssi->global;
+  saver_preferences *p = &si->prefs;
+  if (p->lock_cmd == LOGOUT_CMD && !(si->emergency_lock_p || si->locked_p))
+    {
+      struct stat st;
+      if (!stat ("/usr/bin/gnome-session-save", &st))
+        {
+          pid_t forked = fork_and_exec (ssi, "/usr/bin/gnome-session-save\t--force-logout");
+          if (forked < 1)
+            {
+              char buf [255];
+              snprintf (buf, sizeof(buf), "%s: couldn't fork", blurb());
+              perror (buf);
+            }
+        }
+    }
+}
+
 void
 spawn_screenhack (saver_screen_info *ssi)
 {
diff --git xscreensaver-5.12/driver/trusted-utils.c xscreensaver-5.12/driver/trusted-utils.c
new file mode 100644
--- /dev/null
+++ xscreensaver-5.12/driver/trusted-utils.c
@@ -0,0 +1,171 @@
+/*
+ * Trusted xscreensaver
+ *
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ *
+ * Based on work by Erwann Chenede, Ghee Teo
+ *
+ * Used to check if we are in a multilabel session and to load
+ * additional functionality within the multilabel session.
+ */
+#include <dlfcn.h>
+#include <link.h>
+#include <stdlib.h>
+#include <user_attr.h>
+#include <sys/types.h>
+#include <unistd.h>
+#include <strings.h>
+#include <stdio.h>
+#include "trusted-utils.h"
+
+/*
+ * Checks for Multi label session
+ */
+gboolean
+tsol_is_multi_label_session (void)
+{
+  static char *session = NULL;
+
+  if (!session)
+    session = (char *)getenv("TRUSTED_SESSION");
+
+  if (!session)
+    return FALSE;
+
+  return TRUE;
+}
+
+/*
+ * dynamicly load the libxtsol library
+ */
+static
+void * dlopen_xtsol (void)
+{
+  void  *handle = NULL;
+
+  if ((handle = dlopen ("/usr/lib/libXtsol.so.1", RTLD_LAZY)) != NULL)
+    return handle;
+  if ((handle = dlopen ("/usr/openwin/lib/libXtsol.so.1", RTLD_LAZY)) != NULL)
+    return handle;
+
+  return handle;
+}
+
+/*
+ * dynamicly load the libDtTsol library
+ */
+static
+void * dlopen_gnometsol (void)
+{
+  void  *handle = NULL;
+
+  if ((handle = dlopen ("/usr/lib/libgnometsol.so", RTLD_LAZY)) != NULL)
+    return handle;
+
+  return handle;
+}
+
+xtsol_XTSOLgetWorkstationOwner      libxtsol_XTSOLgetWorkstationOwner = NULL;
+
+void
+XTSOLgetWorkstationOwner(Display *dpy, uid_t *WorkstationOwner)
+{
+  static gpointer xtsol_handle = NULL;
+  static gboolean _xtsol_initialized = FALSE;
+
+  if ( ! _xtsol_initialized )
+    {
+      _xtsol_initialized = TRUE;
+      xtsol_handle = dlopen_xtsol ();
+      if (xtsol_handle != NULL)
+	libxtsol_XTSOLgetWorkstationOwner
+	  = (xtsol_XTSOLgetWorkstationOwner) dlsym(xtsol_handle,
+						   "XTSOLgetWorkstationOwner");
+    }
+
+  if (libxtsol_XTSOLgetWorkstationOwner == NULL)
+    *WorkstationOwner = getuid();
+  else
+    libxtsol_XTSOLgetWorkstationOwner(dpy, WorkstationOwner);
+}
+
+xtsol_XTSOLMakeTPWindow      libxtsol_XTSOLMakeTPWindow = NULL;
+
+void
+XTSOLMakeTPWindow(Display *dpy, Window w)
+{
+  static gpointer xtsol_handle = NULL;
+  static gboolean _xtsol_initialized = FALSE;
+
+  if ( ! _xtsol_initialized )
+    {
+      _xtsol_initialized = TRUE;
+      xtsol_handle = dlopen_xtsol ();
+      if (xtsol_handle != NULL)
+	libxtsol_XTSOLMakeTPWindow
+	  = (xtsol_XTSOLMakeTPWindow) dlsym(xtsol_handle,
+					    "XTSOLMakeTPWindow");
+    }
+
+  if (libxtsol_XTSOLMakeTPWindow)
+    {
+      libxtsol_XTSOLMakeTPWindow(dpy, w);
+    }
+}
+
+gnome_tsol_get_usrattr_val		libgnome_tsol_get_usrattr_val = NULL;
+
+/*
+ * Returns a value from uattr for the given key.
+ * If there is no value in user_attr, then it returns the
+ * system wide default from policy.conf or labelencodings
+ * as appropriate.
+ */
+char *
+getusrattrval(userattr_t *uattr, char *keywd)
+{
+  static gpointer gnometsol_handle = NULL;
+  static gboolean _gnometsol_initialized = FALSE;
+  char *value;
+
+  if ( ! _gnometsol_initialized )
+    {
+      _gnometsol_initialized = TRUE;
+      gnometsol_handle = dlopen_gnometsol ();
+      if (gnometsol_handle != NULL)
+	libgnome_tsol_get_usrattr_val
+	  = (gnome_tsol_get_usrattr_val) dlsym(gnometsol_handle,
+					       "gnome_tsol_get_usrattr_val");
+    }
+
+  if (libgnome_tsol_get_usrattr_val == NULL)
+    {
+      if (strcmp(keywd, USERATTR_IDLETIME_KW) == 0)
+	value = strdup("15");
+      else if (strcmp(keywd, USERATTR_IDLECMD_KW) == 0)
+	value = strdup(USERATTR_IDLECMD_LOCK_KW);
+    } else
+      value = libgnome_tsol_get_usrattr_val(uattr, keywd);
+
+  return ( value );
+}
diff --git xscreensaver-5.12/driver/trusted-utils.h xscreensaver-5.12/driver/trusted-utils.h
new file mode 100644
--- /dev/null
+++ xscreensaver-5.12/driver/trusted-utils.h
@@ -0,0 +1,54 @@
+/*
+ * Trusted xscreensaver
+ *
+ * Copyright (c) 2006, 2010, Oracle and/or its affiliates. All rights reserved.
+ *
+ * Permission is hereby granted, free of charge, to any person obtaining a
+ * copy of this software and associated documentation files (the "Software"),
+ * to deal in the Software without restriction, including without limitation
+ * the rights to use, copy, modify, merge, publish, distribute, sublicense,
+ * and/or sell copies of the Software, and to permit persons to whom the
+ * Software is furnished to do so, subject to the following conditions:
+ *
+ * The above copyright notice and this permission notice (including the next
+ * paragraph) shall be included in all copies or substantial portions of the
+ * Software.
+ *
+ * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
+ * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
+ * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL
+ * THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
+ * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
+ * DEALINGS IN THE SOFTWARE.
+ *
+ * Based on work by Erwann Chenede, Ghee Teo
+ *
+ * Definitions for the trusted functions.
+ */
+#ifndef TRUSTED_XSCREENSAVER_H
+#define TRUSTED_XSCREENSAVER_H
+
+#ifdef HAVE_XTSOL
+#include <X11/extensions/Xtsol.h>
+#endif /* HAVE_XTSOL */
+#include <user_attr.h>
+#include <glib.h>
+#include <X11/Xlib.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+extern gboolean tsol_is_multi_label_session (void);
+extern char *getusrattrval(userattr_t *, char *);
+extern void XTSOLgetWorkstationOwner(Display *, uid_t *);
+
+typedef void (*xtsol_XTSOLgetWorkstationOwner) (Display *, uid_t *);
+extern void XTSOLMakeTPWindow(Display *, Window);
+typedef void (*xtsol_XTSOLMakeTPWindow) (Display *, Window);
+typedef char *(*gnome_tsol_get_usrattr_val) (userattr_t *, char *);
+
+enum {
+	LOCK_CMD = 0,
+	LOGOUT_CMD
+};
+#endif /* TRUSTED_XSCREENSAVER_H */
diff --git xscreensaver-5.12/driver/types.h xscreensaver-5.12/driver/types.h
--- xscreensaver-5.12/driver/types.h
+++ xscreensaver-5.12/driver/types.h
@@ -105,6 +105,8 @@ struct saver_preferences {
   Time initial_delay;		/* how long to sleep after launch */
   Time splash_duration;		/* how long the splash screen stays up */
   Time timeout;			/* how much idle time before activation */
+  int lock_cmd;                 /* tsol only  - whether to lock or logout */
+
   Time lock_timeout;		/* how long after activation locking starts */
   Time cycle;			/* how long each hack should run */
   Time passwd_timeout;		/* how much time before pw dialog goes down */
diff --git xscreensaver-5.12/driver/xscreensaver-getimage.c xscreensaver-5.12/driver/xscreensaver-getimage.c
--- xscreensaver-5.12/driver/xscreensaver-getimage.c
+++ xscreensaver-5.12/driver/xscreensaver-getimage.c
@@ -83,6 +83,7 @@ static char *defaults[] = {
  0
 };
 
+extern Display *global_dpy;
 
 
 char *progname = 0;
@@ -1797,7 +1798,7 @@ main (int argc, char **argv)
 
   toplevel = XtAppInitialize (&app, progclass, 0, 0, &argc, argv,
                               defaults, 0, 0);
-  dpy = XtDisplay (toplevel);
+  global_dpy = dpy = XtDisplay (toplevel);
   screen = XtScreen (toplevel);
   db = XtDatabase (dpy);
   XtGetApplicationNameAndClass (dpy, &s, &progclass);
diff --git xscreensaver-5.12/driver/xscreensaver.c xscreensaver-5.12/driver/xscreensaver.c
--- xscreensaver-5.12/driver/xscreensaver.c
+++ xscreensaver-5.12/driver/xscreensaver.c
@@ -142,6 +142,7 @@
 
 #include <stdio.h>
 #include <ctype.h>
+#include <zone.h>
 #include <X11/Xlib.h>
 
 #ifdef ENABLE_NLS
@@ -229,6 +230,9 @@
 #include "auth.h"
 #include "atoms.h"
 
+#include "trusted-utils.h"
+extern Display *global_dpy;
+
 saver_info *global_si_kludge = 0;	/* I hate C so much... */
 
 /* Globals */
@@ -1183,6 +1187,9 @@ main_loop (saver_info *si)
 
       maybe_reload_init_file (si);
 
+      if (tsol_is_multi_label_session())
+        logout(&si->screens[0]);
+
       if (p->mode == DONT_BLANK)
         {
           if (p->verbose_p)
@@ -1459,6 +1466,9 @@ main (int argc, char **argv)
   struct passwd *spasswd;
   int i;
 
+  if (tsol_is_multi_label_session () && (getzoneid () != 0))
+    exit (1);
+
 #ifdef ENABLE_NLS
   if (!setlocale (LC_ALL, ""))
     fprintf (stderr, "locale not supported by C library\n");
@@ -1509,6 +1519,7 @@ main (int argc, char **argv)
 # endif /* !NO_LOCKING */
 
   shell = connect_to_server (si, &argc, argv);
+  global_dpy = XtDisplay(shell);
   process_command_line (si, &argc, argv);
   stderr_log_file (si);
   print_banner (si);
diff --git xscreensaver-5.12/driver/xscreensaver.h xscreensaver-5.12/driver/xscreensaver.h
--- xscreensaver-5.12/driver/xscreensaver.h
+++ xscreensaver-5.12/driver/xscreensaver.h
@@ -170,6 +170,8 @@ extern struct screenhack_job *make_job (pid_t pid, int screen,
                                         const char *cmd);
 #endif
 
+extern void logout(saver_screen_info *ssi);
+
 /* =======================================================================
    subprocs diagnostics
    ======================================================================= */

