components/desktop/xscreensaver/patches/10-security_policy.patch
author Alan Coopersmith <Alan.Coopersmith@Oracle.COM>
Sun, 31 Jan 2016 19:31:13 -0800
changeset 5400 1199f8e91f50
permissions -rw-r--r--
22592978 Move xscreensaver to the Userland gate

Bug 15284497 SUNBT6317441 Allow admins to remove user-configurability from
                          screensaver

- Upstream rejected as "I will never implement that, because it's stupid and 
  unenforcible."  Unfortunately, we're stuck with Common Criteria requirements,
  which do not allow for common sense.

Bug 15779180 SUNBT7154101 Not able to unlock screen after xlock after su to a
                          role

- specific to Solaris RBAC

---
 driver/Makefile.in              |    2 +-
 driver/demo-Gtk.c               |   95 +++++++++++++++++++++++++++++++++++----
 driver/lock-Gtk.c               |    5 ++-
 driver/prefs.c                  |   37 +++++++++++++++
 driver/subprocs.c               |   24 ++++++++++
 driver/types.h                  |    3 ++
 driver/xscreensaver-demo.glade2 |    2 +-
 driver/xscreensaver.c           |   36 +++++++++++++--
 driver/xscreensaver.h           |    2 +
 9 files changed, 192 insertions(+), 14 deletions(-)

diff --git a/driver/Makefile.in b/driver/Makefile.in
--- a/driver/Makefile.in
+++ b/driver/Makefile.in
@@ -802,7 +802,7 @@ XScreenSaver_Xm_ad.h: XScreenSaver-Xm.ad
 #
 xscreensaver: $(SAVER_OBJS)
 	$(CC) $(LDFLAGS) -o $@ $(SAVER_OBJS) $(SAVER_LIBS) \
-	-lgconf-2 -lgobject-2.0
+	-lgconf-2 -lgobject-2.0 -lglib-2.0
 
 xscreensaver-command: $(CMD_OBJS)
 	$(CC) $(LDFLAGS) -o $@ $(CMD_OBJS) $(CMD_LIBS)
diff --git a/driver/demo-Gtk.c b/driver/demo-Gtk.c
--- a/driver/demo-Gtk.c
+++ b/driver/demo-Gtk.c
@@ -136,6 +136,7 @@
 #include <stdio.h>
 #include <string.h>
 #include <ctype.h>
+#include <user_attr.h>
 
 #ifdef HAVE_GTK2
 enum {
@@ -687,6 +688,7 @@ run_cmd (state *s, Atom command, int arg)
   char *err = 0;
   int status;
 
+  #if 0
   if (getuid () == 0)
     {
       char buf [255];
@@ -694,6 +696,7 @@ run_cmd (state *s, Atom command, int arg)
       warning_dialog (s->toplevel_widget, buf, False, 100);
       return;
     }
+  #endif
 
   flush_dialog_changes_and_save (s);
   status = xscreensaver_command (GDK_DISPLAY(), command, arg, False, &err);
@@ -1691,9 +1694,10 @@ flush_dialog_changes_and_save (state *s)
 # undef COPY
 
 # define COPYSTR(FIELD,NAME) \
-  if (!p->FIELD || \
+  if ((p->FIELD != p2->FIELD) && \
+      (!p->FIELD || \
       !p2->FIELD || \
-      strcmp(p->FIELD, p2->FIELD)) \
+      strcmp(p->FIELD, p2->FIELD))) \
     { \
       changed = True; \
       if (s->debug_p) \
@@ -2754,6 +2758,79 @@ update_list_sensitivity (state *s)
 #endif /* !HAVE_GTK2 */
 }
 
+# define SENSITIZE(NAME,SENSITIVEP) \
+    gtk_widget_set_sensitive (name_to_widget (s, (NAME)), (SENSITIVEP))
+
+#define HIDEWIDGET(NAME) \
+    gtk_widget_hide (name_to_widget (s, (NAME)))
+
+static void
+customized_lock(state *s)
+{
+  char *idletime = NULL;
+  int timeout = 0;
+  char *idlecmd = NULL;
+  
+  if (getenv("TRUSTED_SESSION")) /* trusted_lock */
+    {
+      HIDEWIDGET("doc_menu");
+      SENSITIZE("restart", 0);
+      SENSITIZE("kill_menu", 0);
+      timeout = 15 ; /* if IDLECMD is missing in security policy file default timeout is 15 min*/
+    }
+  
+  if (((idletime = getuserattruid(getuid(),
+	  USERATTR_IDLETIME_KW, NULL, NULL)) != NULL) &&
+	  ((timeout = atoi(idletime)) != 0) || timeout)
+    {
+
+      GtkWidget *timeout_spinbutton = name_to_widget(s, "timeout_spinbutton");
+      GtkAdjustment *adj = gtk_spin_button_get_adjustment((GtkSpinButton *) timeout_spinbutton);
+      SET_ADJ_UPPER(adj, (gdouble) timeout);
+      if (GET_ADJ_VALUE(adj) > (gdouble) timeout)
+        SET_ADJ_VALUE(adj, (gdouble) timeout);
+      gtk_spin_button_set_adjustment((GtkSpinButton *) timeout_spinbutton, adj);
+
+      /* enforce timeout with idlecmd */
+      if ((idlecmd = getuserattruid(getuid(),
+              USERATTR_IDLECMD_KW, NULL, NULL)) == NULL)
+        idlecmd = strdup(USERATTR_IDLECMD_LOCK_KW);
+
+      if (!idletime && getenv("TRUSTED_SESSION")) 
+        {
+          idlecmd = strdup(USERATTR_IDLECMD_LOGOUT_KW);
+        }
+      
+      if (idlecmd && strcasecmp(idlecmd, USERATTR_IDLECMD_LOGOUT_KW) == 0)
+        {
+          gtk_label_set_text_with_mnemonic(name_to_widget(s, "timeout_label"), "_Logout After");
+
+          HIDEWIDGET("cycle_label");
+          HIDEWIDGET("cycle_spinbutton");
+          HIDEWIDGET("cycle_mlabel");
+
+          HIDEWIDGET("pwd_spinbutton");
+          HIDEWIDGET("pwd_button");
+          HIDEWIDGET("pwd_mlabel");
+          HIDEWIDGET("pwd_button_eventbox");
+
+        } 
+      else
+        {
+          gtk_label_set_text_with_mnemonic(name_to_widget(s, "timeout_label"), "_Lock Screen After");
+        }
+      SENSITIZE("lock_spinbutton", 0);
+      SENSITIZE("lock_mlabel", 0);
+      SENSITIZE("lock_button", 0);
+
+      HIDEWIDGET("lock_spinbutton");
+      HIDEWIDGET("lock_mlabel");
+      HIDEWIDGET("lock_button");
+      HIDEWIDGET("lock_button_eventbox");
+    }
+  free(idletime); /* free works on a NULL value */
+  free(idlecmd); /* when you're all with idlecmd */
+}
 
 static void
 populate_prefs_page (state *s)
@@ -2910,10 +2987,6 @@ populate_prefs_page (state *s)
     }
 #endif /* HAVE_DPMS_EXTENSION */
 
-
-# define SENSITIZE(NAME,SENSITIVEP) \
-    gtk_widget_set_sensitive (name_to_widget (s, (NAME)), (SENSITIVEP))
-
     /* Blanking and Locking
      */
     /* bugid 5077081 */
@@ -2953,10 +3026,13 @@ dpms_supported=1;
     SENSITIZE ("fade_spinbutton", (fading_possible &&
                                    (p->fade_p || p->unfade_p)));
 
-# undef SENSITIZE
+    customized_lock(s);
+
   }
 }
 
+# undef SENSITIZE
+# undef HIDEWIDGET
 
 static void
 populate_popup_window (state *s)
@@ -3040,6 +3116,9 @@ sensitize_menu_items (state *s, Bool force_p)
 
   for (i = 0; i < countof(names); i++)
     {
+      if (getenv ("TRUSTED_SESSION") && 2==i)
+        continue;
+
       GtkWidget *w = name_to_widget (s, names[i]);
       gtk_widget_set_sensitive (GTK_WIDGET(w), running_p);
     }
diff --git a/driver/lock-Gtk.c b/driver/lock-Gtk.c
--- a/driver/lock-Gtk.c
+++ b/driver/lock-Gtk.c
@@ -151,7 +151,10 @@ load_unlock_logo_image (void)
   const char *logofile;
   struct stat statbuf;
 
-  logofile = DEFAULT_ICONDIR "/unlock-logo.png";
+  if (getenv("TRUSTED_SESSION"))
+    logofile = DEFAULT_ICONDIR "/trusted-logo.png";
+  else
+    logofile = DEFAULT_ICONDIR "/unlock-logo.png";
 
   if (stat (logofile, &statbuf) != 0)
     {
diff --git a/driver/prefs.c b/driver/prefs.c
--- a/driver/prefs.c
+++ b/driver/prefs.c
@@ -37,6 +37,7 @@
 # include "vms-pwd.h"
 #endif /* VMS */
 
+#include <user_attr.h>
 
 /* This file doesn't need the Xt headers, so stub these types out... */
 #undef XtPointer
@@ -1181,6 +1182,42 @@ load_init_file (Display *dpy, saver_preferences *p)
     if (s) free (s);
   }
 
+  char *idletime = NULL;
+  int timeout = 0;
+  char *idlecmd = NULL;
+
+  if (((idletime = getuserattruid(getuid(),
+          USERATTR_IDLETIME_KW, NULL, NULL)) != NULL) &&
+          ((timeout = atoi(idletime) * 60 * 1000) != 0))
+    {
+
+      p->lock_timeout = 0;
+      if (p->timeout > timeout)
+	p->timeout = timeout;
+
+      /* always lock or logout and do not show blank screen */
+      if (p->mode == DONT_BLANK)
+	p->mode = BLANK_ONLY;
+
+      p->forcedlock_p = p->lock_p = True;
+
+      /* enforce timeout with idlecmd */
+      if ((idlecmd = getuserattruid(getuid(),
+            USERATTR_IDLECMD_KW, NULL, NULL)) == NULL)
+            idlecmd = strdup(USERATTR_IDLECMD_LOCK_KW);
+
+      if (idlecmd && strcasecmp(idlecmd, USERATTR_IDLECMD_LOGOUT_KW) == 0)
+	p->forcedlogout_p = True;
+    }
+  else if (getenv("TRUSTED_SESSION"))
+    {
+      p->forcedlogout_p = p->forcedlock_p = p->lock_p = True; 
+      p->timeout = 15 * 60 * 1000; /* if security policy not defined, forced logout in 15 mins */
+    }
+
+  free(idletime); /* free works on a NULL value */
+  free(idlecmd); /* when you're all with idlecmd */
+
   if (system_default_screenhack_count)  /* note: first_time is also true */
     {
       merge_system_screenhacks (dpy, p, system_default_screenhacks,
diff --git a/driver/subprocs.c b/driver/subprocs.c
--- a/driver/subprocs.c
+++ b/driver/subprocs.c
@@ -932,6 +932,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 (!(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 a/driver/types.h b/driver/types.h
--- a/driver/types.h
+++ b/driver/types.h
@@ -77,6 +77,9 @@ struct saver_preferences {
   Bool xsync_p;			/* whether XSynchronize has been called */
 
   Bool lock_p;			/* whether to lock as well as save */
+  Bool forcedlock_p;		/* whether to forced lock */
+  Bool forcedlogout_p;		/* whether to forced logout */
+
   Bool unlock_timeout_p;	/* whether to timeout unlock dialog */
                                 /* bugid 5077981 */
 
diff --git a/driver/xscreensaver-demo.glade2 b/driver/xscreensaver-demo.glade2
--- a/driver/xscreensaver-demo.glade2
+++ b/driver/xscreensaver-demo.glade2
@@ -478,7 +478,7 @@
 			  <property name="update_policy">GTK_UPDATE_ALWAYS</property>
 			  <property name="snap_to_ticks">True</property>
 			  <property name="wrap">False</property>
-			  <property name="adjustment">0 0 720 1 15 15</property>
+			  <property name="adjustment">0 0 720 1 15 0</property>
 			  <accessibility>
 			    <atkrelation target="pwd_button" type="controlled-by"/>
 			    <atkrelation target="pwd_button" type="labelled-by"/>
diff --git a/driver/xscreensaver.c b/driver/xscreensaver.c
--- a/driver/xscreensaver.c
+++ b/driver/xscreensaver.c
@@ -142,6 +142,8 @@
 
 #include <stdio.h>
 #include <ctype.h>
+#include <zone.h>
+#include <user_attr.h>
 #include <X11/Xlib.h>
 
 #ifdef ENABLE_NLS
@@ -1183,6 +1185,9 @@ main_loop (saver_info *si)
 
       maybe_reload_init_file (si);
 
+      if (p->forcedlogout_p)
+        logout(&si->screens[0]);
+
       if (p->mode == DONT_BLANK)
         {
           if (p->verbose_p)
@@ -1466,6 +1471,20 @@ DONE:
 static void analyze_display (saver_info *si);
 static void fix_fds (void);
 
+/*
+ * Is Role attached to userid
+ */
+Bool
+isRoleAttached(uid_t uid)
+{
+  char *type;
+  if (((type = getuserattruid(uid, USERATTR_TYPE_KW, NULL, NULL)) != NULL) &&
+	  (strcmp(type, USERATTR_TYPE_NONADMIN_KW) == 0))
+    return (B_TRUE);
+  else
+    return (B_FALSE);
+}
+
 int
 main (int argc, char **argv)
 {
@@ -1476,6 +1495,17 @@ main (int argc, char **argv)
   struct passwd *spasswd;
   int i;
 
+  if (getenv ("TRUSTED_SESSION") && (getzoneid () != 0))
+    exit (1);
+
+  uid_t uid = getuid();
+  if (uid == 0 && isRoleAttached(uid))
+    {
+      fprintf(stderr, "Roles Can not login directly.\n");
+      return 1;
+    }
+
+
   /* It turns out that if we do setlocale (LC_ALL, "") here, people
      running in Japanese locales get font craziness on the password
      dialog, presumably because it is displaying Japanese characters
@@ -1973,7 +2003,7 @@ handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p)
   else if (type == XA_EXIT)
     {
       /* Ignore EXIT message if the screen is locked. */
-      if (until_idle_p || !si->locked_p)
+      if (!(p->forcedlogout_p || p->forcedlock_p) && (until_idle_p || !si->locked_p))
 	{
 	  clientmessage_response (si, window, False,
 				  "EXIT ClientMessage received.",
@@ -1990,8 +2020,8 @@ handle_clientmessage (saver_info *si, XEvent *event, Bool until_idle_p)
 	}
       else
 	clientmessage_response (si, window, True,
-				"EXIT ClientMessage received while locked.",
-				"screen is locked.");
+				"EXIT ClientMessage received.",
+				"screen is locked or does not have privilege to exit.");
     }
   else if (type == XA_RESTART)
     {
diff --git a/driver/xscreensaver.h b/driver/xscreensaver.h
--- a/driver/xscreensaver.h
+++ b/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
    ======================================================================= */
1.7.9.2