2011-03-16 Brian Cameron <[email protected]> gnome-2-30
authoryippi
Wed, 16 Mar 2011 17:47:17 +0000
branchgnome-2-30
changeset 21591 4f182365a4b1
parent 21589 9c63a229fe25
child 21592 5d934c4b174e
2011-03-16 Brian Cameron <[email protected]> * base-specs/gnome-panel.spec, patches/gnome-panel-17-rbac.diff: Add patch which causes the panel to filter applets and launchers based on RBAC profiles. * base-specs/gnome-menus.spec, patches/gnome-menus-08-rbac.diff: Add patch which causes panel to filter menu items based on RBAC profiles. * base-specs/glib2.spec, patches/glib-14-gio-rbac.diff: Add patch which causes programs to be run with pfexec or gksu as needed based on RBAC configuration, but only when not in Trusted mode. * base-specs/gnome-session.spec, patches/gnome-session-24-rbac.diff: Add patch which causes autostart programs to be run with pfexec or gksu as needed based on RBAC configuration, but only when not in Trusted mode. * specs/SUNWtgnome-tstripe.spec, patches/tsoljds-tstripe-03-pfexec.diff: Add patch which causes all programs run by the xagent proxy to be run with pfexec. The glib and gnome-session patches only work in non-Trusted mode because this code ensures that programs are run with pfexec as needed when in Trusted mode. * specs/SUNWgnome-cd-burner.spec, patches/brasero-01-libtool.diff: Fix brasero so the desktop file no longer hardcodes gksu. * patches/brasero-01-load-by-gksu.diff: Remove old patch. * specs/SUNWnwam-manager.spec, ext-sources/SUNWnwam-manager-exec_attr: Add exec_attr entries for nwam-manager-properties and the Network applet. * patches/sound-juicer-01-menu-entry.diff: No longer hardcode gksu in the desktop file. * patches/libwnck-01-trusted-extensions.diff: Update patch so that it supports the new "role_changed" and "label_changed" signals. These signals are used by the other patches to identify when these change. * ext-sources/SUNWgnome-system-tools-exec_attr: Add entry for /usr/bin/users-admin. * manpages/man1/gnome-panel.1: Update gnome-panel manpage so that it explains how the panel filters menu items, launchers, and applets and also how it runs programs with pfexec or gksu automatically.
ChangeLog
base-specs/glib2.spec
base-specs/gnome-menus.spec
base-specs/gnome-panel.spec
base-specs/gnome-session.spec
ext-sources/SUNWgnome-system-tools-exec_attr
ext-sources/SUNWnwam-manager-exec_attr
manpages/man1/gnome-panel.1
patches/brasero-01-libtool.diff
patches/brasero-01-load-by-gksu.diff
patches/glib-14-gio-rbac.diff
patches/gnome-menus-08-rbac.diff
patches/gnome-panel-17-rbac.diff
patches/gnome-session-24-rbac.diff
patches/libwnck-01-trusted-extensions.diff
patches/sound-juicer-01-menu-entry.diff
patches/tsoljds-tstripe-03-pfexec.diff
specs/SUNWgnome-cd-burner.spec
specs/SUNWnwam-manager.spec
specs/SUNWtgnome-tstripe.spec
--- a/ChangeLog	Wed Mar 16 06:31:01 2011 +0000
+++ b/ChangeLog	Wed Mar 16 17:47:17 2011 +0000
@@ -1,3 +1,41 @@
+2011-03-16  Brian Cameron  <[email protected]>
+
+	* base-specs/gnome-panel.spec, patches/gnome-panel-17-rbac.diff:
+	  Add patch which causes the panel to filter applets and launchers
+	  based on RBAC profiles.
+	* base-specs/gnome-menus.spec, patches/gnome-menus-08-rbac.diff: Add
+	  patch which causes panel to filter menu items based on RBAC profiles.
+	* base-specs/glib2.spec, patches/glib-14-gio-rbac.diff: Add patch
+	  which causes programs to be run with pfexec or gksu as needed based
+	  on RBAC configuration, but only when not in Trusted mode.
+	* base-specs/gnome-session.spec, patches/gnome-session-24-rbac.diff:
+	  Add patch which causes autostart programs to be run with pfexec or
+	  gksu as needed based on RBAC configuration, but only when not in
+	  Trusted mode.
+	* specs/SUNWtgnome-tstripe.spec,
+	  patches/tsoljds-tstripe-03-pfexec.diff: Add patch which causes all
+	  programs run by the xagent proxy to be run with pfexec.  The glib
+	  and gnome-session patches only work in non-Trusted mode because 
+	  this code ensures that programs are run with pfexec as needed when
+	  in Trusted mode.
+	* specs/SUNWgnome-cd-burner.spec, patches/brasero-01-libtool.diff: Fix
+	  brasero so the desktop file no longer hardcodes gksu.
+	* patches/brasero-01-load-by-gksu.diff: Remove old patch.
+	* specs/SUNWnwam-manager.spec, ext-sources/SUNWnwam-manager-exec_attr:
+	  Add exec_attr entries for nwam-manager-properties and the Network
+	  applet.
+	* patches/sound-juicer-01-menu-entry.diff: No longer hardcode gksu in
+	  the desktop file.
+	* patches/libwnck-01-trusted-extensions.diff: Update patch so that
+	  it supports the new "role_changed" and "label_changed" signals.
+	  These signals are used by the other patches to identify when these
+	  change.
+	* ext-sources/SUNWgnome-system-tools-exec_attr: Add entry for
+	  /usr/bin/users-admin.
+	* manpages/man1/gnome-panel.1: Update gnome-panel manpage so that it
+	  explains how the panel filters menu items, launchers, and applets
+	  and also how it runs programs with pfexec or gksu automatically.
+
 2011-03-16  Laszlo (Laca) Peter  <[email protected]>
 
 	* scripts/copyright-extractor: update based on comments from Jeremy
--- a/base-specs/glib2.spec	Wed Mar 16 06:31:01 2011 +0000
+++ b/base-specs/glib2.spec	Wed Mar 16 17:47:17 2011 +0000
@@ -50,6 +50,8 @@
 Patch12:      glib-12-gio-fen-clear-flag.diff
 #owner:gheet date:2011-03-11 type:bug bugster:6956527
 Patch13:      glib-13-cleanup-libs.diff
+# date:2011-03-14 type:feature owner:yippi bugster:7013977
+Patch14:      glib-14-gio-rbac.diff
 URL:          http://www.gtk.org
 BuildRoot:    %{_tmppath}/%{name}-%{version}-build
 Docdir:	      %{_defaultdocdir}/doc
@@ -96,6 +98,7 @@
 %patch11 -p1
 %patch12 -p1
 %patch13 -p1
+%patch14 -p1
 
 %build
 %ifos linux
@@ -116,7 +119,7 @@
 automake -a -c -f
 autoconf
 export CFLAGS="%optflags"
-export LDFLAGS="%_ldflags "
+export LDFLAGS="%_ldflags -lsocket -lsecdb -lnsl"
 ./configure --prefix=%{_prefix} \
             --mandir=%{_mandir} \
             --datadir=%{_datadir} \
@@ -166,6 +169,9 @@
 %{_mandir}/man3/*
 
 %changelog
+* Mon Mar 14 2011 - [email protected]
+- Add patch glib-14-gio-rbac.diff so desktop entries that need to be run with
+  gksu or pfexec are run properly.  Fixes bugster #7013977.
 * Thu Feb 17 2011 - [email protected]
 - Fixed 7007407, add new patch.
 * Wed Nov 17 2010 - [email protected]
--- a/base-specs/gnome-menus.spec	Wed Mar 16 06:31:01 2011 +0000
+++ b/base-specs/gnome-menus.spec	Wed Mar 16 17:47:17 2011 +0000
@@ -1,6 +1,6 @@
 # spec file for package gnome-menus
 #
-# Copyright (c) 2008 Sun Microsystems, Inc.
+# Copyright (c) 2005-2011 Oracle and/or its affiliates. All rights reserved.
 # This file and all modifications and additions to the pristine
 # package are under the same license as the package itself.
 %define owner jouby 
@@ -35,6 +35,8 @@
 # date:2009-12-03 type:branding owner:jedy
 Patch6:                 gnome-menus-06-python2.6.diff
 Patch7:                 gnome-menus-07-warn.diff
+# date:2011-03-14 type:feature owner:yippi bugster:7013977
+Patch8:                 gnome-menus-08-rbac.diff
 URL:			http://www.gnome.org
 BuildRoot:		%{_tmppath}/%{name}-%{version}-build
 Docdir:			%{_defaultdocdir}/%{name}
@@ -86,6 +88,7 @@
 %patch5 -p1
 %patch6 -p1
 %patch7 -p1
+%patch8 -p1
 
 %build
 %ifos linux
@@ -112,6 +115,7 @@
 aclocal $ACLOCAL_FLAGS -I m4
 automake -a -c -f
 autoconf
+export LDFLAGS="%_ldflags -lsecdb -lsocket -lnsl -ltsol"
 ./configure --prefix=%{_prefix}			\
 	    --sysconfdir=%{_sysconfdir}		\
             --mandir=%{_mandir}
@@ -166,6 +170,10 @@
 %{_includedir}/gnome-menus/*
 
 %changelog
+* Mon Mar 14 2011 - [email protected]
+- Add patch gnome-menus-08-rbac.diff so menu entries are filtered out if the
+  user cannot run them according to RBAC.  If the user can run them via gksu
+  or pfexec, then they are shown.  Fixes bugster #7013977.
 * Wed Jan 19 2011 - [email protected]
 - Updated License tag.
 * Wed Oct 20 2010 - [email protected]
--- a/base-specs/gnome-panel.spec	Wed Mar 16 06:31:01 2011 +0000
+++ b/base-specs/gnome-panel.spec	Wed Mar 16 17:47:17 2011 +0000
@@ -78,6 +78,8 @@
 Patch15:        gnome-panel-15-use-vp-time.diff
 # date:2009-12-08 type:bug owner:jedy bugzilla:594045
 Patch16:        gnome-panel-16-clock.diff
+# date:2011-03-14 type:feature owner:yippi bugster:7013977
+Patch17:        gnome-panel-17-rbac.diff
 URL:          http://www.gnome.org
 BuildRoot:    %{_tmppath}/%{name}-%{version}-build
 Docdir:       %{_defaultdocdir}/gnome-panel
@@ -156,6 +158,7 @@
 %patch14 -p1
 %patch15 -p1
 %patch16 -p1
+%patch17 -p1
 
 cp %SOURCE3 icons
 cp %SOURCE6 icons
@@ -277,6 +280,9 @@
 %{_mandir}/man3/*
 
 %changelog
+* Mon Mar 14 2011 - [email protected]
+- Add patch gnome-panel-17-rbac.diff so applets are filtered out if the
+  user cannot run them according to RBAC.  Fixes bugster #7013977.
 * Tue Jan 12 2011 - [email protected]
 - gnome-panel-07-restrict-app-launching.diff: reworked. The lockdown mode will
   not apply to the Primary Administrator, System Administrator, 
--- a/base-specs/gnome-session.spec	Wed Mar 16 06:31:01 2011 +0000
+++ b/base-specs/gnome-session.spec	Wed Mar 16 17:47:17 2011 +0000
@@ -78,9 +78,10 @@
 Patch21:     gnome-session-21-helper-path.diff
 #owner:migi date:2010-12-14 type:feature
 Patch22:     gnome-session-22-gconf-lockdown.diff
-#owner:brianca date:2009-08-05 type:bug bugster:6986574
+#owner:yippi date:2009-08-05 type:bug bugster:6986574
 Patch23:     gnome-session-23-gdm-inhibit-dialog.diff
-
+# date:2011-03-14 type:feature owner:yippi bugster:7013977
+Patch24:     gnome-session-24-rbac.diff
 URL:          http://www.gnome.org
 BuildRoot:    %{_tmppath}/%{name}-%{version}-build
 Docdir:       %{_defaultdocdir}/%{name}
@@ -138,6 +139,7 @@
 %patch21 -p1
 %patch22 -p1
 %patch23 -p1
+%patch24 -p1
 
 %build
 %ifos linux
@@ -211,6 +213,9 @@
 %{_libdir}/compiz-by-default
 
 %changelog
+* Mon Mar 14 2011 - [email protected]
+- Add patch gnome-session-24-rbac.diff so desktop entries that need to be run
+  with gksu or pfexec are run properly.  Fixes bugster #7013977.
 * Mon Feb 21 2011 - [email protected]
 - Add patch gnome-session-23-gdm-inhibit-dialog.diff to fix CR 6986574.
 * Wed Jan 12 2011 - [email protected]
--- a/ext-sources/SUNWgnome-system-tools-exec_attr	Wed Mar 16 06:31:01 2011 +0000
+++ b/ext-sources/SUNWgnome-system-tools-exec_attr	Wed Mar 16 17:47:17 2011 +0000
@@ -26,4 +26,5 @@
 #
 # execution attributes for profiles. see exec_attr(4)
 #
+User Management:solairs:cmd:::/usr/bin/users-admin:
 User Management:solairs:cmd:::/usr/share/setup-tool-backends/scripts/users-conf:uid=0
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/ext-sources/SUNWnwam-manager-exec_attr	Wed Mar 16 17:47:17 2011 +0000
@@ -0,0 +1,30 @@
+#
+# CDDL HEADER START
+#
+# The contents of this file are subject to the terms of the
+# Common Development and Distribution License (the "License").
+# You may not use this file except in compliance with the License.
+#
+# You can obtain a copy of the license at src/sun_nws/OPENSOLARIS.LICENSE
+# or http://www.opensolaris.org/os/licensing.
+# See the License for the specific language governing permissions
+# and limitations under the License.
+#
+# When distributing Covered Code, include this CDDL HEADER in each
+# file and include the License file at src/sun_nws/OPENSOLARIS.LICENSE.
+# If applicable, add the following below this CDDL HEADER, with the
+# fields enclosed by brackets "[]" replaced with your own identifying
+# information: Portions Copyright [yyyy] [name of copyright owner]
+#
+# CDDL HEADER END
+#
+#
+# Copyright 2006 Sun Microsystems, Inc.  All rights reserved.
+# Use is subject to license terms.
+#
+#ident	"@(#)exec_attr	1.2	06/09/15 SMI"
+#
+# execution attributes for profiles. see exec_attr(4)
+#
+Network Autoconf Admin:solaris:cmd:::/usr/bin/nwam-manager-properties:
+Network Autoconf User:solaris:cmd:::/usr/lib/gnome-netstatus-applet:
--- a/manpages/man1/gnome-panel.1	Wed Mar 16 06:31:01 2011 +0000
+++ b/manpages/man1/gnome-panel.1	Wed Mar 16 17:47:17 2011 +0000
@@ -6,30 +6,152 @@
 %commonents;
 <!ENTITY % booktitles SYSTEM "booktitles.ent">
 %booktitles;
-<!ENTITY suncopy "Copyright (c) 2003,2006 Sun Microsystems, Inc. All Rights Reserved.">
+<!ENTITY suncopy "Copyright (c) 2003-2011 Sun Microsystems, Inc. All Rights Reserved.">
 ]>
-<?Pub UDT _bookmark _target>
-<?Pub Inc>
 <refentry id="gnome-panel-1">
 <!-- %Z%%M% %I% %E% SMI; -->
 <refmeta><refentrytitle>gnome-panel</refentrytitle><manvolnum>1</manvolnum>
-<refmiscinfo class="date">2 Oct 2003</refmiscinfo>
+<refmiscinfo class="date">10 Mar 2011</refmiscinfo>
 <refmiscinfo class="sectdesc">&man1;</refmiscinfo>
 <refmiscinfo class="software">&release;</refmiscinfo>
 <refmiscinfo class="arch">generic</refmiscinfo>
 <refmiscinfo class="copyright">&suncopy;</refmiscinfo>
 </refmeta>
-<indexterm><primary>gnome-panel</primary></indexterm><indexterm><primary>
-display the GNOME panel</primary></indexterm><refnamediv id="gnome-panel-1-name">
-<refname>gnome-panel</refname><refpurpose>display the GNOME panel</refpurpose></refnamediv>
-<refsynopsisdiv id="gnome-panel-1-synp"><title>&synp-tt;</title>
-<cmdsynopsis><command>&cmd;</command>
+<indexterm><primary>gnome-panel</primary></indexterm>
+<indexterm><primary>display the GNOME panel</primary></indexterm>
+
+<refnamediv id="gnome-panel-1-name">
+<refname>gnome-panel</refname>
+<refpurpose>display the GNOME panel</refpurpose>
+</refnamediv>
+
+<refsynopsisdiv id="gnome-panel-1-synp">
+<title>&synp-tt;</title>
+<cmdsynopsis>
+<command>&cmd;</command>
 <arg><option role="nodash"><replaceable>gnome-std-options</replaceable></option></arg>
 </cmdsynopsis></refsynopsisdiv>
+
 <refsect1 id="gnome-panel-1-desc"><title>&desc-tt;</title>
-<para>The GNOME panel displays an area on your screen, which acts as a repository
-for the main menu, application launchers, and applets.</para>
+<para>
+The GNOME Panel displays an area on your screen, which acts as a repository
+for the main menu, application launchers, and applets.  
+</para>
+
+<para>
+The main menu items are specified by desktop files that are located in the
+<filename>/usr/share/applications</filename> directory.  Applets are
+specified by bonobo server files located in the
+<filename>/usr/lib/bonobo/servers</filename> directory.
+
+<para>
+On Solaris, the GNOME Panel is integrated with RBAC to determine which menu
+items, launchers, and applets are presented to the user and how they are
+executed.  The GNOME Panel will only make available menu items, launchers and
+applets that the user can run based on RBAC configuration.
+</para>
+
+<para>
+RBAC can be configured so that programs are associated with Rights Profiles.
+When a program is associated with a Rights Profile, the GNOME Panel makes sure
+that the user has access to the profile and will filter out any programs the
+user cannot run.
+</para>
+
+<para>
+When using Trusted Extensions, different RBAC roles can be associated with each
+workspace via the Trusted Stripe.  So, the GNOME Panel automatically reloads
+the menu items, launchers and applets whenever the workspace switches or
+whenever the user changes to a different role in the Trusted Stripe.
+</para>
+
+<para>
+RBAC can be configured to allow users access to a Rights Profile.  If a program
+can be run with a Rights Profile associated with the user, then the program is
+made available to the user and is run by the GNOME Panel with
+<citerefentry><refentrytitle>pfexec</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+RBAC can be configured to allow users access to a role.  If not using Trusted
+Extensions and if a program can be run with a user or role the user can assume,
+then the program is made available to the user and is run by the GNOME Panel
+with
+<citerefentry><refentrytitle>gksu</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+Programs that are not explicitly assigned security attributes in Rights
+Profiles are not filtered by the GNOME panel.  If using Trusted Extensions or
+if the user's shell is a
+<citerefentry><refentrytitle>pfexec</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+enabled shell like
+<citerefentry><refentrytitle>pfsh</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+or
+<citerefentry><refentrytitle>pfbash</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+then the panel runs all programs not explicitly assigned security attributes in
+Rights Profiles with
+<citerefentry><refentrytitle>pfexec</refentrytitle><manvolnum>1</manvolnum></citerefentry>.
+Running with
+<citerefentry><refentrytitle>pfexec</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+ensures that the user's profile assignments apply to all
+child processes, as well.  Users can also be disallowed from running programs
+by configuring RBAC.  For example, by using the "Stop" profile.
+</para>
+
+<para>
+When processing GNOME Panel menu and launchers, it determines the executable by
+checking the associated application or launcher desktop file.  The GNOME Panel
+checks the executables associated with the Exec and TryExec keys of the desktop
+file to see if they are associated with a profile.  If both are associated with
+a profile, the GNOME Panel uses the profile associated with the Exec key.  When
+processing GNOME Panel applets, it determines the executable by checking the
+applet factory's bonobo server file and uses the value specified in the
+"location" element of the factory's bonobo server configuration file to see if
+it is associated with a profile.
+</para>
+
+<para>
+Some programs that can be shown in the GNOME Panel by default on Solaris are
+associated with profiles via RBAC.  These programs include:
+</para>
+
+<itemizedlist>
+<listitem>brasero uses the "Desktop Removable Media User" profile.</listitem>
+<listitem>sound-juicer uses the "Desktop Removable Media User" profile.</listitem>
+<listitem>users-admin uses the "User Management" profile.</listitem>
+<listitem>nwam-manager-properties uses the "Network Autoconf Admin" profile.</listitem>
+<listitem>The "Network Monitor" applet uses the "Network Autoconf User" profile.</listitem>
+</itemizedlist>
+
+<para>
+The "Desktop Administration" profile includes all of the above profiles, and
+can be used to make them all available to a user.  When not using Trusted
+Extensions, you can configure the GNOME Panel so that it requires a role
+password to be entered before running the program by setting up a role with a
+password and specify the user be associated with the role rather than by
+assigning the profile directly to the user.  RBAC can be configured to support
+these various configurations with the 
+<citerefentry><refentrytitle>profiles</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>roleadd</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+and
+<citerefentry><refentrytitle>usermod</refentrytitle><manvolnum>1</manvolnum></citerefentry>
+commands.
+</para>
+
+<para>
+When integrating a package that contains a program that requires privilege to
+run, then the package should associate the program with a profile in the
+<filename>/etc/security/exec_attr</filename> file.  A new profile can be added
+to the <filename>/etc/security/prof_attr</filename> file if desired.  Once this
+is done, access to the program can be controlled by specifying which users
+have access to this profile, or to a role with the profile.
+</para>
+
+<para>
+Note that the GNOME Panel monitors the <filename>/etc/user_attr</filename>,
+<filename>/etc/security/exec_attr</filename>, and
+<filename>/etc/security/prof_attr</filename> files.  If any of these files
+are modified, the GNOME Panel reloads the menu items, launchers, and applets.
+So any changes made to these RBAC configuration by the system administrator or
+via an RBAC GUI editor will take effect immediately.
+</para>
 </refsect1>
+
 <refsect1 id="gnome-panel-1-opts"><title>&opts-tt;</title>
 <para>The following options are supported:</para>
 <variablelist termlength="medium">
@@ -39,11 +161,19 @@
 5</manvolnum></citerefentry>.</para>
 </listitem></varlistentry>
 </variablelist></refsect1>
+
 <refsect1 id="gnome-panel-1-exam"><title>&exam-tt;</title>
-<example role="example"><title>Launching the GNOME Panel</title>
+<example role="example">
+<title>Launching the GNOME Panel</title>
 <para><screen>example% <userinput>&cmd;</userinput></screen></para>
 </example>
+<example role="example">
+<title>Associating a <replaceable>user</replaceable> with the "Desktop
+Administration" profile</title>
+<para><screen>example% <userinput>usermod -P "Desktop Administration" <replaceable>user</replaceable></userinput></screen></para>
+</example>
 </refsect1>
+
 <refsect1 id="gnome-panel-1-exit"><title>&exit-tt;</title>
 <para>The following exit values are returned:</para>
 <variablelist termlength="xtranarrow"><varlistentry><term><returnvalue>0</returnvalue></term>
@@ -53,41 +183,84 @@
 exited with failure</para>
 </listitem></varlistentry>
 </variablelist></refsect1>
+
 <refsect1 id="gnome-panel-1-file"><title>&file-tt;</title>
 <para>The following files are used by this application:</para>
-<variablelist termlength="medium"><varlistentry><term><filename>/usr/bin/&cmd;</filename> 
-</term><listitem><para>Executable for GNOME panel</para>
-</listitem></varlistentry>
-</variablelist></refsect1>
+
+<variablelist termlength="wide">
+<varlistentry>
+<term><filename>/usr/bin/&cmd;</filename></term>
+<listitem><para>
+Executable for GNOME panel
+</para></listitem></varlistentry>
+
+<varlistentry>
+<term><filename>/usr/lib/bonobo/servers</filename></term>
+<listitem><para>
+Location of Bonobo Servers files.
+</para></listitem></varlistentry>
+
+<varlistentry>
+<term><filename>/usr/share/applications</filename></term>
+<listitem><para>
+Location of GNOME Panel Desktop files.
+</para></listitem></varlistentry>
+</variablelist>
+</refsect1>
+
 <refsect1 id="gnome-panel-1-attr"><title>&attr-tt;</title>
-<para>See <olink targetdocent="REFMAN5" localinfo="attributes-5"><citerefentry>
-<refentrytitle>attributes</refentrytitle><manvolnum>5</manvolnum></citerefentry></olink>
-for descriptions of the following attributes:</para>
+<para>See
+<olink targetdocent="REFMAN5" localinfo="attributes-5">
+<citerefentry><refentrytitle>attributes</refentrytitle><manvolnum>5</manvolnum></citerefentry>
+</olink>
+for descriptions of the following attributes:
+</para>
 <informaltable frame="all">
-<tgroup cols="2" colsep="1" rowsep="1"><colspec colname="COLSPEC0" colwidth="1*">
+<tgroup cols="2" colsep="1" rowsep="1">
+<colspec colname="COLSPEC0" colwidth="1*">
 <colspec colname="COLSPEC1" colwidth="1*">
 <thead>
-<row><entry align="center" valign="middle">ATTRIBUTE TYPE</entry><entry align="center"
-valign="middle">ATTRIBUTE VALUE</entry></row>
+<row>
+<entry align="center" valign="middle">ATTRIBUTE TYPE</entry>
+<entry align="center" valign="middle">ATTRIBUTE VALUE</entry>
+</row>
 </thead>
 <tbody>
-<row><entry><para>Availability</para></entry><entry><para>gnome/gnome-panel
-</para></entry></row>
-<row><entry colname="COLSPEC0"><para>Interface stability</para></entry><entry
-colname="COLSPEC1"><para>Volatile</para></entry></row>
+<row>
+<entry><para>Availability</para></entry>
+<entry><para>gnome/gnome-panel</para></entry>
+</row>
+<row>
+<entry colname="COLSPEC0"><para>Interface stability</para></entry>
+<entry colname="COLSPEC1"><para>Volatile</para></entry>
+</row>
 </tbody>
 </tgroup>
 </informaltable>
 </refsect1>
+
 <refsect1 id="gnome-panel-1-also"><title>&also-tt;</title>
 <!--Reference to another man page-->
 <!--Reference to a Help manual-->
 <!--Reference to a book.-->
-<para><citetitle>Working with Panels Manual</citetitle></para>
-<para>Latest version of the <citetitle>GNOME Desktop User Guide</citetitle> for your platform.</para>
+<para>
+<citetitle>Working with Panels Manual</citetitle>
+</para>
+
 <para>
+Latest version of the <citetitle>GNOME Desktop User Guide</citetitle> for your
+platform.
+</para>
+
+<para>
+<citerefentry><refentrytitle>gksu</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>gnome-panel-screenshot</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>gnome-desktop-item-edit</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>pfexec</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>profiles</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>roleadd</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>usermod</refentrytitle><manvolnum>1</manvolnum></citerefentry>,
+<citerefentry><refentrytitle>libbonobo-2</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>libgnome-destkop-2</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>libpanel-applet-2</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
 <citerefentry><refentrytitle>libwnck-1</refentrytitle><manvolnum>3</manvolnum></citerefentry>,
@@ -95,7 +268,11 @@
 <citerefentry><refentrytitle>gnome-std-options</refentrytitle><manvolnum>5</manvolnum></citerefentry>
 </para>
 </refsect1>
+
 <refsect1 id="gnome-panel-1-note"><title>&note-tt;</title>
-<para>Written by Mark McLoughlin, Sun Microsystems Inc., 2003, 2006.</para>
+<para>
+Written by Mark McLoughlin, Sun Microsystems Inc., 2003, 2006.  Updated by
+Brian Cameron, Sun Microsystems Inc., 2011.
+</para>
 </refsect1>
 </refentry>
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/brasero-01-libtool.diff	Wed Mar 16 17:47:17 2011 +0000
@@ -0,0 +1,22 @@
+--- brasero-2.30.3/configure.in.ori	2010-09-28 11:29:24.261642100 +0100
++++ brasero-2.30.3/configure.in	2010-09-28 11:31:03.972116600 +0100
+@@ -2,6 +2,8 @@
+ AC_INIT([brasero],[2.30.3])
+ AC_CONFIG_SRCDIR(src/main.c)
+ 
++AC_PROG_LIBTOOL
++
+ BRASERO_MAJOR_VERSION=2
+ BRASERO_MINOR_VERSION=30
+ BRASERO_SUB=3
+--- brasero-2.30.3/src/Makefile.am-orig	2011-03-14 17:55:39.288360429 -0500
++++ brasero-2.30.3/src/Makefile.am	2011-03-14 17:56:02.707660708 -0500
+@@ -169,7 +169,7 @@ brasero_LDADD =						\
+ 	$(BRASERO_SEARCH_LIBS)		\
+ 	$(BRASERO_PL_PARSER_LIBS)	\
+ 	$(BRASERO_LIBUNIQUE_LIBS)	\
+-	$(BRASERO_SM_LIBS)
++	$(BRASERO_SM_LIBS) -lICE
+ 
+ EXTRA_DIST =			\
+ 	brasero-marshal.list
--- a/patches/brasero-01-load-by-gksu.diff	Wed Mar 16 06:31:01 2011 +0000
+++ /dev/null	Thu Jan 01 00:00:00 1970 +0000
@@ -1,37 +0,0 @@
-diff --git a/data/brasero.desktop.in.in b/data/brasero.desktop.in.in
-index 87368eb..b0e8041 100644
---- a/data/brasero.desktop.in.in
-+++ b/data/brasero.desktop.in.in
-@@ -4,7 +4,7 @@ _GenericName=Disc Burner
- _Comment=Create and copy CDs and DVDs
- Categories=GNOME;AudioVideo;DiscBurning;
- MimeType=application/x-cd-image;application/x-cdrdao-toc;application/x-cue;application/x-toc;audio/x-scpls;audio/x-ms-asx;audio/x-mp3-playlist;audio/x-mpegurl;application/x-brasero;
--Exec=brasero %U
-+Exec=gksu brasero
- Icon=brasero
- StartupNotify=true
- Terminal=false
-diff -ruN brasero-2.29.4.orig/nautilus/brasero-nautilus.desktop.in.in brasero-2.29.4/nautilus/brasero-nautilus.desktop.in.in
---- brasero-2.29.4.orig/nautilus/brasero-nautilus.desktop.in.in	2010-01-17 23:47:34.732281390 +0000
-+++ brasero-2.29.4/nautilus/brasero-nautilus.desktop.in.in	2010-01-17 23:48:10.159439032 +0000
-@@ -2,8 +2,7 @@
- _Name=CD/DVD Creator
- _Comment=Create CDs and DVDs
- Categories=GNOME;GTK;System;
--TryExec=nautilus
--Exec=nautilus --no-default-window --no-desktop burn:/// 
-+Exec=gksu brasero
- Icon=system-file-manager
- MimeType=x-content/blank-cd;x-content/blank-dvd;x-content/blank-bd;x-content/blank-hddvd;
- StartupNotify=true
---- brasero-2.30.3/configure.in.ori	2010-09-28 11:29:24.261642100 +0100
-+++ brasero-2.30.3/configure.in	2010-09-28 11:31:03.972116600 +0100
-@@ -2,6 +2,8 @@
- AC_INIT([brasero],[2.30.3])
- AC_CONFIG_SRCDIR(src/main.c)
- 
-+AC_PROG_LIBTOOL
-+
- BRASERO_MAJOR_VERSION=2
- BRASERO_MINOR_VERSION=30
- BRASERO_SUB=3
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/glib-14-gio-rbac.diff	Wed Mar 16 17:47:17 2011 +0000
@@ -0,0 +1,512 @@
+--- glib-2.25.1/gio/gdesktopappinfo.c-orig	2011-01-27 17:06:29.353677027 -0600
++++ glib-2.25.1/gio/gdesktopappinfo.c	2011-02-01 20:06:34.199424966 -0600
+@@ -27,6 +27,17 @@
+ #include <string.h>
+ #include <unistd.h>
+ #include <sys/wait.h>
++#include <user_attr.h>
++#include <exec_attr.h>
++#include <stdlib.h>
++#include <secdb.h>
++#include <dlfcn.h>
++#include <pwd.h>
++
++#include <tsol/label.h>
++#include <sys/tsol/label_macro.h>
++#include <X11/Xlib.h>
++#include <X11/extensions/Xtsol.h>
+ 
+ #ifdef HAVE_CRT_EXTERNS_H
+ #include <crt_externs.h>
+@@ -724,6 +735,449 @@ expand_macro (char              macro, 
+   *uri_list = uris;
+ }
+ 
++/*
++ * Note that the following code is in three patches:
++ * - gnome-panel-XX-rbac.diff (filter_with_rbac)
++ * - gnome-menus-XX-rbac.diff (filter_with_rbac)
++ * - glib-XX-gio-rbac.diff    (get_gksu_role)
++ * - gnome-session-XX-rbac.diff (get_gksu_role)
++ *
++ * So if there is a need to fix this code, it is probably necessary to fix the
++ * code in these other two places as well.  Though the functions are a bit
++ * different.
++ */
++static
++void * dlopen_tsol (void)
++{
++   void  *handle = NULL;
++
++   /*
++    * No 64-bit version of libwnck so we can get away with hardcoding
++    * to a single path on this occasion
++    */
++   if ((handle = dlopen ("/usr/lib/libtsol.so.2", RTLD_LAZY)) != NULL)
++       return handle;
++
++   return handle;
++}
++
++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;
++}
++
++static
++void * dlopen_gnometsol (void)
++{
++   void  *handle = NULL;
++
++   if ((handle = dlopen ("/usr/lib/libgnometsol.so", RTLD_LAZY)) != NULL)
++       return handle;
++
++   return handle;
++}
++
++/* Libtsol functions */
++
++typedef int     (*tsol_blequal) (const m_label_t *label1, const m_label_t *label2);
++typedef int     (*tsol_label_to_str) (const m_label_t *label, char **string,
++                 const m_label_str_t conversion_type,
++                 uint_t flags);
++typedef int            (*tsol_str_to_label) (const char *string, m_label_t **label,
++                 const m_label_type_t label_type, uint_t flags,
++                 int *error);
++typedef void (*tsol_m_label_dup) (m_label_t **dst, const m_label_t *src);
++typedef void   (*tsol_m_label_free) (m_label_t *label);
++
++/* Other misc. libtsol functions that seem to be stable */
++typedef blrange_t*             (*tsol_getuserrange) (const char *username);
++typedef int                            (*tsol_blinrange) (const m_label_t *label,
++                         const blrange_t *range);
++typedef void                   (*tsol_blminimum) (m_label_t *minimum_label,
++                         const m_label_t *bounding_label);
++typedef void                   (*tsol_blmaximum) (m_label_t *maximum_label,
++                         const m_label_t *bounding_label);
++typedef m_label_t*             (*tsol_blabel_alloc) (void);
++typedef void                   (*tsol_blabel_free)  (m_label_t *label_p);
++typedef void                   (*tsol_bsllow)  (m_label_t *label);
++typedef void                   (*tsol_bslhigh) (m_label_t *label);
++
++/* libXtsol functions */
++typedef Status (*xtsol_XTSOLgetClientLabel) (Display *dpy, XID xid,
++                 bslabel_t *sl);
++typedef Bool   (*xtsol_XTSOLIsWindowTrusted) (Display *dpy, Window win);
++
++/* libgnometsol functions */
++typedef gpointer       (*gnometsol_gnome_label_builder_new) (char *msg,
++                        blevel_t *upper, blevel_t *lower, int mode);
++typedef GType          (*gnometsol_gnome_label_builder_get_type) (void);
++
++/* libtsol functions */
++tsol_blequal           libtsol_blequal;
++tsol_label_to_str      libtsol_label_to_str;
++tsol_str_to_label      libtsol_str_to_label;
++tsol_m_label_dup libtsol_m_label_dup;
++tsol_m_label_free      libtsol_m_label_free;
++/* Other misc. libtsol functions */
++tsol_blminimum         libtsol_blminimum;
++tsol_blmaximum         libtsol_blmaximum;
++tsol_blinrange      libtsol_blinrange;
++tsol_getuserrange      libtsol_getuserrange;
++tsol_blabel_alloc      libtsol_blabel_alloc;
++tsol_blabel_free       libtsol_blabel_free;
++tsol_bsllow                    libtsol_bsllow;
++tsol_bslhigh           libtsol_bslhigh;
++
++xtsol_XTSOLgetClientLabel      libxtsol_XTSOLgetClientLabel;
++xtsol_XTSOLIsWindowTrusted     libxtsol_XTSOLIsWindowTrusted;
++
++gnometsol_gnome_label_builder_new libgnometsol_gnome_label_builder_new;
++gnometsol_gnome_label_builder_get_type libgnometsol_gnome_label_builder_get_type;
++
++gboolean
++use_trusted_extensions (void)
++{
++  static int trusted = -1;
++
++  /*
++   * Sun Trusted Extensions (tm) for Solaris (tm) support. (Damn I should be a lawyer).
++   *
++   * It is necessary to use dlopen because the label aware extensions to libwnck work
++   * only on systems with the trusted extensions installed and with the SUN_TSOL
++   * xserver extension present
++   */
++
++    if (trusted < 0) {
++        static gpointer tsol_handle = NULL;
++        static gpointer xtsol_handle = NULL;
++        static gpointer gnometsol_handle = NULL;
++
++        if (getenv ("TRUSTED_SESSION") == NULL) {
++          trusted = 0;
++          return 0;
++        }
++
++        tsol_handle = dlopen_tsol ();
++        if (tsol_handle != NULL)
++            xtsol_handle = dlopen_xtsol ();
++        if (tsol_handle && xtsol_handle) {
++
++           /* libtsol functions */
++           libtsol_blequal = (tsol_blequal) dlsym (tsol_handle, "blequal");
++           libtsol_label_to_str = (tsol_label_to_str) dlsym (tsol_handle, "label_to_str");
++           libtsol_str_to_label = (tsol_str_to_label) dlsym (tsol_handle, "str_to_label");
++           libtsol_m_label_dup = (tsol_m_label_dup) dlsym (tsol_handle, "m_label_dup");
++           libtsol_m_label_free = (tsol_m_label_free) dlsym (tsol_handle, "m_label_free");
++
++
++           /* Other misc. libtsol functions */
++           libtsol_blminimum = (tsol_blminimum) dlsym (tsol_handle, "blminimum");
++           libtsol_blmaximum = (tsol_blmaximum) dlsym (tsol_handle, "blmaximum");
++           libtsol_blinrange = (tsol_blinrange) dlsym (tsol_handle, "blinrange");
++           libtsol_getuserrange = (tsol_getuserrange) dlsym (tsol_handle, "getuserrange");
++           libtsol_blabel_alloc = (tsol_blabel_alloc) dlsym (tsol_handle, "blabel_alloc");
++           libtsol_blabel_free  = (tsol_blabel_free)  dlsym (tsol_handle, "blabel_free");
++           libtsol_bsllow  = (tsol_bsllow)  dlsym (tsol_handle, "bsllow");
++           libtsol_bslhigh = (tsol_bslhigh) dlsym (tsol_handle, "bslhigh");
++
++           /* libXtsol functions */
++           libxtsol_XTSOLgetClientLabel = (xtsol_XTSOLgetClientLabel) dlsym (xtsol_handle,
++                                     "XTSOLgetClientLabel");
++           libxtsol_XTSOLIsWindowTrusted = (xtsol_XTSOLIsWindowTrusted) dlsym (xtsol_handle,
++                                      "XTSOLIsWindowTrusted");
++
++           if (libtsol_label_to_str == NULL ||
++               libtsol_str_to_label == NULL ||
++               libtsol_m_label_dup == NULL ||
++               libtsol_m_label_free == NULL ||
++               libtsol_blminimum == NULL ||
++               libtsol_blmaximum == NULL ||
++               libtsol_blinrange == NULL ||
++               libtsol_getuserrange == NULL ||
++               libtsol_blabel_alloc == NULL ||
++               libtsol_blabel_free  == NULL ||
++               libtsol_bsllow  == NULL ||
++               libtsol_bslhigh == NULL ||
++               libxtsol_XTSOLgetClientLabel == NULL ||
++               libxtsol_XTSOLIsWindowTrusted == NULL) {
++               dlclose (tsol_handle);
++               dlclose (xtsol_handle);
++               tsol_handle = NULL;
++               xtsol_handle = NULL;
++            }
++        }
++
++        gnometsol_handle = dlopen_gnometsol ();
++        if (gnometsol_handle != NULL) {
++               libgnometsol_gnome_label_builder_new =
++                               (gnometsol_gnome_label_builder_new) dlsym (gnometsol_handle,
++                               "gnome_label_builder_new");
++              libgnometsol_gnome_label_builder_get_type =
++                               (gnometsol_gnome_label_builder_get_type) dlsym (gnometsol_handle,
++                               "gnome_label_builder_get_type");
++              if (libgnometsol_gnome_label_builder_new == NULL ||
++                  libgnometsol_gnome_label_builder_get_type == NULL)
++                  gnometsol_handle = NULL;
++
++        }
++        trusted = ((tsol_handle != NULL) && (xtsol_handle != NULL) && (gnometsol_handle != NULL)) ? 1 : 0;
++    }
++    return trusted ? TRUE : FALSE;
++}
++
++static gchar *
++get_stripped_exec (const gchar *full_exec)
++{
++        gchar *str1, *str2, *retval, *p;
++
++        str1 = g_strdup (full_exec);
++        p = strtok (str1, " ");
++
++        if (p != NULL)
++                str2 = g_strdup (p);
++        else
++                str2 = g_strdup (full_exec);
++
++        g_free (str1);
++
++	if (g_path_is_absolute (str2)) {
++		retval = g_strdup (str2);
++	} else {
++		retval = g_strdup (g_find_program_in_path ((const gchar *)str2));
++	}
++        g_free (str2);
++
++        return retval;
++}
++
++static
++char * get_validated_stripped_exec (const char *command)
++{
++	const char *username = NULL;
++	char       *stripped_cmd;
++	char       *path;
++
++	username = g_get_user_name ();
++
++	/* Do not use pfexec for root */
++	if (strcmp (username, "root") == 0) {
++		return NULL;
++	}
++
++	stripped_cmd = get_stripped_exec (command);
++	if (stripped_cmd == NULL) {
++		return NULL;
++	}
++
++	path = g_find_program_in_path (g_strstrip (stripped_cmd));
++	if (path == NULL)
++		return NULL;
++
++	return stripped_cmd;
++}
++
++static gboolean
++command_has_profile (const char *command)
++{
++	execattr_t *exec = NULL;
++	gboolean    rc = FALSE;
++
++	/* Check if the program is in any profile. */
++	exec = getexecprof (NULL, KV_COMMAND, command, GET_ALL);
++	if (exec == NULL) {
++		return rc;
++	}
++
++	while (exec != NULL) {
++		if (strcmp (exec->id, "*") != 0) {
++			rc = TRUE;
++			break;
++		}
++		exec = exec->next;
++	}
++
++	free_execattr (exec);
++
++	return rc;
++}
++
++static gboolean
++use_pfexec (char *command)
++{
++	execattr_t *exec = NULL;
++	const char *username = NULL;
++	char       *stripped_cmd;
++	gboolean    trusted;
++	gboolean    has_profile;
++	gboolean    rc;
++
++	rc = FALSE;
++
++	/* Never use pfexec in Trusted mode */
++	trusted = use_trusted_extensions ();
++	if (trusted) {
++		goto out;
++	}
++
++	stripped_cmd = get_validated_stripped_exec (command);
++	if (stripped_cmd == NULL) {
++		goto out;
++	}
++
++	has_profile = command_has_profile (stripped_cmd);
++
++	username = g_get_user_name ();
++
++	/* Check if the user can run the command. */
++	exec = getexecuser (username, KV_COMMAND, stripped_cmd, GET_ALL);
++
++	/*
++	 * If the program is not associated with any profile, then do not
++	 * use pfexec.
++	 */
++	if (exec == NULL)
++		goto out;
++
++	/*
++	 * If getexecuser does not return NULL and the program is not
++	 * associated with any profile, then pfexec is not needed.
++	 */
++	if (has_profile == FALSE) {
++		goto out;
++	}
++
++	/*
++	 * Does the user have a profile that can run the command?
++	 */
++	while (exec != NULL) {
++		if (strcmp (exec->id, "*") != 0) {
++			rc = TRUE;
++			break;
++		}
++		exec = exec->next;
++	}
++out:
++	if (exec != NULL)
++		free_execattr (exec);
++
++	if (stripped_cmd)
++		g_free (stripped_cmd);
++
++	return rc;
++}
++
++/*
++ * Checks RBAC and if the user can run the command with gksu, the role is
++ * passed back, otherwise NULL.
++ */
++gchar *
++get_gksu_role (char *command)
++{
++	execattr_t *exec;
++	userattr_t *user;
++	const char *username = NULL;
++	char       *rc = NULL;
++	char       *stripped_cmd;
++	char       *path;
++	int         i;
++	gboolean    has_profile;
++	gboolean    trusted;
++
++	/* Never use gksu in Trusted mode */
++	trusted = use_trusted_extensions ();
++	if (trusted) {
++		goto out;
++	}
++
++	stripped_cmd = get_validated_stripped_exec (command);
++	if (stripped_cmd == NULL) {
++		goto out;
++	}
++
++	/* If pfexec should be used, then do not use gksu. */
++	if (use_pfexec (command) == TRUE) {
++		goto out;
++	}
++
++	has_profile = command_has_profile (stripped_cmd);
++	username    = g_get_user_name ();
++
++	/* Check if the user can run the command. */
++	exec = getexecuser (username, KV_COMMAND, stripped_cmd, GET_ALL);
++
++	/*
++	 * If the program is not associated with any profile, then do not
++	 * use gksu.
++	 */
++	if (exec == NULL)
++		goto out;
++
++	/*
++	 * If getexecuser does not return NULL and the program is not
++	 * associated with any profile, then gksu is not needed.
++	 */
++	if (has_profile == FALSE) {
++		goto out;
++	}
++
++	/* If no gksu is available, then do not try to use it */
++        path = g_find_program_in_path ("/usr/bin/gksu");
++	if (path == NULL)
++		goto out;
++
++	/* Check if the user is in a role that can run the command. */
++	/* If so, use gksu with that role */
++	if ((user = getusernam (username)) != NULL) {
++		const char *rolelist = NULL;
++		char **v = NULL;
++		char *role = NULL;
++
++		/* Use roles associated with the user. */
++		rolelist = kva_match (user->attr, USERATTR_ROLES_KW);
++
++		if (rolelist != NULL)
++			v = g_strsplit (rolelist, ",", -1);
++
++		for (i=0; v != NULL && v[i] != NULL; i++) {
++			role = g_strdup (v[i]);
++			g_strstrip (role);
++
++			exec = getexecuser (role, KV_COMMAND, stripped_cmd, GET_ALL);
++			while (exec != NULL) {
++				if ((strcmp (role, "root") == 0) ||
++				    (strcmp (exec->id, "*") != 0)) {
++					rc = g_strdup (role);
++					break;
++				}
++				exec = exec->next;
++			}
++
++			g_free (role);
++			free_execattr (exec);
++
++			if (rc != NULL) {
++				break;
++			}
++		}
++		if (v != NULL)
++			g_strfreev (v);
++	}
++
++out:
++	if (stripped_cmd)
++		g_free (stripped_cmd);
++
++	return (rc);
++}
++
+ static gboolean
+ expand_application_parameters (GDesktopAppInfo   *info,
+ 			       GList            **uris,
+@@ -735,6 +1189,9 @@ expand_application_parameters (GDesktopA
+   const char *p = info->exec;
+   GString *expanded_exec;
+   gboolean res;
++  char *gksu_role, *final_cmd;
++  struct passwd *pw;
++  uid_t uid;
+ 
+   if (info->exec == NULL)
+     {
+@@ -766,8 +1223,30 @@ expand_application_parameters (GDesktopA
+       expand_macro ('f', expanded_exec, info, uris);
+     }
+ 
+-  res = g_shell_parse_argv (expanded_exec->str, argc, argv, error);
++  /* Only use a prefix if not in Trusted mode */
++  gksu_role = NULL;
++  if (!use_trusted_extensions ())
++    gksu_role = get_gksu_role (expanded_exec->str);
++
++  uid = getuid ();
++  pw = getpwuid (uid);
++
++  if (gksu_role)
++    final_cmd = g_strdup_printf ("/usr/bin/gksu -u %s %s", gksu_role, expanded_exec->str);
++  else if (use_pfexec (expanded_exec->str) == TRUE ||
++           (pw != NULL && pw->pw_shell != NULL &&
++            strncmp (pw->pw_shell, "/usr/bin/pf", strlen ("/usr/bin/pf")) == 0))
++    final_cmd = g_strdup_printf ("/usr/bin/pfexec %s", expanded_exec->str);
++  else
++    final_cmd = g_strdup_printf ("%s", expanded_exec->str);
++
++  res = g_shell_parse_argv (final_cmd, argc, argv, error);
+   g_string_free (expanded_exec, TRUE);
++
++  if (gksu_role != NULL)
++    g_free (gksu_role);
++  g_free (final_cmd);
++
+   return res;
+ }
+ 
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-menus-08-rbac.diff	Wed Mar 16 17:47:17 2011 +0000
@@ -0,0 +1,1070 @@
+--- gnome-menus-2.30.4/libmenu/Makefile.am-orig	2011-02-01 20:32:20.338888769 -0600
++++ gnome-menus-2.30.4/libmenu/Makefile.am	2011-02-01 20:32:53.397121492 -0600
+@@ -19,7 +19,8 @@ libgnome_menu_sources =			\
+ 	gmenu-tree.c			\
+ 	menu-layout.c			\
+ 	menu-monitor.c			\
+-	menu-util.c
++	menu-util.c			\
++	menu-solaris.c
+ 
+ libgnome_menu_la_SOURCES =		\
+ 	$(libgnome_menu_sources)	\
+@@ -29,7 +30,8 @@ libgnome_menu_la_SOURCES =		\
+ 	gmenu-tree.h			\
+ 	menu-layout.h			\
+ 	menu-monitor.h			\
+-	menu-util.h
++	menu-util.h			\
++	menu-solaris.h
+ 
+ libgnome_menu_la_LIBADD = 		\
+ 	$(GLIB_LIBS)
+--- gnome-menus-2.30.4/libmenu/desktop-entries.c-orig	2011-01-31 14:33:59.083221487 -0600
++++ gnome-menus-2.30.4/libmenu/desktop-entries.c	2011-02-01 17:57:31.679887328 -0600
+@@ -24,6 +24,7 @@
+ #include <string.h>
+ 
+ #include "menu-util.h"
++#include "menu-solaris.h"
+ 
+ #define DESKTOP_ENTRY_GROUP     "Desktop Entry"
+ #define KDE_DESKTOP_ENTRY_GROUP "KDE Desktop Entry"
+@@ -80,6 +81,7 @@ get_flags_from_key_file (DesktopEntry *e
+   char      *tryexec;
+   guint      flags;
+   int        i;
++  gboolean   use_global = FALSE;
+ 
+   error = NULL;
+   no_display = g_key_file_get_boolean (key_file,
+@@ -142,21 +144,41 @@ get_flags_from_key_file (DesktopEntry *e
+     }
+   g_strfreev (strv);
+ 
++  if (strncmp (entry->path,
++               "/usr/share/gnome/trusted/applications",
++               strlen ("/usr/share/gnome/trusted/applications")) == 0)
++    {
++      use_global = TRUE;
++    }
++
+   tryexec_failed = FALSE;
+   tryexec = g_key_file_get_string (key_file,
+                                    desktop_entry_group,
+                                    "TryExec",
+                                    NULL);
++
++  /*
++   * Call filter_with_rbac to check TryExec and also see if the
++   * menu item should be filtered out for RBAC purposes.
++   */
+   if (tryexec)
+     {
+-      char *path;
+-
+-      path = g_find_program_in_path (g_strstrip (tryexec));
++      tryexec_failed = filter_with_rbac (tryexec, use_global);
++      g_free (tryexec);
++    }
+ 
+-      tryexec_failed = (path == NULL);
++  if (tryexec_failed == FALSE)
++    {
++      tryexec = g_key_file_get_string (key_file,
++                                       desktop_entry_group,
++                                       "Exec",
++                                       NULL);
+ 
+-      g_free (path);
+-      g_free (tryexec);
++      if (tryexec)
++        {
++          tryexec_failed = filter_with_rbac (tryexec, use_global);
++          g_free (tryexec);
++        }
+     }
+ 
+   flags = 0;
+--- gnome-menus-2.30.4/libmenu/entry-directories.c-orig	2011-01-31 21:26:01.492500629 -0600
++++ gnome-menus-2.30.4/libmenu/entry-directories.c	2011-01-31 21:55:41.687967111 -0600
+@@ -292,6 +292,9 @@ cached_dir_remove_entry (CachedDir  *dir
+ {
+   GSList *tmp;
+ 
++  if (dir_cache == NULL)
++    return;
++
+   tmp = dir->entries;
+   while (tmp != NULL)
+     {
+@@ -345,6 +348,9 @@ cached_dir_remove_subdir (CachedDir  *di
+ {
+   CachedDir *subdir;
+ 
++  if (dir_cache == NULL)
++    return;
++
+   subdir = find_subdir (dir, basename);
+ 
+   if (subdir != NULL)
+@@ -585,6 +591,9 @@ cached_dir_remove_monitor (CachedDir    
+ {
+   GSList *tmp;
+ 
++  if (dir_cache == NULL)
++    return;
++
+   tmp = dir->monitors;
+   while (tmp != NULL)
+     {
+@@ -619,6 +628,9 @@ cached_dir_remove_reference (CachedDir *
+ {
+   CachedDir *parent;
+ 
++  if (dir_cache == NULL)
++    return;
++
+   parent = dir->parent;
+ 
+   if (--dir->references == 0 && dir->deleted)
+@@ -1221,3 +1233,14 @@ entry_directory_list_remove_monitors (En
+       tmp = tmp->next;
+     }
+ }
++
++void
++_reset_dir_cache (void)
++{
++  if (dir_cache != NULL)
++    {
++      cached_dir_free (dir_cache);
++      dir_cache = NULL;
++    }
++}
++
+--- gnome-menus-2.30.4/libmenu/gmenu-tree.c-orig	2011-01-31 15:51:01.017894153 -0600
++++ gnome-menus-2.30.4/libmenu/gmenu-tree.c	2011-02-01 18:20:16.637612233 -0600
+@@ -19,6 +19,12 @@
+ 
+ #include <config.h>
+ 
++#include <sys/stat.h>
++
++#include <glib.h>
++#include <glib/gstdio.h>
++#include <gio/gio.h>
++
+ #include "gmenu-tree.h"
+ 
+ #include <string.h>
+@@ -29,6 +35,8 @@
+ #include "menu-util.h"
+ #include "canonicalize.h"
+ 
++#include "menu-solaris.h"
++
+ /*
+  * FIXME: it might be useful to be able to construct a menu
+  * tree from a traditional directory based menu hierarchy
+@@ -63,6 +71,18 @@ struct GMenuTree
+   gpointer       user_data;
+   GDestroyNotify dnotify;
+ 
++  gpointer wnckscreen;
++  guint workspace_handler;
++  guint roles_handler;
++  guint labels_handler;
++
++  GFileMonitor *rbac_monitor1;
++  GFileMonitor *rbac_monitor2;
++  GFileMonitor *rbac_monitor3;
++  guint rbac_handler1;
++  guint rbac_handler2;
++  guint rbac_handler3;
++
+   guint canonical : 1;
+ };
+ 
+@@ -229,6 +249,11 @@ gmenu_tree_remove_from_cache (GMenuTree 
+ 
+   menu_verbose ("Removing menu tree from cache: %s\n", cache_key);
+ 
++  if (gmenu_tree_cache == NULL)
++    {
++      g_free (cache_key);
++      return;
++    }
+   g_hash_table_remove (gmenu_tree_cache, cache_key);
+ 
+   g_free (cache_key);
+@@ -630,6 +655,74 @@ gmenu_tree_lookup (const char     *menu_
+   return retval;
+ }
+ 
++/*
++ * This function completely clears the cache which forces the panel to reload
++ * via the monitors it invokes.  We want to reload the entire menu when RBAC
++ * configuration files change or when the users RBAC profile changes (e.g.
++ * on workspace switch in Trusted mode).
++ */
++static void
++rebuild_menu (GMenuTree *tree)
++{
++  if (tree != NULL)
++    {
++      if (gmenu_tree_cache != NULL) 
++        {
++          g_hash_table_destroy (gmenu_tree_cache);
++          gmenu_tree_cache = NULL;
++        }
++
++      _entry_directory_list_empty_desktop_cache ();
++      gmenu_tree_force_reload (tree);
++      _reset_dir_cache ();
++      gmenu_tree_invoke_monitors (tree);
++    }
++}
++
++/*
++ * On workspace switch, reload the entire menu when in Trusted mode.
++ */
++static void
++workspace_changed_callback (gpointer screen, gpointer prev_workspace, gpointer data)
++{
++  GMenuTree *tree;
++
++  tree = (GMenuTree *)data;
++  if (tree != NULL)
++    {
++      rebuild_menu (tree);
++    }
++}
++
++static void
++role_or_label_changed_callback (gpointer workspace, gpointer data)
++{
++  GMenuTree *tree;
++
++  tree = (GMenuTree *)data;
++  if (tree != NULL)
++    {
++      rebuild_menu (tree);
++    }
++}
++
++static gboolean
++rbac_callback (GFileMonitor      *monitor,
++               GFile             *child,
++               GFile             *other_file,
++               GFileMonitorEvent eflags,
++               gpointer          data)
++{
++  GMenuTree *tree;
++
++  tree = (GMenuTree *)data;
++  if (tree != NULL) 
++    {
++      rebuild_menu (tree);
++    }
++}
++
++
+ static GMenuTree *
+ gmenu_tree_new (GMenuTreeType   type,
+ 		const char     *menu_file,
+@@ -637,12 +730,25 @@ gmenu_tree_new (GMenuTreeType   type,
+ 		GMenuTreeFlags  flags)
+ {
+   GMenuTree *tree;
++  GFile *rbac_file;
++  gboolean trusted;
+ 
+   tree = g_new0 (GMenuTree, 1);
+ 
+   tree->type     = type;
+   tree->flags    = flags;
+   tree->refcount = 1;
++  tree->root              = NULL;
++  tree->wnckscreen        = NULL;
++  tree->workspace_handler = 0;
++  tree->roles_handler     = 0;
++  tree->labels_handler    = 0;
++  tree->rbac_monitor1     = NULL;
++  tree->rbac_monitor2     = NULL;
++  tree->rbac_monitor3     = NULL;
++  tree->rbac_handler1     = 0;
++  tree->rbac_handler2     = 0;
++  tree->rbac_handler3     = 0;
+ 
+   tree->sort_key = GMENU_TREE_SORT_NAME;
+ 
+@@ -671,6 +777,70 @@ gmenu_tree_new (GMenuTreeType   type,
+ 	}
+     }
+ 
++  /*
++   * Gince the panel is already monitoring all desktop files, add
++   * monitors for RBAC configuration files.  If these change, we want
++   * to reload the panel.  We check for these files and clear the
++   * cache in handle_entries_changed ().
++   */
++  rbac_file = g_file_new_for_path ("/etc/user_attr");
++  if (rbac_file != NULL) 
++    {
++      tree->rbac_monitor1 = g_file_monitor_file (rbac_file,
++                            G_FILE_MONITOR_NONE, NULL, NULL);
++      if (tree->rbac_monitor1)
++        {
++          tree->rbac_handler1 = g_signal_connect (tree->rbac_monitor1,
++                                "changed",
++                                G_CALLBACK (rbac_callback), tree);
++        }
++      g_object_unref (G_OBJECT (rbac_file));
++    }
++  rbac_file = g_file_new_for_path ("/etc/security/exec_attr");
++  if (rbac_file != NULL) 
++    {
++      tree->rbac_monitor2 = g_file_monitor_file (rbac_file,
++                            G_FILE_MONITOR_NONE, NULL, NULL);
++      if (tree->rbac_monitor2)
++        {
++          tree->rbac_handler2 = g_signal_connect (tree->rbac_monitor2,
++                                "changed",
++                                G_CALLBACK (rbac_callback), tree);
++        }
++      g_object_unref (G_OBJECT (rbac_file));
++    }
++  rbac_file = g_file_new_for_path ("/etc/security/prof_attr");
++  if (rbac_file != NULL) 
++    {
++      tree->rbac_monitor3 = g_file_monitor_file (rbac_file,
++                            G_FILE_MONITOR_NONE, NULL, NULL);
++      if (tree->rbac_monitor3)
++        {
++          tree->rbac_handler3 = g_signal_connect (tree->rbac_monitor3,
++                                "changed",
++                                G_CALLBACK (rbac_callback), tree);
++        }
++      g_object_unref (G_OBJECT (rbac_file));
++    }
++
++  /*
++   * Set up a signal handler to cause the menu to reload on workspace
++   * switch or when the label or role changes, but only do this in Trusted mode.
++   * In Trusted, workspaces are associated with RBAC roles, so a workspace
++   * switch should trigger a menu reload in this situation.
++   */
++  trusted = use_trusted_extensions ();
++  if (trusted == TRUE)
++    {
++      tree->wnckscreen = libmenu_wnck_screen_get_default ();
++      if (tree->wnckscreen)
++        {
++          tree->workspace_handler = g_signal_connect (tree->wnckscreen, "active-workspace-changed", G_CALLBACK(workspace_changed_callback), tree);
++          tree->labels_handler = g_signal_connect (tree->wnckscreen, "labels_changed", G_CALLBACK(role_or_label_changed_callback), tree);
++          tree->roles_handler = g_signal_connect (tree->wnckscreen, "roles_changed", G_CALLBACK(role_or_label_changed_callback), tree);
++        }
++    }
++
+   gmenu_tree_add_to_cache (tree, tree->flags);
+ 
+   return tree;
+@@ -696,6 +866,46 @@ gmenu_tree_unref (GMenuTree *tree)
+   if (--tree->refcount > 0)
+     return;
+ 
++  if (tree->wnckscreen != NULL)
++    {
++      if (tree->workspace_handler != 0)
++        g_signal_handler_disconnect (tree->wnckscreen, tree->workspace_handler);
++      if (tree->roles_handler != 0)
++        g_signal_handler_disconnect (tree->wnckscreen, tree->roles_handler);
++      if (tree->labels_handler != 0)
++        g_signal_handler_disconnect (tree->wnckscreen, tree->labels_handler);
++    }
++
++  if (tree->rbac_monitor1 != NULL)
++    {
++      if (tree->rbac_handler1 != 0)
++        g_signal_handler_disconnect (tree->rbac_monitor1, tree->rbac_handler1);
++      g_object_unref (tree->rbac_monitor1);
++    }
++  if (tree->rbac_monitor2 != NULL)
++    {
++      if (tree->rbac_handler2 != 0)
++        g_signal_handler_disconnect (tree->rbac_monitor2, tree->rbac_handler2);
++      g_object_unref (tree->rbac_monitor2);
++    }
++  if (tree->rbac_monitor3 != NULL)
++    {
++      if (tree->rbac_handler3 != 0)
++        g_signal_handler_disconnect (tree->rbac_monitor3, tree->rbac_handler3);
++      g_object_unref (tree->rbac_monitor3);
++    }
++
++  tree->wnckscreen        = NULL;
++  tree->workspace_handler = 0;
++  tree->roles_handler     = 0;
++  tree->labels_handler    = 0;
++  tree->rbac_monitor1     = NULL;
++  tree->rbac_monitor2     = NULL;
++  tree->rbac_monitor3     = NULL;
++  tree->rbac_handler1     = 0;
++  tree->rbac_handler2     = 0;
++  tree->rbac_handler3     = 0;
++
+   if (tree->dnotify)
+     tree->dnotify (tree->user_data);
+   tree->user_data = NULL;
+@@ -850,6 +1060,7 @@ gmenu_tree_get_directory_from_path (GMen
+ {
+   GMenuTreeDirectory *root;
+   GMenuTreeDirectory *directory;
++  gboolean trusted;
+ 
+   g_return_val_if_fail (tree != NULL, NULL);
+   g_return_val_if_fail (path != NULL, NULL);
+@@ -857,6 +1068,40 @@ gmenu_tree_get_directory_from_path (GMen
+   if (path[0] != G_DIR_SEPARATOR)
+     return NULL;
+ 
++  trusted = use_trusted_extensions ();
++
++  /*
++   * If the zone /usr/share/application directory is not available, just return
++   * NULL.  This will show an empty menu, but the menu will populate when the
++   * directory becomes available since this function is called each time the
++   * panel menu is opened.
++   */
++  if (trusted == TRUE)
++    {
++      char *trusted_system_data_dir = NULL;
++      char *zoneroot = NULL;
++      struct stat statbuf;
++      int r;
++
++      zoneroot = get_zoneroot ();
++      if (zoneroot != NULL)
++        {
++          trusted_system_data_dir = g_strdup_printf ("%s/usr/share",
++                                                   zoneroot);
++          r = g_stat (trusted_system_data_dir, &statbuf);
++          g_free (trusted_system_data_dir);
++
++          if (r < 0 || ! S_ISDIR (statbuf.st_mode))
++            {
++              return NULL;
++            }
++        }
++      else
++        {
++          return NULL;
++        }
++    }
++
+   if (!(root = gmenu_tree_get_root_directory (tree)))
+     return NULL;
+ 
+@@ -2081,7 +2326,48 @@ resolve_default_app_dirs (GMenuTree     
+   MenuLayoutNode     *before;
+   const char * const *system_data_dirs;
+   int                 i;
++  gboolean trusted;
++  gboolean using_trusted = FALSE;
++
++  trusted = use_trusted_extensions ();
+ 
++  /*
++   * Load the applications from the zone specific /usr/share/applications
++   * directory.  The zone is determined from the label associated with the
++   * workspace.
++   */ 
++  if (trusted == TRUE)
++    {
++      char *trusted_system_data_dir = NULL;
++      char *zoneroot = NULL;
++
++      zoneroot = get_zoneroot ();
++
++      if (zoneroot != NULL)
++        {
++          using_trusted = TRUE;
++          trusted_system_data_dir = g_strdup_printf ("%s/usr/share",
++                                                  zoneroot);
++
++          before = add_app_dir (tree,
++			        menu_layout_node_ref (layout),
++			        trusted_system_data_dir);
++
++          g_free (trusted_system_data_dir);
++
++          /*
++           * Add /usr/share/gnome/trusted/applications since desktop files
++           * associated with /usr/share/gnome/TrustedPathExecutables need to
++           * be loaded.
++           */
++          before = add_app_dir (tree,
++			        menu_layout_node_ref (layout),
++			        "/usr/share/gnome/trusted");
++        }
++    }
++
++  if (using_trusted == FALSE)
++    {
+   system_data_dirs = g_get_system_data_dirs ();
+ 
+   before = add_app_dir (tree,
+@@ -2095,6 +2381,7 @@ resolve_default_app_dirs (GMenuTree     
+ 
+       ++i;
+     }
++    }
+ 
+   menu_layout_node_unref (before);
+ 
+@@ -4492,7 +4779,16 @@ static void
+ handle_entries_changed (MenuLayoutNode *layout,
+                         GMenuTree       *tree)
+ {
+-  if (tree->layout == layout)
++  /* If an RBAC configuration file changes, then reload the whole menu */
++  if (tree->basename != NULL &&
++     (strcmp (tree->basename, "user_attr") == 0 ||
++      strcmp (tree->basename, "exec_attr") == 0 ||
++      strcmp (tree->basename, "prof_attr") == 0 ||
++      strcmp (tree->basename, "auth_attr") == 0))
++    {
++      rebuild_menu (tree);
++    }   
++  else if (tree->layout == layout)
+     {
+       gmenu_tree_force_rebuild (tree);
+       gmenu_tree_invoke_monitors (tree);
+--- /dev/null	2011-02-17 17:51:25.000000000 -0600
++++ gnome-menus-2.30.4/libmenu/menu-solaris.h	2011-02-17 17:50:08.763540499 -0600
+@@ -0,0 +1,90 @@
++
++#ifndef __MENU_SOLARIS_H__
++#define __MENU_SOLARIS_H__
++
++#include <tsol/label.h>
++#include <sys/tsol/label_macro.h>
++#include <X11/Xlib.h>
++#include <X11/extensions/Xtsol.h>
++
++#include <glib.h>
++#include <glib-object.h>
++
++G_BEGIN_DECLS
++
++gboolean use_trusted_extensions (void);
++gboolean filter_with_rbac (gchar *, gboolean);
++char * get_zoneroot (void);
++
++/* Libtsol functions */
++
++typedef int     (*tsol_blequal) (const m_label_t *label1, const m_label_t *label2);
++typedef int     (*tsol_label_to_str) (const m_label_t *label, char **string,
++                 const m_label_str_t conversion_type,
++                 uint_t flags);
++typedef int            (*tsol_str_to_label) (const char *string, m_label_t **label,
++                 const m_label_type_t label_type, uint_t flags,
++                 int *error);
++typedef void (*tsol_m_label_dup) (m_label_t **dst, const m_label_t *src);
++typedef void   (*tsol_m_label_free) (m_label_t *label);
++
++/* Other misc. libtsol functions that seem to be stable */
++typedef blrange_t*             (*tsol_getuserrange) (const char *username);
++typedef int                            (*tsol_blinrange) (const m_label_t *label,
++                         const blrange_t *range);
++typedef void                   (*tsol_blminimum) (m_label_t *minimum_label,
++                         const m_label_t *bounding_label);
++typedef void                   (*tsol_blmaximum) (m_label_t *maximum_label,
++                         const m_label_t *bounding_label);
++typedef m_label_t*             (*tsol_blabel_alloc) (void);
++typedef void                   (*tsol_blabel_free)  (m_label_t *label_p);
++typedef void                   (*tsol_bsllow)  (m_label_t *label);
++typedef void                   (*tsol_bslhigh) (m_label_t *label);
++
++/* libXtsol functions */
++typedef Status (*xtsol_XTSOLgetClientLabel) (Display *dpy, XID xid,
++                 bslabel_t *sl);
++typedef Bool   (*xtsol_XTSOLIsWindowTrusted) (Display *dpy, Window win);
++
++/* libgnometsol functions */
++typedef gpointer       (*gnometsol_gnome_label_builder_new) (char *msg,
++                        blevel_t *upper, blevel_t *lower, int mode);
++typedef GType          (*gnometsol_gnome_label_builder_get_type) (void);
++
++/* libwnck functions */
++typedef gpointer        (*menu_wnck_screen_get_default) (void);
++typedef gpointer        (*menu_wnck_screen_get_active_workspace) (gpointer);
++typedef const char*     (*menu_wnck_workspace_get_role) (gpointer);
++typedef const char*     (*menu_wnck_workspace_get_label) (gpointer);
++
++/* libtsol functions */
++tsol_blequal           libtsol_blequal;
++tsol_label_to_str      libtsol_label_to_str;
++tsol_str_to_label      libtsol_str_to_label;
++tsol_m_label_dup libtsol_m_label_dup;
++tsol_m_label_free      libtsol_m_label_free;
++/* Other misc. libtsol functions */
++tsol_blminimum         libtsol_blminimum;
++tsol_blmaximum         libtsol_blmaximum;
++tsol_blinrange      libtsol_blinrange;
++tsol_getuserrange      libtsol_getuserrange;
++tsol_blabel_alloc      libtsol_blabel_alloc;
++tsol_blabel_free       libtsol_blabel_free;
++tsol_bsllow                    libtsol_bsllow;
++tsol_bslhigh           libtsol_bslhigh;
++
++xtsol_XTSOLgetClientLabel      libxtsol_XTSOLgetClientLabel;
++xtsol_XTSOLIsWindowTrusted     libxtsol_XTSOLIsWindowTrusted;
++
++gnometsol_gnome_label_builder_new libgnometsol_gnome_label_builder_new;
++gnometsol_gnome_label_builder_get_type libgnometsol_gnome_label_builder_get_type;
++
++/* libwnck functions */
++menu_wnck_screen_get_default          libmenu_wnck_screen_get_default;
++menu_wnck_screen_get_active_workspace libmenu_wnck_screen_get_active_workspace;
++menu_wnck_workspace_get_role          libmenu_wnck_workspace_get_role;
++menu_wnck_workspace_get_label         libmenu_wnck_workspace_get_label;
++
++G_END_DECLS
++
++#endif /* __MENU_SOLARIS_H__ */
+--- /dev/null	2011-02-01 18:21:34.000000000 -0600
++++ gnome-menus-2.30.4/libmenu/menu-solaris.c	2011-02-01 18:28:12.721308906 -0600
+@@ -0,0 +1,431 @@
++/*
++ * Note that the following code is in three patches:
++ * - gnome-panel-XX-rbac.diff (filter_with_rbac)
++ * - gnome-menus-XX-rbac.diff (filter_with_rbac)
++ * - glib-XX-gio-rbac.diff    (get_gksu_role)
++ * - gnome-session-XX-rbac.diff (get_gksu_role)
++ *
++ * So if there is a need to fix this code, it is probably necessary to fix the
++ * code in these other two places as well.  Though the functions are a bit
++ * different.
++ */
++#include <config.h>
++
++#include <stdlib.h>
++#include <string.h>
++#include <dlfcn.h>
++#include <link.h>
++#include <user_attr.h>
++#include <exec_attr.h>
++#include <secdb.h>
++
++#include "menu-solaris.h"
++
++static
++void * dlopen_tsol (void)
++{
++   void  *handle = NULL;
++
++   /*
++    * No 64-bit version of libwnck so we can get away with hardcoding
++    * to a single path on this occasion
++    */
++   if ((handle = dlopen ("/usr/lib/libtsol.so.2", RTLD_LAZY)) != NULL)
++       return handle;
++
++   return handle;
++}
++
++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;
++}
++
++static
++void * dlopen_gnometsol (void)
++{
++   void  *handle = NULL;
++
++   if ((handle = dlopen ("/usr/lib/libgnometsol.so", RTLD_LAZY)) != NULL)
++       return handle;
++
++   return handle;
++}
++
++static
++void * dlopen_libwnck (void)
++{
++   void  *handle = NULL;
++
++   if ((handle = dlopen ("/usr/lib/libwnck-1.so", RTLD_LAZY)) != NULL)
++       return handle;
++
++   return handle;
++}
++
++gboolean
++use_trusted_extensions (void)
++{
++    static int trusted = -1;
++
++    /*
++     * Sun Trusted Extensions (tm) for Solaris (tm) support. (Damn I should be a lawyer).
++     *
++     * It is necessary to use dlopen because the label aware extensions to libwnck work
++     * only on systems with the trusted extensions installed and with the SUN_TSOL
++     * xserver extension present
++     */
++
++    if (trusted < 0) {
++        static gpointer tsol_handle = NULL;
++        static gpointer xtsol_handle = NULL;
++        static gpointer gnometsol_handle = NULL;
++        static gpointer libwnck_handle = NULL;
++
++        if (getenv ("TRUSTED_SESSION") == NULL) {
++            trusted = 0;
++            return 0;
++        }
++
++	libwnck_handle = dlopen_libwnck ();
++        if (libwnck_handle != NULL)
++            tsol_handle = dlopen_tsol ();
++        if (tsol_handle != NULL)
++            xtsol_handle = dlopen_xtsol ();
++        if (libwnck_handle && tsol_handle && xtsol_handle) {
++
++           libmenu_wnck_screen_get_default = (menu_wnck_screen_get_default) dlsym (libwnck_handle, "wnck_screen_get_default");
++           libmenu_wnck_screen_get_active_workspace = (menu_wnck_screen_get_active_workspace) dlsym (libwnck_handle, "wnck_screen_get_active_workspace");
++           libmenu_wnck_workspace_get_role = (menu_wnck_workspace_get_role) dlsym (libwnck_handle, "wnck_workspace_get_role");
++           libmenu_wnck_workspace_get_label = (menu_wnck_workspace_get_label) dlsym (libwnck_handle, "wnck_workspace_get_label");
++
++           /* libtsol functions */
++           libtsol_blequal = (tsol_blequal) dlsym (tsol_handle, "blequal");
++           libtsol_label_to_str = (tsol_label_to_str) dlsym (tsol_handle, "label_to_str");
++           libtsol_str_to_label = (tsol_str_to_label) dlsym (tsol_handle, "str_to_label");
++           libtsol_m_label_dup = (tsol_m_label_dup) dlsym (tsol_handle, "m_label_dup");
++           libtsol_m_label_free = (tsol_m_label_free) dlsym (tsol_handle, "m_label_free");
++
++           /* Other misc. libtsol functions */
++           libtsol_blminimum = (tsol_blminimum) dlsym (tsol_handle, "blminimum");
++           libtsol_blmaximum = (tsol_blmaximum) dlsym (tsol_handle, "blmaximum");
++           libtsol_blinrange = (tsol_blinrange) dlsym (tsol_handle, "blinrange");
++           libtsol_getuserrange = (tsol_getuserrange) dlsym (tsol_handle, "getuserrange");
++           libtsol_blabel_alloc = (tsol_blabel_alloc) dlsym (tsol_handle, "blabel_alloc");
++           libtsol_blabel_free  = (tsol_blabel_free)  dlsym (tsol_handle, "blabel_free");
++           libtsol_bsllow  = (tsol_bsllow)  dlsym (tsol_handle, "bsllow");
++           libtsol_bslhigh = (tsol_bslhigh) dlsym (tsol_handle, "bslhigh");
++
++           /* libXtsol functions */
++           libxtsol_XTSOLgetClientLabel = (xtsol_XTSOLgetClientLabel) dlsym (xtsol_handle,
++                                     "XTSOLgetClientLabel");
++           libxtsol_XTSOLIsWindowTrusted = (xtsol_XTSOLIsWindowTrusted) dlsym (xtsol_handle,
++                                      "XTSOLIsWindowTrusted");
++
++           if (libtsol_label_to_str == NULL ||
++               libtsol_str_to_label == NULL ||
++               libtsol_m_label_dup == NULL ||
++               libtsol_m_label_free == NULL ||
++               libtsol_blminimum == NULL ||
++               libtsol_blmaximum == NULL ||
++               libtsol_blinrange == NULL ||
++               libtsol_getuserrange == NULL ||
++               libtsol_blabel_alloc == NULL ||
++               libtsol_blabel_free  == NULL ||
++               libtsol_bsllow  == NULL ||
++               libtsol_bslhigh == NULL ||
++               libxtsol_XTSOLgetClientLabel == NULL ||
++               libxtsol_XTSOLIsWindowTrusted == NULL ||
++               libmenu_wnck_screen_get_default == NULL ||
++               libmenu_wnck_screen_get_active_workspace == NULL ||
++               libmenu_wnck_workspace_get_role == NULL ||
++               libmenu_wnck_workspace_get_label == NULL) {
++               dlclose (tsol_handle);
++               dlclose (xtsol_handle);
++               dlclose (libwnck_handle);
++               tsol_handle = NULL;
++               xtsol_handle = NULL;
++               libwnck_handle = NULL;
++            }
++        }
++
++        gnometsol_handle = dlopen_gnometsol ();
++        if (gnometsol_handle != NULL)
++            {
++               libgnometsol_gnome_label_builder_new =
++                               (gnometsol_gnome_label_builder_new) dlsym (gnometsol_handle,
++                               "gnome_label_builder_new");
++              libgnometsol_gnome_label_builder_get_type =
++                               (gnometsol_gnome_label_builder_get_type) dlsym (gnometsol_handle,
++                               "gnome_label_builder_get_type");
++              if (libgnometsol_gnome_label_builder_new == NULL ||
++                  libgnometsol_gnome_label_builder_get_type == NULL)
++                  gnometsol_handle = NULL;
++            }
++        trusted = ((tsol_handle != NULL) && (xtsol_handle != NULL) && (gnometsol_handle != NULL) && (libwnck_handle != NULL)) ? 1 : 0;
++    }
++    return trusted ? TRUE : FALSE;
++}
++
++static gchar *
++get_stripped_exec (const gchar *full_exec, gboolean use_global)
++{
++	gchar *str1, *str2, *retval, *p;
++	char *zoneroot = NULL;
++	gboolean trusted;
++
++	str1 = g_strdup (full_exec);
++	p = strtok (str1, " ");
++
++	if (p != NULL)
++		str2 = g_strdup (p);
++	else
++		str2 = g_strdup (full_exec);
++
++	g_free (str1);
++
++	trusted = use_trusted_extensions ();
++	if (trusted && use_global == FALSE) {
++		zoneroot = get_zoneroot ();
++	}
++
++	if (g_path_is_absolute (str2)) {
++		if (zoneroot != NULL) {
++			retval = g_strdup_printf ("%s/%s", zoneroot, str2);
++		} else {
++			retval = g_strdup (str2);
++		}
++	} else {
++		if (zoneroot != NULL) {
++			/*
++			 * If the desktop file doesn't specify the full path
++			 * and in Trusted mode, then check the zone's /usr/bin
++			 * directory.
++			 */
++			retval = g_strdup_printf ("%s/usr/bin/%s", zoneroot, str2);
++		} else {
++			retval = g_strdup (g_find_program_in_path ((const gchar *)str2));
++
++			/*
++			 * If a program is not installed in the global zone,
++			 * then assume it is installed in /usr/bin.
++			 */
++			if (use_global == TRUE && retval == NULL) {
++				retval = g_strdup_printf ("/usr/bin/%s", str2);
++			}
++		}
++	}
++	g_free (str2);
++
++	return retval;
++}
++
++/*
++ * Checks RBAC to see if the user can run the command.
++ */
++gboolean
++filter_with_rbac (gchar *command, gboolean use_global)
++{
++	execattr_t *exec;
++	gchar *stripped_cmd;
++	gchar *real_cmd;
++	char *path;
++	const char *username = NULL;
++	userattr_t *user;
++	int        i;
++	gboolean   program_has_profile;
++	gboolean   rc;
++	gboolean   trusted;
++
++	rc = TRUE;
++
++	stripped_cmd = get_stripped_exec (command, TRUE);
++	real_cmd     = get_stripped_exec (command, use_global);
++
++	trusted = use_trusted_extensions ();
++	if (trusted) {
++		/*
++		 * In trusted mode, use the single role associated with
++		 * the workspace.
++		 */
++		gpointer wnckscreen = NULL;
++		gpointer wnckworkspace = NULL;
++
++		wnckscreen = libmenu_wnck_screen_get_default ();
++		if (wnckscreen != NULL)
++			wnckworkspace = libmenu_wnck_screen_get_active_workspace (wnckscreen);
++
++		if (wnckworkspace != NULL)
++			username = libmenu_wnck_workspace_get_role (wnckworkspace);
++	}
++
++	if (username == NULL) {
++		username = g_get_user_name ();
++	}
++
++	/* If the command does not exist, do not show it. */
++	if (real_cmd == NULL || stripped_cmd == NULL) {
++		goto out;
++	}
++
++	path = g_find_program_in_path (g_strstrip (real_cmd));
++	if (path == NULL)
++		goto out;
++
++	/*
++	 * All programs should be available to root.  This check is done after
++	 * verifying the binary is in path.
++	 */
++	if (strcmp (username, "root") == 0) {
++		rc = FALSE;
++		goto out;
++	}
++
++	/* Check if the program is in any profile. */
++	program_has_profile = FALSE;
++	exec = getexecprof (NULL, KV_COMMAND, stripped_cmd, GET_ALL);
++	if (exec == NULL) {
++		goto out;
++	}
++
++	while (exec != NULL) {
++		if (strcmp (exec->id, "*") != 0) {
++			program_has_profile = TRUE;
++			break;
++		}
++		exec = exec->next;
++	}
++
++	free_execattr (exec);
++
++	/* Check if the user can run the command.  If not filter it. */
++	exec = getexecuser (username, KV_COMMAND, stripped_cmd, GET_ALL);
++
++	/*
++	 * If the program is not associated with any profile, then do not
++	 * show it.
++	 */
++	if (exec == NULL)
++		goto out;
++
++	/*
++	 * If getexecuser does not return NULL and the program is not
++	 * associated with any profile, then show it.  Otherwise, more
++	 * tests are needed.
++	 */
++	if (use_global == TRUE || program_has_profile == FALSE) {
++		rc = FALSE;
++		goto out;
++	}
++
++	/*
++	 * If the user has a profile that can run the command, then it can
++	 * be shown.
++	 */
++	while (exec != NULL) {
++		if (strcmp (exec->id, "*") != 0) {
++			rc = FALSE;
++			break;
++		}
++		exec = exec->next;
++	}
++
++	free_execattr (exec);
++
++	if (rc == FALSE)
++		goto out;
++
++	if (!trusted) {
++		/* If no gksu is available, then do not try to use it */
++	        path = g_find_program_in_path ("/usr/bin/gksu");
++		if (path == NULL)
++			goto out;
++	}
++
++	/* Check if the user is in a role that can run the command. */
++	/* If so, use gksu with that role */
++	if ((user = getusernam (username)) != NULL) {
++		const char *rolelist = NULL;
++		char **v = NULL;
++		char *role = NULL;
++
++		if (trusted && username != NULL) {
++			/* In trusted mode, use role associated with workspace */
++			rolelist = username;
++		} else {
++			/* Otherwise use roles associated with the user. */
++			rolelist = kva_match (user->attr, USERATTR_ROLES_KW);
++		}
++
++		if (rolelist != NULL)
++			v = g_strsplit (rolelist, ",", -1);
++
++		for (i=0; v != NULL && v[i] != NULL; i++) {
++			role = g_strdup (v[i]);
++			g_strstrip (role);
++
++			exec = getexecuser (role, KV_COMMAND, stripped_cmd, GET_ALL);
++			while (exec != NULL) {
++				if ((strcmp (role, "root") == 0) ||
++				    (strcmp (exec->id, "*") != 0)) {
++					rc = FALSE;
++					break;
++				}
++				exec = exec->next;
++			}
++
++			g_free (role);
++			free_execattr (exec);
++
++			if (rc == FALSE) {
++				break;
++			}
++		}
++		if (v != NULL)
++			g_strfreev (v);
++	}
++
++out:
++	if (stripped_cmd)
++		g_free (stripped_cmd);
++	if (real_cmd)
++		g_free (real_cmd);
++
++	return (rc);
++}
++
++/* Function to return the zone root directory for the current workspace. */
++char *
++get_zoneroot (void)
++{
++  gpointer    wnckscreen    = NULL;
++  gpointer    wnckworkspace = NULL;
++  const char *zonelabelstr  = NULL;
++  m_label_t  *zonelabel     = NULL;
++  char       *zoneroot      = NULL;
++  int         err;
++
++  wnckscreen = libmenu_wnck_screen_get_default ();
++  if (wnckscreen != NULL)
++    wnckworkspace = libmenu_wnck_screen_get_active_workspace (wnckscreen);
++
++  if (wnckworkspace != NULL)
++    zonelabelstr = libmenu_wnck_workspace_get_label (wnckworkspace);
++
++  if (zonelabelstr != NULL)
++    str_to_label (zonelabelstr, &zonelabel, MAC_LABEL, L_NO_CORRECTION, &err);
++
++  if (zonelabel != NULL)
++    zoneroot = getzonerootbylabel (zonelabel);
++
++  return zoneroot;
++}
++
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-panel-17-rbac.diff	Wed Mar 16 17:47:17 2011 +0000
@@ -0,0 +1,853 @@
+--- gnome-panel-2.30.2/gnome-panel/Makefile.am-orig	2011-02-14 14:11:24.393278016 -0600
++++ gnome-panel-2.30.2/gnome-panel/Makefile.am	2011-02-14 14:11:50.011889669 -0600
+@@ -96,6 +96,7 @@ panel_sources =			\
+ 	panel-force-quit.c	\
+ 	panel-lockdown.c	\
+ 	panel-addto.c		\
++	panel-solaris.c		\
+ 	panel-ditem-editor.c	\
+ 	$(NULL)
+ 
+@@ -144,6 +145,7 @@ panel_headers =			\
+ 	panel-addto.h		\
+ 	panel-ditem-editor.h	\
+ 	panel-icon-names.h	\
++	panel-solaris.h		\
+ 	$(NULL)
+ 
+ gnome_panel_SOURCES =			\
+@@ -167,6 +169,7 @@ gnome_desktop_item_edit_SOURCES = \
+ 	panel-util.c		  \
+ 	panel-lockdown.c	\
+ 	panel-gconf.c		\
++	panel-solaris.c		\
+ 	xstuff.c
+ 
+ gnome_desktop_item_edit_LDFLAGS = -export-dynamic
+--- gnome-panel-2.30.2/gnome-panel/menu.c-orig	2011-02-14 13:42:38.016236688 -0600
++++ gnome-panel-2.30.2/gnome-panel/menu.c	2011-02-14 13:46:50.882977628 -0600
+@@ -1283,13 +1283,19 @@ submenu_to_display (GtkWidget *menu,
+ 	void               (*append_callback) (GtkWidget *, gpointer);
+ 	gpointer             append_data;
+ 
+-	if (!g_object_get_data (G_OBJECT (menu), "panel-menu-needs-loading"))
++        /*
++         * Do not just return if directory has not been set.  This can happen
++         * in Trusted mode if the zone is not booted and the zone
++         * /usr/share/application directory is slow to load.
++         */
++	directory = g_object_get_data (G_OBJECT (menu),
++				       "panel-menu-tree-directory");
++
++	if (directory != NULL && !g_object_get_data (G_OBJECT (menu), "panel-menu-needs-loading"))
+ 		return;
+ 
+ 	g_object_set_data (G_OBJECT (menu), "panel-menu-needs-loading", NULL);
+ 
+-	directory = g_object_get_data (G_OBJECT (menu),
+-				       "panel-menu-tree-directory");
+ 	if (!directory) {
+ 		menu_path = g_object_get_data (G_OBJECT (menu),
+ 					       "panel-menu-tree-path");
+@@ -1303,6 +1309,14 @@ submenu_to_display (GtkWidget *menu,
+ 		directory = gmenu_tree_get_directory_from_path (tree,
+ 								menu_path);
+ 
++                /*
++                 * If there is no directory, just return.  This can happen in
++                 * Trusted mode if the zone is not booted and the zone
++                 * /usr/share/application directory is slow to load.
++                 */
++                if (directory == NULL)
++			return;
++
+ 		g_object_set_data_full (G_OBJECT (menu),
+ 					"panel-menu-tree-directory",
+ 					directory,
+@@ -1639,6 +1653,12 @@ handle_gmenu_tree_changed (GMenuTree *tr
+ 				"panel-menu-idle-id",
+ 				GUINT_TO_POINTER (idle_id),
+ 				remove_submenu_to_display_idle);
++
++	/*
++	 * Reload the applets in case RBAC has changed in a way that
++	 * requires the applets to be shown or hidden.
++	 */
++	panel_applet_reload_applets ();
+ }
+ 
+ static void
+--- gnome-panel-2.30.2/gnome-panel/panel-addto.c-orig	2011-02-14 13:42:22.460669011 -0600
++++ gnome-panel-2.30.2/gnome-panel/panel-addto.c	2011-02-14 13:43:36.151288697 -0600
+@@ -50,6 +50,7 @@
+ #include "panel-profile.h"
+ #include "panel-addto.h"
+ #include "panel-icon-names.h"
++#include "panel-solaris.h"
+ 
+ typedef struct {
+ 	PanelWidget *panel_widget;
+@@ -401,6 +402,7 @@ panel_addto_query_applets (GSList *list)
+ 	const char * const *langs;
+ 	GSList             *langs_gslist;
+ 	int                 i;
++	char               *location_info;
+ 
+ 	CORBA_exception_init (&env);
+ 
+@@ -444,6 +446,12 @@ panel_addto_query_applets (GSList *list)
+ 						       "panel:icon",
+ 						       NULL);
+ 
++		location_info = panel_lockdown_get_location (info->iid);
++
++		if (filter_with_rbac (location_info, FALSE)) {
++			continue;
++		}
++	
+ 		if (!name ||
+ 		    panel_lockdown_is_applet_disabled (info->iid)) {
+ 			continue;
+--- gnome-panel-2.30.2/gnome-panel/panel-lockdown.h-orig	2011-02-14 14:35:51.041361289 -0600
++++ gnome-panel-2.30.2/gnome-panel/panel-lockdown.h	2011-02-14 14:36:20.172302961 -0600
+@@ -101,6 +101,8 @@ gboolean panel_lockdown_is_user_authoriz
+ #define SYSTEM_ADMINISTRATOR_PROF "System Administrator"
+ #define ROOT_ROLE "root"
+ 
++char * panel_lockdown_get_location (const char *iid);
++
+ G_END_DECLS
+ 
+ #endif /* __PANEL_LOCKDOWN_H__ */
+--- gnome-panel-2.30.2/gnome-panel/panel-lockdown.c-orig	2011-02-14 13:47:15.639573690 -0600
++++ gnome-panel-2.30.2/gnome-panel/panel-lockdown.c	2011-02-14 13:58:40.663697949 -0600
+@@ -31,11 +31,16 @@
+ #include <libpanel-util/panel-keyfile.h>
+ #include <libgnome/gnome-desktop-tsol-extensions.h>
+ 
++#include <sys/types.h>
++#include <unistd.h>
+ #include <exec_attr.h>
+ #include <user_attr.h>
+ #include <secdb.h>
+ #include <pwd.h>
+ 
++#include <libbonoboui.h>
++#include "panel-solaris.h"
++
+ #define N_LISTENERS 8
+ 
+ #define PANEL_GLOBAL_LOCKDOWN_DIR    "/apps/panel/global"
+@@ -480,10 +485,52 @@ panel_lockdown_get_disable_force_quit (v
+         return panel_lockdown.disable_force_quit;
+ }
+ 
++char *
++panel_lockdown_get_location (const char *iid)
++{
++        Bonobo_ServerInfoList *list;
++        char                  *query;
++        char                  *retval = NULL;
++
++        query = g_strdup_printf ("iid == '%s'", iid);
++
++        list = bonobo_activation_query (query, NULL, NULL);
++        if (list && list->_length > 0 && list->_buffer) {
++                Bonobo_ServerInfo  *info = &list->_buffer [0];
++                const char * const *langs;
++                GSList             *langs_gslist;
++                int                 i;
++
++                retval = g_strdup (info->location_info);
++        }
++
++        /* Get the location of the Factory */
++        query = g_strdup_printf ("iid == '%s'", retval);
++
++        list = bonobo_activation_query (query, NULL, NULL);
++        if (list && list->_length > 0 && list->_buffer) {
++                Bonobo_ServerInfo  *info = &list->_buffer [0];
++                const char * const *langs;
++                GSList             *langs_gslist;
++                int                 i;
++
++                if (retval != NULL)
++                        g_free (retval);
++
++                retval = g_strdup (info->location_info);
++        }
++
++        g_free (query);
++        CORBA_free (list);
++
++        return retval;
++}
++
+ gboolean
+ panel_lockdown_is_applet_disabled (const char *iid)
+ {
+         GSList *l;
++        char *location_info;
+ 
+         g_assert (panel_lockdown.initialized != FALSE);
+ 
+@@ -491,6 +538,10 @@ panel_lockdown_is_applet_disabled (const
+                 if (!strcmp (l->data, iid))
+                         return TRUE;
+ 
++        location_info = panel_lockdown_get_location (iid);
++        if (filter_with_rbac (location_info, FALSE))
++                return TRUE;
++
+         return FALSE;
+ }
+ 
+@@ -626,7 +677,7 @@ panel_lockdown_get_exec_from_ditem (Gnom
+         full_exec = gnome_desktop_item_get_string (ditem,
+                                                    GNOME_DESKTOP_ITEM_EXEC);
+ 
+-        return full_exec;
++        return (gchar *)full_exec;
+ }
+ 
+ gboolean
+@@ -744,16 +795,15 @@ panel_lockdown_is_forbidden_key_file (GK
+ 	gchar *stripped_exec;	/* Executable with arguments stripped away */
+ 	gboolean retval = FALSE;
+ 
+-    /* If restrict_application_launching not set on return TRUE */
+-    if (!panel_lockdown_get_restrict_application_launching ()) {
+-        return retval;
+-    }
+-
+ 	if (key_file != NULL)
+ 	{
+ 		full_exec = panel_key_file_get_string (key_file, "Exec");
+         if (full_exec != NULL) {
+         	stripped_exec = panel_lockdown_get_stripped_exec (full_exec);
++
++		if (filter_with_rbac ((char *)stripped_exec, FALSE))
++			return TRUE;
++
+ 		retval = panel_lockdown_is_forbidden_command (stripped_exec);
+                 g_free (stripped_exec);
+                 if (retval == TRUE) {
+@@ -761,6 +811,12 @@ panel_lockdown_is_forbidden_key_file (GK
+                 }
+ 		}
+ 	}
++
++    /* If restrict_application_launching not set on return TRUE */
++    if (!panel_lockdown_get_restrict_application_launching ()) {
++        return FALSE;
++    }
++
+ 	return retval;
+ }
+ 
+--- gnome-panel-2.30.2/gnome-panel/applet.h-orig	2011-02-14 13:45:05.071344150 -0600
++++ gnome-panel-2.30.2/gnome-panel/applet.h	2011-02-14 13:45:19.866630375 -0600
+@@ -110,6 +110,8 @@ void panel_applet_position_menu (GtkMenu
+ 				 int       *y,
+ 				 gboolean  *push_in,
+ 				 GtkWidget *applet);
++
++void panel_applet_reload_applets (void);
+ G_END_DECLS
+ 
+ #endif
+--- gnome-panel-2.30.2/gnome-panel/applet.c-orig	2011-02-14 13:44:28.172499581 -0600
++++ gnome-panel-2.30.2/gnome-panel/applet.c	2011-02-14 13:44:59.898510420 -0600
+@@ -1247,6 +1247,36 @@ panel_applet_list_applets (void)
+ 	return registered_applets;
+ }
+ 
++void
++panel_applet_reload_applets (void)
++{
++	GSList *applets_to_reload = NULL;
++	GSList *l;
++
++	for (l = registered_applets; l; l = l->next) {
++		AppletInfo *info = l->data;
++
++		if (info->type == PANEL_OBJECT_LAUNCHER)
++			panel_applet_check_visibility(info);
++		else if (info->type == PANEL_OBJECT_BONOBO) {
++			if (panel_applet_frame_needs_refresh (info->data)) {
++				applets_to_reload = g_slist_append (applets_to_reload, info);
++			}
++		}
++	}
++
++	for (l = applets_to_reload; l; l = l->next) {
++		AppletInfo *info = l->data;
++		if (!panel_applet_frame_refresh(info->data)) {
++			panel_applet_recreate_menu(info) ;
++		}
++	}
++
++	if (applets_to_reload != NULL) {
++		g_slist_free (applets_to_reload);
++	}
++}
++
+ AppletInfo *
+ panel_applet_get_by_type (PanelObjectType object_type, GdkScreen *screen)
+ {
+--- gnome-panel-2.30.2/gnome-panel/panel-applet-frame.h-orig	2011-02-15 21:49:12.451179896 -0600
++++ gnome-panel-2.30.2/gnome-panel/panel-applet-frame.h	2011-02-15 21:54:07.673263074 -0600
+@@ -84,6 +84,7 @@ void            panel_applet_frame_set_p
+   * status changing.
+   */
+ gboolean        panel_applet_frame_refresh (PanelAppletFrame *frame);
++gboolean	panel_applet_frame_needs_refresh (PanelAppletFrame *frame);
+ 
+ G_END_DECLS
+ 
+--- gnome-panel-2.30.2/gnome-panel/panel-applet-frame.c-orig	2011-02-15 21:49:04.986691244 -0600
++++ gnome-panel-2.30.2/gnome-panel/panel-applet-frame.c	2011-02-15 21:55:45.501679197 -0600
+@@ -464,6 +464,16 @@ panel_applet_frame_refresh (PanelAppletF
+ 	return FALSE;
+ }
+ 
++gboolean
++panel_applet_frame_needs_refresh (PanelAppletFrame *frame)
++{
++	if ((frame->priv->ui_component == NULL) !=
++		panel_lockdown_is_applet_disabled (frame->priv->iid)) {
++		return TRUE;
++	}
++	return FALSE;
++}
++
+ void
+ panel_applet_frame_change_orientation (PanelAppletFrame *frame,
+ 				       PanelOrientation  orientation)
+--- /dev/null	2011-02-14 13:54:17.000000000 -0600
++++ gnome-panel-2.30.2/gnome-panel/panel-solaris.h	2011-02-14 13:43:36.152570242 -0600
+@@ -0,0 +1,90 @@
++
++#ifndef __MENU_SOLARIS_H__
++#define __MENU_SOLARIS_H__
++
++#include <tsol/label.h>
++#include <sys/tsol/label_macro.h>
++#include <X11/Xlib.h>
++#include <X11/extensions/Xtsol.h>
++
++#include <glib.h>
++#include <glib-object.h>
++
++G_BEGIN_DECLS
++
++gboolean use_trusted_extensions (void);
++gboolean filter_with_rbac (gchar *, gboolean);
++char * get_zoneroot (void);
++
++/* Libtsol functions */
++
++typedef int     (*tsol_blequal) (const m_label_t *label1, const m_label_t *label2);
++typedef int     (*tsol_label_to_str) (const m_label_t *label, char **string,
++                 const m_label_str_t conversion_type,
++                 uint_t flags);
++typedef int            (*tsol_str_to_label) (const char *string, m_label_t **label,
++                 const m_label_type_t label_type, uint_t flags,
++                 int *error);
++typedef void (*tsol_m_label_dup) (m_label_t **dst, const m_label_t *src);
++typedef void   (*tsol_m_label_free) (m_label_t *label);
++
++/* Other misc. libtsol functions that seem to be stable */
++typedef blrange_t*             (*tsol_getuserrange) (const char *username);
++typedef int                            (*tsol_blinrange) (const m_label_t *label,
++                         const blrange_t *range);
++typedef void                   (*tsol_blminimum) (m_label_t *minimum_label,
++                         const m_label_t *bounding_label);
++typedef void                   (*tsol_blmaximum) (m_label_t *maximum_label,
++                         const m_label_t *bounding_label);
++typedef m_label_t*             (*tsol_blabel_alloc) (void);
++typedef void                   (*tsol_blabel_free)  (m_label_t *label_p);
++typedef void                   (*tsol_bsllow)  (m_label_t *label);
++typedef void                   (*tsol_bslhigh) (m_label_t *label);
++
++/* libXtsol functions */
++typedef Status (*xtsol_XTSOLgetClientLabel) (Display *dpy, XID xid,
++                 bslabel_t *sl);
++typedef Bool   (*xtsol_XTSOLIsWindowTrusted) (Display *dpy, Window win);
++
++/* libgnometsol functions */
++typedef gpointer       (*gnometsol_gnome_label_builder_new) (char *msg,
++                        blevel_t *upper, blevel_t *lower, int mode);
++typedef GType          (*gnometsol_gnome_label_builder_get_type) (void);
++
++/* libwnck functions */
++typedef gpointer        (*menu_wnck_screen_get_default) (void);
++typedef gpointer        (*menu_wnck_screen_get_active_workspace) (gpointer);
++typedef const char*     (*menu_wnck_workspace_get_role) (gpointer);
++typedef const char*     (*menu_wnck_workspace_get_label) (gpointer);
++
++/* libtsol functions */
++tsol_blequal           libtsol_blequal;
++tsol_label_to_str      libtsol_label_to_str;
++tsol_str_to_label      libtsol_str_to_label;
++tsol_m_label_dup libtsol_m_label_dup;
++tsol_m_label_free      libtsol_m_label_free;
++/* Other misc. libtsol functions */
++tsol_blminimum         libtsol_blminimum;
++tsol_blmaximum         libtsol_blmaximum;
++tsol_blinrange      libtsol_blinrange;
++tsol_getuserrange      libtsol_getuserrange;
++tsol_blabel_alloc      libtsol_blabel_alloc;
++tsol_blabel_free       libtsol_blabel_free;
++tsol_bsllow                    libtsol_bsllow;
++tsol_bslhigh           libtsol_bslhigh;
++
++xtsol_XTSOLgetClientLabel      libxtsol_XTSOLgetClientLabel;
++xtsol_XTSOLIsWindowTrusted     libxtsol_XTSOLIsWindowTrusted;
++
++gnometsol_gnome_label_builder_new libgnometsol_gnome_label_builder_new;
++gnometsol_gnome_label_builder_get_type libgnometsol_gnome_label_builder_get_type;
++
++/* libwnck functions */
++menu_wnck_screen_get_default          libmenu_wnck_screen_get_default;
++menu_wnck_screen_get_active_workspace libmenu_wnck_screen_get_active_workspace;
++menu_wnck_workspace_get_role          libmenu_wnck_workspace_get_role;
++menu_wnck_workspace_get_label         libmenu_wnck_workspace_get_label;
++
++G_END_DECLS
++
++#endif /* __MENU_SOLARIS_H__ */
+--- /dev/null	2011-02-14 13:54:21.000000000 -0600
++++ gnome-panel-2.30.2/gnome-panel/panel-solaris.c	2011-02-14 13:53:38.466591760 -0600
+@@ -0,0 +1,431 @@
++/*
++ * Note that the following code is in three patches:
++ * - gnome-panel-XX-rbac.diff (filter_with_rbac)
++ * - gnome-menus-XX-rbac.diff (filter_with_rbac)
++ * - glib-XX-gio-rbac.diff    (get_gksu_role)
++ * - gnome-session-XX-rbac.diff (get_gksu_role)
++ *
++ * So if there is a need to fix this code, it is probably necessary to fix the
++ * code in these other two places as well.  Though the functions are a bit
++ * different.
++ */
++#include <config.h>
++
++#include <stdlib.h>
++#include <string.h>
++#include <dlfcn.h>
++#include <link.h>
++#include <user_attr.h>
++#include <exec_attr.h>
++#include <secdb.h>
++
++#include "panel-solaris.h"
++
++static
++void * dlopen_tsol (void)
++{
++   void  *handle = NULL;
++
++   /*
++    * No 64-bit version of libwnck so we can get away with hardcoding
++    * to a single path on this occasion
++    */
++   if ((handle = dlopen ("/usr/lib/libtsol.so.2", RTLD_LAZY)) != NULL)
++       return handle;
++
++   return handle;
++}
++
++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;
++}
++
++static
++void * dlopen_gnometsol (void)
++{
++   void  *handle = NULL;
++
++   if ((handle = dlopen ("/usr/lib/libgnometsol.so", RTLD_LAZY)) != NULL)
++       return handle;
++
++   return handle;
++}
++
++static
++void * dlopen_libwnck (void)
++{
++   void  *handle = NULL;
++
++   if ((handle = dlopen ("/usr/lib/libwnck-1.so", RTLD_LAZY)) != NULL)
++       return handle;
++
++   return handle;
++}
++
++gboolean
++use_trusted_extensions (void)
++{
++    static int trusted = -1;
++
++    /*
++     * Sun Trusted Extensions (tm) for Solaris (tm) support. (Damn I should be a lawyer).
++     *
++     * It is necessary to use dlopen because the label aware extensions to libwnck work
++     * only on systems with the trusted extensions installed and with the SUN_TSOL
++     * xserver extension present
++     */
++
++    if (trusted < 0) {
++        static gpointer tsol_handle = NULL;
++        static gpointer xtsol_handle = NULL;
++        static gpointer gnometsol_handle = NULL;
++        static gpointer libwnck_handle = NULL;
++
++        if (getenv ("TRUSTED_SESSION") == NULL) {
++            trusted = 0;
++            return 0;
++        }
++
++	libwnck_handle = dlopen_libwnck ();
++        if (libwnck_handle != NULL)
++            tsol_handle = dlopen_tsol ();
++        if (tsol_handle != NULL)
++            xtsol_handle = dlopen_xtsol ();
++        if (libwnck_handle && tsol_handle && xtsol_handle) {
++
++           libmenu_wnck_screen_get_default = (menu_wnck_screen_get_default) dlsym (libwnck_handle, "wnck_screen_get_default");
++           libmenu_wnck_screen_get_active_workspace = (menu_wnck_screen_get_active_workspace) dlsym (libwnck_handle, "wnck_screen_get_active_workspace");
++           libmenu_wnck_workspace_get_role = (menu_wnck_workspace_get_role) dlsym (libwnck_handle, "wnck_workspace_get_role");
++           libmenu_wnck_workspace_get_label = (menu_wnck_workspace_get_label) dlsym (libwnck_handle, "wnck_workspace_get_label");
++
++           /* libtsol functions */
++           libtsol_blequal = (tsol_blequal) dlsym (tsol_handle, "blequal");
++           libtsol_label_to_str = (tsol_label_to_str) dlsym (tsol_handle, "label_to_str");
++           libtsol_str_to_label = (tsol_str_to_label) dlsym (tsol_handle, "str_to_label");
++           libtsol_m_label_dup = (tsol_m_label_dup) dlsym (tsol_handle, "m_label_dup");
++           libtsol_m_label_free = (tsol_m_label_free) dlsym (tsol_handle, "m_label_free");
++
++           /* Other misc. libtsol functions */
++           libtsol_blminimum = (tsol_blminimum) dlsym (tsol_handle, "blminimum");
++           libtsol_blmaximum = (tsol_blmaximum) dlsym (tsol_handle, "blmaximum");
++           libtsol_blinrange = (tsol_blinrange) dlsym (tsol_handle, "blinrange");
++           libtsol_getuserrange = (tsol_getuserrange) dlsym (tsol_handle, "getuserrange");
++           libtsol_blabel_alloc = (tsol_blabel_alloc) dlsym (tsol_handle, "blabel_alloc");
++           libtsol_blabel_free  = (tsol_blabel_free)  dlsym (tsol_handle, "blabel_free");
++           libtsol_bsllow  = (tsol_bsllow)  dlsym (tsol_handle, "bsllow");
++           libtsol_bslhigh = (tsol_bslhigh) dlsym (tsol_handle, "bslhigh");
++
++           /* libXtsol functions */
++           libxtsol_XTSOLgetClientLabel = (xtsol_XTSOLgetClientLabel) dlsym (xtsol_handle,
++                                     "XTSOLgetClientLabel");
++           libxtsol_XTSOLIsWindowTrusted = (xtsol_XTSOLIsWindowTrusted) dlsym (xtsol_handle,
++                                      "XTSOLIsWindowTrusted");
++
++           if (libtsol_label_to_str == NULL ||
++               libtsol_str_to_label == NULL ||
++               libtsol_m_label_dup == NULL ||
++               libtsol_m_label_free == NULL ||
++               libtsol_blminimum == NULL ||
++               libtsol_blmaximum == NULL ||
++               libtsol_blinrange == NULL ||
++               libtsol_getuserrange == NULL ||
++               libtsol_blabel_alloc == NULL ||
++               libtsol_blabel_free  == NULL ||
++               libtsol_bsllow  == NULL ||
++               libtsol_bslhigh == NULL ||
++               libxtsol_XTSOLgetClientLabel == NULL ||
++               libxtsol_XTSOLIsWindowTrusted == NULL ||
++               libmenu_wnck_screen_get_default == NULL ||
++               libmenu_wnck_screen_get_active_workspace == NULL ||
++               libmenu_wnck_workspace_get_role == NULL ||
++               libmenu_wnck_workspace_get_label == NULL) {
++               dlclose (tsol_handle);
++               dlclose (xtsol_handle);
++               dlclose (libwnck_handle);
++               tsol_handle = NULL;
++               xtsol_handle = NULL;
++               libwnck_handle = NULL;
++            }
++        }
++
++        gnometsol_handle = dlopen_gnometsol ();
++        if (gnometsol_handle != NULL)
++            {
++               libgnometsol_gnome_label_builder_new =
++                               (gnometsol_gnome_label_builder_new) dlsym (gnometsol_handle,
++                               "gnome_label_builder_new");
++              libgnometsol_gnome_label_builder_get_type =
++                               (gnometsol_gnome_label_builder_get_type) dlsym (gnometsol_handle,
++                               "gnome_label_builder_get_type");
++              if (libgnometsol_gnome_label_builder_new == NULL ||
++                  libgnometsol_gnome_label_builder_get_type == NULL)
++                  gnometsol_handle = NULL;
++            }
++        trusted = ((tsol_handle != NULL) && (xtsol_handle != NULL) && (gnometsol_handle != NULL) && (libwnck_handle != NULL)) ? 1 : 0;
++    }
++    return trusted ? TRUE : FALSE;
++}
++
++static gchar *
++get_stripped_exec (const gchar *full_exec, gboolean use_global)
++{
++	gchar *str1, *str2, *retval, *p;
++	char *zoneroot = NULL;
++	gboolean trusted;
++
++	str1 = g_strdup (full_exec);
++	p = strtok (str1, " ");
++
++	if (p != NULL)
++		str2 = g_strdup (p);
++	else
++		str2 = g_strdup (full_exec);
++
++	g_free (str1);
++
++	trusted = use_trusted_extensions ();
++	if (trusted && use_global == FALSE) {
++		zoneroot = get_zoneroot ();
++	}
++
++	if (g_path_is_absolute (str2)) {
++		if (zoneroot != NULL) {
++			retval = g_strdup_printf ("%s/%s", zoneroot, str2);
++		} else {
++			retval = g_strdup (str2);
++		}
++	} else {
++		if (zoneroot != NULL) {
++			/*
++			 * If the desktop file doesn't specify the full path
++			 * and in Trusted mode, then check the zone's /usr/bin
++			 * directory.
++			 */
++			retval = g_strdup_printf ("%s/usr/bin/%s", zoneroot, str2);
++		} else {
++			retval = g_strdup (g_find_program_in_path ((const gchar *)str2));
++
++			/*
++			 * If a program is not installed in the global zone,
++			 * then assume it is installed in /usr/bin.
++			 */
++			if (use_global == TRUE && retval == NULL) {
++				retval = g_strdup_printf ("/usr/bin/%s", str2);
++			}
++		}
++	}
++	g_free (str2);
++
++	return retval;
++}
++
++/*
++ * Checks RBAC to see if the user can run the command.
++ */
++gboolean
++filter_with_rbac (gchar *command, gboolean use_global)
++{
++	execattr_t *exec;
++	gchar *stripped_cmd;
++	gchar *real_cmd;
++	char *path;
++	const char *username = NULL;
++	userattr_t *user;
++	int        i;
++	gboolean   program_has_profile;
++	gboolean   rc;
++	gboolean   trusted;
++
++	rc = TRUE;
++
++	stripped_cmd = get_stripped_exec (command, TRUE);
++	real_cmd     = get_stripped_exec (command, use_global);
++
++	trusted = use_trusted_extensions ();
++	if (trusted) {
++		/*
++		 * In trusted mode, use the single role associated with
++		 * the workspace.
++		 */
++		gpointer wnckscreen = NULL;
++		gpointer wnckworkspace = NULL;
++
++		wnckscreen = libmenu_wnck_screen_get_default ();
++		if (wnckscreen != NULL)
++			wnckworkspace = libmenu_wnck_screen_get_active_workspace (wnckscreen);
++
++		if (wnckworkspace != NULL)
++			username = libmenu_wnck_workspace_get_role (wnckworkspace);
++	}
++
++	if (username == NULL) {
++		username = g_get_user_name ();
++	}
++
++	/* If the command does not exist, do not show it. */
++	if (real_cmd == NULL || stripped_cmd == NULL) {
++		goto out;
++	}
++
++	path = g_find_program_in_path (g_strstrip (real_cmd));
++	if (path == NULL)
++		goto out;
++
++	/*
++	 * All programs should be available to root.  This check is done after
++	 * verifying the binary is in path.
++	 */
++	if (strcmp (username, "root") == 0) {
++		rc = FALSE;
++		goto out;
++	}
++
++	/* Check if the program is in any profile. */
++	program_has_profile = FALSE;
++	exec = getexecprof (NULL, KV_COMMAND, stripped_cmd, GET_ALL);
++	if (exec == NULL) {
++		goto out;
++	}
++
++	while (exec != NULL) {
++		if (strcmp (exec->id, "*") != 0) {
++			program_has_profile = TRUE;
++			break;
++		}
++		exec = exec->next;
++	}
++
++	free_execattr (exec);
++
++	/* Check if the user can run the command.  If not filter it. */
++	exec = getexecuser (username, KV_COMMAND, stripped_cmd, GET_ALL);
++
++	/*
++	 * If the program is not associated with any profile, then do not
++	 * show it.
++	 */
++	if (exec == NULL)
++		goto out;
++
++	/*
++	 * If getexecuser does not return NULL and the program is not
++	 * associated with any profile, then show it.  Otherwise, more
++	 * tests are needed.
++	 */
++	if (use_global == TRUE || program_has_profile == FALSE) {
++		rc = FALSE;
++		goto out;
++	}
++
++	/*
++	 * If the user has a profile that can run the command, then it can
++	 * be shown.
++	 */
++	while (exec != NULL) {
++		if (strcmp (exec->id, "*") != 0) {
++			rc = FALSE;
++			break;
++		}
++		exec = exec->next;
++	}
++
++	free_execattr (exec);
++
++	if (rc == FALSE)
++		goto out;
++
++	if (!trusted) {
++		/* If no gksu is available, then do not try to use it */
++	        path = g_find_program_in_path ("/usr/bin/gksu");
++		if (path == NULL)
++			goto out;
++	}
++
++	/* Check if the user is in a role that can run the command. */
++	/* If so, use gksu with that role */
++	if ((user = getusernam (username)) != NULL) {
++		const char *rolelist = NULL;
++		char **v = NULL;
++		char *role = NULL;
++
++		if (trusted && username != NULL) {
++			/* In trusted mode, use role associated with workspace */
++			rolelist = username;
++		} else {
++			/* Otherwise use roles associated with the user. */
++			rolelist = kva_match (user->attr, USERATTR_ROLES_KW);
++		}
++
++		if (rolelist != NULL)
++			v = g_strsplit (rolelist, ",", -1);
++
++		for (i=0; v != NULL && v[i] != NULL; i++) {
++			role = g_strdup (v[i]);
++			g_strstrip (role);
++
++			exec = getexecuser (role, KV_COMMAND, stripped_cmd, GET_ALL);
++			while (exec != NULL) {
++				if ((strcmp (role, "root") == 0) ||
++				    (strcmp (exec->id, "*") != 0)) {
++					rc = FALSE;
++					break;
++				}
++				exec = exec->next;
++			}
++
++			g_free (role);
++			free_execattr (exec);
++
++			if (rc == FALSE) {
++				break;
++			}
++		}
++		if (v != NULL)
++			g_strfreev (v);
++	}
++
++out:
++	if (stripped_cmd)
++		g_free (stripped_cmd);
++	if (real_cmd)
++		g_free (real_cmd);
++
++	return (rc);
++}
++
++/* Function to return the zone root directory for the current workspace. */
++char *
++get_zoneroot (void)
++{
++  gpointer    wnckscreen    = NULL;
++  gpointer    wnckworkspace = NULL;
++  const char *zonelabelstr  = NULL;
++  m_label_t  *zonelabel     = NULL;
++  char       *zoneroot      = NULL;
++  int         err;
++
++  wnckscreen = libmenu_wnck_screen_get_default ();
++  if (wnckscreen != NULL)
++    wnckworkspace = libmenu_wnck_screen_get_active_workspace (wnckscreen);
++
++  if (wnckworkspace != NULL)
++    zonelabelstr = libmenu_wnck_workspace_get_label (wnckworkspace);
++
++  if (zonelabelstr != NULL)
++    str_to_label (zonelabelstr, &zonelabel, MAC_LABEL, L_NO_CORRECTION, &err);
++
++  if (zonelabel != NULL)
++    zoneroot = getzonerootbylabel (zonelabel);
++
++  return zoneroot;
++}
++
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/gnome-session-24-rbac.diff	Wed Mar 16 17:47:17 2011 +0000
@@ -0,0 +1,525 @@
+--- gnome-session-2.30.2/egg/eggdesktopfile.c-orig	2011-03-14 16:05:27.567087180 -0500
++++ gnome-session-2.30.2/egg/eggdesktopfile.c	2011-03-14 16:07:41.020838521 -0500
+@@ -29,6 +29,17 @@
+ 
+ #include <string.h>
+ #include <unistd.h>
++#include <user_attr.h>
++#include <exec_attr.h>
++#include <stdlib.h>
++#include <secdb.h>
++#include <dlfcn.h>
++#include <pwd.h>
++
++#include <tsol/label.h>
++#include <sys/tsol/label_macro.h>
++#include <X11/Xlib.h>
++#include <X11/extensions/Xtsol.h>
+ 
+ #include <glib/gi18n.h>
+ #include <gdk/gdkx.h>
+@@ -1066,6 +1077,449 @@ array_putenv (GPtrArray *env, char *vari
+   return env;
+ }
+ 
++/*
++ * Note that the following code is in three patches:
++ * - gnome-panel-XX-rbac.diff   (filter_with_rbac)
++ * - gnome-menus-XX-rbac.diff   (filter_with_rbac)
++ * - glib-XX-gio-rbac.diff      (get_gksu_role)
++ * - gnome-session-XX-rbac.diff (get_gksu_role)
++ *
++ * So if there is a need to fix this code, it is probably necessary to fix the
++ * code in these other two places as well.  Though the functions are a bit
++ * different.
++ */
++static
++void * dlopen_tsol (void)
++{
++   void  *handle = NULL;
++
++   /*
++    * No 64-bit version of libwnck so we can get away with hardcoding
++    * to a single path on this occasion
++    */
++   if ((handle = dlopen ("/usr/lib/libtsol.so.2", RTLD_LAZY)) != NULL)
++       return handle;
++
++   return handle;
++}
++
++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;
++}
++
++static
++void * dlopen_gnometsol (void)
++{
++   void  *handle = NULL;
++
++   if ((handle = dlopen ("/usr/lib/libgnometsol.so", RTLD_LAZY)) != NULL)
++       return handle;
++
++   return handle;
++}
++
++/* Libtsol functions */
++
++typedef int     (*tsol_blequal) (const m_label_t *label1, const m_label_t *label2);
++typedef int     (*tsol_label_to_str) (const m_label_t *label, char **string,
++                 const m_label_str_t conversion_type,
++                 uint_t flags);
++typedef int            (*tsol_str_to_label) (const char *string, m_label_t **label,
++                 const m_label_type_t label_type, uint_t flags,
++                 int *error);
++typedef void (*tsol_m_label_dup) (m_label_t **dst, const m_label_t *src);
++typedef void   (*tsol_m_label_free) (m_label_t *label);
++
++/* Other misc. libtsol functions that seem to be stable */
++typedef blrange_t*             (*tsol_getuserrange) (const char *username);
++typedef int                            (*tsol_blinrange) (const m_label_t *label,
++                         const blrange_t *range);
++typedef void                   (*tsol_blminimum) (m_label_t *minimum_label,
++                         const m_label_t *bounding_label);
++typedef void                   (*tsol_blmaximum) (m_label_t *maximum_label,
++                         const m_label_t *bounding_label);
++typedef m_label_t*             (*tsol_blabel_alloc) (void);
++typedef void                   (*tsol_blabel_free)  (m_label_t *label_p);
++typedef void                   (*tsol_bsllow)  (m_label_t *label);
++typedef void                   (*tsol_bslhigh) (m_label_t *label);
++
++/* libXtsol functions */
++typedef Status (*xtsol_XTSOLgetClientLabel) (Display *dpy, XID xid,
++                 bslabel_t *sl);
++typedef Bool   (*xtsol_XTSOLIsWindowTrusted) (Display *dpy, Window win);
++
++/* libgnometsol functions */
++typedef gpointer       (*gnometsol_gnome_label_builder_new) (char *msg,
++                        blevel_t *upper, blevel_t *lower, int mode);
++typedef GType          (*gnometsol_gnome_label_builder_get_type) (void);
++
++/* libtsol functions */
++tsol_blequal           libtsol_blequal;
++tsol_label_to_str      libtsol_label_to_str;
++tsol_str_to_label      libtsol_str_to_label;
++tsol_m_label_dup libtsol_m_label_dup;
++tsol_m_label_free      libtsol_m_label_free;
++/* Other misc. libtsol functions */
++tsol_blminimum         libtsol_blminimum;
++tsol_blmaximum         libtsol_blmaximum;
++tsol_blinrange      libtsol_blinrange;
++tsol_getuserrange      libtsol_getuserrange;
++tsol_blabel_alloc      libtsol_blabel_alloc;
++tsol_blabel_free       libtsol_blabel_free;
++tsol_bsllow                    libtsol_bsllow;
++tsol_bslhigh           libtsol_bslhigh;
++
++xtsol_XTSOLgetClientLabel      libxtsol_XTSOLgetClientLabel;
++xtsol_XTSOLIsWindowTrusted     libxtsol_XTSOLIsWindowTrusted;
++
++gnometsol_gnome_label_builder_new libgnometsol_gnome_label_builder_new;
++gnometsol_gnome_label_builder_get_type libgnometsol_gnome_label_builder_get_type;
++
++gboolean
++use_trusted_extensions (void)
++{
++  static int trusted = -1;
++
++  /*
++   * Sun Trusted Extensions (tm) for Solaris (tm) support. (Damn I should be a lawyer).
++   *
++   * It is necessary to use dlopen because the label aware extensions to libwnck work
++   * only on systems with the trusted extensions installed and with the SUN_TSOL
++   * xserver extension present
++   */
++
++    if (trusted < 0) {
++        static gpointer tsol_handle = NULL;
++        static gpointer xtsol_handle = NULL;
++        static gpointer gnometsol_handle = NULL;
++
++        if (getenv ("TRUSTED_SESSION") == NULL) {
++          trusted = 0;
++          return 0;
++        }
++
++        tsol_handle = dlopen_tsol ();
++        if (tsol_handle != NULL)
++            xtsol_handle = dlopen_xtsol ();
++        if (tsol_handle && xtsol_handle) {
++
++           /* libtsol functions */
++           libtsol_blequal = (tsol_blequal) dlsym (tsol_handle, "blequal");
++           libtsol_label_to_str = (tsol_label_to_str) dlsym (tsol_handle, "label_to_str");
++           libtsol_str_to_label = (tsol_str_to_label) dlsym (tsol_handle, "str_to_label");
++           libtsol_m_label_dup = (tsol_m_label_dup) dlsym (tsol_handle, "m_label_dup");
++           libtsol_m_label_free = (tsol_m_label_free) dlsym (tsol_handle, "m_label_free");
++
++
++           /* Other misc. libtsol functions */
++           libtsol_blminimum = (tsol_blminimum) dlsym (tsol_handle, "blminimum");
++           libtsol_blmaximum = (tsol_blmaximum) dlsym (tsol_handle, "blmaximum");
++           libtsol_blinrange = (tsol_blinrange) dlsym (tsol_handle, "blinrange");
++           libtsol_getuserrange = (tsol_getuserrange) dlsym (tsol_handle, "getuserrange");
++           libtsol_blabel_alloc = (tsol_blabel_alloc) dlsym (tsol_handle, "blabel_alloc");
++           libtsol_blabel_free  = (tsol_blabel_free)  dlsym (tsol_handle, "blabel_free");
++           libtsol_bsllow  = (tsol_bsllow)  dlsym (tsol_handle, "bsllow");
++           libtsol_bslhigh = (tsol_bslhigh) dlsym (tsol_handle, "bslhigh");
++
++           /* libXtsol functions */
++           libxtsol_XTSOLgetClientLabel = (xtsol_XTSOLgetClientLabel) dlsym (xtsol_handle,
++                                     "XTSOLgetClientLabel");
++           libxtsol_XTSOLIsWindowTrusted = (xtsol_XTSOLIsWindowTrusted) dlsym (xtsol_handle,
++                                      "XTSOLIsWindowTrusted");
++
++           if (libtsol_label_to_str == NULL ||
++               libtsol_str_to_label == NULL ||
++               libtsol_m_label_dup == NULL ||
++               libtsol_m_label_free == NULL ||
++               libtsol_blminimum == NULL ||
++               libtsol_blmaximum == NULL ||
++               libtsol_blinrange == NULL ||
++               libtsol_getuserrange == NULL ||
++               libtsol_blabel_alloc == NULL ||
++               libtsol_blabel_free  == NULL ||
++               libtsol_bsllow  == NULL ||
++               libtsol_bslhigh == NULL ||
++               libxtsol_XTSOLgetClientLabel == NULL ||
++               libxtsol_XTSOLIsWindowTrusted == NULL) {
++               dlclose (tsol_handle);
++               dlclose (xtsol_handle);
++               tsol_handle = NULL;
++               xtsol_handle = NULL;
++            }
++        }
++
++        gnometsol_handle = dlopen_gnometsol ();
++        if (gnometsol_handle != NULL) {
++               libgnometsol_gnome_label_builder_new =
++                               (gnometsol_gnome_label_builder_new) dlsym (gnometsol_handle,
++                               "gnome_label_builder_new");
++              libgnometsol_gnome_label_builder_get_type =
++                               (gnometsol_gnome_label_builder_get_type) dlsym (gnometsol_handle,
++                               "gnome_label_builder_get_type");
++              if (libgnometsol_gnome_label_builder_new == NULL ||
++                  libgnometsol_gnome_label_builder_get_type == NULL)
++                  gnometsol_handle = NULL;
++
++        }
++        trusted = ((tsol_handle != NULL) && (xtsol_handle != NULL) && (gnometsol_handle != NULL)) ? 1 : 0;
++    }
++    return trusted ? TRUE : FALSE;
++}
++
++static gchar *
++get_stripped_exec (const gchar *full_exec)
++{
++        gchar *str1, *str2, *retval, *p;
++
++        str1 = g_strdup (full_exec);
++        p = strtok (str1, " ");
++
++        if (p != NULL)
++                str2 = g_strdup (p);
++        else
++                str2 = g_strdup (full_exec);
++
++        g_free (str1);
++
++	if (g_path_is_absolute (str2)) {
++		retval = g_strdup (str2);
++	} else {
++		retval = g_strdup (g_find_program_in_path ((const gchar *)str2));
++	}
++        g_free (str2);
++
++        return retval;
++}
++
++static
++char * get_validated_stripped_exec (const char *command)
++{
++	const char *username = NULL;
++	char       *stripped_cmd;
++	char       *path;
++
++	username = g_get_user_name ();
++
++	/* Do not use pfexec for root */
++	if (strcmp (username, "root") == 0) {
++		return NULL;
++	}
++
++	stripped_cmd = get_stripped_exec (command);
++	if (stripped_cmd == NULL) {
++		return NULL;
++	}
++
++	path = g_find_program_in_path (g_strstrip (stripped_cmd));
++	if (path == NULL)
++		return NULL;
++
++	return stripped_cmd;
++}
++
++static gboolean
++command_has_profile (const char *command)
++{
++	execattr_t *exec = NULL;
++	gboolean    rc = FALSE;
++
++	/* Check if the program is in any profile. */
++	exec = getexecprof (NULL, KV_COMMAND, command, GET_ALL);
++	if (exec == NULL) {
++		return rc;
++	}
++
++	while (exec != NULL) {
++		if (strcmp (exec->id, "*") != 0) {
++			rc = TRUE;
++			break;
++		}
++		exec = exec->next;
++	}
++
++	free_execattr (exec);
++
++	return rc;
++}
++
++static gboolean
++use_pfexec (char *command)
++{
++	execattr_t *exec = NULL;
++	const char *username = NULL;
++	char       *stripped_cmd;
++	gboolean    trusted;
++	gboolean    has_profile;
++	gboolean    rc;
++
++	rc = FALSE;
++
++	/* Never use pfexec in Trusted mode */
++	trusted = use_trusted_extensions ();
++	if (trusted) {
++		goto out;
++	}
++
++	stripped_cmd = get_validated_stripped_exec (command);
++	if (stripped_cmd == NULL) {
++		goto out;
++	}
++
++	has_profile = command_has_profile (stripped_cmd);
++
++	username = g_get_user_name ();
++
++	/* Check if the user can run the command. */
++	exec = getexecuser (username, KV_COMMAND, stripped_cmd, GET_ALL);
++
++	/*
++	 * If the program is not associated with any profile, then do not
++	 * use pfexec.
++	 */
++	if (exec == NULL)
++		goto out;
++
++	/*
++	 * If getexecuser does not return NULL and the program is not
++	 * associated with any profile, then pfexec is not needed.
++	 */
++	if (has_profile == FALSE) {
++		goto out;
++	}
++
++	/*
++	 * Does the user have a profile that can run the command?
++	 */
++	while (exec != NULL) {
++		if (strcmp (exec->id, "*") != 0) {
++			rc = TRUE;
++			break;
++		}
++		exec = exec->next;
++	}
++out:
++	if (exec != NULL)
++		free_execattr (exec);
++
++	if (stripped_cmd)
++		g_free (stripped_cmd);
++
++	return rc;
++}
++
++/*
++ * Checks RBAC and if the user can run the command with gksu, the role is
++ * passed back, otherwise NULL.
++ */
++gchar *
++get_gksu_role (char *command)
++{
++	execattr_t *exec;
++	userattr_t *user;
++	const char *username = NULL;
++	char       *rc = NULL;
++	char       *stripped_cmd;
++	char       *path;
++	int         i;
++	gboolean    has_profile;
++	gboolean    trusted;
++
++	/* Never use gksu in Trusted mode */
++	trusted = use_trusted_extensions ();
++	if (trusted) {
++		goto out;
++	}
++
++	stripped_cmd = get_validated_stripped_exec (command);
++	if (stripped_cmd == NULL) {
++		goto out;
++	}
++
++	/* If pfexec should be used, then do not use gksu. */
++	if (use_pfexec (command) == TRUE) {
++		goto out;
++	}
++
++	has_profile = command_has_profile (stripped_cmd);
++	username    = g_get_user_name ();
++
++	/* Check if the user can run the command. */
++	exec = getexecuser (username, KV_COMMAND, stripped_cmd, GET_ALL);
++
++	/*
++	 * If the program is not associated with any profile, then do not
++	 * use gksu.
++	 */
++	if (exec == NULL)
++		goto out;
++
++	/*
++	 * If getexecuser does not return NULL and the program is not
++	 * associated with any profile, then gksu is not needed.
++	 */
++	if (has_profile == FALSE) {
++		goto out;
++	}
++
++	/* If no gksu is available, then do not try to use it */
++        path = g_find_program_in_path ("/usr/bin/gksu");
++	if (path == NULL)
++		goto out;
++
++	/* Check if the user is in a role that can run the command. */
++	/* If so, use gksu with that role */
++	if ((user = getusernam (username)) != NULL) {
++		const char *rolelist = NULL;
++		char **v = NULL;
++		char *role = NULL;
++
++		/* Use roles associated with the user. */
++		rolelist = kva_match (user->attr, USERATTR_ROLES_KW);
++
++		if (rolelist != NULL)
++			v = g_strsplit (rolelist, ",", -1);
++
++		for (i=0; v != NULL && v[i] != NULL; i++) {
++			role = g_strdup (v[i]);
++			g_strstrip (role);
++
++			exec = getexecuser (role, KV_COMMAND, stripped_cmd, GET_ALL);
++			while (exec != NULL) {
++				if ((strcmp (role, "root") == 0) ||
++				    (strcmp (exec->id, "*") != 0)) {
++					rc = g_strdup (role);
++					break;
++				}
++				exec = exec->next;
++			}
++
++			g_free (role);
++			free_execattr (exec);
++
++			if (rc != NULL) {
++				break;
++			}
++		}
++		if (v != NULL)
++			g_strfreev (v);
++	}
++
++out:
++	if (stripped_cmd)
++		g_free (stripped_cmd);
++
++	return (rc);
++}
++
+ static gboolean
+ egg_desktop_file_launchv (EggDesktopFile *desktop_file,
+ 			  GSList *documents, va_list args,
+@@ -1078,6 +1532,9 @@ egg_desktop_file_launchv (EggDesktopFile
+   gboolean success, current_success;
+   GdkDisplay *display;
+   char *startup_id;
++  char *gksu_role, *final_cmd;
++  struct passwd *pw;
++  uid_t uid;
+ 
+   GPtrArray   *env = NULL;
+   char       **variables = NULL;
+@@ -1200,11 +1657,42 @@ egg_desktop_file_launchv (EggDesktopFile
+       if (!command)
+ 	goto out;
+ 
+-      if (!g_shell_parse_argv (command, &argc, &argv, error))
+-	{
++      /* Only use a prefix if not in Trusted mode */
++      gksu_role = NULL;
++      if (!use_trusted_extensions ())
++        gksu_role = get_gksu_role (command);
++
++      final_cmd = NULL;
++      if (command != NULL)
++        {
++          /* Only use a prefix if not in Trusted mode */
++          gksu_role = NULL;
++          if (!use_trusted_extensions ())
++            gksu_role = get_gksu_role (command);
++
++          uid = getuid ();
++          pw = getpwuid (uid);
++
++          if (gksu_role)
++            final_cmd = g_strdup_printf ("/usr/bin/gksu -u %s %s", gksu_role, command);
++          else if (use_pfexec (command) == TRUE ||
++                   (pw != NULL && pw->pw_shell != NULL &&
++                    strncmp (pw->pw_shell, "/usr/bin/pf", strlen ("/usr/bin/pf")) == 0))
++            final_cmd = g_strdup_printf ("/usr/bin/pfexec %s", command);
++          else
++            final_cmd = g_strdup_printf ("%s", command);
++        }
++
++      if (gksu_role)
++        g_free (gksu_role);
++
++      if (!g_shell_parse_argv (final_cmd, &argc, &argv, error))
++        {
++	  g_free (final_cmd);
+ 	  g_free (command);
+ 	  goto out;
+ 	}
++      g_free (final_cmd);
+       g_free (command);
+ 
+ #if GTK_CHECK_VERSION (2, 12, 0)
--- a/patches/libwnck-01-trusted-extensions.diff	Wed Mar 16 06:31:01 2011 +0000
+++ b/patches/libwnck-01-trusted-extensions.diff	Wed Mar 16 17:47:17 2011 +0000
@@ -181,7 +181,7 @@
 diff -urN libwnck.orig/libwnck/screen.c libwnck.new/libwnck/screen.c
 --- libwnck.orig/libwnck/screen.c	2008-08-06 23:43:13.472108000 +0100
 +++ libwnck.new/libwnck/screen.c	2008-08-06 23:43:40.084085000 +0100
-@@ -33,11 +33,17 @@
+@@ -35,11 +35,17 @@
  #include "class-group.h"
  #include "xutils.h"
  #include "private.h"
@@ -199,7 +199,7 @@
  /**
   * SECTION:screen
   * @short_description: an object representing a screen.
-@@ -122,6 +128,10 @@
+@@ -124,6 +130,10 @@ struct _WnckScreenPrivate
    guint need_update_active_window : 1;
    guint need_update_workspace_layout : 1;
    guint need_update_workspace_names : 1;
@@ -210,7 +210,16 @@
    guint need_update_bg_pixmap : 1;
    guint need_update_showing_desktop : 1;
    guint need_update_wm : 1;
-@@ -160,6 +170,10 @@
+@@ -148,6 +158,8 @@ enum {
+   SHOWING_DESKTOP_CHANGED,
+   VIEWPORTS_CHANGED,
+   WM_CHANGED,
++  ROLES_CHANGED,
++  LABELS_CHANGED,
+   LAST_SIGNAL
+ };
+ 
+@@ -162,6 +174,10 @@ static void update_active_workspace   (W
  static void update_active_window      (WnckScreen      *screen);
  static void update_workspace_layout   (WnckScreen      *screen);
  static void update_workspace_names    (WnckScreen      *screen);
@@ -221,7 +230,45 @@
  static void update_showing_desktop    (WnckScreen      *screen);
  
  static void queue_update            (WnckScreen      *screen);
-@@ -602,6 +616,10 @@
+@@ -193,6 +209,9 @@ static void emit_showing_desktop_changed
+ static void emit_viewports_changed        (WnckScreen      *screen);
+ static void emit_wm_changed               (WnckScreen *screen);
+ 
++void wnck_screen_emit_roles_changed       (WnckScreen *screen);
++void wmck_screen_emit_labels_changed      (WnckScreen *screen);
++
+ static guint signals[LAST_SIGNAL] = { 0 };
+ 
+ static void
+@@ -502,6 +521,27 @@ wnck_screen_class_init (WnckScreenClass 
+                   NULL, NULL,
+                   g_cclosure_marshal_VOID__VOID,
+                   G_TYPE_NONE, 0);
++
++   /**
++    * Solaris specific signals
++    */
++    signals[ROLES_CHANGED] =
++    g_signal_new ("roles_changed",
++                  G_OBJECT_CLASS_TYPE (object_class),
++                  G_SIGNAL_RUN_LAST,
++                  G_STRUCT_OFFSET (WnckScreenClass, roles_changed),
++                  NULL, NULL,
++                  g_cclosure_marshal_VOID__VOID,
++                  G_TYPE_NONE, 0);
++
++    signals[LABELS_CHANGED] =
++    g_signal_new ("labels_changed",
++                  G_OBJECT_CLASS_TYPE (object_class),
++                  G_SIGNAL_RUN_LAST,
++                  G_STRUCT_OFFSET (WnckScreenClass, labels_changed),
++                  NULL, NULL,
++                  g_cclosure_marshal_VOID__VOID,
++                  G_TYPE_NONE, 0);
+ }
+ 
+ static void
+@@ -608,6 +648,10 @@ wnck_screen_construct (WnckScreen *scree
    screen->priv->need_update_active_window = TRUE;
    screen->priv->need_update_workspace_layout = TRUE;
    screen->priv->need_update_workspace_names = TRUE;
@@ -232,7 +279,7 @@
    screen->priv->need_update_bg_pixmap = TRUE;
    screen->priv->need_update_showing_desktop = TRUE;
    screen->priv->need_update_wm = TRUE;
-@@ -1124,6 +1142,20 @@
+@@ -1144,6 +1188,20 @@ _wnck_screen_process_property_notify (Wn
        screen->priv->need_update_workspace_names = TRUE;
        queue_update (screen);
      }
@@ -253,7 +300,7 @@
    else if (xevent->xproperty.atom ==
             _wnck_atom_get ("_XROOTPMAP_ID"))
      {
-@@ -2220,6 +2252,85 @@
+@@ -2240,6 +2298,85 @@ update_workspace_names (WnckScreen *scre
    g_list_free (copy);
  }
  
@@ -339,7 +386,7 @@
  static void
  update_bg_pixmap (WnckScreen *screen)
  {
-@@ -2305,6 +2416,10 @@
+@@ -2325,6 +2462,10 @@ do_update_now (WnckScreen *screen)
      {
        screen->priv->need_update_viewport_settings = TRUE;
        screen->priv->need_update_workspace_names = TRUE;
@@ -350,7 +397,7 @@
      }
        
    /* First get our big-picture state in order */
-@@ -2317,6 +2432,15 @@
+@@ -2337,6 +2478,15 @@ do_update_now (WnckScreen *screen)
    update_active_window (screen);
    update_workspace_layout (screen);
    update_workspace_names (screen);
@@ -366,7 +413,30 @@
    update_showing_desktop (screen);
    update_wm (screen);
    
-@@ -2815,3 +2939,86 @@
+@@ -2505,6 +2655,22 @@ emit_wm_changed (WnckScreen *screen)
+                  0);
+ }
+ 
++void
++wnck_screen_emit_roles_changed (WnckScreen *screen)
++{
++  g_signal_emit (G_OBJECT (screen),
++                 signals[ROLES_CHANGED],
++                 0);
++}
++
++void
++wnck_screen_emit_labels_changed (WnckScreen *screen)
++{
++  g_signal_emit (G_OBJECT (screen),
++                 signals[LABELS_CHANGED],
++                 0);
++}
++
+ /**
+  * wnck_screen_get_window_manager_name:
+  * @screen: a #WnckScreen.
+@@ -2835,3 +3001,86 @@ _wnck_screen_change_workspace_name (Wnck
  
    g_free (names);
  }
@@ -453,6 +523,32 @@
 +  g_free (labels);
 +}
 +#endif /* HAVE_XTSOL */
+diff -urN libwnck.orig/libwnck/screen.h libwnck.new/libwnck/screen.h
+--- libwnck.orig/libwnck/screen.h	2011-02-18 04:01:52.526645403 -0600
++++ libwnck.new/libwnck/screen.h	2011-02-18 04:03:08.974857147 -0600
+@@ -109,6 +109,12 @@ struct _WnckScreenClass
+   /* Window manager changed */
+   void (* window_manager_changed)   (WnckScreen      *screen);
+ 
++  /* Roles changed */
++  void (* roles_changed)            (WnckScreen      *screen);
++
++  /* Labels changed */
++  void (* labels_changed)           (WnckScreen      *screen);
++
+   /* Padding for future expansion */
+   void (* pad2) (void);
+   void (* pad3) (void);
+@@ -270,6 +276,9 @@ void           wnck_screen_calc_workspac
+ void           wnck_screen_free_workspace_layout (WnckWorkspaceLayout *layout);
+ #endif /* WNCK_DISABLE_DEPRECATED */
+ 
++void wnck_screen_emit_roles_changed (WnckScreen *screen);
++void wnck_screen_emit_labels_changed (WnckScreen *screen);
++
+ 
+ G_END_DECLS
+ 
 diff -urN libwnck.orig/libwnck/tasklist.c libwnck.new/libwnck/tasklist.c
 --- libwnck.orig/libwnck/tasklist.c	2008-08-06 23:43:13.368589000 +0100
 +++ libwnck.new/libwnck/tasklist.c	2008-08-06 23:43:40.101354000 +0100
@@ -2593,7 +2689,7 @@
  #include "workspace.h"
  #include "xutils.h"
  #include "private.h"
-@@ -69,6 +79,13 @@
+@@ -69,6 +79,13 @@ struct _WnckWorkspacePrivate
    WnckScreen *screen;
    int number;
    char *name;
@@ -2607,7 +2703,7 @@
    int width, height;            /* Workspace size */
    int viewport_x, viewport_y;   /* Viewport origin */
    gboolean is_virtual;
-@@ -79,6 +96,10 @@
+@@ -79,6 +96,10 @@ G_DEFINE_TYPE (WnckWorkspace, wnck_works
  
  enum {
    NAME_CHANGED,
@@ -2618,7 +2714,7 @@
    LAST_SIGNAL
  };
  
-@@ -91,6 +112,12 @@
+@@ -91,6 +112,12 @@ static void emit_name_changed (WnckWorks
  
  static guint signals[LAST_SIGNAL] = { 0 };
  
@@ -2631,7 +2727,7 @@
  static void
  wnck_workspace_init (WnckWorkspace *workspace)
  {
-@@ -104,6 +131,9 @@
+@@ -104,6 +131,9 @@ wnck_workspace_init (WnckWorkspace *work
    workspace->priv->viewport_x = 0;
    workspace->priv->viewport_y = 0;
    workspace->priv->is_virtual = FALSE;
@@ -2641,7 +2737,7 @@
  }
  
  static void
-@@ -129,6 +159,24 @@
+@@ -129,6 +159,24 @@ wnck_workspace_class_init (WnckWorkspace
                    NULL, NULL,
                    g_cclosure_marshal_VOID__VOID,
                    G_TYPE_NONE, 0);
@@ -2666,7 +2762,7 @@
  }
  
  static void
-@@ -140,6 +188,11 @@
+@@ -140,6 +188,11 @@ wnck_workspace_finalize (GObject *object
  
    g_free (workspace->priv->name);
    workspace->priv->name = NULL;
@@ -2678,7 +2774,7 @@
    
    G_OBJECT_CLASS (wnck_workspace_parent_class)->finalize (object);
  }
-@@ -179,6 +232,134 @@
+@@ -179,6 +232,134 @@ wnck_workspace_get_name (WnckWorkspace *
    return space->priv->name;
  }
  
@@ -2813,7 +2909,7 @@
  /**
   * wnck_workspace_change_name:
   * @space: a #WnckWorkspace.
-@@ -217,6 +398,29 @@
+@@ -217,6 +398,29 @@ wnck_workspace_get_screen (WnckWorkspace
    return space->priv->screen;
  }
  
@@ -2843,7 +2939,7 @@
  /**
   * wnck_workspace_activate:
   * @space: a #WnckWorkspace.
-@@ -254,6 +458,7 @@
+@@ -254,6 +458,7 @@ _wnck_workspace_create (int number, Wnck
    space->priv->screen = screen;
  
    _wnck_workspace_update_name (space, NULL);
@@ -2851,7 +2947,7 @@
    
    /* Just set reasonable defaults */
    space->priv->width = wnck_screen_get_width (screen);
-@@ -289,6 +494,251 @@
+@@ -289,6 +494,251 @@ _wnck_workspace_update_name (WnckWorkspa
    g_free (old);
  }
  
@@ -3103,7 +3199,7 @@
  static void
  emit_name_changed (WnckWorkspace *space)
  {
-@@ -297,6 +747,24 @@
+@@ -297,6 +747,26 @@ emit_name_changed (WnckWorkspace *space)
                   0);
  }
  
@@ -3114,6 +3210,7 @@
 +  g_signal_emit (G_OBJECT (space),
 +                 signals[LABEL_CHANGED],
 +                 0);
++  wnck_screen_emit_labels_changed (space->priv->screen);
 +}
 +
 +static void
@@ -3122,13 +3219,14 @@
 +  g_signal_emit (G_OBJECT (space),
 +                 signals[ROLE_CHANGED],
 +                 0);
++  wnck_screen_emit_roles_changed (space->priv->screen);
 +}
 +#endif /* HAVE_XTSOL */
 +
  gboolean
  _wnck_workspace_set_geometry (WnckWorkspace *space,
                                int            w,
-@@ -612,3 +1080,33 @@
+@@ -612,3 +1082,33 @@ wnck_workspace_get_neighbor (WnckWorkspa
  
    return wnck_screen_get_workspace (space->priv->screen, index);
  }
--- a/patches/sound-juicer-01-menu-entry.diff	Wed Mar 16 06:31:01 2011 +0000
+++ b/patches/sound-juicer-01-menu-entry.diff	Wed Mar 16 17:47:17 2011 +0000
@@ -1,17 +1,15 @@
 --- sound-juicer-2.26.1/data/sound-juicer.desktop.in.in.old	2009年  4月 27日 一 10:40:18
 +++ sound-juicer-2.26.1/data/sound-juicer.desktop.in.in	2009年  4月 27日 一 10:41:37
-@@ -1,7 +1,11 @@
+@@ -1,6 +1,10 @@
  [Desktop Entry]
 -_Name=Audio CD Extractor
 -_Comment=Copy music from your CDs
--Exec=sound-juicer %u
 +# SUN_BRANDING
 +_Name=CD Ripper
 +# SUN_BRANDING
 +_GenericName=CD Ripper
 +# SUN_BRANDING
 +_Comment=Convert audio CDs to sound files
-+Exec=gksu sound-juicer %u
+ Exec=sound-juicer %u
  Icon=sound-juicer
  StartupNotify=true
- MimeType=x-content/audio-cdda;
--- /dev/null	Thu Jan 01 00:00:00 1970 +0000
+++ b/patches/tsoljds-tstripe-03-pfexec.diff	Wed Mar 16 17:47:17 2011 +0000
@@ -0,0 +1,24 @@
+--- tsoljds-tstripe-0.6.8/src/xagent-proxy.c-orig	2011-03-02 20:41:31.039905623 -0600
++++ tsoljds-tstripe-0.6.8/src/xagent-proxy.c	2011-03-02 20:47:38.725845760 -0600
+@@ -566,15 +566,16 @@ spawn_xagent (int argc, char **argv)
+ 		chdir (pwd.pw_dir);
+ 
+ 		if (role) {
+-			execl ("/usr/bin/tsoljds-xagent", "tsoljds-xagent",
++			execl ("/usr/bin/pfexec", "/usr/bin/pfexec", "/usr/bin/tsoljds-xagent",
+ 			       "--defaultsession", 0);
+ 		} else {
+ 			if (zoneid == 0) {
+-				execl ("/usr/bin/tsoljds-xagent", 
+-				       "tsoljds-xagent", "--nosession", 0);
++				execl ("/usr/bin/pfexec", "/usr/bin/pfexec",
++				       "/usr/bin/tsoljds-xagent", 
++				       "--nosession", 0);
+ 			} else {
+-				execl ("/usr/bin/tsoljds-xagent", 
+-				       "tsoljds-xagent", 0);
++				execl ("/usr/bin/pfexec", "/usr/bin/pfexec",
++				       "/usr/bin/tsoljds-xagent", 0);
+ 			}
+ 		}
+ 	} else if (pid > 0) { /* in the parent */
--- a/specs/SUNWgnome-cd-burner.spec	Wed Mar 16 06:31:01 2011 +0000
+++ b/specs/SUNWgnome-cd-burner.spec	Wed Mar 16 17:47:17 2011 +0000
@@ -29,7 +29,7 @@
 SUNW_Copyright: %{name}.copyright
 BuildRoot:      %{_tmppath}/%{name}-%{version}-build
 # date:2009-05-27 owner:lin type:branding
-Patch1:         brasero-01-load-by-gksu.diff
+Patch1:         brasero-01-libtool.diff
 
 %include default-depend.inc
 %include gnome-consolidation.inc
--- a/specs/SUNWnwam-manager.spec	Wed Mar 16 06:31:01 2011 +0000
+++ b/specs/SUNWnwam-manager.spec	Wed Mar 16 17:47:17 2011 +0000
@@ -19,6 +19,7 @@
 Summary:                 Network Auto-Magic User Interface
 Version:                 %{nwam_manager.version}
 Source:                  %{name}-manpages-0.1.tar.gz
+Source1:                 %{name}-exec_attr
 SUNW_BaseDir:            %{_prefix}
 License:                 %{nwam_manager.license}
 SUNW_Copyright:          %{name}.copyright
@@ -70,6 +71,9 @@
 cd %{_builddir}/%name-%version/sun-manpages
 make install DESTDIR=$RPM_BUILD_ROOT
 
+mkdir -p $RPM_BUILD_ROOT%{_sysconfdir}/security/exec_attr.d
+install --mode=0644 %SOURCE1 $RPM_BUILD_ROOT%{_sysconfdir}/security/exec_attr.d/desktop-administration-nwam-manager
+
 %if %build_l10n
 %else
 # REMOVE l10n FILES
@@ -141,6 +145,9 @@
 %dir %attr (-, root, sys) %{_sysconfdir}/xdg
 %dir %attr (-, root, sys) %{_sysconfdir}/xdg/autostart
 %attr (-, root, sys) %{_sysconfdir}/xdg/autostart/*
+%dir %attr(0755, root, sys) /etc/security
+%dir %attr(0755, root, sys) /etc/security/exec_attr.d
+%attr (0444, root, sys) %{_sysconfdir}/security/exec_attr.d/*
 
 %if %build_l10n
 %files l10n
@@ -153,6 +160,8 @@
 %endif
 
 %changelog
+* Mon Mar 14 2011 - [email protected]
+- Add exec_attr entries.
 * Thu Aug 19 2010 - [email protected]
 - Update license.
 * Fri Feb 24 2010 - [email protected]
--- a/specs/SUNWtgnome-tstripe.spec	Wed Mar 16 06:31:01 2011 +0000
+++ b/specs/SUNWtgnome-tstripe.spec	Wed Mar 16 17:47:17 2011 +0000
@@ -25,6 +25,7 @@
 Source:			 http://dlc.sun.com/osol/jds/downloads/extras/tjds/tsoljds-tstripe-%{tstripe_version}.tar.bz2
 Patch1:			 tsoljds-tstripe-01-dont-set-DISPLAY.diff
 Patch2:			 tsoljds-tstripe-02-TPEXEC.diff
+Patch3:                  tsoljds-tstripe-03-pfexec.diff
 %if %build_l10n
 Source1:                 l10n-configure.sh
 %endif
@@ -33,7 +34,7 @@
 BuildRoot:               %{_tmppath}/%{name}-%{version}-build
 
 %include default-depend.inc
-%include gnome-consolidation.inc
+%include gnome-onsolidation.inc
 Requires: SUNWlibgnomecanvas
 Requires: SUNWgnome-panel
 Requires: SUNWtgnome-tsol-libs
@@ -57,6 +58,7 @@
 
 %patch1 -p1
 %patch2 -p1
+%patch3 -p1
 
 %build
 export ACLOCAL_FLAGS="-I /usr/share/aclocal"
@@ -133,6 +135,10 @@
 
 %changelog
 * Wed Mar 09 2011 - [email protected]
+- Add patch tsoljds-tstripe-03-pfexec.diff so that the proxy always calls
+  tsoljds-xagent with pfexec.
+
+* Wed Mar 09 2011 - [email protected]
 - Add code to remove l10n if %build_l10n is not true.
 
 * Tue Mar 01 2011 - [email protected]