Selinux patch - for comments



Hi, this patch adds gnome-vfs support for selinux. It adds the raw selinux context field into the GnomeVfsFileInfo structure. It's based on an older patch from Dan Walsh, but with additions to complete it. The read_directory, get_file_info, get_file_info_from_handle, and set_file_info functions were modified, for the file method.

Patch is posted here for comments. I've done very little testing, so I'm not sure if it works yet. I can tell get_file_info is working (test output is correct, and nautilus displays context fine). I haven't gotten the write interface for nautilus set up yet, so not sure if set_file_info works [ can't see why it wouldn't work, but I need to test this ].


diff -Naurp --exclude-from excludes gnome-vfs/configure.in gnome-vfs.new/configure.in
--- gnome-vfs/configure.in	2006-02-27 17:54:56.000000000 -0500
+++ gnome-vfs.new/configure.in	2006-02-27 19:32:21.000000000 -0500
@@ -1111,6 +1111,19 @@ AC_CHECK_LIB(fam, FAMOpen,
 AC_SUBST(FAM_LIBS)
 fi
 
+dnl ****************************
+dnl *** Check for libselinux ***
+dnl ****************************
+SELINUX_LIBS=
+msg_selinux=no
+AC_CHECK_LIB(selinux, is_selinux_enabled,
+   [AC_CHECK_HEADERS(selinux/selinux.h,
+     [AC_DEFINE(HAVE_SELINUX, 1, [Define to 1 if libselinux is available])
+      SELINUX_LIBS="-lselinux"
+      msg_selinux=yes])
+   ])
+AC_SUBST(SELINUX_LIBS)
+
 dnl **************************
 dnl *** Checks for gtk-doc ***
 dnl **************************
@@ -1237,6 +1250,7 @@ echo "
       	Avahi support:		     $msg_avahi
       	Howl support:		     $msg_howl
 	HAL  support:                $msg_hal
+	SELinux support:             $msg_selinux
 	gnome-mount support:	     $msg_gnome_mount
 	Gtk Doc:                     $enable_gtk_doc
 	FS monitor backends:         $fs_monitor_backends
diff -Naurp --exclude-from excludes gnome-vfs/libgnomevfs/gnome-vfs-file-info.c gnome-vfs.new/libgnomevfs/gnome-vfs-file-info.c
--- gnome-vfs/libgnomevfs/gnome-vfs-file-info.c	2005-11-14 06:41:13.000000000 -0500
+++ gnome-vfs.new/libgnomevfs/gnome-vfs-file-info.c	2006-02-27 19:46:43.000000000 -0500
@@ -132,6 +132,7 @@ gnome_vfs_file_info_clear (GnomeVFSFileI
 	g_free (info->name);
 	g_free (info->symlink_name);
 	g_free (info->mime_type);
+	g_free (info->selinux_context);
 
 	/* Ensure the ref count is maintained correctly */
 	g_static_mutex_lock (&file_info_ref_lock);
@@ -196,6 +197,7 @@ gnome_vfs_file_info_copy (GnomeVFSFileIn
 	dest->name = g_strdup (src->name);
 	dest->symlink_name = g_strdup (src->symlink_name);
 	dest->mime_type = g_strdup (src->mime_type);
+	dest->selinux_context = g_strdup (src->selinux_context);
 
 	dest->refcount = old_refcount;
 
@@ -254,6 +256,20 @@ symlink_name_matches (char *a, char *b)
 	}
 }
 
+static gboolean
+selinux_context_matches (char *a, char*b) 
+{
+	if (a == NULL && b == NULL) {
+		return TRUE;
+	} else if ((a != NULL && b == NULL) ||
+	           (a == NULL && b != NULL)) {
+		return FALSE;
+	} else {
+		g_assert (a != NULL && b != NULL);
+		return strcmp (a, b) == 0;
+	}
+}
+
 /**
  * gnome_vfs_file_info_matches:
  * @a: first #GnomeVFSFileInfo struct to compare.
@@ -295,6 +311,7 @@ gnome_vfs_file_info_matches (const Gnome
 	    || a->uid != b->uid
 	    || a->gid != b->gid
 	    || strcmp (a->name, b->name) != 0
+	    || !selinux_context_matches (a->selinux_context, b->selinux_context)
 	    || !mime_matches (a->mime_type, b->mime_type)
 	    || !symlink_name_matches (a->symlink_name, b->symlink_name)) {
 		return FALSE;
diff -Naurp --exclude-from excludes gnome-vfs/libgnomevfs/gnome-vfs-file-info.h gnome-vfs.new/libgnomevfs/gnome-vfs-file-info.h
--- gnome-vfs/libgnomevfs/gnome-vfs-file-info.h	2006-02-24 07:53:31.000000000 -0500
+++ gnome-vfs.new/libgnomevfs/gnome-vfs-file-info.h	2006-02-27 16:14:31.000000000 -0500
@@ -126,7 +126,8 @@ typedef enum {
  * @GNOME_VFS_FILE_INFO_FIELDS_ACCESS: Access bits of the permissions
  * bitfield are valid
  * @GNOME_VFS_FILE_INFO_FIELDS_IDS: UID and GID information are valid
- *
+ * @GNOME_VFS_FILE_INFO_FIELDS_SELINUX_CONTEXT: SELinux Security context is valid
+ * 
  * Flags indicating what fields in a GnomeVFSFileInfo struct are valid. 
  * Name is always assumed valid (how else would you have gotten a
  * FileInfo struct otherwise?)
@@ -149,7 +150,8 @@ typedef enum {
 	GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME = 1 << 12,
 	GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE = 1 << 13,
 	GNOME_VFS_FILE_INFO_FIELDS_ACCESS = 1 << 14,
-	GNOME_VFS_FILE_INFO_FIELDS_IDS = 1 << 15
+	GNOME_VFS_FILE_INFO_FIELDS_IDS = 1 << 15,
+	GNOME_VFS_FILE_INFO_FIELDS_SELINUX_CONTEXT = 1 << 16
 } GnomeVFSFileInfoFields;
 
 /* FIXME: It's silly to use the symbolic constants for POSIX here.
@@ -264,13 +266,15 @@ typedef struct {
 
 	guint refcount;
 
+	/* SELinux security context. -- ascii string, raw format. */
+	char* selinux_context;
+
 	/* Reserved for future expansions to GnomeVFSFileInfo without having
 	   to break ABI compatibility */
 	void *reserved1;
 	void *reserved2;
 	void *reserved3;
 	void *reserved4;
-	void *reserved5;
 } GnomeVFSFileInfo;
 
 /**
@@ -304,7 +308,8 @@ typedef enum {
 	GNOME_VFS_FILE_INFO_FORCE_SLOW_MIME_TYPE = 1 << 2,
 	GNOME_VFS_FILE_INFO_FOLLOW_LINKS = 1 << 3,
 	GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS = 1 << 4,
-	GNOME_VFS_FILE_INFO_NAME_ONLY = 1 << 5
+	GNOME_VFS_FILE_INFO_NAME_ONLY = 1 << 5,
+	GNOME_VFS_FILE_INFO_GET_SELINUX_CONTEXT = 1 << 6
 } GnomeVFSFileInfoOptions;
 
 /**
@@ -324,7 +329,8 @@ typedef enum {
 	GNOME_VFS_SET_FILE_INFO_NAME = 1 << 0,
 	GNOME_VFS_SET_FILE_INFO_PERMISSIONS = 1 << 1,
 	GNOME_VFS_SET_FILE_INFO_OWNER = 1 << 2,
-	GNOME_VFS_SET_FILE_INFO_TIME = 1 << 3
+	GNOME_VFS_SET_FILE_INFO_TIME = 1 << 3,
+	GNOME_VFS_SET_FILE_INFO_SELINUX_CONTEXT = 1 << 4
 } GnomeVFSSetFileInfoMask;
 
 
diff -Naurp --exclude-from excludes gnome-vfs/libgnomevfs/Makefile.am gnome-vfs.new/libgnomevfs/Makefile.am
--- gnome-vfs/libgnomevfs/Makefile.am	2006-01-16 04:01:15.000000000 -0500
+++ gnome-vfs.new/libgnomevfs/Makefile.am	2006-02-25 13:00:29.000000000 -0500
@@ -125,6 +125,7 @@ libgnomevfs_2_la_LIBADD =			\
 	$(FNMATCH_LIBS)				\
 	$(SOCKET_LIBS)				\
 	$(INTLLIBS)				\
+	$(SELINUX_LIBS)				\
 	$(NULL)
 
 libgnomevfs_2_la_LDFLAGS =			\
diff -Naurp --exclude-from excludes gnome-vfs/modules/file-method.c gnome-vfs.new/modules/file-method.c
--- gnome-vfs/modules/file-method.c	2006-02-27 03:54:52.000000000 -0500
+++ gnome-vfs.new/modules/file-method.c	2006-02-27 21:47:44.000000000 -0500
@@ -60,6 +60,10 @@
 #include <fam.h>
 #endif
 
+#ifdef HAVE_SELINUX
+#include <selinux/selinux.h>
+#endif
+
 #if defined(HAVE_LINUX_INOTIFY_H) || defined(HAVE_SYS_INOTIFY_H)
 #define USE_INOTIFY 1
 #include "inotify-helper.h"
@@ -720,6 +724,75 @@ read_link (const gchar *full_name)
 }
 #endif
 
+/* Get the SELinux security context */
+static int
+get_selinux_context (
+	GnomeVFSFileInfo *info,
+	const char *full_name,
+	GnomeVFSFileInfoOptions options)
+{
+#ifdef HAVE_SELINUX
+	if (is_selinux_enabled()) {
+
+		if ((options & GNOME_VFS_FILE_INFO_FOLLOW_LINKS) == 0
+			&& (info->type == GNOME_VFS_FILE_TYPE_SYMBOLIC_LINK)) {
+
+			/* we are a symlink and aren't asked to follow -
+			 * return the type for a symlink */
+						
+			if (lgetfilecon_raw(full_name, &info->selinux_context) < 0)
+				return gnome_vfs_result_from_errno ();
+		} else {
+
+			if (getfilecon_raw(full_name, &info->selinux_context) < 0)
+				return gnome_vfs_result_from_errno ();
+		}
+
+		info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SELINUX_CONTEXT;
+		return GNOME_VFS_OK;
+	}
+
+	return GNOME_VFS_OK;
+#endif
+}
+
+/* Get the SELinux security context from handle */
+static int 
+get_selinux_context_from_handle (
+	GnomeVFSFileInfo *info,
+	FileHandle *handle)
+{
+#ifdef HAVE_SELINUX
+	if (is_selinux_enabled()) {
+		if (fgetfilecon_raw(handle->fd, &info->selinux_context) >= 0) 
+			return gnome_vfs_result_from_errno ();	
+
+		info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_SELINUX_CONTEXT;
+		return GNOME_VFS_OK;
+	}	
+
+	return GNOME_VFS_OK;
+#endif
+}
+
+/* Set the SELinux security context */
+static int 
+set_selinux_context (
+	const GnomeVFSFileInfo *info,
+	const char *full_name) 
+{
+#ifdef HAVE_SELINUX
+	if (is_selinux_enabled()) {
+		if (setfilecon_raw(full_name, info->selinux_context) < 0)
+			return gnome_vfs_result_from_errno ();
+
+		return GNOME_VFS_OK;
+	}
+
+	return GNOME_VFS_OK;
+#endif
+}
+
 static void
 get_access_info (GnomeVFSFileInfo *file_info,
 		 const gchar *full_name)
@@ -1024,6 +1097,12 @@ do_read_directory (GnomeVFSMethod *metho
 	if (handle->options & GNOME_VFS_FILE_INFO_NAME_ONLY) {
 		return GNOME_VFS_OK;
 	}
+
+	if (handle->options & GNOME_VFS_FILE_INFO_GET_SELINUX_CONTEXT) {
+
+		/* Attempt to get selinux contet, ignore error (see below) */
+		get_selinux_context(file_info, full_name, handle->options);
+	}
 		
 	if (get_stat_info (file_info, full_name, handle->options, &statbuf) != GNOME_VFS_OK) {
 		/* Return OK - this should not terminate the directory iteration
@@ -1036,7 +1115,7 @@ do_read_directory (GnomeVFSMethod *metho
 	if (handle->options & GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS) {
 		get_access_info (file_info, full_name);
 	}
-	
+
 	if (handle->options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) {
 		get_mime_type (file_info, full_name, handle->options, &statbuf);
 	}
@@ -1070,6 +1149,14 @@ do_get_file_info (GnomeVFSMethod *method
 		return result;
 	}
 
+	if (options & GNOME_VFS_FILE_INFO_GET_SELINUX_CONTEXT) {
+		result = get_selinux_context (file_info, full_name, options);
+		if (result != GNOME_VFS_OK) { 
+			g_free (full_name);
+			return result;
+		}
+	} 
+
 	if (options & GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS) {
 		get_access_info (file_info, full_name);
 	}
@@ -1114,6 +1201,14 @@ do_get_file_info_from_handle (GnomeVFSMe
 		return result;
 	}
 
+	if (options & GNOME_VFS_FILE_INFO_GET_SELINUX_CONTEXT) {
+		result = get_selinux_context_from_handle (file_info, file_handle);
+		if (result != GNOME_VFS_OK) {
+			g_free (full_name);
+			return result;
+		}
+	}
+
 	if (options & GNOME_VFS_FILE_INFO_GET_MIME_TYPE) {
 		get_mime_type (file_info, full_name, options, &statbuf);
 	}
@@ -2225,6 +2320,14 @@ do_set_file_info (GnomeVFSMethod *method
 		}
 	}
 
+	if (mask & GNOME_VFS_SET_FILE_INFO_SELINUX_CONTEXT) {
+		GnomeVFSResult result = set_selinux_context(info, full_name);
+		if (result < 0) {
+			g_free(full_name);
+			return result;
+		}
+	}
+
 	if (gnome_vfs_context_check_cancellation (context)) {
 		g_free (full_name);
 		return GNOME_VFS_ERROR_CANCELLED;
diff -Naurp --exclude-from excludes gnome-vfs/test/test-info.c gnome-vfs.new/test/test-info.c
--- gnome-vfs/test/test-info.c	2002-10-29 08:45:00.000000000 -0500
+++ gnome-vfs.new/test/test-info.c	2006-02-28 01:23:09.000000000 -0500
@@ -124,7 +124,9 @@ print_file_info (const GnomeVFSFileInfo 
              printf ("Executable        : %s\n", 
                      (info->permissions&GNOME_VFS_PERM_ACCESS_EXECUTABLE?"YES":"NO"));
      }
-     
+
+	if (info->valid_fields&GNOME_VFS_FILE_INFO_FIELDS_SELINUX_CONTEXT)
+		printf ("SELinux Context   : %s\n", info->selinux_context);     
 
 #undef FLAG_STRING
 }
@@ -162,6 +164,7 @@ main (int argc,
 						  info,
 						  (GNOME_VFS_FILE_INFO_GET_MIME_TYPE
 						   | GNOME_VFS_FILE_INFO_GET_ACCESS_RIGHTS
+						   | GNOME_VFS_FILE_INFO_GET_SELINUX_CONTEXT
 						   | GNOME_VFS_FILE_INFO_FOLLOW_LINKS));
 		if (result != GNOME_VFS_OK) {
 			fprintf (stderr, "%s: %s: %s\n",


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]