Index: configure.in
===================================================================
RCS file: /cvs/gnome/gnome-vfs/configure.in,v
retrieving revision 1.392
diff -u -r1.392 configure.in
--- configure.in	25 Oct 2005 14:05:07 -0000	1.392
+++ configure.in	9 Nov 2005 16:52:01 -0000
@@ -1008,6 +1008,19 @@
 	AC_DEFINE(HAVE_SOCKETPAIR,1,[Define if you have the socketpair function.])
 fi
 
+dnl *****************
+dnl *** ACL stuff ***
+dnl *****************
+AC_CHECK_HEADERS(acl/libacl.h, have_acl_header=yes, have_acl_header=no)
+AC_CHECK_FUNCS(acl_get_file, have_acl_func=yes, 
+			[AC_SEARCH_LIBS(acl_get_file, [acl], have_acl_func=yes)])
+
+if test "$have_acl_func$have_acl_header" = "yesyes"; then
+  have_acl_support=yes
+fi
+
+AM_CONDITIONAL(HAVE_ACL, test $have_acl_support = yes)
+
 dnl =====================
 dnl File system monitors
 dnl =====================
@@ -1153,6 +1166,7 @@
       	Avahi support:		     $msg_avahi
       	Howl support:		     $msg_howl
 	HAL  support:                $msg_hal
+	ACL  support:                $have_acl_support
 	Gtk Doc:                     $enable_gtk_doc
 	FS monitor backends:         $fs_monitor_backends
 	Samba method:		     $msg_samba
Index: libgnomevfs/Makefile.am
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/Makefile.am,v
retrieving revision 1.141
diff -u -r1.141 Makefile.am
--- libgnomevfs/Makefile.am	7 Sep 2005 23:03:10 -0000	1.141
+++ libgnomevfs/Makefile.am	9 Nov 2005 16:52:01 -0000
@@ -210,6 +210,9 @@
 	gnome-vfs-drive.h			\
 	gnome-vfs-enum-types.h			\
 	gnome-vfs-file-info.h			\
+	gnome-vfs-file-acl.h		\
+	gnome-vfs-file-acl-backend.h  \
+	gnome-vfs-file-acl-backend-posix.h \
 	gnome-vfs-file-size.h			\
 	gnome-vfs-find-directory.h		\
 	gnome-vfs-handle.h			\
@@ -245,7 +248,15 @@
 	gnome-vfs-dllmain.c			\
 	$(NULL)
 
+if HAVE_ACL
+libgnomevfs_acl_sources = \
+	gnome-vfs-file-acl.c			\
+	gnome-vfs-file-acl-backend.c  	\
+	gnome-vfs-file-acl-backend-posix.c
+endif
+
 libgnomevfs_unix_sources =			\
+	$(libgnomevfs_acl_sources)         \
 	gnome-vfs-cdrom.c			\
 	gnome-vfs-dns-sd.c			\
 	gnome-vfs-parse-ls.c			\
Index: libgnomevfs/gnome-vfs-file-info.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/libgnomevfs/gnome-vfs-file-info.h,v
retrieving revision 1.31
diff -u -r1.31 gnome-vfs-file-info.h
--- libgnomevfs/gnome-vfs-file-info.h	6 May 2005 11:52:40 -0000	1.31
+++ libgnomevfs/gnome-vfs-file-info.h	9 Nov 2005 16:52:01 -0000
@@ -30,6 +30,7 @@
 #include <libgnomevfs/gnome-vfs-file-size.h>
 #include <libgnomevfs/gnome-vfs-result.h>
 #include <libgnomevfs/gnome-vfs-uri.h>
+#include <libgnomevfs/gnome-vfs-file-acl.h>
 #include <sys/stat.h>
 #include <sys/types.h>
 
@@ -124,6 +125,7 @@
  * @GNOME_VFS_FILE_INFO_FIELDS_SYMLINK_NAME: Symlink name field is valid
  * @GNOME_VFS_FILE_INFO_FIELDS_MIME_TYPE: Mime type field is valid
  * @GNOME_VFS_FILE_INFO_FIELDS_ACCESS: Access bits of the permissions
+ * @GNOME_VFS_FILE_INFO_FIELDS_ACL: ACLs field is valid
  * bitfield are valid
  *
  * Flags indicating what fields in a GnomeVFSFileInfo struct are valid. 
@@ -147,7 +149,8 @@
 	GNOME_VFS_FILE_INFO_FIELDS_CTIME = 1 << 11,
 	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_ACCESS = 1 << 14,
+	GNOME_VFS_FILE_INFO_FIELDS_ACL = 1 << 15
 } GnomeVFSFileInfoFields;
 
 /* FIXME: It's silly to use the symbolic constants for POSIX here.
@@ -262,13 +265,15 @@
 
 	guint refcount;
 
+	/* File ACLs */
+	GnomeVFSFileACL *acl;
+
 	/* Reserved for future expansions to GnomeVFSFileInfo without having
 	   to break ABI compatibility */
 	void *reserved1;
 	void *reserved2;
 	void *reserved3;
 	void *reserved4;
-	void *reserved5;
 } GnomeVFSFileInfo;
 
 /**
@@ -285,6 +290,7 @@
  * to what would return access(2) on a local file system (ie is the 
  * file readable, writable and/or executable). Can be really slow on 
  * remote file systems
+ * @GNOME_VFS_FILE_INFO_GET_ACL: get ACLs for the file
  *
  * Packed boolean bitfield representing options that can
  * be passed into a gnome_vfs_get_file_info() call (or other
@@ -298,7 +304,8 @@
 	GNOME_VFS_FILE_INFO_FORCE_FAST_MIME_TYPE = 1 << 1,
 	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_GET_ACCESS_RIGHTS = 1 << 4,
+	GNOME_VFS_FILE_INFO_GET_ACL = 1 << 5
 } GnomeVFSFileInfoOptions;
 
 /**
@@ -308,6 +315,7 @@
  * @GNOME_VFS_SET_FILE_INFO_PERMISSIONS: change the permissions
  * @GNOME_VFS_SET_FILE_INFO_OWNER: change the file's owner
  * @GNOME_VFS_SET_FILE_INFO_TIME: change the file's time stamp(s)
+ * @GNOME_VFS_SET_FILE_INFO_ACL: change the file's ACLs	
  *
  * Packed boolean bitfield representing the aspects of the file
  * to be changed in a gnome_vfs_set_file_info() call.
@@ -318,7 +326,8 @@
 	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_ACL = 1 << 4
 } GnomeVFSSetFileInfoMask;
 
 
Index: modules/file-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/file-method.c,v
retrieving revision 1.144
diff -u -r1.144 file-method.c
--- modules/file-method.c	15 Jul 2005 13:46:53 -0000	1.144
+++ modules/file-method.c	9 Nov 2005 16:52:02 -0000
@@ -711,6 +711,32 @@
 	g_free (directory_handle);
 }
 
+/* ACL */
+static GnomeVFSResult
+get_acl (GnomeVFSFileInfo *info,
+	 const char *full_name,
+	 GnomeVFSFileInfoOptions options,
+	 struct stat *stat_buffer)
+{
+	GnomeVFSResult ret;
+
+	if (info->acl != NULL) {
+		gnome_vfs_file_acl_free (info->acl);
+		info->acl = NULL;
+	}
+	
+	info->acl = gnome_vfs_file_acl_new ();
+	if (info->acl == NULL) 
+		return GNOME_VFS_ERROR_NO_MEMORY;
+	
+	ret = gnome_vfs_file_acl_read (info->acl, full_name);
+	if (ret != GNOME_VFS_OK)
+		return ret;
+
+	info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_ACL;
+	return GNOME_VFS_OK;
+}
+
 /* MIME detection code.  */
 static void
 get_mime_type (GnomeVFSFileInfo *info,
@@ -1066,6 +1092,10 @@
 		get_mime_type (file_info, full_name, handle->options, &statbuf);
 	}
 
+	if (handle->options & GNOME_VFS_FILE_INFO_GET_ACL) {
+		get_acl (file_info, full_name, handle->options, &statbuf);
+	}
+
 	return GNOME_VFS_OK;
 }
 
@@ -1103,6 +1133,10 @@
 		get_mime_type (file_info, full_name, options, &statbuf);
 	}
 
+	if (options & GNOME_VFS_FILE_INFO_GET_ACL) {
+		get_acl (file_info, full_name, options, &statbuf);
+	}
+
 	g_free (full_name);
 
 	return GNOME_VFS_OK;
@@ -1143,6 +1177,10 @@
 		get_mime_type (file_info, full_name, options, &statbuf);
 	}
 
+	if (options & GNOME_VFS_FILE_INFO_GET_ACL) {
+		get_acl (file_info, full_name, options, &statbuf);
+	}
+
 	g_free (full_name);
 
 	return GNOME_VFS_OK;
@@ -2275,6 +2313,18 @@
 			return gnome_vfs_result_from_errno ();
 		}
 	}
+
+	if (gnome_vfs_context_check_cancellation (context)) {
+		g_free (full_name);
+		return GNOME_VFS_ERROR_CANCELLED;
+	}
+
+	if (mask & GNOME_VFS_SET_FILE_INFO_ACL) {
+		GnomeVFSResult ret;
+
+		ret = gnome_vfs_file_acl_commit (info->acl);
+		if (ret != GNOME_VFS_OK) return ret;
+ 	}
 
 	g_free (full_name);
 
--- /dev/null	2005-11-09 07:48:09.336509500 +0000
+++ libgnomevfs/gnome-vfs-file-acl-backend-posix.c	2005-11-09 16:47:19.000000000 +0000
@@ -0,0 +1,501 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-vfs-file-acl.h - Handling of ACL file information for the GNOME
+   Virtual File System.
+
+   Copyright (C) 2005 Sun Microsystems
+
+   The Gnome Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Alvaro Lopez Ortega <alvaro@sun.com>
+*/
+
+#include "gnome-vfs-file-acl-backend-posix.h"
+
+#include <errno.h>
+#include <string.h>
+#include <unistd.h>
+#include <stdlib.h>
+#include <sys/types.h>
+#include <sys/resource.h>
+#include <pwd.h>
+#include <grp.h>
+
+#include <acl/libacl.h>
+
+/* constants for permission specifiers */
+#define CMD_PERM_READ           4
+#define CMD_PERM_WRITE          2
+#define CMD_PERM_EXECUTE        1
+#define CMD_PERM_COND_EXECUTE   8
+
+
+struct _GnomeVFSFileACLBackendPosix {
+	GnomeVFSFileACLBackend base;
+
+	gchar *filepath;
+
+	acl_t acl_info;
+	acl_t acl_default_info;
+
+	gboolean acl_info_modified;
+	gboolean acl_default_info_modified;	
+};
+
+
+static GnomeVFSResult
+aclerrno_to_vfserror (int acl_errno)
+{
+	switch (acl_errno) {
+	case ENOENT:			 
+	case EINVAL:       
+		return GNOME_VFS_ERROR_BAD_FILE;
+	case EACCES:     
+		return GNOME_VFS_ERROR_ACCESS_DENIED;
+	case ENAMETOOLONG: 
+		return GNOME_VFS_ERROR_NAME_TOO_LONG;
+	case EPERM:
+		return GNOME_VFS_ERROR_NOT_PERMITTED;
+	case ENOSPC:
+		return GNOME_VFS_ERROR_NO_SPACE;
+	case EROFS:
+		return GNOME_VFS_ERROR_READ_ONLY_FILE_SYSTEM;
+	default:
+		break;
+	}
+	
+	return GNOME_VFS_ERROR_GENERIC;
+}
+
+
+static void
+set_permset (acl_permset_t permset, mode_t perm)
+{
+        if (perm & CMD_PERM_READ)
+                acl_add_perm (permset, ACL_READ);
+        else
+                acl_delete_perm (permset, ACL_READ);
+	   
+        if (perm & CMD_PERM_WRITE)
+                acl_add_perm (permset, ACL_WRITE);
+        else
+                acl_delete_perm (permset, ACL_WRITE);
+	   
+        if (perm & CMD_PERM_EXECUTE)
+                acl_add_perm (permset, ACL_EXECUTE);
+        else
+                acl_delete_perm (permset, ACL_EXECUTE);
+}
+
+
+static int
+resolve_id (char *id)
+{
+	glong  val;
+	char  *end;
+
+        val = strtol (id, &end, 0);
+	
+	if (end == id || errno == ERANGE)
+		return -1;
+
+	if (val < (glong) - G_MAXINT || val > (glong) G_MAXINT)
+		return -1;
+	
+	return val;
+}
+
+
+static int
+parse_acl_str (const gchar *acl_str, acl_tag_t *type, uid_t *id, mode_t *perm, gboolean *is_default)
+{
+	gchar **parts;
+	gchar  *id_str;
+	gchar  *kind;
+	gchar  *value;
+	gchar  *tmp;
+	guint   i;
+
+	/* Split it */
+	parts = g_strsplit (acl_str, ":", 0);
+
+	/* Check the pieces */
+	for (i=0; parts[i] != NULL; i++);
+	if ((i > 4) || (i < 3)) 
+		goto error;
+	
+	/* Check if there is an extra entry */
+	i = 0;
+	*is_default = FALSE;
+	if ((strcasecmp (parts[0], "d") == 0) ||
+	    (strcasecmp (parts[0], "default") == 0))
+	{
+		i++;
+		*is_default = TRUE;
+	}
+
+	/* Assign each chunck */
+	kind   = parts[i++];
+	id_str = parts[i++];
+	value  = parts[i++];
+
+	if (parts[i] != NULL)
+		goto error;
+	
+	/* Parse them */
+	if ((strcasecmp (kind, "u") == 0) || 
+	    (strcasecmp (kind, "user") == 0)) {
+		*type = ACL_USER;
+		
+		*id = resolve_id (id_str);
+		if (*id == -1) {
+			struct passwd *passwd;
+
+			passwd = getpwnam(id_str);
+			if (passwd == NULL) goto error;
+
+			*id = passwd->pw_uid;
+		}
+	}
+
+	else if ((strcasecmp (kind, "g") == 0) || 
+		 (strcasecmp (kind, "group") == 0)) {
+		*type = ACL_GROUP;
+
+		*id = resolve_id (id_str);
+		if (*id == -1) {
+			struct group *group;
+			
+			group = getgrnam (id_str);
+			if (group == NULL) goto error;
+			
+			*id = group->gr_gid;
+		}
+	}
+
+	else if ((strcasecmp (kind, "o") == 0) || 
+		 (strcasecmp (kind, "other") == 0)) {
+		*type = ACL_OTHER;
+
+		if (strlen(id_str) >= 1)
+			goto error;
+	}
+	
+	/* Parse permissions */
+	*perm = 0;
+	for (tmp = value; *tmp; tmp++) {
+		if (*tmp == 'r')
+			*perm |= CMD_PERM_READ;
+		else if (*tmp == 'w')
+			*perm |= CMD_PERM_WRITE;
+		else if (*tmp == 'x')
+			*perm |= CMD_PERM_EXECUTE;
+	}
+
+	/* Clean up and return */
+	g_strfreev (parts);
+	return 0;
+
+error:
+	g_strfreev (parts);
+	return 1;
+}
+
+
+static acl_entry_t
+find_entry (acl_t acl, acl_tag_t type, id_t id)
+{
+        acl_entry_t  ent;
+        acl_tag_t    e_type;
+        id_t        *e_id_p;
+	
+        if (acl_get_entry(acl, ACL_FIRST_ENTRY, &ent) != 1)
+                return NULL;
+	
+        for(;;) {
+                acl_get_tag_type(ent, &e_type);
+                if (type == e_type) {
+                        if (id == ACL_UNDEFINED_ID) 
+                                return ent;
+
+			e_id_p = acl_get_qualifier(ent);
+
+			if (e_id_p == NULL)
+				return NULL;
+
+			if (*e_id_p == id) {
+				acl_free(e_id_p);
+				return ent;
+			}
+
+			acl_free(e_id_p);
+                }
+
+                if (acl_get_entry(acl, ACL_NEXT_ENTRY, &ent) != 1)
+                        return NULL;
+        }
+}
+
+
+static int
+clone_entry (acl_t  from_acl, acl_tag_t from_type,
+	     acl_t *to_acl,   acl_tag_t to_type)
+{
+        acl_entry_t from_entry;
+	acl_entry_t to_entry;
+
+        from_entry = find_entry(from_acl, from_type, ACL_UNDEFINED_ID);
+        if (from_entry == NULL) return 1;
+
+	if (acl_create_entry(to_acl, &to_entry) != 0)
+		return -1;
+
+	acl_copy_entry(to_entry, from_entry);
+	acl_set_tag_type(to_entry, to_type);
+	   
+	return 0;
+}
+
+
+static GnomeVFSResult 
+_free (GnomeVFSFileACLBackendPosix *aclb)
+{
+	if (aclb->filepath != NULL)
+		g_free (aclb->filepath);
+
+	if (aclb->acl_info != NULL)
+		acl_free (aclb->acl_info);
+	   
+	if (aclb->acl_default_info != NULL)
+		acl_free (aclb->acl_default_info);
+	   
+	return _gnome_vfs_file_acl_backend_free_base ((GnomeVFSFileACLBackend *)aclb);
+}
+
+
+static GnomeVFSResult 
+_add (GnomeVFSFileACLBackendPosix *aclb, const gchar *acl_str)
+{
+	int           re;
+	acl_t         acl_obj   = NULL;
+	acl_entry_t   new_entry = NULL;
+	acl_permset_t permset   = NULL;
+
+	acl_tag_t     type;
+	uid_t         id;
+	mode_t        perm;
+	gboolean      is_default;
+
+	/* Parse string
+	 */
+	re = parse_acl_str (acl_str, &type, &id, &perm, &is_default);
+	if (re != 0)
+		return GNOME_VFS_ERROR_NOT_FOUND;
+	
+	/* Pick up the right one */
+	acl_obj = (is_default) ? aclb->acl_default_info : aclb->acl_info;
+
+	if (acl_obj == NULL)
+		return GNOME_VFS_ERROR_NOT_FOUND;
+
+	/* Add the entry
+	 */
+	new_entry = find_entry (acl_obj, type, id);
+	if (new_entry == NULL) {
+		/* new */
+		if (is_default)
+			re = acl_create_entry (&aclb->acl_default_info, &new_entry);
+		else 
+			re = acl_create_entry (&aclb->acl_info, &new_entry);
+		if (re != 0) return aclerrno_to_vfserror (errno);
+
+		/* it might be a new object */
+		acl_obj = (is_default) ? aclb->acl_default_info : aclb->acl_info;
+
+		/* e_tag */
+		re = acl_set_tag_type (new_entry, type);
+		if (re != 0) return aclerrno_to_vfserror (errno);
+		
+		/* e_id */
+		re = acl_set_qualifier (new_entry, &id);
+		if (re != 0) return aclerrno_to_vfserror (errno);
+	}
+
+	/* e_perm */
+	re = acl_get_permset (new_entry, &permset);
+	if (re != 0) return aclerrno_to_vfserror (errno);
+	set_permset (permset, perm);
+
+	/* fix it up: default */
+	if (is_default) {
+		if (! find_entry (aclb->acl_default_info, ACL_USER_OBJ, ACL_UNDEFINED_ID)) {
+			clone_entry (aclb->acl_info, ACL_USER_OBJ, &aclb->acl_default_info, ACL_USER_OBJ);
+		}
+
+		if (! find_entry (aclb->acl_default_info, ACL_GROUP_OBJ, ACL_UNDEFINED_ID)) {
+			clone_entry (aclb->acl_info, ACL_GROUP_OBJ, &aclb->acl_default_info, ACL_GROUP_OBJ);
+		}
+
+		if (! find_entry (aclb->acl_default_info, ACL_OTHER, ACL_UNDEFINED_ID)) {
+			clone_entry (aclb->acl_info, ACL_OTHER, &aclb->acl_default_info, ACL_OTHER);
+		}
+	}
+
+	/* fix it up: access + default */
+	if (acl_equiv_mode (acl_obj, NULL) != 0) {
+		if (! find_entry (acl_obj, ACL_MASK, ACL_UNDEFINED_ID)) {			
+			clone_entry (acl_obj, ACL_GROUP_OBJ, &acl_obj, ACL_MASK);
+		}
+
+		acl_obj = (is_default) ? aclb->acl_default_info : aclb->acl_info;
+
+		re = acl_calc_mask (&acl_obj);
+		if (re != 0) return aclerrno_to_vfserror (errno);
+	}
+
+	
+	if (is_default)
+		aclb->acl_default_info_modified = TRUE;
+	else
+		aclb->acl_info_modified = TRUE;
+
+	return GNOME_VFS_OK;
+}
+
+
+static GnomeVFSResult 
+_del (GnomeVFSFileACLBackendPosix *aclb, const gchar *acl_str)
+{
+	acl_t         acl_obj;
+	guint         re;
+	acl_entry_t   entry;
+
+	acl_tag_t     type;
+	uid_t         id;
+	mode_t        perm;
+	gboolean      is_default;
+
+	/* Parse string
+	 */
+	re = parse_acl_str (acl_str, &type, &id, &perm, &is_default);
+	if (re != 0)
+		return GNOME_VFS_ERROR_NOT_FOUND;
+	
+	/* Pick up the right one */
+	acl_obj = (is_default) ? aclb->acl_default_info : aclb->acl_info;
+
+	if (acl_obj == NULL)
+		return GNOME_VFS_ERROR_NOT_FOUND;
+
+	entry = find_entry (acl_obj, type, id);
+	if (entry == NULL) return GNOME_VFS_ERROR_NOT_FOUND;
+
+	acl_delete_entry (acl_obj, entry);
+
+	if (is_default)
+		aclb->acl_default_info_modified = TRUE;
+	else
+		aclb->acl_info_modified = TRUE;
+
+	return GNOME_VFS_OK;
+}
+
+
+static GnomeVFSResult 
+_is_valid (GnomeVFSFileACLBackendPosix *aclb, const gchar *acl_str)
+{
+	return GNOME_VFS_OK;
+}
+
+
+static GnomeVFSResult 
+_read (GnomeVFSFileACLBackendPosix *aclb, const gchar *filepath)
+{
+	aclb->filepath = g_strdup (filepath);
+
+	aclb->acl_info = acl_get_file (filepath, ACL_TYPE_ACCESS);
+	aclb->acl_default_info = acl_get_file (filepath, ACL_TYPE_DEFAULT);
+	
+	return GNOME_VFS_OK;
+}
+
+
+static GnomeVFSResult 
+_commit (GnomeVFSFileACLBackendPosix *aclb)
+{
+	gint ret;
+
+	if (aclb->filepath == NULL)
+		return GNOME_VFS_ERROR_GENERIC;
+	
+	if ((aclb->acl_info == NULL) &&
+	    (aclb->acl_default_info == NULL))
+		return GNOME_VFS_OK;
+	
+	if (aclb->acl_info_modified && (aclb->acl_info != NULL)) {
+		ret = acl_set_file (aclb->filepath, ACL_TYPE_ACCESS, aclb->acl_info);
+		if (ret < 0) return aclerrno_to_vfserror (errno);
+	}
+
+	if (aclb->acl_default_info_modified && (aclb->acl_default_info != NULL)) {
+		ret = acl_set_file (aclb->filepath, ACL_TYPE_DEFAULT, aclb->acl_default_info);
+		if (ret < 0) return aclerrno_to_vfserror (errno);
+	}
+
+	return GNOME_VFS_OK;
+}
+
+
+static gchar *  
+_get_text (GnomeVFSFileACLBackendPosix *aclb)
+{
+	return acl_to_any_text (aclb->acl_info, NULL, ',', 0);
+}
+
+
+static const gchar *  
+_get_support (GnomeVFSFileACLBackendPosix *aclb)
+{
+	return "d:ugo:rwx";
+}
+
+
+GnomeVFSFileACLBackend * 
+gnome_vfs_file_acl_backend_posix_new (void)
+{
+	GnomeVFSFileACLBackendPosix *new;
+	GnomeVFSFileACLBackend      *backend;
+
+	new = g_new0 (GnomeVFSFileACLBackendPosix, 1);	   
+	backend = (GnomeVFSFileACLBackend *)new;
+
+	new->filepath = NULL;
+
+	new->acl_info_modified         = FALSE;
+	new->acl_default_info_modified = FALSE;
+
+	backend->add         = (void *) _add;
+	backend->del         = (void *) _del;
+	backend->is_valid    = (void *) _is_valid;
+	backend->read        = (void *) _read;
+	backend->get_text    = (void *) _get_text;
+	backend->commit      = (void *) _commit;
+	backend->get_support = (void *) _get_support;
+	backend->free        = (void *) _free;
+	   
+	return backend;
+}
+
+
--- /dev/null	2005-11-09 07:48:09.336509500 +0000
+++ libgnomevfs/gnome-vfs-file-acl-backend-posix.h	2005-11-03 15:50:05.000000000 +0000
@@ -0,0 +1,39 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-vfs-file-acl.h - Handling of ACL file information for the GNOME
+   Virtual File System.
+
+   Copyright (C) 2005 Sun Microsystems
+
+   The Gnome Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Alvaro Lopez Ortega <alvaro@sun.com>
+*/
+
+#ifndef GNOME_VFS_FILE_ACL_BACKEND_POSIX_H
+#define GNOME_VFS_FILE_ACL_BACKEND_POSIX_H
+
+#include <libgnomevfs/gnome-vfs-file-acl-backend.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GnomeVFSFileACLBackendPosix GnomeVFSFileACLBackendPosix;
+
+GnomeVFSFileACLBackend * gnome_vfs_file_acl_backend_posix_new (void);
+
+G_END_DECLS
+
+#endif /* GNOME_VFS_FILE_ACL_BACKEND_POSIX_H */
+
--- /dev/null	2005-11-09 07:48:09.336509500 +0000
+++ libgnomevfs/gnome-vfs-file-acl-backend.c	2005-11-09 11:36:46.000000000 +0000
@@ -0,0 +1,115 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-vfs-file-acl.h - Handling of ACL file information for the GNOME
+   Virtual File System.
+
+   Copyright (C) 2005 Sun Microsystems
+
+   The Gnome Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Alvaro Lopez Ortega <alvaro@sun.com>
+*/
+
+#include "gnome-vfs-file-acl-backend.h"
+
+
+
+GnomeVFSResult   
+_gnome_vfs_file_acl_backend_free_base (GnomeVFSFileACLBackend *aclb)
+{
+	g_free (aclb);
+	return GNOME_VFS_OK;
+}
+
+
+GnomeVFSResult    
+gnome_vfs_file_acl_backend_free (GnomeVFSFileACLBackend *aclb)
+{
+	if (aclb->free == NULL)
+		return GNOME_VFS_ERROR_GENERIC;
+
+	return aclb->free (aclb);
+}
+
+
+GnomeVFSResult    
+gnome_vfs_file_acl_backend_add (GnomeVFSFileACLBackend *aclb, const gchar *acl_str)
+{
+	if (aclb->add == NULL)
+		return GNOME_VFS_ERROR_GENERIC;
+
+	return aclb->add (aclb, acl_str);
+}
+
+
+GnomeVFSResult    
+gnome_vfs_file_acl_backend_del (GnomeVFSFileACLBackend *aclb, const gchar *acl_str)
+{
+	if (aclb->del == NULL)
+		return GNOME_VFS_ERROR_GENERIC;
+
+	return aclb->del (aclb, acl_str);
+}
+
+
+GnomeVFSResult    
+gnome_vfs_file_acl_backend_is_valid (GnomeVFSFileACLBackend *aclb, const gchar *acl_str)
+{
+	if (aclb->is_valid == NULL)
+		return GNOME_VFS_ERROR_GENERIC;
+
+	return aclb->is_valid (aclb, acl_str);
+}
+
+
+GnomeVFSResult
+gnome_vfs_file_acl_backend_read (GnomeVFSFileACLBackend *aclb, const gchar *filepath)
+{
+	if (aclb->read == NULL)
+		return GNOME_VFS_ERROR_GENERIC;
+
+	return aclb->read (aclb, filepath);
+}
+
+
+gchar * 
+gnome_vfs_file_acl_backend_get_text (GnomeVFSFileACLBackend *aclb)
+{
+	if (aclb->get_text == NULL)
+		return NULL;
+
+	return aclb->get_text (aclb);
+}
+
+
+GnomeVFSResult    
+gnome_vfs_file_acl_backend_commit (GnomeVFSFileACLBackend *aclb)
+{
+	if (aclb->commit == NULL)
+		return GNOME_VFS_ERROR_GENERIC;
+
+	return aclb->commit (aclb);
+}
+
+
+const gchar * 
+gnome_vfs_file_acl_backend_get_support (GnomeVFSFileACLBackend *aclb)
+{
+	if (aclb->get_support == NULL)
+		return NULL;
+
+	return aclb->get_support (aclb);
+}
+
--- /dev/null	2005-11-09 07:48:09.336509500 +0000
+++ libgnomevfs/gnome-vfs-file-acl-backend.h	2005-11-09 11:36:13.000000000 +0000
@@ -0,0 +1,70 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-vfs-file-acl.h - Handling of ACL file information for the GNOME
+   Virtual File System.
+
+   Copyright (C) 2005 Sun Microsystems
+
+   The Gnome Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Alvaro Lopez Ortega <alvaro@sun.com>
+*/
+
+#ifndef GNOME_VFS_FILE_ACL_BACKEND_H
+#define GNOME_VFS_FILE_ACL_BACKEND_H
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <libgnomevfs/gnome-vfs-result.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+
+G_BEGIN_DECLS
+
+typedef struct _GnomeVFSFileACLBackend GnomeVFSFileACLBackend;
+
+struct _GnomeVFSFileACLBackend {
+	GnomeVFSResult (*add)         (GnomeVFSFileACLBackend *aclb, const gchar *acl_str);
+	GnomeVFSResult (*del)         (GnomeVFSFileACLBackend *aclb, const gchar *acl_str);
+	GnomeVFSResult (*is_valid)    (GnomeVFSFileACLBackend *aclb, const gchar *acl_str);
+	GnomeVFSResult (*read)        (GnomeVFSFileACLBackend *aclb, const gchar *filepath);
+	gchar       *  (*get_text)    (GnomeVFSFileACLBackend *aclb);
+	GnomeVFSResult (*commit)      (GnomeVFSFileACLBackend *aclb);	   
+	const gchar *  (*get_support) (GnomeVFSFileACLBackend *aclb);
+	GnomeVFSResult (*free)        (GnomeVFSFileACLBackend *aclb);
+};
+
+
+
+GnomeVFSResult    gnome_vfs_file_acl_backend_free        (GnomeVFSFileACLBackend *aclb);
+
+GnomeVFSResult    gnome_vfs_file_acl_backend_add         (GnomeVFSFileACLBackend *aclb, const gchar *acl_str);
+GnomeVFSResult    gnome_vfs_file_acl_backend_del         (GnomeVFSFileACLBackend *aclb, const gchar *acl_str);
+GnomeVFSResult    gnome_vfs_file_acl_backend_is_valid    (GnomeVFSFileACLBackend *aclb, const gchar *acl_str);
+
+GnomeVFSResult    gnome_vfs_file_acl_backend_read        (GnomeVFSFileACLBackend *aclb, const gchar *filepath);
+gchar           * gnome_vfs_file_acl_backend_get_text    (GnomeVFSFileACLBackend *aclb);
+
+GnomeVFSResult    gnome_vfs_file_acl_backend_commit      (GnomeVFSFileACLBackend *aclb);
+const gchar     * gnome_vfs_file_acl_backend_get_support (GnomeVFSFileACLBackend *aclb);
+
+
+/* Protected methods
+ */
+GnomeVFSResult   _gnome_vfs_file_acl_backend_free_base  (GnomeVFSFileACLBackend *aclb);
+
+G_END_DECLS
+
+#endif /* GNOME_VFS_FILE_ACL_BACKEND_H */
--- /dev/null	2005-11-09 07:48:09.336509500 +0000
+++ libgnomevfs/gnome-vfs-file-acl.c	2005-11-09 11:41:31.000000000 +0000
@@ -0,0 +1,166 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-vfs-file-acl.h - Handling of ACL file information for the GNOME
+   Virtual File System.
+
+   Copyright (C) 2005 Sun Microsystems
+
+   The Gnome Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Alvaro Lopez Ortega <alvaro@sun.com>
+*/
+
+#include <config.h>
+
+#include <errno.h>
+#include <string.h>
+
+#include "gnome-vfs-file-acl.h"
+#include "gnome-vfs-file-acl-backend.h"
+#include "gnome-vfs-file-acl-backend-posix.h"
+
+
+struct _GnomeVFSFileACL {
+	GnomeVFSFileACLBackend *handler;
+	const char             *support;
+};
+
+
+GnomeVFSFileACL * 
+gnome_vfs_file_acl_new (void)
+{
+        GnomeVFSFileACL *new;
+
+        new = g_new0 (GnomeVFSFileACL, 1);
+        return new;
+}
+
+
+void
+gnome_vfs_file_acl_free (GnomeVFSFileACL *acl)
+{
+	if (acl->support != NULL)
+		g_free ((gchar *)acl->support);
+
+        g_free (acl);
+}
+
+
+GnomeVFSFileACL * 
+gnome_vfs_file_acl_dup (GnomeVFSFileACL *acl)
+{
+        GnomeVFSFileACL *target;
+
+        target = g_new0 (GnomeVFSFileACL, 1);
+        memcpy (target, acl, sizeof(GnomeVFSFileACL));
+
+	if (acl->support != NULL)
+		target->support = g_strdup (acl->support);
+
+        return target;
+}
+
+
+static GnomeVFSFileACLBackend *
+create_handler (GnomeVFSFileACL *acl, const gchar *filepath)
+{
+	/* It has to look for the right backend:
+	 * By the moment the only supported backend is POSIX..
+	 */
+	return (GnomeVFSFileACLBackend *)gnome_vfs_file_acl_backend_posix_new ();
+}
+
+
+GnomeVFSResult    
+gnome_vfs_file_acl_add (GnomeVFSFileACL *acl, const gchar *acl_str)
+{	
+	GnomeVFSResult re;
+ 
+	g_return_val_if_fail (acl->handler != NULL, GNOME_VFS_ERROR_GENERIC);
+
+	re = gnome_vfs_file_acl_backend_is_valid (acl->handler, acl_str);
+	if (re != GNOME_VFS_OK) return re;
+	
+	return gnome_vfs_file_acl_backend_add (acl->handler, acl_str);
+}
+
+
+GnomeVFSResult
+gnome_vfs_file_acl_del (GnomeVFSFileACL *acl, const gchar *acl_str)
+{
+	GnomeVFSResult re;
+
+	g_return_val_if_fail (acl->handler != NULL, GNOME_VFS_ERROR_GENERIC);
+
+	re = gnome_vfs_file_acl_backend_is_valid (acl->handler, acl_str);
+	if (re != GNOME_VFS_OK) return re;
+
+	return gnome_vfs_file_acl_backend_del (acl->handler, acl_str);
+}
+
+
+GnomeVFSResult    
+gnome_vfs_file_acl_modify (GnomeVFSFileACL *acl, const gchar *acl_old, const gchar *acl_str)
+{
+	GnomeVFSResult ret;
+
+	g_return_val_if_fail (acl->handler != NULL, GNOME_VFS_ERROR_GENERIC);
+
+	ret = gnome_vfs_file_acl_del (acl, acl_old);
+	if (ret != GNOME_VFS_OK) return ret;
+
+	return gnome_vfs_file_acl_add (acl, acl_str);
+}
+
+
+GnomeVFSResult
+gnome_vfs_file_acl_read (GnomeVFSFileACL *acl, const gchar *filepath)
+{
+	if (acl->handler != NULL) {
+		gnome_vfs_file_acl_backend_free (acl->handler);
+		acl->handler = NULL;
+	}
+
+	acl->handler = create_handler (acl, filepath);
+	if (acl->handler == NULL) return GNOME_VFS_ERROR_GENERIC;
+
+	return gnome_vfs_file_acl_backend_read (acl->handler, filepath);
+}
+
+
+gchar * 
+gnome_vfs_file_acl_get_text (GnomeVFSFileACL *acl)
+{
+	g_return_val_if_fail (acl->handler != NULL, NULL);
+
+	return gnome_vfs_file_acl_backend_get_text (acl->handler);
+}
+
+
+GnomeVFSResult
+gnome_vfs_file_acl_commit (GnomeVFSFileACL *acl)
+{
+	g_return_val_if_fail (acl->handler != NULL, GNOME_VFS_ERROR_GENERIC);
+	return gnome_vfs_file_acl_backend_commit (acl->handler);
+}
+
+
+const gchar * 
+gnome_vfs_file_acl_get_support (GnomeVFSFileACL *acl)
+{
+	g_return_val_if_fail (acl->handler != NULL, NULL);
+	return gnome_vfs_file_acl_backend_get_support (acl->handler);
+}
+
--- /dev/null	2005-11-09 07:48:09.336509500 +0000
+++ libgnomevfs/gnome-vfs-file-acl.h	2005-11-09 11:03:46.000000000 +0000
@@ -0,0 +1,60 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* gnome-vfs-file-acl.h - Handling of ACL file information for the GNOME
+   Virtual File System.
+
+   Copyright (C) 2005 Sun Microsystems
+
+   The Gnome Library is free software; you can redistribute it and/or
+   modify it under the terms of the GNU Library General Public License as
+   published by the Free Software Foundation; either version 2 of the
+   License, or (at your option) any later version.
+
+   The Gnome Library 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
+   Library General Public License for more details.
+
+   You should have received a copy of the GNU Library General Public
+   License along with the Gnome Library; see the file COPYING.LIB.  If not,
+   write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+   Boston, MA 02111-1307, USA.
+
+   Author: Alvaro Lopez Ortega <alvaro@sun.com>
+*/
+
+#ifndef GNOME_VFS_FILE_ACL_H
+#define GNOME_VFS_FILE_ACL_H
+
+#include <unistd.h>
+#include <sys/types.h>
+
+#include <libgnomevfs/gnome-vfs-result.h>
+#include <libgnomevfs/gnome-vfs-uri.h>
+
+G_BEGIN_DECLS
+
+/**
+ * GnomeVFSFileACL:
+ * 
+ * The GnomeVFSFileACL structure contains information about a file ACL.
+ **/
+typedef struct _GnomeVFSFileACL GnomeVFSFileACL;
+
+
+GnomeVFSFileACL * gnome_vfs_file_acl_new         (void);
+void              gnome_vfs_file_acl_free        (GnomeVFSFileACL *acl);
+GnomeVFSFileACL * gnome_vfs_file_acl_dup         (GnomeVFSFileACL *acl);
+
+GnomeVFSResult    gnome_vfs_file_acl_add         (GnomeVFSFileACL *acl, const gchar *acl_str);
+GnomeVFSResult    gnome_vfs_file_acl_del         (GnomeVFSFileACL *acl, const gchar *acl_str);
+GnomeVFSResult    gnome_vfs_file_acl_modify      (GnomeVFSFileACL *acl, const gchar *acl_old, const gchar *acl_str);
+
+GnomeVFSResult    gnome_vfs_file_acl_read        (GnomeVFSFileACL *acl, const gchar *filepath);
+gchar           * gnome_vfs_file_acl_get_text    (GnomeVFSFileACL *acl);
+
+GnomeVFSResult    gnome_vfs_file_acl_commit      (GnomeVFSFileACL *acl);
+const gchar     * gnome_vfs_file_acl_get_support (GnomeVFSFileACL *acl);
+
+G_END_DECLS
+
+#endif /* GNOME_VFS_FILE_ACL_H */
