Report on Extending the lockdown framework in GNOME and making it even more deployment friendly

Part 1: Global Desktop Items in Nautilus

The requirement

The Story

Carlos has set up an internal wiki for the dinosaur park, so that scientists can have a central place to log information about their projects. Say a researcher does voyeurism in the name of science, and finds out how stegosauruses manage to mate while avoiding hurting each other with their sharp armored plates. The researcher will then want to enter this data in the park's internal wiki, so that someone else, who investigates the gestation of land-based dinosaurs, can access this data. The problem Carlos has is that researchers can never remember the URL of that wiki. He even tried to make it the default web page to be shown on people's browsers, but they kept complaining that they preferred to use boingboing.net instead. Carlos has decided that he will put an icon on people's desktops, which they can double-click to launch a browser and show the park's wiki. Similarly, Carlos wants to have some icons on the desktop which people can use to launch commonly-used programs. Nautilus supports showing icons for desktop entries, but there is no way to configure them centrally (except for maybe using Sabayon to predefine specific items, but that's not a very elegant solution).

The Solution

There needs to be a way for the administrator to install desktop entries (".desktop files") that are used by Nautilus on user's desktops, in addition to what users may put in their own ~/Desktop directories. That is, we need to have support for global desktop items in Nautilus.

The Implementation

Overview

A GConf key (/apps/nautilus/desktop/global_item_dir) specifies a directory which contains all the .desktop files to be displayed as read only links in the relevant user's desktop. Desktop administrators would be able to predefine these items by using a small application which is integrated with Sabayon. Moreover, this feature would be controlled by a key (/apps/nautilus/desktop/global_items_visible), which, if enabled would actually show the global desktop items.

Coding Details

Nautilus

Items displayed on the desktop (which is managed by Nautilus) are represented by instances of NautilusDesktopLink. The NautilusDesktopLink class was modified to have a new type, viz NAUTILUS_TYPE_DESKTOP_LINK. All NautilusDesktopLinks are managed by an instance of NautilusDesktopLinkMonitor (which is created when Nautilus is started). If the Gconf key /apps/nautilus/desktop/global_items_visible is set to TRUE, NautiluDesktopLinkMonitor reads the files in directory which is specified by the Gconf key /apps/nautilus/desktop/global_item_dir and creates the relevant NautilusDesktopLink.

Sabayon

Sabayon uses a consistent naming system for the global desktop link directory viz: $(sysconfdir)/desktop-profiles/desktop-items/{profile-name} which also take care of distributing these links if the requirement arises. The implementation in Sabayon is as follows:

  1. A Edit->Desktop Links menu item in the Sabayon profile editor window shows the desktop links editing tool (the global link directory is predefined as $(sysconfdir)/desktop-profiles/desktop-items/{profile-name} as soon as the user clicks on the menu item).

  2. The link editing tool has a check box to enable/disable the global (mandatory) desktop links.

AddRemoveDesktopLinks.png

Part 2: Restricted Views in Nautilus (and the GTKFileChooser)

The requirement

The Story

Alicia is the administrator for the internet cafe. She wants her customers to be able to save files on their home directories: she can afford to give students a modest amount of space on her server's hard drive so that they can do school work and keep it there. However, Alicia wants to simplify the students' view of the software by only showing the contents of home directories: she doesn't want students to see "File System" nor "Network Servers" in the Nautilus places sidebar. Alicia would therefore like to say that only certain directories (and their subdirectories) should be visible to certain users. One of the customers, Ricardo Tapia, should only be able to see /home/premium-customers/ricardo and its subdirectories --- he certainly doesn't care to see /usr or /var. Similarly, this limited view of the file system should also be seen in the GTK+ file chooser. See the section called "Scenario: Lock-down" in http://primates.ximian.com/~federico/docs/file-chooser-extension-spec/index.html

The Solution

The administrator should be able to define a restricted set of directories which users in a profile will be able to view. For example, a user may only be allowed to view the contents of his home directory and its subdirectories. For an enterprise setting, users may also be allowed to view a shared network mount ("/mnt/shared"). Moreover, the user need not be aware that other directories in the system exists, for the "simplified view" part.

The Implementation

Nautilus

I added NautilusLockdownManager to libnautilus-private, a singleton which is designed to handle all lockdown related settings for Nautilus. At the moment libnautilus-private/nautilus-lockdown-manager.h looks like

/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*-

   nautilus-lockdown-manager.h: singleton that manages lockdown 
    
   Copyright (C) 2003 Red Hat, Inc.
   Copyright (C) 2007 Sayamindu Dasgupta <sayamindu@gnome.org>
  
   This program is free software; you can redistribute it and/or
   modify it under the terms of the GNU General Public License as
   published by the Free Software Foundation; either version 2 of the
   License, or (at your option) any later version.
  
   This program is distributed in the hope that it will be useful,
   but WITHOUT ANY WARRANTY; without even the implied warranty of
   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
   General Public License for more details.
  
   You should have received a copy of the GNU General Public
   License along with this program; if not, write to the
   Free Software Foundation, Inc., 59 Temple Place - Suite 330,
   Boston, MA 02111-1307, USA.
  
   Based on nautilus-desktop-link-monitor.h by Alexander Larsson
*/


#ifndef NAUTILUS_LOCKDOWN_MANAGER_H
#define NAUTILUS_LOCKDOWN_MANAGER_H

#include <gtk/gtkwidget.h>


#define NAUTILUS_TYPE_LOCKDOWN_MANAGER \
        (nautilus_lockdown_manager_get_type ())
#define NAUTILUS_LOCKDOWN_MANAGER(obj) \
        (GTK_CHECK_CAST ((obj), NAUTILUS_TYPE_LOCKDOWN_MANAGER, NautilusLockdownManager))
#define NAUTILUS_LOCKDOWN_MANAGER_CLASS(klass) \
        (GTK_CHECK_CLASS_CAST ((klass), NAUTILUS_TYPE_LOCKDOWN_MANAGER, NautilusLockdownManager))
#define NAUTILUS_IS_LOCKDOWN_MANAGER(obj) \
        (GTK_CHECK_TYPE ((obj), NAUTILUS_TYPE_LOCKDOWN_MANAGER))
#define NAUTILUS_IS_LOCKDOWN_MANAGER_CLASS(klass) \
        (GTK_CHECK_CLASS_TYPE ((klass), NAUTILUS_TYPE_LOCKDOWN_MANAGER))

typedef struct NautilusLockdownManagerDetails NautilusLockdownManagerDetails;

typedef struct {
        GObject parent_slot;
        NautilusLockdownManagerDetails *details;
} NautilusLockdownManager;

typedef struct {
        GObjectClass parent_slot;
} NautilusLockdownManagerClass;

GType   nautilus_lockdown_manager_get_type (void);

NautilusLockdownManager *   nautilus_lockdown_manager_get (void);

gboolean nautilus_lockdown_manager_is_uri_allowed (NautilusLockdownManager *manager,
                const char *uri);

#endif /* NAUTILUS_LOCKDOWN_MANAGER_H */

nautilus_lockdown_manager_is_uri_allowed gets an URI and returns TRUE if the URI is accessible by the user. Currently a whitelist of URIs is defined for the GConf key /apps/nautilus/lockdown/allowed_uris. To this whitelist, the user $HOME is added at runtime, along with some special locations like trash:///, network:///, etc. The mountpoints of the removable storage devices attached to the system is also added to the whitelist, since policy on these devices will be set by PolicyKit in the near future.

nautilus_lockdown_manager_is_uri_allowed is called when the user tries to change locations via the Location Entry dialog (Ctrl-L) and also while creating the path button and the path bar in spatial and navigational modes respectively. This effectively adds rerooting support to Nautilus, where to the user, $HOME becomes the root of the filesystem, navigation to an upper level is not allowed unless explicitely allowed by the administrator.

NautilusSpatial.png NautilusNavigational.png

GNOME Control Center and GTK+

To maintain consistency in the filesystem view presented to the user, the restriction is also implemented in the GTKFileChooser. Since GTK+ cannot read GConf settings directly, gnome-settings-daemon in GNOME Control Center was modified to propagate the GConf settings via XSettings. Since I couldn't find a way to make xsettings handle lists, I simply sent a "^" seperated list of paths in the whitelist to the xsettings manager.

Index: gnome-settings-daemon/gnome-settings-xsettings.c
===================================================================
--- gnome-settings-daemon/gnome-settings-xsettings.c    (revision 7979)
+++ gnome-settings-daemon/gnome-settings-xsettings.c    (working copy)
@@ -27,6 +27,9 @@
 #include <gdk/gdkx.h>
 #include <gconf/gconf-client.h>
 
+#include <libgnomevfs/gnome-vfs-utils.h>
+
+
 #include "gnome-settings-module.h"
 #include "xsettings-manager.h"
 #include "utils.h"
@@ -196,6 +199,36 @@
                                   tmp);
 }
 
+static void
+translate_list_string_restricted_dir (TranslationEntry *trans,
+                GConfValue          *value)
+{
+    int i;
+    GString *string;
+    const GSList *slist, *node; 
+    const GConfValue *next_value;
+
+    g_assert (value->type == trans->gconf_type);
+
+    string = g_string_new(g_get_home_dir());
+    
+    /* FIXME: Do I need to add network:///, computer:///, etc as well ? */
+    slist = gconf_value_get_list(value);
+    for (node = slist; node != NULL; node = node->next) { 
+        next_value = node->data;
+        g_string_append_printf (string, "^%s", 
+                gnome_vfs_escape_path_string(gconf_value_get_string (next_value)));
+    }
+
+    for (i = 0; managers [i]; i++) {
+        xsettings_manager_set_string (managers [i],
+                                  trans->xsetting_name,
+                                   string->str);
+    }
+
+}
+
+
 static TranslationEntry translations [] = {
        { "/desktop/gnome/peripherals/mouse/double_click",      "Net/DoubleClickTime",
          GCONF_VALUE_INT,              translate_int_int },
@@ -241,6 +274,10 @@
          GCONF_VALUE_BOOL,             translate_bool_int },
        { "/desktop/gnome/interface/show_unicode_menu",  "Gtk/ShowUnicodeMenu",
          GCONF_VALUE_BOOL,             translate_bool_int },
+    { "/apps/nautilus/lockdown/enable_restricted_views", "Lockdown/EnableRestrictedViews",
+      GCONF_VALUE_BOOL,     translate_bool_int }, 
+    { "/apps/nautilus/lockdown/allowed_uris", "Lockdown/AllowedURIs",
+      GCONF_VALUE_LIST,     translate_list_string_restricted_dir },
 };
 
 static TranslationEntry*
@@ -326,12 +363,14 @@
                xsettings_manager_notify (managers [i]);
 }
 
+
 static gboolean
 gnome_settings_module_xsettings_initialize (GnomeSettingsModule *module, GConfClient *config_client)
 {
        gnome_settings_register_config_callback ("/desktop/gnome/peripherals/mouse", xsettings_callback);
        gnome_settings_register_config_callback ("/desktop/gtk", xsettings_callback);
        gnome_settings_register_config_callback ("/desktop/gnome/interface", xsettings_callback);
+    gnome_settings_register_config_callback ("/apps/nautilus/lockdown", xsettings_callback);
 
 #ifdef HAVE_XFT2
        gnome_settings_register_config_callback (FONT_RENDER_DIR, xft_callback);

In GTK+, the following properties were added to GtkSettings

  • gtk-allowed-uris: List of URIs accessible to the user

  • gtk-enable-restricted-view: Whether user should be restricted to a whitelist of URIs

To make the view consistent with Nautilus, GtkPathBar, as well as GtkFileChooserDefault were both modified to provide rerooting support and to restrict the user within the whitelisted directories.

Moreover, the roots of the whitelisted directories were added to the sidebar as per suggestions made by my mentor, since it allows easy access to the directories that the administrator wants the user to access.

FileChooser.png

Pessulus

In order to make the manipulation of the path whitelist easier for the admins, support was added to Pessulus (based on the code which handles protocol whitelist for Epiphany) to let adminsitrators add/remove/edit paths from the whitelist.

PessulusRestrictedView.png

Part 3: Desktop Administrators' Guide to GNOME Lockdown and Preconfiguration

First version of the document has been completed.

Outreach/SummerOfCode/2007/Reports/Sayamindu (last edited 2013-12-03 18:32:09 by WilliamJonMcCann)