ACL to permissions patch
- From: Alvaro Lopez Ortega <alvaro sun com>
- To: "gnome-vfs-list gnome org" <gnome-vfs-list gnome org>
- Subject: ACL to permissions patch
- Date: Wed, 13 Dec 2006 14:39:08 +0000
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 <alvaro sun com>
+
+ * 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 <chris gnome-de org>
* 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;
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]