Hi guys,

  I've just realized that I forgot to apply a quite important patch to
  the ACL branch that we created before the 2.16 release.

  The patch makes the VFS to check the ACL entries - if present - when
  it calculates a file access permission.

  Right now, Nautilus is misbehaving on ACL enabled file systems
  because the gnome-vfs file module only checks the file permissions
  without checking the ACL entries.

  The patch is attach.  Is it okay to commit to HEAD?

--
Greetings, alo.
Index: ChangeLog
===================================================================
RCS file: /cvs/gnome/gnome-vfs/ChangeLog,v
retrieving revision 1.2545
diff -u -r1.2545 ChangeLog
--- ChangeLog   1 Dec 2006 22:26:16 -0000       1.2545
+++ ChangeLog   13 Dec 2006 13:51:49 -0000
@@ -1,3 +1,23 @@
+2006-12-13  Alvaro Lopez Ortega  <[EMAIL PROTECTED]>
+
+       * acinclude.m4: Added new macros to detect the type of the
+       getpwnam_r() and getgrnam_r() system calls.
+
+       * configure.in: Updated to use the new FW_CHECK_GRP and
+       FW_CHECK_PW macros.
+
+       * modules/file-method-acl.c (secure_getpwnam, secure_getgrnam):
+       Added to new functions that ensure thread safeness.
+
+       * modules/file-method-acl.h,
+       modules/file-method-acl.c (get_access_info_acl): This new
+       functions checks the ACL entries in order to fill up the file info
+       access information.
+
+       * modules/file-method.c (get_access_info): It has to check the ACL
+       information if present. It fixes some permission problems in
+       Nautilus when using ACL enabled file systems.
+       
 2006-12-01  Christian Neumair  <[EMAIL PROTECTED]>
 
        * libgnomevfs/gnome-vfs-unix-mounts.c:
Index: acinclude.m4
===================================================================
RCS file: /cvs/gnome/gnome-vfs/acinclude.m4,v
retrieving revision 1.10
diff -u -r1.10 acinclude.m4
--- acinclude.m4        26 Nov 2005 11:19:44 -0000      1.10
+++ acinclude.m4        13 Dec 2006 13:51:49 -0000
@@ -556,3 +556,89 @@
 
 
 dnl end of neon macros
+
+
+dnl
+dnl checks for password entry functions and header files
+dnl
+AC_DEFUN([FW_CHECK_PWD],
+[
+
+HAVE_GETPWNAM_R=""
+
+AC_MSG_CHECKING(for getpwnam_r with 5 parameters)
+AC_TRY_COMPILE([#include <pwd.h>
+#include <stdlib.h>],
+getpwnam_r(NULL,NULL,NULL,0,NULL);,AC_DEFINE(HAVE_GETPWNAM_R_5,1,Some systems 
have getpwnam_r) AC_DEFINE(HAVE_
+ETPWNAM_R,1,Some systems have getpwnam_r) AC_MSG_RESULT(yes); 
HAVE_GETPWNAM_R="yes", AC_MSG_RESULT(no))
+
+if ( test -z "$HAVE_GETPWNAM_R" )
+then
+       AC_MSG_CHECKING(for getpwnam_r with 4 parameters)
+       AC_TRY_COMPILE([#include <pwd.h>
+#include <stdlib.h>],
+getpwnam_r(NULL,NULL,NULL,0);,AC_DEFINE(HAVE_GETPWNAM_R_4,1,Some systems have 
getpwnam_r) AC_DEFINE(HAVE_GETPW
+AM_R,1,Some systems have getpwnam_r) AC_MSG_RESULT(yes), AC_MSG_RESULT(no))
+fi
+
+HAVE_GETPWUID_R=""
+
+AC_MSG_CHECKING(for getpwuid_r with 5 parameters)
+AC_TRY_COMPILE([#include <pwd.h>
+#include <stdlib.h>],
+getpwuid_r(0,NULL,NULL,0,NULL);,AC_DEFINE(HAVE_GETPWUID_R_5,1,Some systems 
have getpwuid_r) AC_DEFINE(HAVE_GET
+WUID_R,1,Some systems have getpwuid_r) AC_MSG_RESULT(yes); 
HAVE_GETPWUID_R="yes", AC_MSG_RESULT(no))
+
+if ( test -z "$HAVE_GETPWUID_R" )
+then
+       AC_MSG_CHECKING(for getpwuid_r with 4 parameters)
+       AC_TRY_COMPILE([#include <pwd.h>
+#include <stdlib.h>],
+getpwuid_r(0,NULL,NULL,0);,AC_DEFINE(HAVE_GETPWUID_R_4,1,Some systems have 
getpwuid_r) AC_DEFINE(HAVE_GETPWUID
+R,1,Some systems have getpwuid_r) AC_MSG_RESULT(yes), AC_MSG_RESULT(no))
+fi
+
+])
+
+
+dnl
+dnl checks for group entry functions and header files
+dnl
+AC_DEFUN([FW_CHECK_GRP],
+[
+
+HAVE_GETGRNAM_R=""
+
+AC_MSG_CHECKING(for getgrnam_r with 5 parameters)
+AC_TRY_COMPILE([#include <grp.h>
+#include <stdlib.h>],
+getgrnam_r(NULL,NULL,NULL,0,NULL);,AC_DEFINE(HAVE_GETGRNAM_R_5,1,Some systems 
have getgrnam_r) AC_DEFINE(HAVE_
+ETGRNAM_R,1,Some systems have getgrnam_r) AC_MSG_RESULT(yes); 
HAVE_GETGRNAM_R="yes", AC_MSG_RESULT(no))
+
+if ( test -z "$HAVE_GETGRNAM_R" )
+then
+       AC_MSG_CHECKING(for getgrnam_r with 4 parameters)
+       AC_TRY_COMPILE([#include <grp.h>
+#include <stdlib.h>],
+getgrnam_r(NULL,NULL,NULL,0);,AC_DEFINE(HAVE_GETGRNAM_R_4,1,Some systems have 
getgrnam_r) AC_DEFINE(HAVE_GETGR
+AM_R,1,Some systems have getgrnam_r) AC_MSG_RESULT(yes), AC_MSG_RESULT(no))
+fi
+
+HAVE_GETGRGID_R=""
+
+AC_MSG_CHECKING(for getgrgid_r with 5 parameters)
+AC_TRY_COMPILE([#include <grp.h>
+#include <stdlib.h>],
+getgrgid_r(0,NULL,NULL,0,NULL);,AC_DEFINE(HAVE_GETGRGID_R_5,1,Some systems 
have getgrgid_r) AC_DEFINE(HAVE_GET
+RGID_R,1,Some systems have getgrgid_r) AC_MSG_RESULT(yes); 
HAVE_GETGRGID_R="yes", AC_MSG_RESULT(no))
+
+if ( test -z "$HAVE_GETGRGID_R" )
+then
+       AC_MSG_CHECKING(for getgrgid_r with 4 parameters)
+       AC_TRY_COMPILE([#include <grp.h>
+#include <stdlib.h>],
+getgrgid_r(0,NULL,NULL,0);,AC_DEFINE(HAVE_GETGRGID_R_4,1,Some systems have 
getgrgid_r) AC_DEFINE(HAVE_GETGRGID
+R,1,Some systems have getgrgid_r) AC_MSG_RESULT(yes), AC_MSG_RESULT(no))
+fi
+
+])
Index: configure.in
===================================================================
RCS file: /cvs/gnome/gnome-vfs/configure.in,v
retrieving revision 1.451
diff -u -r1.451 configure.in
--- configure.in        23 Nov 2006 12:58:57 -0000      1.451
+++ configure.in        13 Dec 2006 13:51:49 -0000
@@ -1092,52 +1092,10 @@
     AC_CHECK_FUNCS(acl_extended_file)
     
     AC_CHECK_HEADERS([pwd.h])
-    if test "$ac_cv_header_pwd_h" = "yes"; then
-               AC_CACHE_CHECK([for posix getpwuid_r],
-                       ac_cv_func_posix_getpwuid_r,
-                       [AC_TRY_RUN([
-#include <errno.h>
-#include <pwd.h>
-int main () { 
-    char buffer[10000];
-    struct passwd pwd, *pwptr = &pwd;
-    int error;
-    errno = 0;
-    error = getpwuid_r (0, &pwd, buffer, 
-                        sizeof (buffer), &pwptr);
-   return (error < 0 && errno == ENOSYS) 
-          || error == ENOSYS; 
-}                               ],
-                               [ac_cv_func_posix_getpwuid_r=yes],
-                               [ac_cv_func_posix_getpwuid_r=no])])
-               dnl GLIB_ASSERT_SET(ac_cv_func_posix_getpwuid_r)
-               if test "$ac_cv_func_posix_getpwuid_r" = yes; then
-                       AC_DEFINE(HAVE_POSIX_GETPWUID_R,1,
-                               [Have POSIX function getpwuid_r])
-               else
-                       AC_CACHE_CHECK([for nonposix getpwuid_r],
-                               ac_cv_func_nonposix_getpwuid_r,
-                               [AC_TRY_LINK([#include <pwd.h>],
-                                       [char buffer[10000];
-                                       struct passwd pwd;
-                                       getpwuid_r (0, &pwd, buffer, 
-                                                       sizeof (buffer));],
-                                       [ac_cv_func_nonposix_getpwuid_r=yes],
-                                       [ac_cv_func_nonposix_getpwuid_r=no])])
-                       dnl GLIB_ASSERT_SET(ac_cv_func_nonposix_getpwuid_r)
-                       if test "$ac_cv_func_nonposix_getpwuid_r" = yes; then
-                               AC_DEFINE(HAVE_NONPOSIX_GETPWUID_R,1,
-                                       [Have non-POSIX function getpwuid_r])
-                       fi
-               fi
-       fi 
+    FW_CHECK_PWD
 
-       AC_CHECK_HEADERS([grp.h])
-
-       AC_CHECK_FUNCS(getgrgid_r)
-       AC_CHECK_FUNCS(getgrnam_r)
-       AC_CHECK_FUNCS(getpwnam_r)
-       
+    AC_CHECK_HEADERS([grp.h])
+    FW_CHECK_GRP      
 fi
 
 AC_SUBST(ACL_LIBS)
Index: modules/file-method-acl.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/file-method-acl.c,v
retrieving revision 1.4
diff -u -r1.4 file-method-acl.c
--- modules/file-method-acl.c   23 Jul 2006 10:28:24 -0000      1.4
+++ modules/file-method-acl.c   13 Dec 2006 13:51:49 -0000
@@ -1013,3 +1013,225 @@
 }
 
 
+#ifndef HAVE_GETPWNAM_R
+G_LOCK_DEFINE (getpwnam_lock);
+#endif
+
+static int
+secure_getpwnam (const char *name, struct passwd *pwbuf, char *buf, size_t 
buflen)
+{
+#ifndef HAVE_GETPWNAM_R
+       size_t         pw_name_len   = 0;
+       size_t         pw_passwd_len = 0;
+       size_t         pw_gecos_len  = 0;
+       size_t         pw_dir_len    = 0;
+       size_t         pw_shell_len  = 0;
+       char          *ptr;
+       struct passwd *tmp;
+
+       G_LOCK(getpwnam_lock);
+
+       tmp = getpwnam (name);
+       if (tmp == NULL) 
+               return errno;
+
+       if (tmp->pw_name)   pw_name_len   = strlen(tmp->pw_name);
+       if (tmp->pw_passwd) pw_passwd_len = strlen(tmp->pw_passwd);
+       if (tmp->pw_gecos)  pw_gecos_len  = strlen(tmp->pw_gecos);
+       if (tmp->pw_dir)    pw_dir_len    = strlen(tmp->pw_dir);
+       if (tmp->pw_shell)  pw_shell_len  = strlen(tmp->pw_shell);
+
+       if ((pw_name_len + pw_passwd_len + 
+            pw_gecos_len + pw_dir_len + pw_shell_len) > buflen)
+               return ERANGE;
+
+       memset (buf, 0, buflen);
+       ptr = buf;       
+
+       if (tmp->pw_name) {
+               memcpy (ptr, tmp->pw_name, pw_name_len);
+               pwbuf->pw_name = ptr;
+               ptr += pw_name_len + 1;
+       }
+
+       if (tmp->pw_passwd) {
+               memcpy (ptr, tmp->pw_passwd, pw_passwd_len);
+               pwbuf->pw_passwd = ptr;
+               ptr += pw_passwd_len + 1;
+       }
+
+       if (tmp->pw_gecos) {
+               memcpy (ptr, tmp->pw_gecos, pw_gecos_len);
+               pwbuf->pw_gecos = ptr;
+               ptr += pw_gecos_len + 1;
+       }
+
+       if (tmp->pw_dir) {
+               memcpy (ptr, tmp->pw_dir, pw_dir_len);
+               pwbuf->pw_dir = ptr;
+               ptr += pw_dir_len + 1;
+       }
+
+
+       if (tmp->pw_shell) {
+               memcpy (ptr, tmp->pw_shell, pw_shell_len);
+               pwbuf->pw_shell = ptr;
+               ptr += pw_shell_len + 1;
+       }
+
+       G_UNLOCK(getpwnam_lock);
+       return 0;
+
+#elif HAVE_GETPWNAM_R_5
+       struct passwd *tmp;
+
+       return getpwnam_r (name, pwbuf, buf, buflen, &tmp);
+
+#elif HAVE_GETPWNAM_R_4
+
+       return getpwnam_r (name, pwbuf, buf, buflen);
+#endif
+
+       return 0;
+}
+
+
+#ifndef HAVE_GETGRNAM_R
+G_LOCK_DEFINE (getgrnam_lock);
+#endif
+
+static int
+secure_getgrnam (const char *name, struct group *grbuf, char *buf, size_t 
buflen)
+{
+#ifndef HAVE_GETGRNAM_R
+       size_t        gr_name_len   = 0;
+       size_t        gr_passwd_len = 0;
+       char         *ptr;
+       struct group *tmp;
+
+       G_LOCK(getgrnam_lock);
+
+       tmp = getgrnam (name);
+       if (tmp == NULL) 
+               return errno;
+
+       if (tmp->gr_name)   gr_name_len   = strlen(tmp->gr_name);
+       if (tmp->gr_passwd) gr_passwd_len = strlen(tmp->gr_passwd);
+
+       if ((gr_name_len + gr_passwd_len) > buflen)
+               return ERANGE;
+
+       memset (buf, 0, buflen);
+       ptr = buf;
+
+       grbuf->gr_gid = tmp->gr_gid;
+
+       if (tmp->gr_name) {
+               memcpy (ptr, tmp->gr_name, gr_name_len);
+               grbuf->gr_name = ptr;
+               ptr += gr_name_len + 1;
+       }
+
+       if (tmp->gr_passwd) {
+               memcpy (ptr, tmp->gr_passwd, gr_passwd_len);
+               grbuf->gr_passwd = ptr;
+               ptr += gr_passwd_len + 1;
+       }
+
+       // TODO: Duplicate char **tmp->gr_mem
+
+       G_UNLOCK(getgrnam_lock);
+       return 0;
+
+#elif HAVE_GETGRNAM_R_5
+       struct group *tmp;
+
+       return getgrnam_r (name, grbuf, buf, buflen, &tmp);
+
+#elif HAVE_GETGRNAM_R_4
+
+       return getgrnam_r (name, grbuf, buf, buflen);
+#endif
+
+       return 0;
+}
+
+void
+get_access_info_acl (GnomeVFSFileInfo *file_info,
+                     const gchar      *full_name)
+{
+         GList *acls, *iter;
+         GnomeVFSACL *acl;
+
+         acls = gnome_vfs_acl_get_ace_list (file_info->acl);
+
+         for (iter = acls; iter; iter = iter->next) {
+               int            i, re;
+               const char    *id;
+               uid_t          uid;
+               gid_t          gid;
+               struct group  *group;
+               GnomeVFSACE   *ace;
+               int            sup_groups_num;
+               gid_t          sup_groups[NGROUPS_MAX];
+               struct passwd *passwd;
+               struct passwd  pwd;
+               struct group   grp;
+               char           buf[1024];
+
+               ace = iter->data;
+               
+               id = gnome_vfs_ace_get_id (ace);
+               if (id == NULL) continue;
+
+               /* User */
+               re = secure_getpwnam (id, &pwd, buf, 1024);
+               if (re == 0) {
+                       uid = passwd->pw_uid;
+               } else {
+                       errno = 0;
+                       uid = atoi (id);
+                       if (errno != 0) 
+                               continue;
+               } 
+
+               /* Group */
+               group = secure_getgrnam (id, &grp, buf, 1024);
+               if (group != NULL) {
+                       gid = group->gr_gid;
+               } else {
+                       errno = 0;
+                       gid = atoi (id);
+                       if (errno != 0) 
+                               continue;
+               }
+
+                /* Suplementary groups */
+                sup_groups_num = getgroups(NGROUPS_MAX, sup_groups);
+
+               if ((file_info->uid == uid) ||
+                    (file_info->gid == gid)) 
+                {
+                       if (gnome_vfs_ace_check_perm (ace,GNOME_VFS_ACL_READ))
+                               file_info->permissions |= 
GNOME_VFS_PERM_ACCESS_READABLE;
+                       if (gnome_vfs_ace_check_perm (ace,GNOME_VFS_ACL_WRITE))
+                               file_info->permissions |= 
GNOME_VFS_PERM_ACCESS_WRITABLE;
+                       if (gnome_vfs_ace_check_perm 
(ace,GNOME_VFS_ACL_EXECUTE))
+                               file_info->permissions |= 
GNOME_VFS_PERM_ACCESS_EXECUTABLE;
+               } 
+               
+
+               for (i = 0; i < sup_groups_num; i++) {
+                       if (gid == sup_groups[i]) {
+                               if (gnome_vfs_ace_check_perm 
(ace,GNOME_VFS_ACL_READ))
+                                       file_info->permissions |= 
GNOME_VFS_PERM_ACCESS_READABLE;
+                               if (gnome_vfs_ace_check_perm 
(ace,GNOME_VFS_ACL_WRITE))
+                                       file_info->permissions |= 
GNOME_VFS_PERM_ACCESS_WRITABLE;
+                               if (gnome_vfs_ace_check_perm 
(ace,GNOME_VFS_ACL_EXECUTE))
+                                       file_info->permissions |= 
GNOME_VFS_PERM_ACCESS_EXECUTABLE;
+                       }
+               }
+       }
+
+       gnome_vfs_acl_free_ace_list (acls);     
+}
Index: modules/file-method-acl.h
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/file-method-acl.h,v
retrieving revision 1.2
diff -u -r1.2 file-method-acl.h
--- modules/file-method-acl.h   8 Jun 2006 13:30:56 -0000       1.2
+++ modules/file-method-acl.h   13 Dec 2006 13:51:49 -0000
@@ -43,7 +43,9 @@
                             const GnomeVFSFileInfo *info,
                              GnomeVFSContext         *context);
 
-G_END_DECLS
+void           get_access_info_acl (GnomeVFSFileInfo *info,
+                                   const gchar      *path);
 
+G_END_DECLS
 
 #endif /*FILEACL_H*/
Index: modules/file-method.c
===================================================================
RCS file: /cvs/gnome/gnome-vfs/modules/file-method.c,v
retrieving revision 1.162
diff -u -r1.162 file-method.c
--- modules/file-method.c       17 Oct 2006 09:54:59 -0000      1.162
+++ modules/file-method.c       13 Dec 2006 13:51:49 -0000
@@ -858,6 +858,10 @@
                        }
                }
        }
+
+       if (file_info->acl) {
+               get_access_info_acl (file_info, full_name);
+       }
 #endif
 
      file_info->valid_fields |= GNOME_VFS_FILE_INFO_FIELDS_ACCESS;
_______________________________________________
gnome-vfs-list mailing list
[email protected]
http://mail.gnome.org/mailman/listinfo/gnome-vfs-list

Reply via email to