Package: proftpd Version: 1.3.1-17 Severity: normal Tags: patch This bug has been fixed upstream, please include the patch from bug #3150 ( http://bugs.proftpd.org/show_bug.cgi?id=3150 ) in the next release.
>From the original bug report: If an ACL for a directory or file does not include a mask entry, retrieval and checking of the mask fails and mod_facl denies access. Other file utilities ( and the POSIX ACL specs ) seem to assume mask::rwx if no entry is present. This acl: --snip-- fs:/home/proftpd/Info# getfacl Humour # file: Humour # owner: root # group: Users user::rwx group::rwx other::--- --snip-- should grant full access to the group Users, but doesn't. Regards, Tobias -- System Information: Debian Release: 4.0 APT prefers stable APT policy: (150, 'stable'), (100, 'testing'), (50, 'unstable') Architecture: i386 (i686) Shell: /bin/sh linked to /bin/bash Kernel: Linux 2.6.25.4 Locale: LANG=en_GB.UTF8, LC_CTYPE=en_GB.UTF8 (charmap=UTF-8)
Index: modules/mod_facl.c =================================================================== RCS file: /cvsroot/proftp/proftpd/modules/mod_facl.c,v retrieving revision 1.11 diff -u -r1.11 mod_facl.c --- modules/mod_facl.c 18 Jul 2007 16:41:47 -0000 1.11 +++ modules/mod_facl.c 16 Dec 2008 19:07:11 -0000 @@ -354,7 +354,7 @@ } } - /* 5. If not matched above, and if one of the group IDs matches one + /* 4. If not matched above, and if one of the group IDs matches one * of the named group entries, and that entry contains the requested * permissions, use that entry for access. */ @@ -441,7 +441,7 @@ } } - /* 6. If not matched above, and if one of the group IDs matches + /* 5. If not matched above, and if one of the group IDs matches * the group owner or any of the named group entries, but neither * the group owner entry nor any of the named group entries contains * the requested permissions, access is denied. @@ -449,7 +449,7 @@ /* XXX implement this condition properly */ - /* 7. If not matched above, the other entry determines access. + /* 6. If not matched above, the other entry determines access. */ if (!have_access_entry) { ae = acl_other_entry; @@ -465,7 +465,8 @@ * entry contains the requested permissions, access is permitted. * * Otherwise, if the selected entry and the mask entry both contain - * the requested permissions, access is permitted. + * the requested permissions (or there is no mask entry), access is + * permitted. * * Otherwise, access is denied. */ @@ -506,19 +507,29 @@ strerror(errno)); } - if (acl_get_permset(acl_mask_entry, &mask_perms) < 0) { - pr_trace_msg(trace_channel, 5, - "error retrieving mask permission set: %s", strerror(errno)); - } - # if defined(HAVE_BSD_POSIX_ACL) ret1 = acl_get_perm_np(ent_perms, get_facl_perm_for_mode(mode)); - ret2 = acl_get_perm_np(mask_perms, get_facl_perm_for_mode(mode)); # elif defined(HAVE_LINUX_POSIX_ACL) ret1 = acl_get_perm(ent_perms, get_facl_perm_for_mode(mode)); - ret2 = acl_get_perm(mask_perms, get_facl_perm_for_mode(mode)); # endif + if (acl_mask_entry != NULL) { + if (acl_get_permset(acl_mask_entry, &mask_perms) < 0) { + pr_trace_msg(trace_channel, 5, + "error retrieving mask permission set: %s", strerror(errno)); + } + +# if defined(HAVE_BSD_POSIX_ACL) + ret2 = acl_get_perm_np(mask_perms, get_facl_perm_for_mode(mode)); +# elif defined(HAVE_LINUX_POSIX_ACL) + ret2 = acl_get_perm(mask_perms, get_facl_perm_for_mode(mode)); +# endif + + } else { + /* If there is no mask entry, then access should be granted. */ + ret2 = 1; + } + if (ret1 == 1 && ret2 == 1) { res = 0; @@ -553,7 +564,7 @@ # elif defined(HAVE_SOLARIS_POSIX_ACL) register unsigned int i; - int have_access_entry = FALSE, idx, res = -1; + int have_access_entry = FALSE, have_mask_entry = FALSE, idx, res = -1; pool *acl_pool; aclent_t *acls = acl; aclent_t ae; @@ -652,6 +663,7 @@ } else if (acls[i].a_type & CLASS_OBJ) { memcpy(&acl_mask_entry, &(acls[i]), sizeof(aclent_t)); + have_mask_entry = TRUE; } } @@ -738,7 +750,7 @@ } } - /* 5. If not matched above, and if one of the group IDs matches one + /* 4. If not matched above, and if one of the group IDs matches one * of the named group entries, and that entry contains the requested * permissions, use that entry for access. */ @@ -790,7 +802,7 @@ } } - /* 6. If not matched above, and if one of the group IDs matches + /* 5. If not matched above, and if one of the group IDs matches * the group owner or any of the named group entries, but neither * the group owner entry nor any of the named group entries contains * the requested permissions, access is denied. @@ -798,7 +810,7 @@ /* XXX implement this condition properly */ - /* 7. If not matched above, the other entry determines access. + /* 6. If not matched above, the other entry determines access. */ if (!have_access_entry) { memcpy(&ae, &acl_other_entry, sizeof(aclent_t)); @@ -814,7 +826,8 @@ * entry contains the requested permissions, access is permitted. * * Otherwise, if the selected entry and the mask entry both contain - * the requested permissions, access is permitted. + * the requested permissions (or there is no mask entry), access is + * permitted. * * Otherwise, access is denied. */ @@ -826,9 +839,18 @@ break; default: - if ((ae.a_perm & mode) && - (acl_mask_entry.a_perm & mode)) - res = 0; + if (have_mask_entry) { + if ((ae.a_perm & mode) && + (acl_mask_entry.a_perm & mode)) + res = 0; + + } else { + + /* If there is no mask entry, then access should be granted. */ + if (ae.a_perm & mode) + res = 0; + } + break; }